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