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"
13 Returns the length of a Null-terminated Unicode string.
15 This function returns the number of Unicode characters in the Null-terminated
16 Unicode string specified by String.
18 If String is NULL, then ASSERT().
19 If String is not aligned on a 16-bit boundary, then ASSERT().
20 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
21 PcdMaximumUnicodeStringLength Unicode characters, not including the
22 Null-terminator, then ASSERT().
24 @param String A pointer to a Null-terminated Unicode string.
26 @return The length of String.
32 IN CONST CHAR16
*String
37 ASSERT (String
!= NULL
);
38 ASSERT (((UINTN
) String
& BIT0
) == 0);
40 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
42 // If PcdMaximumUnicodeStringLength is not zero,
43 // length should not more than PcdMaximumUnicodeStringLength
45 if (PcdGet32 (PcdMaximumUnicodeStringLength
) != 0) {
46 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
)) {
124 return *FirstString
- *SecondString
;
128 Compares up to a specified length the contents of two Null-terminated Unicode strings,
129 and returns the difference between the first mismatched Unicode characters.
131 This function compares the Null-terminated Unicode string FirstString to the
132 Null-terminated Unicode string SecondString. At most, Length Unicode
133 characters will be compared. If Length is 0, then 0 is returned. If
134 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
135 value returned is the first mismatched Unicode character in SecondString
136 subtracted from the first mismatched Unicode character in FirstString.
138 If Length > 0 and FirstString is NULL, then ASSERT().
139 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
140 If Length > 0 and SecondString is NULL, then ASSERT().
141 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
142 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
143 PcdMaximumUnicodeStringLength, then ASSERT().
144 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
145 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
147 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
148 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
151 @param FirstString A pointer to a Null-terminated Unicode string.
152 @param SecondString A pointer to a Null-terminated Unicode string.
153 @param Length The maximum number of Unicode characters to compare.
155 @retval 0 FirstString is identical to SecondString.
156 @return others FirstString is not identical to SecondString.
162 IN CONST CHAR16
*FirstString
,
163 IN CONST CHAR16
*SecondString
,
172 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
173 // Length tests are performed inside StrLen().
175 ASSERT (StrSize (FirstString
) != 0);
176 ASSERT (StrSize (SecondString
) != 0);
178 if (PcdGet32 (PcdMaximumUnicodeStringLength
) != 0) {
179 ASSERT (Length
<= PcdGet32 (PcdMaximumUnicodeStringLength
));
182 while ((*FirstString
!= L
'\0') &&
183 (*SecondString
!= L
'\0') &&
184 (*FirstString
== *SecondString
) &&
191 return *FirstString
- *SecondString
;
196 Returns the first occurrence of a Null-terminated Unicode sub-string
197 in a Null-terminated Unicode string.
199 This function scans the contents of the Null-terminated Unicode string
200 specified by String and returns the first occurrence of SearchString.
201 If SearchString is not found in String, then NULL is returned. If
202 the length of SearchString is zero, then String is
205 If String is NULL, then ASSERT().
206 If String is not aligned on a 16-bit boundary, then ASSERT().
207 If SearchString is NULL, then ASSERT().
208 If SearchString is not aligned on a 16-bit boundary, then ASSERT().
210 If PcdMaximumUnicodeStringLength is not zero, and SearchString
211 or String contains more than PcdMaximumUnicodeStringLength Unicode
212 characters, not including the Null-terminator, then ASSERT().
214 @param String A pointer to a Null-terminated Unicode string.
215 @param SearchString A pointer to a Null-terminated Unicode string to search for.
217 @retval NULL If the SearchString does not appear in String.
218 @return others If there is a match.
224 IN CONST CHAR16
*String
,
225 IN CONST CHAR16
*SearchString
228 CONST CHAR16
*FirstMatch
;
229 CONST CHAR16
*SearchStringTmp
;
232 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
233 // Length tests are performed inside StrLen().
235 ASSERT (StrSize (String
) != 0);
236 ASSERT (StrSize (SearchString
) != 0);
238 if (*SearchString
== L
'\0') {
239 return (CHAR16
*) String
;
242 while (*String
!= L
'\0') {
243 SearchStringTmp
= SearchString
;
246 while ((*String
== *SearchStringTmp
)
247 && (*String
!= L
'\0')) {
252 if (*SearchStringTmp
== L
'\0') {
253 return (CHAR16
*) FirstMatch
;
256 if (*String
== L
'\0') {
260 String
= FirstMatch
+ 1;
267 Check if a Unicode character is a decimal character.
269 This internal function checks if a Unicode character is a
270 decimal character. The valid decimal character is from
273 @param Char The character to check against.
275 @retval TRUE If the Char is a decmial character.
276 @retval FALSE If the Char is not a decmial character.
281 InternalIsDecimalDigitCharacter (
285 return (BOOLEAN
) (Char
>= L
'0' && Char
<= L
'9');
289 Convert a Unicode character to upper case only if
290 it maps to a valid small-case ASCII character.
292 This internal function only deal with Unicode character
293 which maps to a valid small-case ASCII character, i.e.
294 L'a' to L'z'. For other Unicode character, the input character
295 is returned directly.
297 @param Char The character to convert.
299 @retval LowerCharacter If the Char is with range L'a' to L'z'.
300 @retval Unchanged Otherwise.
309 if (Char
>= L
'a' && Char
<= L
'z') {
310 return (CHAR16
) (Char
- (L
'a' - L
'A'));
317 Convert a Unicode character to numerical value.
319 This internal function only deal with Unicode character
320 which maps to a valid hexadecimal ASII character, i.e.
321 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
322 Unicode character, the value returned does not make sense.
324 @param Char The character to convert.
326 @return The numerical value converted.
331 InternalHexCharToUintn (
335 if (InternalIsDecimalDigitCharacter (Char
)) {
339 return (10 + CharToUpper (Char
) - L
'A');
343 Check if a Unicode character is a hexadecimal character.
345 This internal function checks if a Unicode character is a
346 decimal character. The valid hexadecimal character is
347 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
350 @param Char The character to check against.
352 @retval TRUE If the Char is a hexadecmial character.
353 @retval FALSE If the Char is not a hexadecmial character.
358 InternalIsHexaDecimalDigitCharacter (
363 return (BOOLEAN
) (InternalIsDecimalDigitCharacter (Char
) ||
364 (Char
>= L
'A' && Char
<= L
'F') ||
365 (Char
>= L
'a' && Char
<= L
'f'));
369 Convert a Null-terminated Unicode decimal string to a value of
372 This function returns a value of type UINTN by interpreting the contents
373 of the Unicode string specified by String as a decimal number. The format
374 of the input Unicode string String is:
376 [spaces] [decimal digits].
378 The valid decimal digit character is in the range [0-9]. The
379 function will ignore the pad space, which includes spaces or
380 tab characters, before [decimal digits]. The running zero in the
381 beginning of [decimal digits] will be ignored. Then, the function
382 stops at the first character that is a not a valid decimal character
383 or a Null-terminator, whichever one comes first.
385 If String is NULL, then ASSERT().
386 If String is not aligned in a 16-bit boundary, then ASSERT().
387 If String has only pad spaces, then 0 is returned.
388 If String has no pad spaces or valid decimal digits,
390 If the number represented by String overflows according
391 to the range defined by UINTN, then MAX_UINTN is returned.
393 If PcdMaximumUnicodeStringLength is not zero, and String contains
394 more than PcdMaximumUnicodeStringLength Unicode characters, not including
395 the Null-terminator, then ASSERT().
397 @param String A pointer to a Null-terminated Unicode string.
399 @retval Value translated from String.
405 IN CONST CHAR16
*String
410 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
);
510 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
512 This function returns a value of type UINT64 by interpreting the contents
513 of the Unicode string specified by String as a hexadecimal number.
514 The format of the input Unicode string String is
516 [spaces][zeros][x][hexadecimal digits].
518 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
519 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
520 If "x" appears in the input string, it must be prefixed with at least one 0.
521 The function will ignore the pad space, which includes spaces or tab characters,
522 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
523 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
524 first valid hexadecimal digit. Then, the function stops at the first character that is
525 a not a valid hexadecimal character or NULL, whichever one comes first.
527 If String is NULL, then ASSERT().
528 If String is not aligned in a 16-bit boundary, then ASSERT().
529 If String has only pad spaces, then zero is returned.
530 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
531 then zero is returned.
532 If the number represented by String overflows according to the range defined by
533 UINT64, then MAX_UINT64 is returned.
535 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
536 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
539 @param String A pointer to a Null-terminated Unicode string.
541 @retval Value translated from String.
547 IN CONST CHAR16
*String
552 StrHexToUint64S (String
, (CHAR16
**) NULL
, &Result
);
557 Check if a ASCII character is a decimal character.
559 This internal function checks if a Unicode character is a
560 decimal character. The valid decimal character is from
563 @param Char The character to check against.
565 @retval TRUE If the Char is a decmial character.
566 @retval FALSE If the Char is not a decmial character.
571 InternalAsciiIsDecimalDigitCharacter (
575 return (BOOLEAN
) (Char
>= '0' && Char
<= '9');
579 Check if a ASCII character is a hexadecimal character.
581 This internal function checks if a ASCII character is a
582 decimal character. The valid hexadecimal character is
583 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
586 @param Char The character to check against.
588 @retval TRUE If the Char is a hexadecmial character.
589 @retval FALSE If the Char is not a hexadecmial character.
594 InternalAsciiIsHexaDecimalDigitCharacter (
599 return (BOOLEAN
) (InternalAsciiIsDecimalDigitCharacter (Char
) ||
600 (Char
>= 'A' && Char
<= 'F') ||
601 (Char
>= 'a' && Char
<= 'f'));
606 Returns the length of a Null-terminated ASCII string.
608 This function returns the number of ASCII characters in the Null-terminated
609 ASCII string specified by String.
611 If Length > 0 and Destination is NULL, then ASSERT().
612 If Length > 0 and Source is NULL, then ASSERT().
613 If PcdMaximumAsciiStringLength is not zero and String contains more than
614 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
617 @param String A pointer to a Null-terminated ASCII string.
619 @return The length of String.
625 IN CONST CHAR8
*String
630 ASSERT (String
!= NULL
);
632 for (Length
= 0; *String
!= '\0'; String
++, Length
++) {
634 // If PcdMaximumUnicodeStringLength is not zero,
635 // length should not more than PcdMaximumUnicodeStringLength
637 if (PcdGet32 (PcdMaximumAsciiStringLength
) != 0) {
638 ASSERT (Length
< PcdGet32 (PcdMaximumAsciiStringLength
));
645 Returns the size of a Null-terminated ASCII string in bytes, including the
648 This function returns the size, in bytes, of the Null-terminated ASCII string
651 If String is NULL, then ASSERT().
652 If PcdMaximumAsciiStringLength is not zero and String contains more than
653 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
656 @param String A pointer to a Null-terminated ASCII string.
658 @return The size of String.
664 IN CONST CHAR8
*String
667 return (AsciiStrLen (String
) + 1) * sizeof (*String
);
671 Compares two Null-terminated ASCII strings, and returns the difference
672 between the first mismatched ASCII characters.
674 This function compares the Null-terminated ASCII string FirstString to the
675 Null-terminated ASCII string SecondString. If FirstString is identical to
676 SecondString, then 0 is returned. Otherwise, the value returned is the first
677 mismatched ASCII character in SecondString subtracted from the first
678 mismatched ASCII character in FirstString.
680 If FirstString is NULL, then ASSERT().
681 If SecondString is NULL, then ASSERT().
682 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
683 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
685 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
686 than PcdMaximumAsciiStringLength ASCII characters, not including the
687 Null-terminator, then ASSERT().
689 @param FirstString A pointer to a Null-terminated ASCII string.
690 @param SecondString A pointer to a Null-terminated ASCII string.
692 @retval ==0 FirstString is identical to SecondString.
693 @retval !=0 FirstString is not identical to SecondString.
699 IN CONST CHAR8
*FirstString
,
700 IN CONST CHAR8
*SecondString
704 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
706 ASSERT (AsciiStrSize (FirstString
));
707 ASSERT (AsciiStrSize (SecondString
));
709 while ((*FirstString
!= '\0') && (*FirstString
== *SecondString
)) {
714 return *FirstString
- *SecondString
;
718 Converts a lowercase Ascii character to upper one.
720 If Chr is lowercase Ascii character, then converts it to upper one.
722 If Value >= 0xA0, then ASSERT().
723 If (Value & 0x0F) >= 0x0A, then ASSERT().
725 @param Chr one Ascii character
727 @return The uppercase value of Ascii character
736 return (UINT8
) ((Chr
>= 'a' && Chr
<= 'z') ? Chr
- ('a' - 'A') : Chr
);
740 Convert a ASCII character to numerical value.
742 This internal function only deal with Unicode character
743 which maps to a valid hexadecimal ASII character, i.e.
744 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
745 ASCII character, the value returned does not make sense.
747 @param Char The character to convert.
749 @return The numerical value converted.
754 InternalAsciiHexCharToUintn (
758 if (InternalIsDecimalDigitCharacter (Char
)) {
762 return (10 + AsciiCharToUpper (Char
) - 'A');
767 Performs a case insensitive comparison of two Null-terminated ASCII strings,
768 and returns the difference between the first mismatched ASCII characters.
770 This function performs a case insensitive comparison of the Null-terminated
771 ASCII string FirstString to the Null-terminated ASCII string SecondString. If
772 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
773 value returned is the first mismatched lower case ASCII character in
774 SecondString subtracted from the first mismatched lower case ASCII character
777 If FirstString is NULL, then ASSERT().
778 If SecondString is NULL, then ASSERT().
779 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
780 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
782 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
783 than PcdMaximumAsciiStringLength ASCII characters, not including the
784 Null-terminator, then ASSERT().
786 @param FirstString A pointer to a Null-terminated ASCII string.
787 @param SecondString A pointer to a Null-terminated ASCII string.
789 @retval ==0 FirstString is identical to SecondString using case insensitive
791 @retval !=0 FirstString is not identical to SecondString using case
792 insensitive comparisons.
798 IN CONST CHAR8
*FirstString
,
799 IN CONST CHAR8
*SecondString
802 CHAR8 UpperFirstString
;
803 CHAR8 UpperSecondString
;
806 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
808 ASSERT (AsciiStrSize (FirstString
));
809 ASSERT (AsciiStrSize (SecondString
));
811 UpperFirstString
= AsciiCharToUpper (*FirstString
);
812 UpperSecondString
= AsciiCharToUpper (*SecondString
);
813 while ((*FirstString
!= '\0') && (*SecondString
!= '\0') && (UpperFirstString
== UpperSecondString
)) {
816 UpperFirstString
= AsciiCharToUpper (*FirstString
);
817 UpperSecondString
= AsciiCharToUpper (*SecondString
);
820 return UpperFirstString
- UpperSecondString
;
824 Compares two Null-terminated ASCII strings with maximum lengths, and returns
825 the difference between the first mismatched ASCII characters.
827 This function compares the Null-terminated ASCII string FirstString to the
828 Null-terminated ASCII string SecondString. At most, Length ASCII characters
829 will be compared. If Length is 0, then 0 is returned. If FirstString is
830 identical to SecondString, then 0 is returned. Otherwise, the value returned
831 is the first mismatched ASCII character in SecondString subtracted from the
832 first mismatched ASCII character in FirstString.
834 If Length > 0 and FirstString is NULL, then ASSERT().
835 If Length > 0 and SecondString is NULL, then ASSERT().
836 If PcdMaximumAsciiStringLength is not zero, and Length is greater than
837 PcdMaximumAsciiStringLength, then ASSERT().
838 If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than
839 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
841 If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than
842 PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,
845 @param FirstString A pointer to a Null-terminated ASCII string.
846 @param SecondString A pointer to a Null-terminated ASCII string.
847 @param Length The maximum number of ASCII characters for compare.
849 @retval ==0 FirstString is identical to SecondString.
850 @retval !=0 FirstString is not identical to SecondString.
856 IN CONST CHAR8
*FirstString
,
857 IN CONST CHAR8
*SecondString
,
866 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
868 ASSERT (AsciiStrSize (FirstString
));
869 ASSERT (AsciiStrSize (SecondString
));
871 if (PcdGet32 (PcdMaximumAsciiStringLength
) != 0) {
872 ASSERT (Length
<= PcdGet32 (PcdMaximumAsciiStringLength
));
875 while ((*FirstString
!= '\0') &&
876 (*SecondString
!= '\0') &&
877 (*FirstString
== *SecondString
) &&
883 return *FirstString
- *SecondString
;
888 Returns the first occurrence of a Null-terminated ASCII sub-string
889 in a Null-terminated ASCII string.
891 This function scans the contents of the ASCII string specified by String
892 and returns the first occurrence of SearchString. If SearchString is not
893 found in String, then NULL is returned. If the length of SearchString is zero,
894 then String is returned.
896 If String is NULL, then ASSERT().
897 If SearchString is NULL, then ASSERT().
899 If PcdMaximumAsciiStringLength is not zero, and SearchString or
900 String contains more than PcdMaximumAsciiStringLength Unicode characters
901 not including the Null-terminator, then ASSERT().
903 @param String A pointer to a Null-terminated ASCII string.
904 @param SearchString A pointer to a Null-terminated ASCII string to search for.
906 @retval NULL If the SearchString does not appear in String.
907 @retval others If there is a match return the first occurrence of SearchingString.
908 If the length of SearchString is zero,return String.
914 IN CONST CHAR8
*String
,
915 IN CONST CHAR8
*SearchString
918 CONST CHAR8
*FirstMatch
;
919 CONST CHAR8
*SearchStringTmp
;
922 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
924 ASSERT (AsciiStrSize (String
) != 0);
925 ASSERT (AsciiStrSize (SearchString
) != 0);
927 if (*SearchString
== '\0') {
928 return (CHAR8
*) String
;
931 while (*String
!= '\0') {
932 SearchStringTmp
= SearchString
;
935 while ((*String
== *SearchStringTmp
)
936 && (*String
!= '\0')) {
941 if (*SearchStringTmp
== '\0') {
942 return (CHAR8
*) FirstMatch
;
945 if (*String
== '\0') {
949 String
= FirstMatch
+ 1;
956 Convert a Null-terminated ASCII decimal string to a value of type
959 This function returns a value of type UINTN by interpreting the contents
960 of the ASCII string String as a decimal number. The format of the input
961 ASCII string String is:
963 [spaces] [decimal digits].
965 The valid decimal digit character is in the range [0-9]. The function will
966 ignore the pad space, which includes spaces or tab characters, before the digits.
967 The running zero in the beginning of [decimal digits] will be ignored. Then, the
968 function stops at the first character that is a not a valid decimal character or
969 Null-terminator, whichever on comes first.
971 If String has only pad spaces, then 0 is returned.
972 If String has no pad spaces or valid decimal digits, then 0 is returned.
973 If the number represented by String overflows according to the range defined by
974 UINTN, then MAX_UINTN is returned.
975 If String is NULL, then ASSERT().
976 If PcdMaximumAsciiStringLength is not zero, and String contains more than
977 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
980 @param String A pointer to a Null-terminated ASCII string.
982 @retval Value translated from String.
987 AsciiStrDecimalToUintn (
988 IN CONST CHAR8
*String
993 AsciiStrDecimalToUintnS (String
, (CHAR8
**) NULL
, &Result
);
999 Convert a Null-terminated ASCII decimal string to a value of type
1002 This function returns a value of type UINT64 by interpreting the contents
1003 of the ASCII string String as a decimal number. The format of the input
1004 ASCII string String is:
1006 [spaces] [decimal digits].
1008 The valid decimal digit character is in the range [0-9]. The function will
1009 ignore the pad space, which includes spaces or tab characters, before the digits.
1010 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1011 function stops at the first character that is a not a valid decimal character or
1012 Null-terminator, whichever on comes first.
1014 If String has only pad spaces, then 0 is returned.
1015 If String has no pad spaces or valid decimal digits, then 0 is returned.
1016 If the number represented by String overflows according to the range defined by
1017 UINT64, then MAX_UINT64 is returned.
1018 If String is NULL, then ASSERT().
1019 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1020 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1023 @param String A pointer to a Null-terminated ASCII string.
1025 @retval Value translated from String.
1030 AsciiStrDecimalToUint64 (
1031 IN CONST CHAR8
*String
1036 AsciiStrDecimalToUint64S (String
, (CHAR8
**) NULL
, &Result
);
1041 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
1043 This function returns a value of type UINTN by interpreting the contents of
1044 the ASCII string String as a hexadecimal number. The format of the input ASCII
1047 [spaces][zeros][x][hexadecimal digits].
1049 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1050 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1051 appears in the input string, it must be prefixed with at least one 0. The function
1052 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1053 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1054 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1055 digit. Then, the function stops at the first character that is a not a valid
1056 hexadecimal character or Null-terminator, whichever on comes first.
1058 If String has only pad spaces, then 0 is returned.
1059 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1062 If the number represented by String overflows according to the range defined by UINTN,
1063 then MAX_UINTN is returned.
1064 If String is NULL, then ASSERT().
1065 If PcdMaximumAsciiStringLength is not zero,
1066 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1067 the Null-terminator, then ASSERT().
1069 @param String A pointer to a Null-terminated ASCII string.
1071 @retval Value translated from String.
1076 AsciiStrHexToUintn (
1077 IN CONST CHAR8
*String
1082 AsciiStrHexToUintnS (String
, (CHAR8
**) NULL
, &Result
);
1088 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
1090 This function returns a value of type UINT64 by interpreting the contents of
1091 the ASCII string String as a hexadecimal number. The format of the input ASCII
1094 [spaces][zeros][x][hexadecimal digits].
1096 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1097 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1098 appears in the input string, it must be prefixed with at least one 0. The function
1099 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1100 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1101 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1102 digit. Then, the function stops at the first character that is a not a valid
1103 hexadecimal character or Null-terminator, whichever on comes first.
1105 If String has only pad spaces, then 0 is returned.
1106 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1109 If the number represented by String overflows according to the range defined by UINT64,
1110 then MAX_UINT64 is returned.
1111 If String is NULL, then ASSERT().
1112 If PcdMaximumAsciiStringLength is not zero,
1113 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1114 the Null-terminator, then ASSERT().
1116 @param String A pointer to a Null-terminated ASCII string.
1118 @retval Value translated from String.
1123 AsciiStrHexToUint64 (
1124 IN CONST CHAR8
*String
1129 AsciiStrHexToUint64S (String
, (CHAR8
**) NULL
, &Result
);
1134 STATIC CHAR8 EncodingTable
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1135 "abcdefghijklmnopqrstuvwxyz"
1139 Convert binary data to a Base64 encoded ascii string based on RFC4648.
1141 Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.
1142 The Ascii string is produced by converting the data string specified by Source and SourceLength.
1144 @param Source Input UINT8 data
1145 @param SourceLength Number of UINT8 bytes of data
1146 @param Destination Pointer to output string buffer
1147 @param DestinationSize Size of ascii buffer. Set to 0 to get the size needed.
1148 Caller is responsible for passing in buffer of DestinationSize
1150 @retval RETURN_SUCCESS When ascii buffer is filled in.
1151 @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.
1152 @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).
1153 @retval RETURN_BUFFER_TOO_SMALL If SourceLength is 0 and DestinationSize is <1.
1154 @retval RETURN_BUFFER_TOO_SMALL If Destination is NULL or DestinationSize is smaller than required buffersize.
1160 IN CONST UINT8
*Source
,
1161 IN UINTN SourceLength
,
1162 OUT CHAR8
*Destination OPTIONAL
,
1163 IN OUT UINTN
*DestinationSize
1171 // Check pointers, and SourceLength is valid
1173 if ((Source
== NULL
) || (DestinationSize
== NULL
)) {
1174 return RETURN_INVALID_PARAMETER
;
1178 // Allow for RFC 4648 test vector 1
1180 if (SourceLength
== 0) {
1181 if (*DestinationSize
< 1) {
1182 *DestinationSize
= 1;
1183 return RETURN_BUFFER_TOO_SMALL
;
1185 *DestinationSize
= 1;
1186 *Destination
= '\0';
1187 return RETURN_SUCCESS
;
1191 // Check if SourceLength or DestinationSize is valid
1193 if ((SourceLength
>= (MAX_ADDRESS
- (UINTN
)Source
)) || (*DestinationSize
>= (MAX_ADDRESS
- (UINTN
)Destination
))){
1194 return RETURN_INVALID_PARAMETER
;
1198 // 4 ascii per 3 bytes + NULL
1200 RequiredSize
= ((SourceLength
+ 2) / 3) * 4 + 1;
1201 if ((Destination
== NULL
) || *DestinationSize
< RequiredSize
) {
1202 *DestinationSize
= RequiredSize
;
1203 return RETURN_BUFFER_TOO_SMALL
;
1206 Left
= SourceLength
;
1209 // Encode 24 bits (three bytes) into 4 ascii characters
1213 *Destination
++ = EncodingTable
[( Source
[0] & 0xfc) >> 2 ];
1214 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4) + ((Source
[1] & 0xf0) >> 4)];
1215 *Destination
++ = EncodingTable
[((Source
[1] & 0x0f) << 2) + ((Source
[2] & 0xc0) >> 6)];
1216 *Destination
++ = EncodingTable
[( Source
[2] & 0x3f)];
1222 // Handle the remainder, and add padding '=' characters as necessary.
1228 // No bytes Left, done.
1234 // One more data byte, two pad characters
1236 *Destination
++ = EncodingTable
[( Source
[0] & 0xfc) >> 2];
1237 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4)];
1238 *Destination
++ = '=';
1239 *Destination
++ = '=';
1244 // Two more data bytes, and one pad character
1246 *Destination
++ = EncodingTable
[( Source
[0] & 0xfc) >> 2];
1247 *Destination
++ = EncodingTable
[((Source
[0] & 0x03) << 4) + ((Source
[1] & 0xf0) >> 4)];
1248 *Destination
++ = EncodingTable
[((Source
[1] & 0x0f) << 2)];
1249 *Destination
++ = '=';
1253 // Add terminating NULL
1255 *Destination
= '\0';
1256 return RETURN_SUCCESS
;
1260 Decode Base64 ASCII encoded data to 8-bit binary representation, based on
1263 Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.
1265 Whitespace is ignored at all positions:
1266 - 0x09 ('\t') horizontal tab
1267 - 0x0A ('\n') new line
1268 - 0x0B ('\v') vertical tab
1269 - 0x0C ('\f') form feed
1270 - 0x0D ('\r') carriage return
1273 The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated
1274 and enforced at the end of the Base64 ASCII encoded data, and only there.
1276 Other characters outside of the encoding alphabet cause the function to
1277 reject the Base64 ASCII encoded data.
1279 @param[in] Source Array of CHAR8 elements containing the Base64
1280 ASCII encoding. May be NULL if SourceSize is
1283 @param[in] SourceSize Number of CHAR8 elements in Source.
1285 @param[out] Destination Array of UINT8 elements receiving the decoded
1286 8-bit binary representation. Allocated by the
1287 caller. May be NULL if DestinationSize is
1288 zero on input. If NULL, decoding is
1289 performed, but the 8-bit binary
1290 representation is not stored. If non-NULL and
1291 the function returns an error, the contents
1292 of Destination are indeterminate.
1294 @param[in,out] DestinationSize On input, the number of UINT8 elements that
1295 the caller allocated for Destination. On
1296 output, if the function returns
1297 RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,
1298 the number of UINT8 elements that are
1299 required for decoding the Base64 ASCII
1300 representation. If the function returns a
1301 value different from both RETURN_SUCCESS and
1302 RETURN_BUFFER_TOO_SMALL, then DestinationSize
1303 is indeterminate on output.
1305 @retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have
1306 been decoded to on-output DestinationSize
1307 UINT8 elements at Destination. Note that
1308 RETURN_SUCCESS covers the case when
1309 DestinationSize is zero on input, and
1310 Source decodes to zero bytes (due to
1311 containing at most ignored whitespace).
1313 @retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not
1314 large enough for decoding SourceSize CHAR8
1315 elements at Source. The required number of
1316 UINT8 elements has been stored to
1319 @retval RETURN_INVALID_PARAMETER DestinationSize is NULL.
1321 @retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.
1323 @retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is
1326 @retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +
1327 SourceSize) would wrap around MAX_ADDRESS.
1329 @retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +
1330 DestinationSize) would wrap around
1331 MAX_ADDRESS, as specified on input.
1333 @retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,
1334 and CHAR8[SourceSize] at Source overlaps
1335 UINT8[DestinationSize] at Destination, as
1338 @retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in
1344 IN CONST CHAR8
*Source OPTIONAL
,
1345 IN UINTN SourceSize
,
1346 OUT UINT8
*Destination OPTIONAL
,
1347 IN OUT UINTN
*DestinationSize
1350 BOOLEAN PaddingMode
;
1351 UINTN SixBitGroupsConsumed
;
1353 UINTN OriginalDestinationSize
;
1357 UINT8 DestinationOctet
;
1359 if (DestinationSize
== NULL
) {
1360 return RETURN_INVALID_PARAMETER
;
1364 // Check Source array validity.
1366 if (Source
== NULL
) {
1367 if (SourceSize
> 0) {
1369 // At least one CHAR8 element at NULL Source.
1371 return RETURN_INVALID_PARAMETER
;
1373 } else if (SourceSize
> MAX_ADDRESS
- (UINTN
)Source
) {
1375 // Non-NULL Source, but it wraps around.
1377 return RETURN_INVALID_PARAMETER
;
1381 // Check Destination array validity.
1383 if (Destination
== NULL
) {
1384 if (*DestinationSize
> 0) {
1386 // At least one UINT8 element at NULL Destination.
1388 return RETURN_INVALID_PARAMETER
;
1390 } else if (*DestinationSize
> MAX_ADDRESS
- (UINTN
)Destination
) {
1392 // Non-NULL Destination, but it wraps around.
1394 return RETURN_INVALID_PARAMETER
;
1398 // Check for overlap.
1400 if (Source
!= NULL
&& Destination
!= NULL
) {
1402 // Both arrays have been provided, and we know from earlier that each array
1403 // is valid in itself.
1405 if ((UINTN
)Source
+ SourceSize
<= (UINTN
)Destination
) {
1407 // Source array precedes Destination array, OK.
1409 } else if ((UINTN
)Destination
+ *DestinationSize
<= (UINTN
)Source
) {
1411 // Destination array precedes Source array, OK.
1417 return RETURN_INVALID_PARAMETER
;
1422 // Decoding loop setup.
1424 PaddingMode
= FALSE
;
1425 SixBitGroupsConsumed
= 0;
1427 OriginalDestinationSize
= *DestinationSize
;
1428 *DestinationSize
= 0;
1433 for (SourceIndex
= 0; SourceIndex
< SourceSize
; SourceIndex
++) {
1434 SourceChar
= Source
[SourceIndex
];
1437 // Whitespace is ignored at all positions (regardless of padding mode).
1439 if (SourceChar
== '\t' || SourceChar
== '\n' || SourceChar
== '\v' ||
1440 SourceChar
== '\f' || SourceChar
== '\r' || SourceChar
== ' ') {
1445 // If we're in padding mode, accept another padding character, as long as
1446 // that padding character completes the quantum. This completes case (2)
1447 // from RFC4648, Chapter 4. "Base 64 Encoding":
1449 // (2) The final quantum of encoding input is exactly 8 bits; here, the
1450 // final unit of encoded output will be two characters followed by two
1451 // "=" padding characters.
1454 if (SourceChar
== '=' && SixBitGroupsConsumed
== 3) {
1455 SixBitGroupsConsumed
= 0;
1458 return RETURN_INVALID_PARAMETER
;
1462 // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:
1463 // The Base 64 Alphabet".
1465 if ('A' <= SourceChar
&& SourceChar
<= 'Z') {
1466 Base64Value
= SourceChar
- 'A';
1467 } else if ('a' <= SourceChar
&& SourceChar
<= 'z') {
1468 Base64Value
= 26 + (SourceChar
- 'a');
1469 } else if ('0' <= SourceChar
&& SourceChar
<= '9') {
1470 Base64Value
= 52 + (SourceChar
- '0');
1471 } else if (SourceChar
== '+') {
1473 } else if (SourceChar
== '/') {
1475 } else if (SourceChar
== '=') {
1477 // Enter padding mode.
1481 if (SixBitGroupsConsumed
== 2) {
1483 // If we have consumed two 6-bit groups from the current quantum before
1484 // encountering the first padding character, then this is case (2) from
1485 // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,
1486 // and we'll enforce another padding character.
1488 SixBitGroupsConsumed
= 3;
1489 } else if (SixBitGroupsConsumed
== 3) {
1491 // If we have consumed three 6-bit groups from the current quantum
1492 // before encountering the first padding character, then this is case
1493 // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now
1496 SixBitGroupsConsumed
= 0;
1499 // Padding characters are not allowed at the first two positions of a
1502 return RETURN_INVALID_PARAMETER
;
1506 // Wherever in a quantum we enter padding mode, we enforce the padding
1507 // bits pending in the accumulator -- from the last 6-bit group just
1508 // preceding the padding character -- to be zero. Refer to RFC4648,
1509 // Chapter 3.5. "Canonical Encoding".
1511 if (Accumulator
!= 0) {
1512 return RETURN_INVALID_PARAMETER
;
1516 // Advance to the next source character.
1521 // Other characters outside of the encoding alphabet are rejected.
1523 return RETURN_INVALID_PARAMETER
;
1527 // Feed the bits of the current 6-bit group of the quantum to the
1530 Accumulator
= (Accumulator
<< 6) | Base64Value
;
1531 SixBitGroupsConsumed
++;
1532 switch (SixBitGroupsConsumed
) {
1535 // No octet to spill after consuming the first 6-bit group of the
1536 // quantum; advance to the next source character.
1541 // 12 bits accumulated (6 pending + 6 new); prepare for spilling an
1542 // octet. 4 bits remain pending.
1544 DestinationOctet
= (UINT8
)(Accumulator
>> 4);
1549 // 10 bits accumulated (4 pending + 6 new); prepare for spilling an
1550 // octet. 2 bits remain pending.
1552 DestinationOctet
= (UINT8
)(Accumulator
>> 2);
1556 ASSERT (SixBitGroupsConsumed
== 4);
1558 // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.
1559 // The quantum is complete, 0 bits remain pending.
1561 DestinationOctet
= (UINT8
)Accumulator
;
1563 SixBitGroupsConsumed
= 0;
1568 // Store the decoded octet if there's room left. Increment
1569 // (*DestinationSize) unconditionally.
1571 if (*DestinationSize
< OriginalDestinationSize
) {
1572 ASSERT (Destination
!= NULL
);
1573 Destination
[*DestinationSize
] = DestinationOctet
;
1575 (*DestinationSize
)++;
1578 // Advance to the next source character.
1583 // If Source terminates mid-quantum, then Source is invalid.
1585 if (SixBitGroupsConsumed
!= 0) {
1586 return RETURN_INVALID_PARAMETER
;
1592 if (*DestinationSize
<= OriginalDestinationSize
) {
1593 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));