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