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