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