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