2 Unicode and ASCII string primitives.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "BaseLibInternals.h"
12 Returns the length of a Null-terminated Unicode string.
14 This function returns the number of Unicode characters in the Null-terminated
15 Unicode string specified by String.
17 If String is NULL, then ASSERT().
18 If String is not aligned on a 16-bit boundary, then ASSERT().
19 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
20 PcdMaximumUnicodeStringLength Unicode characters, not including the
21 Null-terminator, then ASSERT().
23 @param String A pointer to a Null-terminated Unicode string.
25 @return The length of String.
31 IN CONST CHAR16
*String
36 ASSERT (String
!= NULL
);
37 ASSERT (((UINTN
)String
& BIT0
) == 0);
39 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
41 // If PcdMaximumUnicodeStringLength is not zero,
42 // length should not more than PcdMaximumUnicodeStringLength
44 if (PcdGet32 (PcdMaximumUnicodeStringLength
) != 0) {
45 ASSERT (Length
< PcdGet32 (PcdMaximumUnicodeStringLength
));
53 Returns the size of a Null-terminated Unicode string in bytes, including the
56 This function returns the size, in bytes, of the Null-terminated Unicode string
59 If String is NULL, then ASSERT().
60 If String is not aligned on a 16-bit boundary, then ASSERT().
61 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
62 PcdMaximumUnicodeStringLength Unicode characters, not including the
63 Null-terminator, then ASSERT().
65 @param String A pointer to a Null-terminated Unicode string.
67 @return The size of String.
73 IN CONST CHAR16
*String
76 return (StrLen (String
) + 1) * sizeof (*String
);
80 Compares two Null-terminated Unicode strings, and returns the difference
81 between the first mismatched Unicode characters.
83 This function compares the Null-terminated Unicode string FirstString to the
84 Null-terminated Unicode string SecondString. If FirstString is identical to
85 SecondString, then 0 is returned. Otherwise, the value returned is the first
86 mismatched Unicode character in SecondString subtracted from the first
87 mismatched Unicode character in FirstString.
89 If FirstString is NULL, then ASSERT().
90 If FirstString is not aligned on a 16-bit boundary, then ASSERT().
91 If SecondString is NULL, then ASSERT().
92 If SecondString is not aligned on a 16-bit boundary, then ASSERT().
93 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
94 than PcdMaximumUnicodeStringLength Unicode characters, not including the
95 Null-terminator, then ASSERT().
96 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
97 than PcdMaximumUnicodeStringLength Unicode characters, not including the
98 Null-terminator, then ASSERT().
100 @param FirstString A pointer to a Null-terminated Unicode string.
101 @param SecondString A pointer to a Null-terminated Unicode string.
103 @retval 0 FirstString is identical to SecondString.
104 @return others FirstString is not identical to SecondString.
110 IN CONST CHAR16
*FirstString
,
111 IN CONST CHAR16
*SecondString
115 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
117 ASSERT (StrSize (FirstString
) != 0);
118 ASSERT (StrSize (SecondString
) != 0);
120 while ((*FirstString
!= L
'\0') && (*FirstString
== *SecondString
)) {
125 return *FirstString
- *SecondString
;
129 Compares up to a specified length the contents of two Null-terminated Unicode strings,
130 and returns the difference between the first mismatched Unicode characters.
132 This function compares the Null-terminated Unicode string FirstString to the
133 Null-terminated Unicode string SecondString. At most, Length Unicode
134 characters will be compared. If Length is 0, then 0 is returned. If
135 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
136 value returned is the first mismatched Unicode character in SecondString
137 subtracted from the first mismatched Unicode character in FirstString.
139 If Length > 0 and FirstString is NULL, then ASSERT().
140 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
141 If Length > 0 and SecondString is NULL, then ASSERT().
142 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
143 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
144 PcdMaximumUnicodeStringLength, then ASSERT().
145 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
146 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
148 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
149 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
152 @param FirstString A pointer to a Null-terminated Unicode string.
153 @param SecondString A pointer to a Null-terminated Unicode string.
154 @param Length The maximum number of Unicode characters to compare.
156 @retval 0 FirstString is identical to SecondString.
157 @return others FirstString is not identical to SecondString.
163 IN CONST CHAR16
*FirstString
,
164 IN CONST CHAR16
*SecondString
,
173 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
174 // Length tests are performed inside StrLen().
176 ASSERT (StrSize (FirstString
) != 0);
177 ASSERT (StrSize (SecondString
) != 0);
179 if (PcdGet32 (PcdMaximumUnicodeStringLength
) != 0) {
180 ASSERT (Length
<= PcdGet32 (PcdMaximumUnicodeStringLength
));
183 while ((*FirstString
!= L
'\0') &&
184 (*SecondString
!= L
'\0') &&
185 (*FirstString
== *SecondString
) &&
193 return *FirstString
- *SecondString
;
197 Returns the first occurrence of a Null-terminated Unicode sub-string
198 in a Null-terminated Unicode string.
200 This function scans the contents of the Null-terminated Unicode string
201 specified by String and returns the first occurrence of SearchString.
202 If SearchString is not found in String, then NULL is returned. If
203 the length of SearchString is zero, then String is
206 If String is NULL, then ASSERT().
207 If String is not aligned on a 16-bit boundary, then ASSERT().
208 If SearchString is NULL, then ASSERT().
209 If SearchString is not aligned on a 16-bit boundary, then ASSERT().
211 If PcdMaximumUnicodeStringLength is not zero, and SearchString
212 or String contains more than PcdMaximumUnicodeStringLength Unicode
213 characters, not including the Null-terminator, then ASSERT().
215 @param String A pointer to a Null-terminated Unicode string.
216 @param SearchString A pointer to a Null-terminated Unicode string to search for.
218 @retval NULL If the SearchString does not appear in String.
219 @return others If there is a match.
225 IN CONST CHAR16
*String
,
226 IN CONST CHAR16
*SearchString
229 CONST CHAR16
*FirstMatch
;
230 CONST CHAR16
*SearchStringTmp
;
233 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
234 // Length tests are performed inside StrLen().
236 ASSERT (StrSize (String
) != 0);
237 ASSERT (StrSize (SearchString
) != 0);
239 if (*SearchString
== L
'\0') {
240 return (CHAR16
*)String
;
243 while (*String
!= L
'\0') {
244 SearchStringTmp
= SearchString
;
247 while ( (*String
== *SearchStringTmp
)
248 && (*String
!= L
'\0'))
254 if (*SearchStringTmp
== L
'\0') {
255 return (CHAR16
*)FirstMatch
;
258 if (*String
== L
'\0') {
262 String
= FirstMatch
+ 1;
269 Check if a Unicode character is a decimal character.
271 This internal function checks if a Unicode character is a
272 decimal character. The valid decimal character is from
275 @param Char The character to check against.
277 @retval TRUE If the Char is a decmial character.
278 @retval FALSE If the Char is not a decmial character.
283 InternalIsDecimalDigitCharacter (
287 return (BOOLEAN
)(Char
>= L
'0' && Char
<= L
'9');
291 Convert a Unicode character to upper case only if
292 it maps to a valid small-case ASCII character.
294 This internal function only deal with Unicode character
295 which maps to a valid small-case ASCII character, i.e.
296 L'a' to L'z'. For other Unicode character, the input character
297 is returned directly.
299 @param Char The character to convert.
301 @retval LowerCharacter If the Char is with range L'a' to L'z'.
302 @retval Unchanged Otherwise.
311 if ((Char
>= L
'a') && (Char
<= L
'z')) {
312 return (CHAR16
)(Char
- (L
'a' - L
'A'));
319 Convert a Unicode character to numerical value.
321 This internal function only deal with Unicode character
322 which maps to a valid hexadecimal ASII character, i.e.
323 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
324 Unicode character, the value returned does not make sense.
326 @param Char The character to convert.
328 @return The numerical value converted.
333 InternalHexCharToUintn (
337 if (InternalIsDecimalDigitCharacter (Char
)) {
341 return (10 + CharToUpper (Char
) - L
'A');
345 Check if a Unicode character is a hexadecimal character.
347 This internal function checks if a Unicode character is a
348 decimal character. The valid hexadecimal character is
349 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
352 @param Char The character to check against.
354 @retval TRUE If the Char is a hexadecmial character.
355 @retval FALSE If the Char is not a hexadecmial character.
360 InternalIsHexaDecimalDigitCharacter (
364 return (BOOLEAN
)(InternalIsDecimalDigitCharacter (Char
) ||
365 (Char
>= L
'A' && Char
<= L
'F') ||
366 (Char
>= L
'a' && Char
<= L
'f'));
370 Convert a Null-terminated Unicode decimal string to a value of
373 This function returns a value of type UINTN by interpreting the contents
374 of the Unicode string specified by String as a decimal number. The format
375 of the input Unicode string String is:
377 [spaces] [decimal digits].
379 The valid decimal digit character is in the range [0-9]. The
380 function will ignore the pad space, which includes spaces or
381 tab characters, before [decimal digits]. The running zero in the
382 beginning of [decimal digits] will be ignored. Then, the function
383 stops at the first character that is a not a valid decimal character
384 or a Null-terminator, whichever one comes first.
386 If String is NULL, then ASSERT().
387 If String is not aligned in a 16-bit boundary, then ASSERT().
388 If String has only pad spaces, then 0 is returned.
389 If String has no pad spaces or valid decimal digits,
391 If the number represented by String overflows according
392 to the range defined by UINTN, then MAX_UINTN is returned.
394 If PcdMaximumUnicodeStringLength is not zero, and String contains
395 more than PcdMaximumUnicodeStringLength Unicode characters, not including
396 the Null-terminator, then ASSERT().
398 @param String A pointer to a Null-terminated Unicode string.
400 @retval Value translated from String.
406 IN CONST CHAR16
*String
411 StrDecimalToUintnS (String
, (CHAR16
**)NULL
, &Result
);
416 Convert a Null-terminated Unicode decimal string to a value of
419 This function returns a value of type UINT64 by interpreting the contents
420 of the Unicode string specified by String as a decimal number. The format
421 of the input Unicode string String is:
423 [spaces] [decimal digits].
425 The valid decimal digit character is in the range [0-9]. The
426 function will ignore the pad space, which includes spaces or
427 tab characters, before [decimal digits]. The running zero in the
428 beginning of [decimal digits] will be ignored. Then, the function
429 stops at the first character that is a not a valid decimal character
430 or a Null-terminator, whichever one comes first.
432 If String is NULL, then ASSERT().
433 If String is not aligned in a 16-bit boundary, then ASSERT().
434 If String has only pad spaces, then 0 is returned.
435 If String has no pad spaces or valid decimal digits,
437 If the number represented by String overflows according
438 to the range defined by UINT64, then MAX_UINT64 is returned.
440 If PcdMaximumUnicodeStringLength is not zero, and String contains
441 more than PcdMaximumUnicodeStringLength Unicode characters, not including
442 the Null-terminator, then ASSERT().
444 @param String A pointer to a Null-terminated Unicode string.
446 @retval Value translated from String.
452 IN CONST CHAR16
*String
457 StrDecimalToUint64S (String
, (CHAR16
**)NULL
, &Result
);
462 Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
464 This function returns a value of type UINTN by interpreting the contents
465 of the Unicode string specified by String as a hexadecimal number.
466 The format of the input Unicode string String is:
468 [spaces][zeros][x][hexadecimal digits].
470 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
471 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
472 If "x" appears in the input string, it must be prefixed with at least one 0.
473 The function will ignore the pad space, which includes spaces or tab characters,
474 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
475 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
476 first valid hexadecimal digit. Then, the function stops at the first character that is
477 a not a valid hexadecimal character or NULL, whichever one comes first.
479 If String is NULL, then ASSERT().
480 If String is not aligned in a 16-bit boundary, then ASSERT().
481 If String has only pad spaces, then zero is returned.
482 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
483 then zero is returned.
484 If the number represented by String overflows according to the range defined by
485 UINTN, then MAX_UINTN is returned.
487 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
488 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
491 @param String A pointer to a Null-terminated Unicode string.
493 @retval Value translated from String.
499 IN CONST CHAR16
*String
504 StrHexToUintnS (String
, (CHAR16
**)NULL
, &Result
);
509 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
511 This function returns a value of type UINT64 by interpreting the contents
512 of the Unicode string specified by String as a hexadecimal number.
513 The format of the input Unicode string String is
515 [spaces][zeros][x][hexadecimal digits].
517 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
518 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
519 If "x" appears in the input string, it must be prefixed with at least one 0.
520 The function will ignore the pad space, which includes spaces or tab characters,
521 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
522 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
523 first valid hexadecimal digit. Then, the function stops at the first character that is
524 a not a valid hexadecimal character or NULL, whichever one comes first.
526 If String is NULL, then ASSERT().
527 If String is not aligned in a 16-bit boundary, then ASSERT().
528 If String has only pad spaces, then zero is returned.
529 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
530 then zero is returned.
531 If the number represented by String overflows according to the range defined by
532 UINT64, then MAX_UINT64 is returned.
534 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
535 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
538 @param String A pointer to a Null-terminated Unicode string.
540 @retval Value translated from String.
546 IN CONST CHAR16
*String
551 StrHexToUint64S (String
, (CHAR16
**)NULL
, &Result
);
556 Check if a ASCII character is a decimal character.
558 This internal function checks if a Unicode character is a
559 decimal character. The valid decimal character is from
562 @param Char The character to check against.
564 @retval TRUE If the Char is a decmial character.
565 @retval FALSE If the Char is not a decmial character.
570 InternalAsciiIsDecimalDigitCharacter (
574 return (BOOLEAN
)(Char
>= '0' && Char
<= '9');
578 Check if a ASCII character is a hexadecimal character.
580 This internal function checks if a ASCII character is a
581 decimal character. The valid hexadecimal character is
582 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
585 @param Char The character to check against.
587 @retval TRUE If the Char is a hexadecmial character.
588 @retval FALSE If the Char is not a hexadecmial character.
593 InternalAsciiIsHexaDecimalDigitCharacter (
597 return (BOOLEAN
)(InternalAsciiIsDecimalDigitCharacter (Char
) ||
598 (Char
>= 'A' && Char
<= 'F') ||
599 (Char
>= 'a' && Char
<= 'f'));
603 Returns the length of a Null-terminated ASCII string.
605 This function returns the number of ASCII characters in the Null-terminated
606 ASCII string specified by String.
608 If Length > 0 and Destination is NULL, then ASSERT().
609 If Length > 0 and Source is NULL, then ASSERT().
610 If PcdMaximumAsciiStringLength is not zero and String contains more than
611 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
614 @param String A pointer to a Null-terminated ASCII string.
616 @return The length of String.
622 IN CONST CHAR8
*String
627 ASSERT (String
!= NULL
);
629 for (Length
= 0; *String
!= '\0'; String
++, Length
++) {
631 // If PcdMaximumUnicodeStringLength is not zero,
632 // length should not more than PcdMaximumUnicodeStringLength
634 if (PcdGet32 (PcdMaximumAsciiStringLength
) != 0) {
635 ASSERT (Length
< PcdGet32 (PcdMaximumAsciiStringLength
));
643 Returns the size of a Null-terminated ASCII string in bytes, including the
646 This function returns the size, in bytes, of the Null-terminated ASCII string
649 If String is NULL, then ASSERT().
650 If PcdMaximumAsciiStringLength is not zero and String contains more than
651 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
654 @param String A pointer to a Null-terminated ASCII string.
656 @return The size of String.
662 IN CONST CHAR8
*String
665 return (AsciiStrLen (String
) + 1) * sizeof (*String
);
669 Compares two Null-terminated ASCII strings, and returns the difference
670 between the first mismatched ASCII characters.
672 This function compares the Null-terminated ASCII string FirstString to the
673 Null-terminated ASCII string SecondString. If FirstString is identical to
674 SecondString, then 0 is returned. Otherwise, the value returned is the first
675 mismatched ASCII character in SecondString subtracted from the first
676 mismatched ASCII character in FirstString.
678 If FirstString is NULL, then ASSERT().
679 If SecondString is NULL, then ASSERT().
680 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
681 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
683 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
684 than PcdMaximumAsciiStringLength ASCII characters, not including the
685 Null-terminator, then ASSERT().
687 @param FirstString A pointer to a Null-terminated ASCII string.
688 @param SecondString A pointer to a Null-terminated ASCII string.
690 @retval ==0 FirstString is identical to SecondString.
691 @retval !=0 FirstString is not identical to SecondString.
697 IN CONST CHAR8
*FirstString
,
698 IN CONST CHAR8
*SecondString
702 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
704 ASSERT (AsciiStrSize (FirstString
));
705 ASSERT (AsciiStrSize (SecondString
));
707 while ((*FirstString
!= '\0') && (*FirstString
== *SecondString
)) {
712 return *FirstString
- *SecondString
;
716 Converts a lowercase Ascii character to upper one.
718 If Chr is lowercase Ascii character, then converts it to upper one.
720 If Value >= 0xA0, then ASSERT().
721 If (Value & 0x0F) >= 0x0A, then ASSERT().
723 @param Chr one Ascii character
725 @return The uppercase value of Ascii character
734 return (UINT8
)((Chr
>= 'a' && Chr
<= 'z') ? Chr
- ('a' - 'A') : Chr
);
738 Convert a ASCII character to numerical value.
740 This internal function only deal with Unicode character
741 which maps to a valid hexadecimal ASII character, i.e.
742 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
743 ASCII character, the value returned does not make sense.
745 @param Char The character to convert.
747 @return The numerical value converted.
752 InternalAsciiHexCharToUintn (
756 if (InternalIsDecimalDigitCharacter (Char
)) {
760 return (10 + AsciiCharToUpper (Char
) - 'A');
764 Performs a case insensitive comparison of two Null-terminated ASCII strings,
765 and returns the difference between the first mismatched ASCII characters.
767 This function performs a case insensitive comparison of the Null-terminated
768 ASCII string FirstString to the Null-terminated ASCII string SecondString. If
769 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
770 value returned is the first mismatched lower case ASCII character in
771 SecondString subtracted from the first mismatched lower case ASCII character
774 If FirstString is NULL, then ASSERT().
775 If SecondString is NULL, then ASSERT().
776 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
777 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
779 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
780 than PcdMaximumAsciiStringLength ASCII characters, not including the
781 Null-terminator, then ASSERT().
783 @param FirstString A pointer to a Null-terminated ASCII string.
784 @param SecondString A pointer to a Null-terminated ASCII string.
786 @retval ==0 FirstString is identical to SecondString using case insensitive
788 @retval !=0 FirstString is not identical to SecondString using case
789 insensitive comparisons.
795 IN CONST CHAR8
*FirstString
,
796 IN CONST CHAR8
*SecondString
799 CHAR8 UpperFirstString
;
800 CHAR8 UpperSecondString
;
803 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
805 ASSERT (AsciiStrSize (FirstString
));
806 ASSERT (AsciiStrSize (SecondString
));
808 UpperFirstString
= AsciiCharToUpper (*FirstString
);
809 UpperSecondString
= AsciiCharToUpper (*SecondString
);
810 while ((*FirstString
!= '\0') && (*SecondString
!= '\0') && (UpperFirstString
== UpperSecondString
)) {
813 UpperFirstString
= AsciiCharToUpper (*FirstString
);
814 UpperSecondString
= AsciiCharToUpper (*SecondString
);
817 return UpperFirstString
- UpperSecondString
;
821 Compares two Null-terminated ASCII strings with maximum lengths, and returns
822 the difference between the first mismatched ASCII characters.
824 This function compares the Null-terminated ASCII string FirstString to the
825 Null-terminated ASCII string SecondString. At most, Length ASCII characters
826 will be compared. If Length is 0, then 0 is returned. If FirstString is
827 identical to SecondString, then 0 is returned. Otherwise, the value returned
828 is the first mismatched ASCII character in SecondString subtracted from the
829 first mismatched ASCII character in FirstString.
831 If Length > 0 and FirstString is NULL, then ASSERT().
832 If Length > 0 and SecondString is NULL, then ASSERT().
833 If PcdMaximumAsciiStringLength is not zero, and Length is greater than
834 PcdMaximumAsciiStringLength, then ASSERT().
835 If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
836 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
838 If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
839 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
842 @param FirstString A pointer to a Null-terminated ASCII string.
843 @param SecondString A pointer to a Null-terminated ASCII string.
844 @param Length The maximum number of ASCII characters for compare.
846 @retval ==0 FirstString is identical to SecondString.
847 @retval !=0 FirstString is not identical to SecondString.
853 IN CONST CHAR8
*FirstString
,
854 IN CONST CHAR8
*SecondString
,
863 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
865 ASSERT (AsciiStrSize (FirstString
));
866 ASSERT (AsciiStrSize (SecondString
));
868 if (PcdGet32 (PcdMaximumAsciiStringLength
) != 0) {
869 ASSERT (Length
<= PcdGet32 (PcdMaximumAsciiStringLength
));
872 while ((*FirstString
!= '\0') &&
873 (*SecondString
!= '\0') &&
874 (*FirstString
== *SecondString
) &&
882 return *FirstString
- *SecondString
;
886 Returns the first occurrence of a Null-terminated ASCII sub-string
887 in a Null-terminated ASCII string.
889 This function scans the contents of the ASCII string specified by String
890 and returns the first occurrence of SearchString. If SearchString is not
891 found in String, then NULL is returned. If the length of SearchString is zero,
892 then String is returned.
894 If String is NULL, then ASSERT().
895 If SearchString is NULL, then ASSERT().
897 If PcdMaximumAsciiStringLength is not zero, and SearchString or
898 String contains more than PcdMaximumAsciiStringLength Unicode characters
899 not including the Null-terminator, then ASSERT().
901 @param String A pointer to a Null-terminated ASCII string.
902 @param SearchString A pointer to a Null-terminated ASCII string to search for.
904 @retval NULL If the SearchString does not appear in String.
905 @retval others If there is a match return the first occurrence of SearchingString.
906 If the length of SearchString is zero,return String.
912 IN CONST CHAR8
*String
,
913 IN CONST CHAR8
*SearchString
916 CONST CHAR8
*FirstMatch
;
917 CONST CHAR8
*SearchStringTmp
;
920 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
922 ASSERT (AsciiStrSize (String
) != 0);
923 ASSERT (AsciiStrSize (SearchString
) != 0);
925 if (*SearchString
== '\0') {
926 return (CHAR8
*)String
;
929 while (*String
!= '\0') {
930 SearchStringTmp
= SearchString
;
933 while ( (*String
== *SearchStringTmp
)
934 && (*String
!= '\0'))
940 if (*SearchStringTmp
== '\0') {
941 return (CHAR8
*)FirstMatch
;
944 if (*String
== '\0') {
948 String
= FirstMatch
+ 1;
955 Convert a Null-terminated ASCII decimal string to a value of type
958 This function returns a value of type UINTN by interpreting the contents
959 of the ASCII string String as a decimal number. The format of the input
960 ASCII string String is:
962 [spaces] [decimal digits].
964 The valid decimal digit character is in the range [0-9]. The function will
965 ignore the pad space, which includes spaces or tab characters, before the digits.
966 The running zero in the beginning of [decimal digits] will be ignored. Then, the
967 function stops at the first character that is a not a valid decimal character or
968 Null-terminator, whichever on comes first.
970 If String has only pad spaces, then 0 is returned.
971 If String has no pad spaces or valid decimal digits, then 0 is returned.
972 If the number represented by String overflows according to the range defined by
973 UINTN, then MAX_UINTN is returned.
974 If String is NULL, then ASSERT().
975 If PcdMaximumAsciiStringLength is not zero, and String contains more than
976 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
979 @param String A pointer to a Null-terminated ASCII string.
981 @retval Value translated from String.
986 AsciiStrDecimalToUintn (
987 IN CONST CHAR8
*String
992 AsciiStrDecimalToUintnS (String
, (CHAR8
**)NULL
, &Result
);
997 Convert a Null-terminated ASCII decimal string to a value of type
1000 This function returns a value of type UINT64 by interpreting the contents
1001 of the ASCII string String as a decimal number. The format of the input
1002 ASCII string String is:
1004 [spaces] [decimal digits].
1006 The valid decimal digit character is in the range [0-9]. The function will
1007 ignore the pad space, which includes spaces or tab characters, before the digits.
1008 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1009 function stops at the first character that is a not a valid decimal character or
1010 Null-terminator, whichever on comes first.
1012 If String has only pad spaces, then 0 is returned.
1013 If String has no pad spaces or valid decimal digits, then 0 is returned.
1014 If the number represented by String overflows according to the range defined by
1015 UINT64, then MAX_UINT64 is returned.
1016 If String is NULL, then ASSERT().
1017 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1018 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1021 @param String A pointer to a Null-terminated ASCII string.
1023 @retval Value translated from String.
1028 AsciiStrDecimalToUint64 (
1029 IN CONST CHAR8
*String
1034 AsciiStrDecimalToUint64S (String
, (CHAR8
**)NULL
, &Result
);
1039 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
1041 This function returns a value of type UINTN by interpreting the contents of
1042 the ASCII string String as a hexadecimal number. The format of the input ASCII
1045 [spaces][zeros][x][hexadecimal digits].
1047 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1048 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1049 appears in the input string, it must be prefixed with at least one 0. The function
1050 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1051 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1052 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1053 digit. Then, the function stops at the first character that is a not a valid
1054 hexadecimal character or Null-terminator, whichever on comes first.
1056 If String has only pad spaces, then 0 is returned.
1057 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1060 If the number represented by String overflows according to the range defined by UINTN,
1061 then MAX_UINTN is returned.
1062 If String is NULL, then ASSERT().
1063 If PcdMaximumAsciiStringLength is not zero,
1064 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1065 the Null-terminator, then ASSERT().
1067 @param String A pointer to a Null-terminated ASCII string.
1069 @retval Value translated from String.
1074 AsciiStrHexToUintn (
1075 IN CONST CHAR8
*String
1080 AsciiStrHexToUintnS (String
, (CHAR8
**)NULL
, &Result
);
1085 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
1087 This function returns a value of type UINT64 by interpreting the contents of
1088 the ASCII string String as a hexadecimal number. The format of the input ASCII
1091 [spaces][zeros][x][hexadecimal digits].
1093 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1094 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1095 appears in the input string, it must be prefixed with at least one 0. The function
1096 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1097 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1098 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1099 digit. Then, the function stops at the first character that is a not a valid
1100 hexadecimal character or Null-terminator, whichever on comes first.
1102 If String has only pad spaces, then 0 is returned.
1103 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1106 If the number represented by String overflows according to the range defined by UINT64,
1107 then MAX_UINT64 is returned.
1108 If String is NULL, then ASSERT().
1109 If PcdMaximumAsciiStringLength is not zero,
1110 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1111 the Null-terminator, then ASSERT().
1113 @param String A pointer to a Null-terminated ASCII string.
1115 @retval Value translated from String.
1120 AsciiStrHexToUint64 (
1121 IN CONST CHAR8
*String
1126 AsciiStrHexToUint64S (String
, (CHAR8
**)NULL
, &Result
);
1130 STATIC CHAR8 EncodingTable
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1131 "abcdefghijklmnopqrstuvwxyz"
1135 Convert binary data to a Base64 encoded ascii string based on RFC4648.
1137 Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.
1138 The Ascii string is produced by converting the data string specified by Source and SourceLength.
1140 @param Source Input UINT8 data
1141 @param SourceLength Number of UINT8 bytes of data
1142 @param Destination Pointer to output string buffer
1143 @param DestinationSize Size of ascii buffer. Set to 0 to get the size needed.
1144 Caller is responsible for passing in buffer of DestinationSize
1146 @retval RETURN_SUCCESS When ascii buffer is filled in.
1147 @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.
1148 @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).
1149 @retval RETURN_BUFFER_TOO_SMALL If SourceLength is 0 and DestinationSize is <1.
1150 @retval RETURN_BUFFER_TOO_SMALL If Destination is NULL or DestinationSize is smaller than required buffersize.
1156 IN CONST UINT8
*Source
,
1157 IN UINTN SourceLength
,
1158 OUT CHAR8
*Destination OPTIONAL
,
1159 IN OUT UINTN
*DestinationSize
1166 // Check pointers, and SourceLength is valid
1168 if ((Source
== NULL
) || (DestinationSize
== NULL
)) {
1169 return RETURN_INVALID_PARAMETER
;
1173 // Allow for RFC 4648 test vector 1
1175 if (SourceLength
== 0) {
1176 if (*DestinationSize
< 1) {
1177 *DestinationSize
= 1;
1178 return RETURN_BUFFER_TOO_SMALL
;
1181 *DestinationSize
= 1;
1182 *Destination
= '\0';
1183 return RETURN_SUCCESS
;
1187 // Check if SourceLength or DestinationSize is valid
1189 if ((SourceLength
>= (MAX_ADDRESS
- (UINTN
)Source
)) || (*DestinationSize
>= (MAX_ADDRESS
- (UINTN
)Destination
))) {
1190 return RETURN_INVALID_PARAMETER
;
1194 // 4 ascii per 3 bytes + NULL
1196 RequiredSize
= ((SourceLength
+ 2) / 3) * 4 + 1;
1197 if ((Destination
== NULL
) || (*DestinationSize
< RequiredSize
)) {
1198 *DestinationSize
= RequiredSize
;
1199 return RETURN_BUFFER_TOO_SMALL
;
1202 Left
= SourceLength
;
1205 // Encode 24 bits (three bytes) into 4 ascii characters
1208 *Destination
++ = EncodingTable
[(Source
[0] & 0xfc) >> 2];
1209 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4) + ((Source
[1] & 0xf0) >> 4)];
1210 *Destination
++ = EncodingTable
[((Source
[1] & 0x0f) << 2) + ((Source
[2] & 0xc0) >> 6)];
1211 *Destination
++ = EncodingTable
[(Source
[2] & 0x3f)];
1217 // Handle the remainder, and add padding '=' characters as necessary.
1223 // No bytes Left, done.
1229 // One more data byte, two pad characters
1231 *Destination
++ = EncodingTable
[(Source
[0] & 0xfc) >> 2];
1232 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4)];
1233 *Destination
++ = '=';
1234 *Destination
++ = '=';
1239 // Two more data bytes, and one pad character
1241 *Destination
++ = EncodingTable
[(Source
[0] & 0xfc) >> 2];
1242 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4) + ((Source
[1] & 0xf0) >> 4)];
1243 *Destination
++ = EncodingTable
[((Source
[1] & 0x0f) << 2)];
1244 *Destination
++ = '=';
1249 // Add terminating NULL
1251 *Destination
= '\0';
1252 return RETURN_SUCCESS
;
1256 Decode Base64 ASCII encoded data to 8-bit binary representation, based on
1259 Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.
1261 Whitespace is ignored at all positions:
1262 - 0x09 ('\t') horizontal tab
1263 - 0x0A ('\n') new line
1264 - 0x0B ('\v') vertical tab
1265 - 0x0C ('\f') form feed
1266 - 0x0D ('\r') carriage return
1269 The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated
1270 and enforced at the end of the Base64 ASCII encoded data, and only there.
1272 Other characters outside of the encoding alphabet cause the function to
1273 reject the Base64 ASCII encoded data.
1275 @param[in] Source Array of CHAR8 elements containing the Base64
1276 ASCII encoding. May be NULL if SourceSize is
1279 @param[in] SourceSize Number of CHAR8 elements in Source.
1281 @param[out] Destination Array of UINT8 elements receiving the decoded
1282 8-bit binary representation. Allocated by the
1283 caller. May be NULL if DestinationSize is
1284 zero on input. If NULL, decoding is
1285 performed, but the 8-bit binary
1286 representation is not stored. If non-NULL and
1287 the function returns an error, the contents
1288 of Destination are indeterminate.
1290 @param[in,out] DestinationSize On input, the number of UINT8 elements that
1291 the caller allocated for Destination. On
1292 output, if the function returns
1293 RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,
1294 the number of UINT8 elements that are
1295 required for decoding the Base64 ASCII
1296 representation. If the function returns a
1297 value different from both RETURN_SUCCESS and
1298 RETURN_BUFFER_TOO_SMALL, then DestinationSize
1299 is indeterminate on output.
1301 @retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have
1302 been decoded to on-output DestinationSize
1303 UINT8 elements at Destination. Note that
1304 RETURN_SUCCESS covers the case when
1305 DestinationSize is zero on input, and
1306 Source decodes to zero bytes (due to
1307 containing at most ignored whitespace).
1309 @retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not
1310 large enough for decoding SourceSize CHAR8
1311 elements at Source. The required number of
1312 UINT8 elements has been stored to
1315 @retval RETURN_INVALID_PARAMETER DestinationSize is NULL.
1317 @retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.
1319 @retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is
1322 @retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +
1323 SourceSize) would wrap around MAX_ADDRESS.
1325 @retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +
1326 DestinationSize) would wrap around
1327 MAX_ADDRESS, as specified on input.
1329 @retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,
1330 and CHAR8[SourceSize] at Source overlaps
1331 UINT8[DestinationSize] at Destination, as
1334 @retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in
1340 IN CONST CHAR8
*Source OPTIONAL
,
1341 IN UINTN SourceSize
,
1342 OUT UINT8
*Destination OPTIONAL
,
1343 IN OUT UINTN
*DestinationSize
1346 BOOLEAN PaddingMode
;
1347 UINTN SixBitGroupsConsumed
;
1349 UINTN OriginalDestinationSize
;
1353 UINT8 DestinationOctet
;
1355 if (DestinationSize
== NULL
) {
1356 return RETURN_INVALID_PARAMETER
;
1360 // Check Source array validity.
1362 if (Source
== NULL
) {
1363 if (SourceSize
> 0) {
1365 // At least one CHAR8 element at NULL Source.
1367 return RETURN_INVALID_PARAMETER
;
1369 } else if (SourceSize
> MAX_ADDRESS
- (UINTN
)Source
) {
1371 // Non-NULL Source, but it wraps around.
1373 return RETURN_INVALID_PARAMETER
;
1377 // Check Destination array validity.
1379 if (Destination
== NULL
) {
1380 if (*DestinationSize
> 0) {
1382 // At least one UINT8 element at NULL Destination.
1384 return RETURN_INVALID_PARAMETER
;
1386 } else if (*DestinationSize
> MAX_ADDRESS
- (UINTN
)Destination
) {
1388 // Non-NULL Destination, but it wraps around.
1390 return RETURN_INVALID_PARAMETER
;
1394 // Check for overlap.
1396 if ((Source
!= NULL
) && (Destination
!= NULL
)) {
1398 // Both arrays have been provided, and we know from earlier that each array
1399 // is valid in itself.
1401 if ((UINTN
)Source
+ SourceSize
<= (UINTN
)Destination
) {
1403 // Source array precedes Destination array, OK.
1405 } else if ((UINTN
)Destination
+ *DestinationSize
<= (UINTN
)Source
) {
1407 // Destination array precedes Source array, OK.
1413 return RETURN_INVALID_PARAMETER
;
1418 // Decoding loop setup.
1420 PaddingMode
= FALSE
;
1421 SixBitGroupsConsumed
= 0;
1423 OriginalDestinationSize
= *DestinationSize
;
1424 *DestinationSize
= 0;
1429 for (SourceIndex
= 0; SourceIndex
< SourceSize
; SourceIndex
++) {
1430 SourceChar
= Source
[SourceIndex
];
1433 // Whitespace is ignored at all positions (regardless of padding mode).
1435 if ((SourceChar
== '\t') || (SourceChar
== '\n') || (SourceChar
== '\v') ||
1436 (SourceChar
== '\f') || (SourceChar
== '\r') || (SourceChar
== ' '))
1442 // If we're in padding mode, accept another padding character, as long as
1443 // that padding character completes the quantum. This completes case (2)
1444 // from RFC4648, Chapter 4. "Base 64 Encoding":
1446 // (2) The final quantum of encoding input is exactly 8 bits; here, the
1447 // final unit of encoded output will be two characters followed by two
1448 // "=" padding characters.
1451 if ((SourceChar
== '=') && (SixBitGroupsConsumed
== 3)) {
1452 SixBitGroupsConsumed
= 0;
1456 return RETURN_INVALID_PARAMETER
;
1460 // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:
1461 // The Base 64 Alphabet".
1463 if (('A' <= SourceChar
) && (SourceChar
<= 'Z')) {
1464 Base64Value
= SourceChar
- 'A';
1465 } else if (('a' <= SourceChar
) && (SourceChar
<= 'z')) {
1466 Base64Value
= 26 + (SourceChar
- 'a');
1467 } else if (('0' <= SourceChar
) && (SourceChar
<= '9')) {
1468 Base64Value
= 52 + (SourceChar
- '0');
1469 } else if (SourceChar
== '+') {
1471 } else if (SourceChar
== '/') {
1473 } else if (SourceChar
== '=') {
1475 // Enter padding mode.
1479 if (SixBitGroupsConsumed
== 2) {
1481 // If we have consumed two 6-bit groups from the current quantum before
1482 // encountering the first padding character, then this is case (2) from
1483 // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,
1484 // and we'll enforce another padding character.
1486 SixBitGroupsConsumed
= 3;
1487 } else if (SixBitGroupsConsumed
== 3) {
1489 // If we have consumed three 6-bit groups from the current quantum
1490 // before encountering the first padding character, then this is case
1491 // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now
1494 SixBitGroupsConsumed
= 0;
1497 // Padding characters are not allowed at the first two positions of a
1500 return RETURN_INVALID_PARAMETER
;
1504 // Wherever in a quantum we enter padding mode, we enforce the padding
1505 // bits pending in the accumulator -- from the last 6-bit group just
1506 // preceding the padding character -- to be zero. Refer to RFC4648,
1507 // Chapter 3.5. "Canonical Encoding".
1509 if (Accumulator
!= 0) {
1510 return RETURN_INVALID_PARAMETER
;
1514 // Advance to the next source character.
1519 // Other characters outside of the encoding alphabet are rejected.
1521 return RETURN_INVALID_PARAMETER
;
1525 // Feed the bits of the current 6-bit group of the quantum to the
1528 Accumulator
= (Accumulator
<< 6) | Base64Value
;
1529 SixBitGroupsConsumed
++;
1530 switch (SixBitGroupsConsumed
) {
1533 // No octet to spill after consuming the first 6-bit group of the
1534 // quantum; advance to the next source character.
1539 // 12 bits accumulated (6 pending + 6 new); prepare for spilling an
1540 // octet. 4 bits remain pending.
1542 DestinationOctet
= (UINT8
)(Accumulator
>> 4);
1547 // 10 bits accumulated (4 pending + 6 new); prepare for spilling an
1548 // octet. 2 bits remain pending.
1550 DestinationOctet
= (UINT8
)(Accumulator
>> 2);
1554 ASSERT (SixBitGroupsConsumed
== 4);
1556 // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.
1557 // The quantum is complete, 0 bits remain pending.
1559 DestinationOctet
= (UINT8
)Accumulator
;
1561 SixBitGroupsConsumed
= 0;
1566 // Store the decoded octet if there's room left. Increment
1567 // (*DestinationSize) unconditionally.
1569 if (*DestinationSize
< OriginalDestinationSize
) {
1570 ASSERT (Destination
!= NULL
);
1571 Destination
[*DestinationSize
] = DestinationOctet
;
1574 (*DestinationSize
)++;
1577 // Advance to the next source character.
1582 // If Source terminates mid-quantum, then Source is invalid.
1584 if (SixBitGroupsConsumed
!= 0) {
1585 return RETURN_INVALID_PARAMETER
;
1591 if (*DestinationSize
<= OriginalDestinationSize
) {
1592 return RETURN_SUCCESS
;
1595 return RETURN_BUFFER_TOO_SMALL
;
1599 Converts an 8-bit value to an 8-bit BCD value.
1601 Converts the 8-bit value specified by Value to BCD. The BCD value is
1604 If Value >= 100, then ASSERT().
1606 @param Value The 8-bit value to convert to BCD. Range 0..99.
1608 @return The BCD value.
1617 ASSERT (Value
< 100);
1618 return (UINT8
)(((Value
/ 10) << 4) | (Value
% 10));
1622 Converts an 8-bit BCD value to an 8-bit value.
1624 Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
1627 If Value >= 0xA0, then ASSERT().
1628 If (Value & 0x0F) >= 0x0A, then ASSERT().
1630 @param Value The 8-bit BCD value to convert to an 8-bit value.
1632 @return The 8-bit value is returned.
1641 ASSERT (Value
< 0xa0);
1642 ASSERT ((Value
& 0xf) < 0xa);
1643 return (UINT8
)((Value
>> 4) * 10 + (Value
& 0xf));