]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/String.c
Remove incorrect assertion. According to spec, it should not assert and should return 0.
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
CommitLineData
e1f414b6 1/** @file\r
2 Unicode and ASCII string primatives.\r
3\r
24dcb5e5 4 Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
e1f414b6 5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
e1f414b6 13**/\r
14\r
e1f414b6 15#include "BaseLibInternals.h"\r
16\r
24dcb5e5 17#define QUOTIENT_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 / 10)\r
18#define REMAINDER_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 % 10)\r
19\r
20#define QUOTIENT_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 / 16)\r
21#define REMAINDER_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 % 16)\r
22\r
23#define QUOTIENT_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 / 10)\r
24#define REMAINDER_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 % 10)\r
25\r
26#define QUOTIENT_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 / 16)\r
27#define REMAINDER_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 % 16)\r
28\r
e1f414b6 29/**\r
30 Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
31 string and returns the new Unicode string.\r
32\r
33 This function copies the contents of the Unicode string Source to the Unicode\r
34 string Destination, and returns Destination. If Source and Destination\r
35 overlap, then the results are undefined.\r
36\r
37 If Destination is NULL, then ASSERT().\r
38 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
39 If Source is NULL, then ASSERT().\r
40 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
41 If Source and Destination overlap, then ASSERT().\r
42 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
9aa049d9 43 PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 44 Null-terminator, then ASSERT().\r
45\r
46 @param Destination Pointer to a Null-terminated Unicode string.\r
47 @param Source Pointer to a Null-terminated Unicode string.\r
48\r
9aa049d9 49 @return Destination.\r
e1f414b6 50\r
51**/\r
52CHAR16 *\r
53EFIAPI\r
54StrCpy (\r
55 OUT CHAR16 *Destination,\r
56 IN CONST CHAR16 *Source\r
57 )\r
58{\r
59 CHAR16 *ReturnValue;\r
60\r
61 //\r
62 // Destination cannot be NULL\r
63 //\r
64 ASSERT (Destination != NULL);\r
24dcb5e5 65 ASSERT (((UINTN) Destination & BIT0) == 0);\r
e1f414b6 66\r
67 //\r
68 // Destination and source cannot overlap\r
69 //\r
70 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
71 ASSERT ((UINTN)(Source - Destination) > StrLen (Source));\r
72\r
73 ReturnValue = Destination;\r
42eedea9 74 while (*Source != 0) {\r
e1f414b6 75 *(Destination++) = *(Source++);\r
76 }\r
77 *Destination = 0;\r
78 return ReturnValue;\r
79}\r
80\r
81/**\r
9aa049d9 82 Copies up to a specified length from one Null-terminated Unicode string to \r
83 another Null-terminated Unicode string and returns the new Unicode string.\r
e1f414b6 84\r
85 This function copies the contents of the Unicode string Source to the Unicode\r
86 string Destination, and returns Destination. At most, Length Unicode\r
87 characters are copied from Source to Destination. If Length is 0, then\r
88 Destination is returned unmodified. If Length is greater that the number of\r
89 Unicode characters in Source, then Destination is padded with Null Unicode\r
90 characters. If Source and Destination overlap, then the results are\r
91 undefined.\r
92\r
93 If Length > 0 and Destination is NULL, then ASSERT().\r
94 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
95 If Length > 0 and Source is NULL, then ASSERT().\r
77f863ee 96 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 97 If Source and Destination overlap, then ASSERT().\r
98 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
9aa049d9 99 PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 100 Null-terminator, then ASSERT().\r
101\r
102 @param Destination Pointer to a Null-terminated Unicode string.\r
103 @param Source Pointer to a Null-terminated Unicode string.\r
104 @param Length Maximum number of Unicode characters to copy.\r
105\r
9aa049d9 106 @return Destination.\r
e1f414b6 107\r
108**/\r
109CHAR16 *\r
110EFIAPI\r
111StrnCpy (\r
112 OUT CHAR16 *Destination,\r
113 IN CONST CHAR16 *Source,\r
114 IN UINTN Length\r
115 )\r
116{\r
117 CHAR16 *ReturnValue;\r
118\r
119 if (Length == 0) {\r
120 return Destination;\r
121 }\r
122\r
123 //\r
124 // Destination cannot be NULL if Length is not zero\r
125 //\r
126 ASSERT (Destination != NULL);\r
24dcb5e5 127 ASSERT (((UINTN) Destination & BIT0) == 0);\r
e1f414b6 128\r
129 //\r
130 // Destination and source cannot overlap\r
e1f414b6 131 //\r
132 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
133 ASSERT ((UINTN)(Source - Destination) >= Length);\r
134\r
135 ReturnValue = Destination;\r
136\r
137 while ((*Source != L'\0') && (Length > 0)) {\r
138 *(Destination++) = *(Source++);\r
139 Length--;\r
140 }\r
141\r
142 ZeroMem (Destination, Length * sizeof (*Destination));\r
143 return ReturnValue;\r
144}\r
145\r
146/**\r
147 Returns the length of a Null-terminated Unicode string.\r
148\r
149 This function returns the number of Unicode characters in the Null-terminated\r
150 Unicode string specified by String.\r
151\r
152 If String is NULL, then ASSERT().\r
153 If String is not aligned on a 16-bit boundary, then ASSERT().\r
154 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
9aa049d9 155 PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 156 Null-terminator, then ASSERT().\r
157\r
158 @param String Pointer to a Null-terminated Unicode string.\r
159\r
160 @return The length of String.\r
161\r
162**/\r
163UINTN\r
164EFIAPI\r
165StrLen (\r
166 IN CONST CHAR16 *String\r
167 )\r
168{\r
169 UINTN Length;\r
170\r
171 ASSERT (String != NULL);\r
24dcb5e5 172 ASSERT (((UINTN) String & BIT0) == 0);\r
e1f414b6 173\r
174 for (Length = 0; *String != L'\0'; String++, Length++) {\r
175 //\r
176 // If PcdMaximumUnicodeStringLength is not zero,\r
177 // length should not more than PcdMaximumUnicodeStringLength\r
178 //\r
179 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
180 ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));\r
181 }\r
182 }\r
183 return Length;\r
184}\r
185\r
186/**\r
187 Returns the size of a Null-terminated Unicode string in bytes, including the\r
188 Null terminator.\r
189\r
9aa049d9 190 This function returns the size, in bytes, of the Null-terminated Unicode string \r
191 specified by String.\r
e1f414b6 192\r
193 If String is NULL, then ASSERT().\r
194 If String is not aligned on a 16-bit boundary, then ASSERT().\r
195 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
9aa049d9 196 PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 197 Null-terminator, then ASSERT().\r
198\r
199 @param String Pointer to a Null-terminated Unicode string.\r
200\r
9aa049d9 201 @return The size of String.\r
e1f414b6 202\r
203**/\r
204UINTN\r
205EFIAPI\r
206StrSize (\r
207 IN CONST CHAR16 *String\r
208 )\r
209{\r
210 return (StrLen (String) + 1) * sizeof (*String);\r
211}\r
212\r
213/**\r
214 Compares two Null-terminated Unicode strings, and returns the difference\r
215 between the first mismatched Unicode characters.\r
216\r
217 This function compares the Null-terminated Unicode string FirstString to the\r
218 Null-terminated Unicode string SecondString. If FirstString is identical to\r
219 SecondString, then 0 is returned. Otherwise, the value returned is the first\r
220 mismatched Unicode character in SecondString subtracted from the first\r
221 mismatched Unicode character in FirstString.\r
222\r
223 If FirstString is NULL, then ASSERT().\r
224 If FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
225 If SecondString is NULL, then ASSERT().\r
226 If SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
227 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
9aa049d9 228 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 229 Null-terminator, then ASSERT().\r
230 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
9aa049d9 231 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
e1f414b6 232 Null-terminator, then ASSERT().\r
233\r
234 @param FirstString Pointer to a Null-terminated Unicode string.\r
235 @param SecondString Pointer to a Null-terminated Unicode string.\r
236\r
1106ffe1 237 @retval 0 FirstString is identical to SecondString.\r
9aa049d9 238 @return others FirstString is not identical to SecondString.\r
e1f414b6 239\r
240**/\r
241INTN\r
242EFIAPI\r
243StrCmp (\r
244 IN CONST CHAR16 *FirstString,\r
245 IN CONST CHAR16 *SecondString\r
246 )\r
247{\r
248 //\r
249 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength\r
250 //\r
251 ASSERT (StrSize (FirstString) != 0);\r
252 ASSERT (StrSize (SecondString) != 0);\r
253\r
254 while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
255 FirstString++;\r
256 SecondString++;\r
257 }\r
258 return *FirstString - *SecondString;\r
259}\r
260\r
261/**\r
9aa049d9 262 Compares up to a specified length the contents of two Null-terminated Unicode strings,\r
263 and returns the difference between the first mismatched Unicode characters.\r
2fc60b70 264 \r
e1f414b6 265 This function compares the Null-terminated Unicode string FirstString to the\r
266 Null-terminated Unicode string SecondString. At most, Length Unicode\r
267 characters will be compared. If Length is 0, then 0 is returned. If\r
268 FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
269 value returned is the first mismatched Unicode character in SecondString\r
270 subtracted from the first mismatched Unicode character in FirstString.\r
271\r
272 If Length > 0 and FirstString is NULL, then ASSERT().\r
77f863ee 273 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 274 If Length > 0 and SecondString is NULL, then ASSERT().\r
77f863ee 275 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 276 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
277 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
278 Null-terminator, then ASSERT().\r
279 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
280 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
281 Null-terminator, then ASSERT().\r
282\r
283 @param FirstString Pointer to a Null-terminated Unicode string.\r
284 @param SecondString Pointer to a Null-terminated Unicode string.\r
285 @param Length Maximum number of Unicode characters to compare.\r
286\r
1106ffe1 287 @retval 0 FirstString is identical to SecondString.\r
9aa049d9 288 @return others FirstString is not identical to SecondString.\r
e1f414b6 289\r
290**/\r
291INTN\r
292EFIAPI\r
293StrnCmp (\r
294 IN CONST CHAR16 *FirstString,\r
295 IN CONST CHAR16 *SecondString,\r
296 IN UINTN Length\r
297 )\r
298{\r
2bfb6009 299 if (Length == 0) {\r
e1f414b6 300 return 0;\r
301 }\r
302\r
303 //\r
304 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
305 // Length tests are performed inside StrLen().\r
306 //\r
307 ASSERT (StrSize (FirstString) != 0);\r
308 ASSERT (StrSize (SecondString) != 0);\r
309\r
310 while ((*FirstString != L'\0') &&\r
311 (*FirstString == *SecondString) &&\r
312 (Length > 1)) {\r
313 FirstString++;\r
314 SecondString++;\r
315 Length--;\r
316 }\r
317\r
318 return *FirstString - *SecondString;\r
319}\r
320\r
321/**\r
322 Concatenates one Null-terminated Unicode string to another Null-terminated\r
323 Unicode string, and returns the concatenated Unicode string.\r
324\r
325 This function concatenates two Null-terminated Unicode strings. The contents\r
326 of Null-terminated Unicode string Source are concatenated to the end of\r
327 Null-terminated Unicode string Destination. The Null-terminated concatenated\r
328 Unicode String is returned. If Source and Destination overlap, then the\r
329 results are undefined.\r
330\r
331 If Destination is NULL, then ASSERT().\r
77f863ee 332 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 333 If Source is NULL, then ASSERT().\r
77f863ee 334 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
e1f414b6 335 If Source and Destination overlap, then ASSERT().\r
336 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
337 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
338 Null-terminator, then ASSERT().\r
339 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
340 PcdMaximumUnicodeStringLength Unicode characters not including the\r
341 Null-terminator, then ASSERT().\r
342 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
343 and Source results in a Unicode string with more than\r
344 PcdMaximumUnicodeStringLength Unicode characters not including the\r
345 Null-terminator, then ASSERT().\r
346\r
347 @param Destination Pointer to a Null-terminated Unicode string.\r
348 @param Source Pointer to a Null-terminated Unicode string.\r
349\r
9aa049d9 350 @return Destination.\r
e1f414b6 351\r
352**/\r
353CHAR16 *\r
354EFIAPI\r
355StrCat (\r
356 IN OUT CHAR16 *Destination,\r
357 IN CONST CHAR16 *Source\r
358 )\r
359{\r
360 StrCpy (Destination + StrLen (Destination), Source);\r
361\r
362 //\r
363 // Size of the resulting string should never be zero.\r
364 // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
365 //\r
366 ASSERT (StrSize (Destination) != 0);\r
367 return Destination;\r
368}\r
369\r
370/**\r
9aa049d9 371 Concatenates up to a specified length one Null-terminated Unicode to the end \r
372 of another Null-terminated Unicode string, and returns the concatenated \r
e1f414b6 373 Unicode string.\r
374\r
375 This function concatenates two Null-terminated Unicode strings. The contents\r
376 of Null-terminated Unicode string Source are concatenated to the end of\r
377 Null-terminated Unicode string Destination, and Destination is returned. At\r
378 most, Length Unicode characters are concatenated from Source to the end of\r
379 Destination, and Destination is always Null-terminated. If Length is 0, then\r
380 Destination is returned unmodified. If Source and Destination overlap, then\r
381 the results are undefined.\r
382\r
383 If Destination is NULL, then ASSERT().\r
384 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
385 If Length > 0 and Source is NULL, then ASSERT().\r
386 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
387 If Source and Destination overlap, then ASSERT().\r
388 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
389 than PcdMaximumUnicodeStringLength Unicode characters not including the\r
390 Null-terminator, then ASSERT().\r
391 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
392 PcdMaximumUnicodeStringLength Unicode characters not including the\r
393 Null-terminator, then ASSERT().\r
394 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
395 and Source results in a Unicode string with more than\r
396 PcdMaximumUnicodeStringLength Unicode characters not including the\r
397 Null-terminator, then ASSERT().\r
398\r
399 @param Destination Pointer to a Null-terminated Unicode string.\r
400 @param Source Pointer to a Null-terminated Unicode string.\r
401 @param Length Maximum number of Unicode characters to concatenate from\r
402 Source.\r
403\r
9aa049d9 404 @return Destination.\r
e1f414b6 405\r
406**/\r
407CHAR16 *\r
408EFIAPI\r
409StrnCat (\r
410 IN OUT CHAR16 *Destination,\r
411 IN CONST CHAR16 *Source,\r
412 IN UINTN Length\r
413 )\r
414{\r
415 StrnCpy (Destination + StrLen (Destination), Source, Length);\r
416\r
417 //\r
418 // Size of the resulting string should never be zero.\r
419 // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
420 //\r
421 ASSERT (StrSize (Destination) != 0);\r
422 return Destination;\r
423}\r
424\r
425/**\r
9aa049d9 426 Returns the first occurrence of a Null-terminated Unicode sub-string\r
e1f414b6 427 in a Null-terminated Unicode string.\r
428\r
9aa049d9 429 This function scans the contents of the Null-terminated Unicode string\r
430 specified by String and returns the first occurrence of SearchString.\r
431 If SearchString is not found in String, then NULL is returned. If\r
432 the length of SearchString is zero, then String is\r
e1f414b6 433 returned.\r
9aa049d9 434\r
e1f414b6 435 If String is NULL, then ASSERT().\r
436 If String is not aligned on a 16-bit boundary, then ASSERT().\r
437 If SearchString is NULL, then ASSERT().\r
438 If SearchString is not aligned on a 16-bit boundary, then ASSERT().\r
439\r
9aa049d9 440 If PcdMaximumUnicodeStringLength is not zero, and SearchString\r
441 or String contains more than PcdMaximumUnicodeStringLength Unicode\r
e1f414b6 442 characters not including the Null-terminator, then ASSERT().\r
443\r
9aa049d9 444 @param String Pointer to a Null-terminated Unicode string.\r
445 @param SearchString Pointer to a Null-terminated Unicode string to search for.\r
e1f414b6 446\r
9aa049d9 447 @retval NULL If the SearchString does not appear in String.\r
448 @return others If there is a match.\r
e1f414b6 449\r
450**/\r
451CHAR16 *\r
452EFIAPI\r
453StrStr (\r
2fc60b70 454 IN CONST CHAR16 *String,\r
455 IN CONST CHAR16 *SearchString\r
e1f414b6 456 )\r
457{\r
458 CONST CHAR16 *FirstMatch;\r
459 CONST CHAR16 *SearchStringTmp;\r
460\r
e1f414b6 461 //\r
4df26661 462 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
463 // Length tests are performed inside StrLen().\r
e1f414b6 464 //\r
4df26661 465 ASSERT (StrSize (String) != 0);\r
466 ASSERT (StrSize (SearchString) != 0);\r
e1f414b6 467\r
468 while (*String != '\0') {\r
469 SearchStringTmp = SearchString;\r
470 FirstMatch = String;\r
471 \r
472 while ((*String == *SearchStringTmp) \r
473 && (*SearchStringTmp != '\0') \r
474 && (*String != '\0')) {\r
475 String++;\r
476 SearchStringTmp++;\r
477 } \r
478 \r
955c32f2 479 if (*SearchStringTmp == '\0') {\r
e1f414b6 480 return (CHAR16 *) FirstMatch;\r
481 }\r
482\r
483 if (SearchStringTmp == SearchString) {\r
484 //\r
485 // If no character from SearchString match,\r
486 // move the pointer to the String under search\r
487 // by one character.\r
488 //\r
489 String++;\r
490 }\r
491 }\r
492\r
493 return NULL;\r
494}\r
495\r
496/**\r
497 Check if a Unicode character is a decimal character.\r
498\r
499 This internal function checks if a Unicode character is a \r
500 decimal character. The valid decimal character is from\r
501 L'0' to L'9'.\r
502\r
e1f414b6 503 @param Char The character to check against.\r
504\r
505 @retval TRUE If the Char is a decmial character.\r
24dcb5e5 506 @retval FALSE If the Char is not a decmial character.\r
e1f414b6 507\r
508**/\r
e1f414b6 509BOOLEAN\r
42eedea9 510EFIAPI\r
e1f414b6 511InternalIsDecimalDigitCharacter (\r
512 IN CHAR16 Char\r
513 )\r
514{\r
515 return (BOOLEAN) (Char >= L'0' && Char <= L'9');\r
516}\r
517\r
518/**\r
519 Convert a Unicode character to upper case only if \r
520 it maps to a valid small-case ASCII character.\r
521\r
522 This internal function only deal with Unicode character\r
24dcb5e5 523 which maps to a valid small-case ASCII character, i.e.\r
e1f414b6 524 L'a' to L'z'. For other Unicode character, the input character\r
525 is returned directly.\r
526\r
e1f414b6 527 @param Char The character to convert.\r
528\r
529 @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
530 @retval Unchanged Otherwise.\r
531\r
532**/\r
e1f414b6 533CHAR16\r
42eedea9 534EFIAPI\r
e1f414b6 535InternalCharToUpper (\r
536 IN CHAR16 Char\r
537 )\r
538{\r
539 if (Char >= L'a' && Char <= L'z') {\r
540 return (CHAR16) (Char - (L'a' - L'A'));\r
541 }\r
542\r
543 return Char;\r
544}\r
545\r
546/**\r
547 Convert a Unicode character to numerical value.\r
548\r
549 This internal function only deal with Unicode character\r
550 which maps to a valid hexadecimal ASII character, i.e.\r
551 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other \r
552 Unicode character, the value returned does not make sense.\r
553\r
554 @param Char The character to convert.\r
555\r
24dcb5e5 556 @return The numerical value converted.\r
e1f414b6 557\r
558**/\r
e1f414b6 559UINTN\r
42eedea9 560EFIAPI\r
e1f414b6 561InternalHexCharToUintn (\r
562 IN CHAR16 Char\r
563 )\r
564{\r
565 if (InternalIsDecimalDigitCharacter (Char)) {\r
566 return Char - L'0';\r
567 }\r
568\r
569 return (UINTN) (10 + InternalCharToUpper (Char) - L'A');\r
570}\r
571\r
572/**\r
573 Check if a Unicode character is a hexadecimal character.\r
574\r
575 This internal function checks if a Unicode character is a \r
576 decimal character. The valid hexadecimal character is \r
577 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
578\r
579\r
580 @param Char The character to check against.\r
581\r
582 @retval TRUE If the Char is a hexadecmial character.\r
24dcb5e5 583 @retval FALSE If the Char is not a hexadecmial character.\r
e1f414b6 584\r
585**/\r
e1f414b6 586BOOLEAN\r
42eedea9 587EFIAPI\r
e1f414b6 588InternalIsHexaDecimalDigitCharacter (\r
589 IN CHAR16 Char\r
590 )\r
591{\r
592\r
593 return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||\r
594 (Char >= L'A' && Char <= L'F') ||\r
595 (Char >= L'a' && Char <= L'f'));\r
596}\r
597\r
598/**\r
9aa049d9 599 Convert a Null-terminated Unicode decimal string to a value of\r
e1f414b6 600 type UINTN.\r
601\r
9aa049d9 602 This function returns a value of type UINTN by interpreting the contents\r
603 of the Unicode string specified by String as a decimal number. The format\r
e1f414b6 604 of the input Unicode string String is:\r
9aa049d9 605\r
2fe241a2 606 [spaces] [decimal digits].\r
9aa049d9 607\r
608 The valid decimal digit character is in the range [0-9]. The\r
609 function will ignore the pad space, which includes spaces or\r
610 tab characters, before [decimal digits]. The running zero in the\r
611 beginning of [decimal digits] will be ignored. Then, the function\r
612 stops at the first character that is a not a valid decimal character\r
613 or a Null-terminator, whichever one comes first.\r
614\r
e1f414b6 615 If String is NULL, then ASSERT().\r
9aa049d9 616 If String is not aligned in a 16-bit boundary, then ASSERT().\r
e1f414b6 617 If String has only pad spaces, then 0 is returned.\r
9aa049d9 618 If String has no pad spaces or valid decimal digits,\r
e1f414b6 619 then 0 is returned.\r
9aa049d9 620 If the number represented by String overflows according\r
e1f414b6 621 to the range defined by UINTN, then ASSERT().\r
9aa049d9 622\r
623 If PcdMaximumUnicodeStringLength is not zero, and String contains\r
624 more than PcdMaximumUnicodeStringLength Unicode characters not including\r
e1f414b6 625 the Null-terminator, then ASSERT().\r
626\r
9aa049d9 627 @param String Pointer to a Null-terminated Unicode string.\r
e1f414b6 628\r
9aa049d9 629 @retval Value translated from String.\r
e1f414b6 630\r
631**/\r
632UINTN\r
633EFIAPI\r
634StrDecimalToUintn (\r
2fc60b70 635 IN CONST CHAR16 *String\r
e1f414b6 636 )\r
637{\r
638 UINTN Result;\r
639 \r
4df26661 640 //\r
641 // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
642 // Length tests are performed inside StrLen().\r
643 //\r
644 ASSERT (StrSize (String) != 0);\r
e1f414b6 645\r
646 //\r
647 // Ignore the pad spaces (space or tab)\r
648 //\r
955c32f2 649 while ((*String == L' ') || (*String == L'\t')) {\r
e1f414b6 650 String++;\r
651 }\r
652\r
653 //\r
654 // Ignore leading Zeros after the spaces\r
655 //\r
955c32f2 656 while (*String == L'0') {\r
e1f414b6 657 String++;\r
658 }\r
659\r
660 Result = 0;\r
661\r
662 while (InternalIsDecimalDigitCharacter (*String)) {\r
663 //\r
664 // If the number represented by String overflows according \r
665 // to the range defined by UINTN, then ASSERT().\r
666 //\r
24dcb5e5 667 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) ||\r
955c32f2 668 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) &&\r
24dcb5e5 669 (*String - L'0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10)\r
e1f414b6 670 );\r
671\r
672 Result = Result * 10 + (*String - L'0');\r
673 String++;\r
674 }\r
675 \r
676 return Result;\r
677}\r
678\r
679\r
680/**\r
9aa049d9 681 Convert a Null-terminated Unicode decimal string to a value of\r
e1f414b6 682 type UINT64.\r
683\r
9aa049d9 684 This function returns a value of type UINT64 by interpreting the contents\r
685 of the Unicode string specified by String as a decimal number. The format\r
e1f414b6 686 of the input Unicode string String is:\r
9aa049d9 687\r
2fe241a2 688 [spaces] [decimal digits].\r
9aa049d9 689\r
690 The valid decimal digit character is in the range [0-9]. The\r
691 function will ignore the pad space, which includes spaces or\r
692 tab characters, before [decimal digits]. The running zero in the\r
693 beginning of [decimal digits] will be ignored. Then, the function\r
694 stops at the first character that is a not a valid decimal character\r
695 or a Null-terminator, whichever one comes first.\r
696\r
e1f414b6 697 If String is NULL, then ASSERT().\r
9aa049d9 698 If String is not aligned in a 16-bit boundary, then ASSERT().\r
e1f414b6 699 If String has only pad spaces, then 0 is returned.\r
9aa049d9 700 If String has no pad spaces or valid decimal digits,\r
e1f414b6 701 then 0 is returned.\r
9aa049d9 702 If the number represented by String overflows according\r
e1f414b6 703 to the range defined by UINT64, then ASSERT().\r
9aa049d9 704\r
705 If PcdMaximumUnicodeStringLength is not zero, and String contains\r
706 more than PcdMaximumUnicodeStringLength Unicode characters not including\r
e1f414b6 707 the Null-terminator, then ASSERT().\r
708\r
9aa049d9 709 @param String Pointer to a Null-terminated Unicode string.\r
e1f414b6 710\r
9aa049d9 711 @retval Value translated from String.\r
e1f414b6 712\r
713**/\r
714UINT64\r
715EFIAPI\r
716StrDecimalToUint64 (\r
2fc60b70 717 IN CONST CHAR16 *String\r
e1f414b6 718 )\r
719{\r
720 UINT64 Result;\r
721 \r
4df26661 722 //\r
723 // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
724 // Length tests are performed inside StrLen().\r
725 //\r
726 ASSERT (StrSize (String) != 0);\r
e1f414b6 727\r
728 //\r
729 // Ignore the pad spaces (space or tab)\r
730 //\r
955c32f2 731 while ((*String == L' ') || (*String == L'\t')) {\r
e1f414b6 732 String++;\r
733 }\r
734\r
735 //\r
736 // Ignore leading Zeros after the spaces\r
737 //\r
955c32f2 738 while (*String == L'0') {\r
e1f414b6 739 String++;\r
740 }\r
741\r
742 Result = 0;\r
743\r
744 while (InternalIsDecimalDigitCharacter (*String)) {\r
745 //\r
746 // If the number represented by String overflows according \r
747 // to the range defined by UINTN, then ASSERT().\r
748 //\r
24dcb5e5 749 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) || \r
955c32f2 750 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) && \r
24dcb5e5 751 (*String - L'0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10)\r
e1f414b6 752 );\r
753\r
754 Result = MultU64x32 (Result, 10) + (*String - L'0');\r
755 String++;\r
756 }\r
757 \r
758 return Result;\r
759}\r
760\r
761/**\r
762 Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.\r
763\r
9aa049d9 764 This function returns a value of type UINTN by interpreting the contents\r
765 of the Unicode string specified by String as a hexadecimal number.\r
e1f414b6 766 The format of the input Unicode string String is:\r
9aa049d9 767\r
768 [spaces][zeros][x][hexadecimal digits].\r
769\r
770 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
771 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
772 If "x" appears in the input string, it must be prefixed with at least one 0.\r
773 The function will ignore the pad space, which includes spaces or tab characters,\r
774 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
775 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
776 first valid hexadecimal digit. Then, the function stops at the first character that is\r
e1f414b6 777 a not a valid hexadecimal character or NULL, whichever one comes first.\r
778\r
779 If String is NULL, then ASSERT().\r
780 If String is not aligned in a 16-bit boundary, then ASSERT().\r
781 If String has only pad spaces, then zero is returned.\r
9aa049d9 782 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
e1f414b6 783 then zero is returned.\r
9aa049d9 784 If the number represented by String overflows according to the range defined by\r
e1f414b6 785 UINTN, then ASSERT().\r
786\r
9aa049d9 787 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
788 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,\r
e1f414b6 789 then ASSERT().\r
790\r
9aa049d9 791 @param String Pointer to a Null-terminated Unicode string.\r
e1f414b6 792\r
9aa049d9 793 @retval Value translated from String.\r
e1f414b6 794\r
795**/\r
796UINTN\r
797EFIAPI\r
798StrHexToUintn (\r
2fc60b70 799 IN CONST CHAR16 *String\r
e1f414b6 800 )\r
801{\r
802 UINTN Result;\r
803\r
4df26661 804 //\r
805 // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
806 // Length tests are performed inside StrLen().\r
807 //\r
808 ASSERT (StrSize (String) != 0);\r
e1f414b6 809 \r
810 //\r
811 // Ignore the pad spaces (space or tab) \r
812 //\r
955c32f2 813 while ((*String == L' ') || (*String == L'\t')) {\r
e1f414b6 814 String++;\r
815 }\r
816\r
817 //\r
818 // Ignore leading Zeros after the spaces\r
819 //\r
955c32f2 820 while (*String == L'0') {\r
e1f414b6 821 String++;\r
822 }\r
823\r
824 if (InternalCharToUpper (*String) == L'X') {\r
955c32f2 825 if (*(String - 1) != L'0') {\r
e1f414b6 826 return 0;\r
827 }\r
828 //\r
829 // Skip the 'X'\r
830 //\r
831 String++;\r
832 }\r
833\r
834 Result = 0;\r
835 \r
836 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
837 //\r
838 // If the Hex Number represented by String overflows according \r
839 // to the range defined by UINTN, then ASSERT().\r
840 //\r
24dcb5e5 841 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) ||\r
955c32f2 842 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) && \r
24dcb5e5 843 (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16))\r
e1f414b6 844 );\r
845\r
846 Result = (Result << 4) + InternalHexCharToUintn (*String);\r
847 String++;\r
848 }\r
849\r
850 return Result;\r
851}\r
852\r
853\r
854/**\r
855 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
856\r
9aa049d9 857 This function returns a value of type UINT64 by interpreting the contents\r
858 of the Unicode string specified by String as a hexadecimal number.\r
859 The format of the input Unicode string String is\r
860\r
861 [spaces][zeros][x][hexadecimal digits].\r
862\r
863 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
864 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
865 If "x" appears in the input string, it must be prefixed with at least one 0.\r
866 The function will ignore the pad space, which includes spaces or tab characters,\r
867 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
868 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
869 first valid hexadecimal digit. Then, the function stops at the first character that is\r
e1f414b6 870 a not a valid hexadecimal character or NULL, whichever one comes first.\r
871\r
872 If String is NULL, then ASSERT().\r
873 If String is not aligned in a 16-bit boundary, then ASSERT().\r
874 If String has only pad spaces, then zero is returned.\r
9aa049d9 875 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
e1f414b6 876 then zero is returned.\r
9aa049d9 877 If the number represented by String overflows according to the range defined by\r
e1f414b6 878 UINT64, then ASSERT().\r
879\r
9aa049d9 880 If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
881 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,\r
e1f414b6 882 then ASSERT().\r
883\r
9aa049d9 884 @param String Pointer to a Null-terminated Unicode string.\r
e1f414b6 885\r
9aa049d9 886 @retval Value translated from String.\r
e1f414b6 887\r
2fc60b70 888**/\r
e1f414b6 889UINT64\r
890EFIAPI\r
891StrHexToUint64 (\r
2fc60b70 892 IN CONST CHAR16 *String\r
e1f414b6 893 )\r
894{\r
895 UINT64 Result;\r
896\r
4df26661 897 //\r
898 // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
899 // Length tests are performed inside StrLen().\r
900 //\r
901 ASSERT (StrSize (String) != 0);\r
e1f414b6 902 \r
903 //\r
904 // Ignore the pad spaces (space or tab) \r
905 //\r
955c32f2 906 while ((*String == L' ') || (*String == L'\t')) {\r
e1f414b6 907 String++;\r
908 }\r
909\r
910 //\r
911 // Ignore leading Zeros after the spaces\r
912 //\r
955c32f2 913 while (*String == L'0') {\r
e1f414b6 914 String++;\r
915 }\r
916\r
917 if (InternalCharToUpper (*String) == L'X') {\r
955c32f2 918 ASSERT (*(String - 1) == L'0');\r
919 if (*(String - 1) != L'0') {\r
e1f414b6 920 return 0;\r
921 }\r
922 //\r
923 // Skip the 'X'\r
924 //\r
925 String++;\r
926 }\r
927\r
928 Result = 0;\r
929 \r
930 while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
931 //\r
932 // If the Hex Number represented by String overflows according \r
933 // to the range defined by UINTN, then ASSERT().\r
934 //\r
24dcb5e5 935 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16)|| \r
955c32f2 936 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) && \r
24dcb5e5 937 (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16))\r
e1f414b6 938 );\r
939\r
940 Result = LShiftU64 (Result, 4);\r
941 Result = Result + InternalHexCharToUintn (*String);\r
942 String++;\r
943 }\r
944\r
945 return Result;\r
946}\r
947\r
948/**\r
949 Check if a ASCII character is a decimal character.\r
950\r
951 This internal function checks if a Unicode character is a \r
952 decimal character. The valid decimal character is from\r
953 '0' to '9'.\r
954\r
955 @param Char The character to check against.\r
956\r
957 @retval TRUE If the Char is a decmial character.\r
24dcb5e5 958 @retval FALSE If the Char is not a decmial character.\r
e1f414b6 959\r
960**/\r
e1f414b6 961BOOLEAN\r
42eedea9 962EFIAPI\r
e1f414b6 963InternalAsciiIsDecimalDigitCharacter (\r
964 IN CHAR8 Char\r
965 )\r
966{\r
967 return (BOOLEAN) (Char >= '0' && Char <= '9');\r
968}\r
969\r
970/**\r
971 Check if a ASCII character is a hexadecimal character.\r
972\r
973 This internal function checks if a ASCII character is a \r
974 decimal character. The valid hexadecimal character is \r
975 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
976\r
977\r
978 @param Char The character to check against.\r
979\r
980 @retval TRUE If the Char is a hexadecmial character.\r
24dcb5e5 981 @retval FALSE If the Char is not a hexadecmial character.\r
e1f414b6 982\r
983**/\r
e1f414b6 984BOOLEAN\r
42eedea9 985EFIAPI\r
e1f414b6 986InternalAsciiIsHexaDecimalDigitCharacter (\r
987 IN CHAR8 Char\r
988 )\r
989{\r
990\r
991 return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||\r
992 (Char >= 'A' && Char <= 'F') ||\r
993 (Char >= 'a' && Char <= 'f'));\r
994}\r
995\r
996/**\r
9aa049d9 997 Convert a Null-terminated Unicode string to a Null-terminated\r
e1f414b6 998 ASCII string and returns the ASCII string.\r
9aa049d9 999\r
1000 This function converts the content of the Unicode string Source\r
1001 to the ASCII string Destination by copying the lower 8 bits of\r
1002 each Unicode character. It returns Destination.\r
1003\r
1004 If any Unicode characters in Source contain non-zero value in\r
1005 the upper 8 bits, then ASSERT().\r
e1f414b6 1006\r
1007 If Destination is NULL, then ASSERT().\r
1008 If Source is NULL, then ASSERT().\r
1009 If Source is not aligned on a 16-bit boundary, then ASSERT().\r
1010 If Source and Destination overlap, then ASSERT().\r
1011\r
9aa049d9 1012 If PcdMaximumUnicodeStringLength is not zero, and Source contains\r
1013 more than PcdMaximumUnicodeStringLength Unicode characters not including\r
e1f414b6 1014 the Null-terminator, then ASSERT().\r
9aa049d9 1015\r
1016 If PcdMaximumAsciiStringLength is not zero, and Source contains more\r
1017 than PcdMaximumAsciiStringLength Unicode characters not including the\r
e1f414b6 1018 Null-terminator, then ASSERT().\r
1019\r
1020 @param Source Pointer to a Null-terminated Unicode string.\r
1021 @param Destination Pointer to a Null-terminated ASCII string.\r
1022\r
9aa049d9 1023 @return Destination.\r
e1f414b6 1024\r
1025**/\r
1026CHAR8 *\r
1027EFIAPI\r
1028UnicodeStrToAsciiStr (\r
2fc60b70 1029 IN CONST CHAR16 *Source,\r
1030 OUT CHAR8 *Destination\r
e1f414b6 1031 )\r
1032{\r
4df26661 1033 CHAR8 *ReturnValue;\r
1034\r
e1f414b6 1035 ASSERT (Destination != NULL);\r
4df26661 1036\r
1037 //\r
1038 // ASSERT if Source is long than PcdMaximumUnicodeStringLength.\r
1039 // Length tests are performed inside StrLen().\r
1040 //\r
1041 ASSERT (StrSize (Source) != 0);\r
e1f414b6 1042\r
1043 //\r
1044 // Source and Destination should not overlap\r
1045 //\r
1046 ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));\r
1047 ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));\r
1048\r
e1f414b6 1049\r
4df26661 1050 ReturnValue = Destination;\r
e1f414b6 1051 while (*Source != '\0') {\r
1052 //\r
1053 // If any Unicode characters in Source contain \r
1054 // non-zero value in the upper 8 bits, then ASSERT().\r
1055 //\r
1056 ASSERT (*Source < 0x100);\r
1057 *(Destination++) = (CHAR8) *(Source++);\r
1058 }\r
1059\r
1060 *Destination = '\0';\r
4df26661 1061\r
1062 //\r
1063 // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.\r
1064 // Length tests are performed inside AsciiStrLen().\r
1065 //\r
1066 ASSERT (AsciiStrSize (ReturnValue) != 0);\r
1067\r
1068 return ReturnValue;\r
e1f414b6 1069}\r
1070\r
1071\r
1072/**\r
1073 Copies one Null-terminated ASCII string to another Null-terminated ASCII\r
1074 string and returns the new ASCII string.\r
1075\r
1076 This function copies the contents of the ASCII string Source to the ASCII\r
1077 string Destination, and returns Destination. If Source and Destination\r
1078 overlap, then the results are undefined.\r
1079\r
1080 If Destination is NULL, then ASSERT().\r
1081 If Source is NULL, then ASSERT().\r
1082 If Source and Destination overlap, then ASSERT().\r
1083 If PcdMaximumAsciiStringLength is not zero and Source contains more than\r
1084 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1085 then ASSERT().\r
1086\r
1087 @param Destination Pointer to a Null-terminated ASCII string.\r
1088 @param Source Pointer to a Null-terminated ASCII string.\r
1089\r
9aa049d9 1090 @return Destination\r
e1f414b6 1091\r
1092**/\r
1093CHAR8 *\r
1094EFIAPI\r
1095AsciiStrCpy (\r
1096 OUT CHAR8 *Destination,\r
1097 IN CONST CHAR8 *Source\r
1098 )\r
1099{\r
1100 CHAR8 *ReturnValue;\r
1101\r
1102 //\r
1103 // Destination cannot be NULL\r
1104 //\r
1105 ASSERT (Destination != NULL);\r
1106\r
1107 //\r
1108 // Destination and source cannot overlap\r
1109 //\r
1110 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
1111 ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));\r
1112\r
1113 ReturnValue = Destination;\r
42eedea9 1114 while (*Source != 0) {\r
e1f414b6 1115 *(Destination++) = *(Source++);\r
1116 }\r
1117 *Destination = 0;\r
1118 return ReturnValue;\r
1119}\r
1120\r
1121/**\r
9aa049d9 1122 Copies up to a specified length one Null-terminated ASCII string to another \r
1123 Null-terminated ASCII string and returns the new ASCII string.\r
e1f414b6 1124\r
1125 This function copies the contents of the ASCII string Source to the ASCII\r
1126 string Destination, and returns Destination. At most, Length ASCII characters\r
1127 are copied from Source to Destination. If Length is 0, then Destination is\r
1128 returned unmodified. If Length is greater that the number of ASCII characters\r
1129 in Source, then Destination is padded with Null ASCII characters. If Source\r
1130 and Destination overlap, then the results are undefined.\r
1131\r
1132 If Destination is NULL, then ASSERT().\r
1133 If Source is NULL, then ASSERT().\r
1134 If Source and Destination overlap, then ASSERT().\r
1135 If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
1136 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1137 then ASSERT().\r
1138\r
1139 @param Destination Pointer to a Null-terminated ASCII string.\r
1140 @param Source Pointer to a Null-terminated ASCII string.\r
1141 @param Length Maximum number of ASCII characters to copy.\r
1142\r
9aa049d9 1143 @return Destination\r
e1f414b6 1144\r
1145**/\r
1146CHAR8 *\r
1147EFIAPI\r
1148AsciiStrnCpy (\r
1149 OUT CHAR8 *Destination,\r
1150 IN CONST CHAR8 *Source,\r
1151 IN UINTN Length\r
1152 )\r
1153{\r
1154 CHAR8 *ReturnValue;\r
1155\r
2bfb6009 1156 if (Length == 0) {\r
e1f414b6 1157 return Destination;\r
1158 }\r
1159\r
1160 //\r
1161 // Destination cannot be NULL\r
1162 //\r
1163 ASSERT (Destination != NULL);\r
1164\r
1165 //\r
1166 // Destination and source cannot overlap\r
1167 //\r
1168 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
1169 ASSERT ((UINTN)(Source - Destination) >= Length);\r
1170\r
1171 ReturnValue = Destination;\r
1172\r
42eedea9 1173 while (*Source != 0 && Length > 0) {\r
e1f414b6 1174 *(Destination++) = *(Source++);\r
1175 Length--;\r
1176 }\r
1177\r
1178 ZeroMem (Destination, Length * sizeof (*Destination));\r
1179 return ReturnValue;\r
1180}\r
1181\r
1182/**\r
1183 Returns the length of a Null-terminated ASCII string.\r
1184\r
1185 This function returns the number of ASCII characters in the Null-terminated\r
1186 ASCII string specified by String.\r
1187\r
9aa049d9 1188 If Length > 0 and Destination is NULL, then ASSERT().\r
1189 If Length > 0 and Source is NULL, then ASSERT().\r
e1f414b6 1190 If PcdMaximumAsciiStringLength is not zero and String contains more than\r
1191 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1192 then ASSERT().\r
1193\r
1194 @param String Pointer to a Null-terminated ASCII string.\r
1195\r
1196 @return The length of String.\r
1197\r
1198**/\r
1199UINTN\r
1200EFIAPI\r
1201AsciiStrLen (\r
1202 IN CONST CHAR8 *String\r
1203 )\r
1204{\r
1205 UINTN Length;\r
1206\r
1207 ASSERT (String != NULL);\r
1208\r
1209 for (Length = 0; *String != '\0'; String++, Length++) {\r
1210 //\r
1211 // If PcdMaximumUnicodeStringLength is not zero,\r
1212 // length should not more than PcdMaximumUnicodeStringLength\r
1213 //\r
1214 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
1215 ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));\r
1216 }\r
1217 }\r
1218 return Length;\r
1219}\r
1220\r
1221/**\r
1222 Returns the size of a Null-terminated ASCII string in bytes, including the\r
1223 Null terminator.\r
1224\r
1225 This function returns the size, in bytes, of the Null-terminated ASCII string\r
1226 specified by String.\r
1227\r
1228 If String is NULL, then ASSERT().\r
1229 If PcdMaximumAsciiStringLength is not zero and String contains more than\r
1230 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1231 then ASSERT().\r
1232\r
1233 @param String Pointer to a Null-terminated ASCII string.\r
1234\r
1235 @return The size of String.\r
1236\r
1237**/\r
1238UINTN\r
1239EFIAPI\r
1240AsciiStrSize (\r
1241 IN CONST CHAR8 *String\r
1242 )\r
1243{\r
1244 return (AsciiStrLen (String) + 1) * sizeof (*String);\r
1245}\r
1246\r
1247/**\r
1248 Compares two Null-terminated ASCII strings, and returns the difference\r
1249 between the first mismatched ASCII characters.\r
1250\r
1251 This function compares the Null-terminated ASCII string FirstString to the\r
1252 Null-terminated ASCII string SecondString. If FirstString is identical to\r
1253 SecondString, then 0 is returned. Otherwise, the value returned is the first\r
1254 mismatched ASCII character in SecondString subtracted from the first\r
1255 mismatched ASCII character in FirstString.\r
1256\r
1257 If FirstString is NULL, then ASSERT().\r
1258 If SecondString is NULL, then ASSERT().\r
1259 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
1260 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1261 then ASSERT().\r
1262 If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
1263 than PcdMaximumAsciiStringLength ASCII characters not including the\r
1264 Null-terminator, then ASSERT().\r
1265\r
1266 @param FirstString Pointer to a Null-terminated ASCII string.\r
1267 @param SecondString Pointer to a Null-terminated ASCII string.\r
1268\r
9aa049d9 1269 @retval ==0 FirstString is identical to SecondString.\r
1270 @retval !=0 FirstString is not identical to SecondString.\r
e1f414b6 1271\r
1272**/\r
1273INTN\r
1274EFIAPI\r
1275AsciiStrCmp (\r
1276 IN CONST CHAR8 *FirstString,\r
1277 IN CONST CHAR8 *SecondString\r
1278 )\r
1279{\r
1280 //\r
1281 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
1282 //\r
1283 ASSERT (AsciiStrSize (FirstString));\r
1284 ASSERT (AsciiStrSize (SecondString));\r
1285\r
1286 while ((*FirstString != '\0') && (*FirstString == *SecondString)) {\r
1287 FirstString++;\r
1288 SecondString++;\r
1289 }\r
1290\r
1291 return *FirstString - *SecondString;\r
1292}\r
1293\r
1294/**\r
24dcb5e5 1295 Converts a lowercase Ascii character to upper one.\r
e1f414b6 1296\r
1297 If Chr is lowercase Ascii character, then converts it to upper one.\r
1298\r
1299 If Value >= 0xA0, then ASSERT().\r
1300 If (Value & 0x0F) >= 0x0A, then ASSERT().\r
1301\r
42eedea9 1302 @param Chr one Ascii character\r
e1f414b6 1303\r
1304 @return The uppercase value of Ascii character \r
1305\r
1306**/\r
e1f414b6 1307CHAR8\r
42eedea9 1308EFIAPI\r
e1f414b6 1309AsciiToUpper (\r
1310 IN CHAR8 Chr\r
1311 )\r
1312{\r
1313 return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);\r
1314}\r
1315\r
1316/**\r
1317 Convert a ASCII character to numerical value.\r
1318\r
1319 This internal function only deal with Unicode character\r
1320 which maps to a valid hexadecimal ASII character, i.e.\r
1321 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other \r
1322 ASCII character, the value returned does not make sense.\r
1323\r
1324 @param Char The character to convert.\r
1325\r
24dcb5e5 1326 @return The numerical value converted.\r
e1f414b6 1327\r
1328**/\r
e1f414b6 1329UINTN\r
42eedea9 1330EFIAPI\r
e1f414b6 1331InternalAsciiHexCharToUintn (\r
1332 IN CHAR8 Char\r
1333 )\r
1334{\r
1335 if (InternalIsDecimalDigitCharacter (Char)) {\r
1336 return Char - '0';\r
1337 }\r
1338\r
1339 return (UINTN) (10 + AsciiToUpper (Char) - 'A');\r
1340}\r
1341\r
1342\r
1343/**\r
1344 Performs a case insensitive comparison of two Null-terminated ASCII strings,\r
1345 and returns the difference between the first mismatched ASCII characters.\r
1346\r
1347 This function performs a case insensitive comparison of the Null-terminated\r
1348 ASCII string FirstString to the Null-terminated ASCII string SecondString. If\r
1349 FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
1350 value returned is the first mismatched lower case ASCII character in\r
1351 SecondString subtracted from the first mismatched lower case ASCII character\r
1352 in FirstString.\r
1353\r
1354 If FirstString is NULL, then ASSERT().\r
1355 If SecondString is NULL, then ASSERT().\r
1356 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
1357 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1358 then ASSERT().\r
1359 If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
1360 than PcdMaximumAsciiStringLength ASCII characters not including the\r
1361 Null-terminator, then ASSERT().\r
1362\r
1363 @param FirstString Pointer to a Null-terminated ASCII string.\r
1364 @param SecondString Pointer to a Null-terminated ASCII string.\r
1365\r
9aa049d9 1366 @retval ==0 FirstString is identical to SecondString using case insensitive\r
1106ffe1 1367 comparisons.\r
9aa049d9 1368 @retval !=0 FirstString is not identical to SecondString using case\r
1369 insensitive comparisons.\r
e1f414b6 1370\r
1371**/\r
1372INTN\r
1373EFIAPI\r
1374AsciiStriCmp (\r
1375 IN CONST CHAR8 *FirstString,\r
1376 IN CONST CHAR8 *SecondString\r
1377 )\r
1378{\r
1379 CHAR8 UpperFirstString;\r
1380 CHAR8 UpperSecondString;\r
1381\r
1382 //\r
1383 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
1384 //\r
1385 ASSERT (AsciiStrSize (FirstString));\r
1386 ASSERT (AsciiStrSize (SecondString));\r
1387\r
1388 UpperFirstString = AsciiToUpper (*FirstString);\r
1389 UpperSecondString = AsciiToUpper (*SecondString);\r
1390 while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
1391 FirstString++;\r
1392 SecondString++;\r
1393 UpperFirstString = AsciiToUpper (*FirstString);\r
1394 UpperSecondString = AsciiToUpper (*SecondString);\r
1395 }\r
1396\r
1397 return UpperFirstString - UpperSecondString;\r
1398}\r
1399\r
1400/**\r
1401 Compares two Null-terminated ASCII strings with maximum lengths, and returns\r
1402 the difference between the first mismatched ASCII characters.\r
1403\r
1404 This function compares the Null-terminated ASCII string FirstString to the\r
1405 Null-terminated ASCII string SecondString. At most, Length ASCII characters\r
1406 will be compared. If Length is 0, then 0 is returned. If FirstString is\r
1407 identical to SecondString, then 0 is returned. Otherwise, the value returned\r
1408 is the first mismatched ASCII character in SecondString subtracted from the\r
1409 first mismatched ASCII character in FirstString.\r
1410\r
9aa049d9 1411 If Length > 0 and FirstString is NULL, then ASSERT().\r
1412 If Length > 0 and SecondString is NULL, then ASSERT().\r
e1f414b6 1413 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
1414 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1415 then ASSERT().\r
1416 If PcdMaximumAsciiStringLength is not zero and SecondString contains more than\r
1417 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1418 then ASSERT().\r
1419\r
1420 @param FirstString Pointer to a Null-terminated ASCII string.\r
1421 @param SecondString Pointer to a Null-terminated ASCII string.\r
9aa049d9 1422 @param Length Maximum number of ASCII characters for compare.\r
2fc60b70 1423 \r
9aa049d9 1424 @retval ==0 FirstString is identical to SecondString.\r
1425 @retval !=0 FirstString is not identical to SecondString.\r
e1f414b6 1426\r
1427**/\r
1428INTN\r
1429EFIAPI\r
1430AsciiStrnCmp (\r
1431 IN CONST CHAR8 *FirstString,\r
1432 IN CONST CHAR8 *SecondString,\r
1433 IN UINTN Length\r
1434 )\r
1435{\r
2bfb6009 1436 if (Length == 0) {\r
e1f414b6 1437 return 0;\r
1438 }\r
1439\r
1440 //\r
1441 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
1442 //\r
1443 ASSERT (AsciiStrSize (FirstString));\r
1444 ASSERT (AsciiStrSize (SecondString));\r
1445\r
1446 while ((*FirstString != '\0') &&\r
1447 (*FirstString == *SecondString) &&\r
1448 (Length > 1)) {\r
1449 FirstString++;\r
1450 SecondString++;\r
1451 Length--;\r
1452 }\r
1453 return *FirstString - *SecondString;\r
1454}\r
1455\r
1456/**\r
1457 Concatenates one Null-terminated ASCII string to another Null-terminated\r
1458 ASCII string, and returns the concatenated ASCII string.\r
1459\r
1460 This function concatenates two Null-terminated ASCII strings. The contents of\r
1461 Null-terminated ASCII string Source are concatenated to the end of Null-\r
1462 terminated ASCII string Destination. The Null-terminated concatenated ASCII\r
1463 String is returned.\r
1464\r
1465 If Destination is NULL, then ASSERT().\r
1466 If Source is NULL, then ASSERT().\r
1467 If PcdMaximumAsciiStringLength is not zero and Destination contains more than\r
1468 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1469 then ASSERT().\r
1470 If PcdMaximumAsciiStringLength is not zero and Source contains more than\r
1471 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1472 then ASSERT().\r
1473 If PcdMaximumAsciiStringLength is not zero and concatenating Destination and\r
1474 Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
1475 ASCII characters, then ASSERT().\r
1476\r
1477 @param Destination Pointer to a Null-terminated ASCII string.\r
1478 @param Source Pointer to a Null-terminated ASCII string.\r
1479\r
9aa049d9 1480 @return Destination\r
e1f414b6 1481\r
1482**/\r
1483CHAR8 *\r
1484EFIAPI\r
1485AsciiStrCat (\r
1486 IN OUT CHAR8 *Destination,\r
1487 IN CONST CHAR8 *Source\r
1488 )\r
1489{\r
1490 AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);\r
1491\r
1492 //\r
1493 // Size of the resulting string should never be zero.\r
1494 // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
1495 //\r
1496 ASSERT (AsciiStrSize (Destination) != 0);\r
1497 return Destination;\r
1498}\r
1499\r
1500/**\r
9aa049d9 1501 Concatenates up to a specified length one Null-terminated ASCII string to \r
1502 the end of another Null-terminated ASCII string, and returns the \r
1503 concatenated ASCII string.\r
e1f414b6 1504\r
1505 This function concatenates two Null-terminated ASCII strings. The contents\r
1506 of Null-terminated ASCII string Source are concatenated to the end of Null-\r
1507 terminated ASCII string Destination, and Destination is returned. At most,\r
1508 Length ASCII characters are concatenated from Source to the end of\r
1509 Destination, and Destination is always Null-terminated. If Length is 0, then\r
1510 Destination is returned unmodified. If Source and Destination overlap, then\r
1511 the results are undefined.\r
1512\r
9aa049d9 1513 If Length > 0 and Destination is NULL, then ASSERT().\r
1514 If Length > 0 and Source is NULL, then ASSERT().\r
e1f414b6 1515 If Source and Destination overlap, then ASSERT().\r
1516 If PcdMaximumAsciiStringLength is not zero, and Destination contains more than\r
1517 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1518 then ASSERT().\r
1519 If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
1520 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
1521 then ASSERT().\r
1522 If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and\r
1523 Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
1524 ASCII characters not including the Null-terminator, then ASSERT().\r
1525\r
1526 @param Destination Pointer to a Null-terminated ASCII string.\r
1527 @param Source Pointer to a Null-terminated ASCII string.\r
1528 @param Length Maximum number of ASCII characters to concatenate from\r
1529 Source.\r
1530\r
9aa049d9 1531 @return Destination\r
e1f414b6 1532\r
1533**/\r
1534CHAR8 *\r
1535EFIAPI\r
1536AsciiStrnCat (\r
1537 IN OUT CHAR8 *Destination,\r
1538 IN CONST CHAR8 *Source,\r
1539 IN UINTN Length\r
1540 )\r
1541{\r
1542 AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);\r
1543\r
1544 //\r
1545 // Size of the resulting string should never be zero.\r
1546 // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
1547 //\r
1548 ASSERT (AsciiStrSize (Destination) != 0);\r
1549 return Destination;\r
1550}\r
1551\r
1552/**\r
9aa049d9 1553 Returns the first occurrence of a Null-terminated ASCII sub-string\r
e1f414b6 1554 in a Null-terminated ASCII string.\r
1555\r
9aa049d9 1556 This function scans the contents of the ASCII string specified by String\r
1557 and returns the first occurrence of SearchString. If SearchString is not\r
1558 found in String, then NULL is returned. If the length of SearchString is zero,\r
e1f414b6 1559 then String is returned.\r
9aa049d9 1560\r
e1f414b6 1561 If String is NULL, then ASSERT().\r
1562 If SearchString is NULL, then ASSERT().\r
1563\r
9aa049d9 1564 If PcdMaximumAsciiStringLength is not zero, and SearchString or\r
1565 String contains more than PcdMaximumAsciiStringLength Unicode characters\r
e1f414b6 1566 not including the Null-terminator, then ASSERT().\r
1567\r
4df26661 1568 @param String Pointer to a Null-terminated ASCII string.\r
1569 @param SearchString Pointer to a Null-terminated ASCII string to search for.\r
e1f414b6 1570\r
1571 @retval NULL If the SearchString does not appear in String.\r
9aa049d9 1572 @retval others If there is a match return the first occurrence of SearchingString.\r
1573 If the length of SearchString is zero,return String.\r
e1f414b6 1574\r
1575**/\r
1576CHAR8 *\r
1577EFIAPI\r
1578AsciiStrStr (\r
2fc60b70 1579 IN CONST CHAR8 *String,\r
1580 IN CONST CHAR8 *SearchString\r
e1f414b6 1581 )\r
1582{\r
1583 CONST CHAR8 *FirstMatch;\r
1584 CONST CHAR8 *SearchStringTmp;\r
1585\r
e1f414b6 1586 //\r
4df26661 1587 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
e1f414b6 1588 //\r
4df26661 1589 ASSERT (AsciiStrSize (String) != 0);\r
1590 ASSERT (AsciiStrSize (SearchString) != 0);\r
e1f414b6 1591\r
1592 while (*String != '\0') {\r
1593 SearchStringTmp = SearchString;\r
1594 FirstMatch = String;\r
1595 \r
1596 while ((*String == *SearchStringTmp) \r
1597 && (*SearchStringTmp != '\0') \r
1598 && (*String != '\0')) {\r
1599 String++;\r
1600 SearchStringTmp++;\r
1601 } \r
1602 \r
1603 if (*SearchStringTmp == '\0') {\r
1604 return (CHAR8 *) FirstMatch;\r
1605 }\r
1606\r
1607 if (SearchStringTmp == SearchString) {\r
1608 //\r
1609 // If no character from SearchString match,\r
1610 // move the pointer to the String under search\r
1611 // by one character.\r
1612 //\r
1613 String++;\r
1614 }\r
1615\r
1616 }\r
1617\r
1618 return NULL;\r
1619}\r
1620\r
1621/**\r
9aa049d9 1622 Convert a Null-terminated ASCII decimal string to a value of type\r
e1f414b6 1623 UINTN.\r
1624\r
9aa049d9 1625 This function returns a value of type UINTN by interpreting the contents\r
1626 of the ASCII string String as a decimal number. The format of the input\r
e1f414b6 1627 ASCII string String is:\r
9aa049d9 1628\r
e1f414b6 1629 [spaces] [decimal digits].\r
9aa049d9 1630\r
1631 The valid decimal digit character is in the range [0-9]. The function will\r
1632 ignore the pad space, which includes spaces or tab characters, before the digits.\r
1633 The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
1634 function stops at the first character that is a not a valid decimal character or\r
e1f414b6 1635 Null-terminator, whichever on comes first.\r
9aa049d9 1636\r
e1f414b6 1637 If String has only pad spaces, then 0 is returned.\r
1638 If String has no pad spaces or valid decimal digits, then 0 is returned.\r
9aa049d9 1639 If the number represented by String overflows according to the range defined by\r
e1f414b6 1640 UINTN, then ASSERT().\r
1641 If String is NULL, then ASSERT().\r
9aa049d9 1642 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1643 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
e1f414b6 1644 then ASSERT().\r
1645\r
9aa049d9 1646 @param String Pointer to a Null-terminated ASCII string.\r
e1f414b6 1647\r
9aa049d9 1648 @retval Value translated from String.\r
e1f414b6 1649\r
1650**/\r
1651UINTN\r
1652EFIAPI\r
1653AsciiStrDecimalToUintn (\r
4df26661 1654 IN CONST CHAR8 *String\r
e1f414b6 1655 )\r
1656{\r
1657 UINTN Result;\r
1658 \r
4df26661 1659 //\r
1660 // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
1661 //\r
1662 ASSERT (AsciiStrSize (String) != 0);\r
e1f414b6 1663\r
1664 //\r
1665 // Ignore the pad spaces (space or tab)\r
1666 //\r
955c32f2 1667 while ((*String == ' ') || (*String == '\t' )) {\r
e1f414b6 1668 String++;\r
1669 }\r
1670\r
1671 //\r
1672 // Ignore leading Zeros after the spaces\r
1673 //\r
955c32f2 1674 while (*String == '0') {\r
e1f414b6 1675 String++;\r
1676 }\r
1677\r
1678 Result = 0;\r
1679\r
1680 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
1681 //\r
1682 // If the number represented by String overflows according \r
1683 // to the range defined by UINTN, then ASSERT().\r
1684 //\r
24dcb5e5 1685 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) ||\r
955c32f2 1686 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) && \r
24dcb5e5 1687 (*String - '0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10)\r
e1f414b6 1688 );\r
1689\r
1690 Result = Result * 10 + (*String - '0');\r
1691 String++;\r
1692 }\r
1693 \r
1694 return Result;\r
1695}\r
1696\r
1697\r
1698/**\r
9aa049d9 1699 Convert a Null-terminated ASCII decimal string to a value of type\r
e1f414b6 1700 UINT64.\r
1701\r
9aa049d9 1702 This function returns a value of type UINT64 by interpreting the contents\r
1703 of the ASCII string String as a decimal number. The format of the input\r
e1f414b6 1704 ASCII string String is:\r
9aa049d9 1705\r
e1f414b6 1706 [spaces] [decimal digits].\r
9aa049d9 1707\r
1708 The valid decimal digit character is in the range [0-9]. The function will\r
1709 ignore the pad space, which includes spaces or tab characters, before the digits.\r
1710 The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
1711 function stops at the first character that is a not a valid decimal character or\r
e1f414b6 1712 Null-terminator, whichever on comes first.\r
9aa049d9 1713\r
e1f414b6 1714 If String has only pad spaces, then 0 is returned.\r
1715 If String has no pad spaces or valid decimal digits, then 0 is returned.\r
9aa049d9 1716 If the number represented by String overflows according to the range defined by\r
e1f414b6 1717 UINT64, then ASSERT().\r
1718 If String is NULL, then ASSERT().\r
9aa049d9 1719 If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
1720 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
e1f414b6 1721 then ASSERT().\r
1722\r
9aa049d9 1723 @param String Pointer to a Null-terminated ASCII string.\r
e1f414b6 1724\r
9aa049d9 1725 @retval Value translated from String.\r
e1f414b6 1726\r
1727**/\r
1728UINT64\r
1729EFIAPI\r
1730AsciiStrDecimalToUint64 (\r
2fc60b70 1731 IN CONST CHAR8 *String\r
e1f414b6 1732 )\r
1733{\r
1734 UINT64 Result;\r
1735 \r
4df26661 1736 //\r
1737 // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
1738 //\r
1739 ASSERT (AsciiStrSize (String) != 0);\r
e1f414b6 1740\r
1741 //\r
1742 // Ignore the pad spaces (space or tab)\r
1743 //\r
955c32f2 1744 while ((*String == ' ') || (*String == '\t' )) {\r
e1f414b6 1745 String++;\r
1746 }\r
1747\r
1748 //\r
1749 // Ignore leading Zeros after the spaces\r
1750 //\r
955c32f2 1751 while (*String == '0') {\r
e1f414b6 1752 String++;\r
1753 }\r
1754\r
1755 Result = 0;\r
1756\r
1757 while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
1758 //\r
1759 // If the number represented by String overflows according \r
1760 // to the range defined by UINTN, then ASSERT().\r
1761 //\r
24dcb5e5 1762 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) || \r
955c32f2 1763 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) && \r
24dcb5e5 1764 (*String - '0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10)\r
e1f414b6 1765 );\r
1766\r
1767 Result = MultU64x32 (Result, 10) + (*String - '0');\r
1768 String++;\r
1769 }\r
1770 \r
1771 return Result;\r
1772}\r
1773\r
1774/**\r
1775 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.\r
1776\r
9aa049d9 1777 This function returns a value of type UINTN by interpreting the contents of\r
1778 the ASCII string String as a hexadecimal number. The format of the input ASCII\r
e1f414b6 1779 string String is:\r
9aa049d9 1780\r
e1f414b6 1781 [spaces][zeros][x][hexadecimal digits].\r
9aa049d9 1782\r
1783 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1784 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
1785 appears in the input string, it must be prefixed with at least one 0. The function\r
1786 will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
1787 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
1788 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
1789 digit. Then, the function stops at the first character that is a not a valid\r
e1f414b6 1790 hexadecimal character or Null-terminator, whichever on comes first.\r
9aa049d9 1791\r
e1f414b6 1792 If String has only pad spaces, then 0 is returned.\r
1793 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
1794 0 is returned.\r
1795\r
9aa049d9 1796 If the number represented by String overflows according to the range defined by UINTN,\r
e1f414b6 1797 then ASSERT().\r
1798 If String is NULL, then ASSERT().\r
9aa049d9 1799 If PcdMaximumAsciiStringLength is not zero,\r
1800 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
e1f414b6 1801 the Null-terminator, then ASSERT().\r
1802\r
9aa049d9 1803 @param String Pointer to a Null-terminated ASCII string.\r
e1f414b6 1804\r
9aa049d9 1805 @retval Value translated from String.\r
e1f414b6 1806\r
1807**/\r
1808UINTN\r
1809EFIAPI\r
1810AsciiStrHexToUintn (\r
2fc60b70 1811 IN CONST CHAR8 *String\r
e1f414b6 1812 )\r
1813{\r
1814 UINTN Result;\r
1815\r
4df26661 1816 //\r
1817 // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
1818 //\r
1819 ASSERT (AsciiStrSize (String) != 0);\r
e1f414b6 1820 \r
1821 //\r
1822 // Ignore the pad spaces (space or tab) \r
1823 //\r
955c32f2 1824 while ((*String == ' ') || (*String == '\t' )) {\r
e1f414b6 1825 String++;\r
1826 }\r
1827\r
1828 //\r
1829 // Ignore leading Zeros after the spaces\r
1830 //\r
955c32f2 1831 while (*String == '0') {\r
e1f414b6 1832 String++;\r
1833 }\r
1834\r
1835 if (AsciiToUpper (*String) == 'X') {\r
955c32f2 1836 ASSERT (*(String - 1) == '0');\r
1837 if (*(String - 1) != '0') {\r
e1f414b6 1838 return 0;\r
1839 }\r
1840 //\r
1841 // Skip the 'X'\r
1842 //\r
1843 String++;\r
1844 }\r
1845\r
1846 Result = 0;\r
1847 \r
1848 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
1849 //\r
1850 // If the Hex Number represented by String overflows according \r
1851 // to the range defined by UINTN, then ASSERT().\r
1852 //\r
24dcb5e5 1853 ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) ||\r
955c32f2 1854 ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) && \r
24dcb5e5 1855 (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16))\r
e1f414b6 1856 );\r
1857\r
1858 Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);\r
1859 String++;\r
1860 }\r
1861\r
1862 return Result;\r
1863}\r
1864\r
1865\r
1866/**\r
1867 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.\r
1868\r
9aa049d9 1869 This function returns a value of type UINT64 by interpreting the contents of\r
1870 the ASCII string String as a hexadecimal number. The format of the input ASCII\r
e1f414b6 1871 string String is:\r
9aa049d9 1872\r
e1f414b6 1873 [spaces][zeros][x][hexadecimal digits].\r
9aa049d9 1874\r
1875 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
1876 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
1877 appears in the input string, it must be prefixed with at least one 0. The function\r
1878 will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
1879 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
1880 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
1881 digit. Then, the function stops at the first character that is a not a valid\r
e1f414b6 1882 hexadecimal character or Null-terminator, whichever on comes first.\r
9aa049d9 1883\r
e1f414b6 1884 If String has only pad spaces, then 0 is returned.\r
1885 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
1886 0 is returned.\r
1887\r
9aa049d9 1888 If the number represented by String overflows according to the range defined by UINT64,\r
e1f414b6 1889 then ASSERT().\r
1890 If String is NULL, then ASSERT().\r
9aa049d9 1891 If PcdMaximumAsciiStringLength is not zero,\r
1892 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
e1f414b6 1893 the Null-terminator, then ASSERT().\r
1894\r
9aa049d9 1895 @param String Pointer to a Null-terminated ASCII string.\r
e1f414b6 1896\r
9aa049d9 1897 @retval Value translated from String.\r
e1f414b6 1898\r
1899**/\r
1900UINT64\r
1901EFIAPI\r
1902AsciiStrHexToUint64 (\r
2fc60b70 1903 IN CONST CHAR8 *String\r
e1f414b6 1904 )\r
1905{\r
1906 UINT64 Result;\r
1907\r
4df26661 1908 //\r
1909 // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
1910 //\r
1911 ASSERT (AsciiStrSize (String) != 0);\r
e1f414b6 1912 \r
1913 //\r
1914 // Ignore the pad spaces (space or tab) and leading Zeros\r
1915 //\r
1916 //\r
1917 // Ignore the pad spaces (space or tab) \r
1918 //\r
955c32f2 1919 while ((*String == ' ') || (*String == '\t' )) {\r
e1f414b6 1920 String++;\r
1921 }\r
1922\r
1923 //\r
1924 // Ignore leading Zeros after the spaces\r
1925 //\r
955c32f2 1926 while (*String == '0') {\r
e1f414b6 1927 String++;\r
1928 }\r
1929\r
1930 if (AsciiToUpper (*String) == 'X') {\r
955c32f2 1931 ASSERT (*(String - 1) == '0');\r
1932 if (*(String - 1) != '0') {\r
e1f414b6 1933 return 0;\r
1934 }\r
1935 //\r
1936 // Skip the 'X'\r
1937 //\r
1938 String++;\r
1939 }\r
1940\r
1941 Result = 0;\r
1942 \r
1943 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
1944 //\r
1945 // If the Hex Number represented by String overflows according \r
1946 // to the range defined by UINTN, then ASSERT().\r
1947 //\r
24dcb5e5 1948 ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16) ||\r
955c32f2 1949 ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) && \r
24dcb5e5 1950 (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16))\r
e1f414b6 1951 );\r
1952\r
1953 Result = LShiftU64 (Result, 4);\r
1954 Result = Result + InternalAsciiHexCharToUintn (*String);\r
1955 String++;\r
1956 }\r
1957\r
1958 return Result;\r
1959}\r
1960\r
1961\r
1962/**\r
9aa049d9 1963 Convert one Null-terminated ASCII string to a Null-terminated\r
e1f414b6 1964 Unicode string and returns the Unicode string.\r
1965\r
9aa049d9 1966 This function converts the contents of the ASCII string Source to the Unicode\r
1967 string Destination, and returns Destination. The function terminates the\r
1968 Unicode string Destination by appending a Null-terminator character at the end.\r
1969 The caller is responsible to make sure Destination points to a buffer with size\r
e1f414b6 1970 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
9aa049d9 1971\r
e1f414b6 1972 If Destination is NULL, then ASSERT().\r
1973 If Destination is not aligned on a 16-bit boundary, then ASSERT().\r
1974 If Source is NULL, then ASSERT().\r
1975 If Source and Destination overlap, then ASSERT().\r
9aa049d9 1976 If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
1977 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
e1f414b6 1978 then ASSERT().\r
9aa049d9 1979 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
1980 PcdMaximumUnicodeStringLength ASCII characters not including the\r
e1f414b6 1981 Null-terminator, then ASSERT().\r
1982\r
1983 @param Source Pointer to a Null-terminated ASCII string.\r
1984 @param Destination Pointer to a Null-terminated Unicode string.\r
1985\r
9aa049d9 1986 @return Destination.\r
e1f414b6 1987\r
1988**/\r
1989CHAR16 *\r
1990EFIAPI\r
1991AsciiStrToUnicodeStr (\r
4df26661 1992 IN CONST CHAR8 *Source,\r
1993 OUT CHAR16 *Destination\r
e1f414b6 1994 )\r
1995{\r
4df26661 1996 CHAR16 *ReturnValue;\r
1997\r
e1f414b6 1998 ASSERT (Destination != NULL);\r
e1f414b6 1999\r
2000 //\r
4df26661 2001 // ASSERT Source is less long than PcdMaximumAsciiStringLength\r
e1f414b6 2002 //\r
4df26661 2003 ASSERT (AsciiStrSize (Source) != 0);\r
e1f414b6 2004\r
2005 //\r
4df26661 2006 // Source and Destination should not overlap\r
e1f414b6 2007 //\r
4df26661 2008 ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));\r
2009 ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));\r
e1f414b6 2010\r
4df26661 2011 \r
2012 ReturnValue = Destination;\r
e1f414b6 2013 while (*Source != '\0') {\r
2014 *(Destination++) = (CHAR16) *(Source++);\r
2015 }\r
2016 //\r
2017 // End the Destination with a NULL.\r
2018 //\r
2019 *Destination = '\0';\r
2020\r
4df26661 2021 //\r
2022 // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength\r
2023 //\r
2024 ASSERT (StrSize (ReturnValue) != 0);\r
2025\r
2026 return ReturnValue;\r
e1f414b6 2027}\r
2028\r
2029/**\r
2030 Converts an 8-bit value to an 8-bit BCD value.\r
2031\r
2032 Converts the 8-bit value specified by Value to BCD. The BCD value is\r
2033 returned.\r
2034\r
2035 If Value >= 100, then ASSERT().\r
2036\r
2037 @param Value The 8-bit value to convert to BCD. Range 0..99.\r
2038\r
9aa049d9 2039 @return The BCD value.\r
e1f414b6 2040\r
2041**/\r
2042UINT8\r
2043EFIAPI\r
2044DecimalToBcd8 (\r
2045 IN UINT8 Value\r
2046 )\r
2047{\r
2048 ASSERT (Value < 100);\r
2049 return (UINT8) (((Value / 10) << 4) | (Value % 10));\r
2050}\r
2051\r
2052/**\r
2053 Converts an 8-bit BCD value to an 8-bit value.\r
2054\r
2055 Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit\r
2056 value is returned.\r
2057\r
2058 If Value >= 0xA0, then ASSERT().\r
2059 If (Value & 0x0F) >= 0x0A, then ASSERT().\r
2060\r
2061 @param Value The 8-bit BCD value to convert to an 8-bit value.\r
2062\r
9aa049d9 2063 @return The 8-bit value is returned.\r
e1f414b6 2064\r
2065**/\r
2066UINT8\r
2067EFIAPI\r
2068BcdToDecimal8 (\r
2069 IN UINT8 Value\r
2070 )\r
2071{\r
2072 ASSERT (Value < 0xa0);\r
2073 ASSERT ((Value & 0xf) < 0xa);\r
2074 return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));\r
2075}\r