/** @file\r
- Unicode and ASCII string primatives.\r
+ Unicode and ASCII string primitives.\r
\r
- Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
/**\r
[ATTENTION] This function will be deprecated for security reason.\r
\r
- Copies up to a specified length from one Null-terminated Unicode string to \r
+ Copies up to a specified length from one Null-terminated Unicode string to\r
another Null-terminated Unicode string and returns the new Unicode string.\r
\r
This function copies the contents of the Unicode string Source to the Unicode\r
If Length > 0 and Source is NULL, then ASSERT().\r
If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Length is greater than \r
+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
PcdMaximumUnicodeStringLength, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
Returns the size of a Null-terminated Unicode string in bytes, including the\r
Null terminator.\r
\r
- This function returns the size, in bytes, of the Null-terminated Unicode string \r
+ This function returns the size, in bytes, of the Null-terminated Unicode string\r
specified by String.\r
\r
If String is NULL, then ASSERT().\r
/**\r
Compares up to a specified length the contents of two Null-terminated Unicode strings,\r
and returns the difference between the first mismatched Unicode characters.\r
- \r
+\r
This function compares the Null-terminated Unicode string FirstString to the\r
Null-terminated Unicode string SecondString. At most, Length Unicode\r
characters will be compared. If Length is 0, then 0 is returned. If\r
}\r
\r
while ((*FirstString != L'\0') &&\r
+ (*SecondString != L'\0') &&\r
(*FirstString == *SecondString) &&\r
(Length > 1)) {\r
FirstString++;\r
/**\r
[ATTENTION] This function will be deprecated for security reason.\r
\r
- Concatenates up to a specified length one Null-terminated Unicode to the end \r
- of another Null-terminated Unicode string, and returns the concatenated \r
+ Concatenates up to a specified length one Null-terminated Unicode to the end\r
+ of another Null-terminated Unicode string, and returns the concatenated\r
Unicode string.\r
\r
This function concatenates two Null-terminated Unicode strings. The contents\r
If Length > 0 and Source is NULL, then ASSERT().\r
If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().\r
If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Length is greater than \r
+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
PcdMaximumUnicodeStringLength, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
while (*String != L'\0') {\r
SearchStringTmp = SearchString;\r
FirstMatch = String;\r
- \r
- while ((*String == *SearchStringTmp) \r
+\r
+ while ((*String == *SearchStringTmp)\r
&& (*String != L'\0')) {\r
String++;\r
SearchStringTmp++;\r
- } \r
- \r
+ }\r
+\r
if (*SearchStringTmp == L'\0') {\r
return (CHAR16 *) FirstMatch;\r
}\r
/**\r
Check if a Unicode character is a decimal character.\r
\r
- This internal function checks if a Unicode character is a \r
+ This internal function checks if a Unicode character is a\r
decimal character. The valid decimal character is from\r
L'0' to L'9'.\r
\r
}\r
\r
/**\r
- Convert a Unicode character to upper case only if \r
+ Convert a Unicode character to upper case only if\r
it maps to a valid small-case ASCII character.\r
\r
This internal function only deal with Unicode character\r
**/\r
CHAR16\r
EFIAPI\r
-InternalCharToUpper (\r
+CharToUpper (\r
IN CHAR16 Char\r
)\r
{\r
\r
This internal function only deal with Unicode character\r
which maps to a valid hexadecimal ASII character, i.e.\r
- L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other \r
+ L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
Unicode character, the value returned does not make sense.\r
\r
@param Char The character to convert.\r
return Char - L'0';\r
}\r
\r
- return (UINTN) (10 + InternalCharToUpper (Char) - L'A');\r
+ return (10 + CharToUpper (Char) - L'A');\r
}\r
\r
/**\r
Check if a Unicode character is a hexadecimal character.\r
\r
- This internal function checks if a Unicode character is a \r
- decimal character. The valid hexadecimal character is \r
+ This internal function checks if a Unicode character is a\r
+ decimal character. The valid hexadecimal character is\r
L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
\r
\r
If String has no pad spaces or valid decimal digits,\r
then 0 is returned.\r
If the number represented by String overflows according\r
- to the range defined by UINTN, then ASSERT().\r
+ to the range defined by UINTN, then MAX_UINTN is returned.\r
\r
If PcdMaximumUnicodeStringLength is not zero, and String contains\r
more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
)\r
{\r
UINTN Result;\r
- \r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside StrLen().\r
- //\r
- ASSERT (StrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- Result = 0;\r
\r
- while (InternalIsDecimalDigitCharacter (*String)) {\r
- //\r
- // If the number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));\r
-\r
- Result = Result * 10 + (*String - L'0');\r
- String++;\r
- }\r
- \r
+ StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result);\r
return Result;\r
}\r
\r
If String has no pad spaces or valid decimal digits,\r
then 0 is returned.\r
If the number represented by String overflows according\r
- to the range defined by UINT64, then ASSERT().\r
+ to the range defined by UINT64, then MAX_UINT64 is returned.\r
\r
If PcdMaximumUnicodeStringLength is not zero, and String contains\r
more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
)\r
{\r
UINT64 Result;\r
- \r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside StrLen().\r
- //\r
- ASSERT (StrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- Result = 0;\r
-\r
- while (InternalIsDecimalDigitCharacter (*String)) {\r
- //\r
- // If the number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));\r
-\r
- Result = MultU64x32 (Result, 10) + (*String - L'0');\r
- String++;\r
- }\r
- \r
+ StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);\r
return Result;\r
}\r
\r
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
then zero is returned.\r
If the number represented by String overflows according to the range defined by\r
- UINTN, then ASSERT().\r
+ UINTN, then MAX_UINTN is returned.\r
\r
If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
{\r
UINTN Result;\r
\r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside StrLen().\r
- //\r
- ASSERT (StrSize (String) != 0);\r
- \r
- //\r
- // Ignore the pad spaces (space or tab) \r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- if (InternalCharToUpper (*String) == L'X') {\r
- if (*(String - 1) != L'0') {\r
- return 0;\r
- }\r
- //\r
- // Skip the 'X'\r
- //\r
- String++;\r
- }\r
-\r
- Result = 0;\r
- \r
- while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
- //\r
- // If the Hex Number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));\r
-\r
- Result = (Result << 4) + InternalHexCharToUintn (*String);\r
- String++;\r
- }\r
-\r
+ StrHexToUintnS (String, (CHAR16 **) NULL, &Result);\r
return Result;\r
}\r
\r
If String has no leading pad spaces, leading zeros or valid hexadecimal digits,\r
then zero is returned.\r
If the number represented by String overflows according to the range defined by\r
- UINT64, then ASSERT().\r
+ UINT64, then MAX_UINT64 is returned.\r
\r
If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
{\r
UINT64 Result;\r
\r
- //\r
- // ASSERT String is less long than PcdMaximumUnicodeStringLength.\r
- // Length tests are performed inside StrLen().\r
- //\r
- ASSERT (StrSize (String) != 0);\r
- \r
- //\r
- // Ignore the pad spaces (space or tab) \r
- //\r
- while ((*String == L' ') || (*String == L'\t')) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == L'0') {\r
- String++;\r
- }\r
-\r
- if (InternalCharToUpper (*String) == L'X') {\r
- ASSERT (*(String - 1) == L'0');\r
- if (*(String - 1) != L'0') {\r
- return 0;\r
- }\r
- //\r
- // Skip the 'X'\r
- //\r
- String++;\r
- }\r
-\r
- Result = 0;\r
- \r
- while (InternalIsHexaDecimalDigitCharacter (*String)) {\r
- //\r
- // If the Hex Number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));\r
-\r
- Result = LShiftU64 (Result, 4);\r
- Result = Result + InternalHexCharToUintn (*String);\r
- String++;\r
- }\r
-\r
+ StrHexToUint64S (String, (CHAR16 **) NULL, &Result);\r
return Result;\r
}\r
\r
/**\r
Check if a ASCII character is a decimal character.\r
\r
- This internal function checks if a Unicode character is a \r
+ This internal function checks if a Unicode character is a\r
decimal character. The valid decimal character is from\r
'0' to '9'.\r
\r
/**\r
Check if a ASCII character is a hexadecimal character.\r
\r
- This internal function checks if a ASCII character is a \r
- decimal character. The valid hexadecimal character is \r
+ This internal function checks if a ASCII character is a\r
+ decimal character. The valid hexadecimal character is\r
L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
\r
\r
ReturnValue = Destination;\r
while (*Source != '\0') {\r
//\r
- // If any Unicode characters in Source contain \r
+ // If any Unicode characters in Source contain\r
// non-zero value in the upper 8 bits, then ASSERT().\r
//\r
ASSERT (*Source < 0x100);\r
/**\r
[ATTENTION] This function will be deprecated for security reason.\r
\r
- Copies up to a specified length one Null-terminated ASCII string to another \r
+ Copies up to a specified length one Null-terminated ASCII string to another\r
Null-terminated ASCII string and returns the new ASCII string.\r
\r
This function copies the contents of the ASCII string Source to the ASCII\r
If Destination is NULL, then ASSERT().\r
If Source is NULL, then ASSERT().\r
If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero, and Length is greater than \r
+ If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
PcdMaximumAsciiStringLength, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
\r
@param Chr one Ascii character\r
\r
- @return The uppercase value of Ascii character \r
+ @return The uppercase value of Ascii character\r
\r
**/\r
CHAR8\r
EFIAPI\r
-InternalBaseLibAsciiToUpper (\r
+AsciiCharToUpper (\r
IN CHAR8 Chr\r
)\r
{\r
\r
This internal function only deal with Unicode character\r
which maps to a valid hexadecimal ASII character, i.e.\r
- '0' to '9', 'a' to 'f' or 'A' to 'F'. For other \r
+ '0' to '9', 'a' to 'f' or 'A' to 'F'. For other\r
ASCII character, the value returned does not make sense.\r
\r
@param Char The character to convert.\r
return Char - '0';\r
}\r
\r
- return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A');\r
+ return (10 + AsciiCharToUpper (Char) - 'A');\r
}\r
\r
\r
ASSERT (AsciiStrSize (FirstString));\r
ASSERT (AsciiStrSize (SecondString));\r
\r
- UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);\r
- UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
- while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
+ UpperFirstString = AsciiCharToUpper (*FirstString);\r
+ UpperSecondString = AsciiCharToUpper (*SecondString);\r
+ while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {\r
FirstString++;\r
SecondString++;\r
- UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);\r
- UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
+ UpperFirstString = AsciiCharToUpper (*FirstString);\r
+ UpperSecondString = AsciiCharToUpper (*SecondString);\r
}\r
\r
return UpperFirstString - UpperSecondString;\r
\r
If Length > 0 and FirstString is NULL, then ASSERT().\r
If Length > 0 and SecondString is NULL, then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero, and Length is greater than \r
+ If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
PcdMaximumAsciiStringLength, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than\r
PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
@param FirstString A pointer to a Null-terminated ASCII string.\r
@param SecondString A pointer to a Null-terminated ASCII string.\r
@param Length The maximum number of ASCII characters for compare.\r
- \r
+\r
@retval ==0 FirstString is identical to SecondString.\r
@retval !=0 FirstString is not identical to SecondString.\r
\r
}\r
\r
while ((*FirstString != '\0') &&\r
+ (*SecondString != '\0') &&\r
(*FirstString == *SecondString) &&\r
(Length > 1)) {\r
FirstString++;\r
/**\r
[ATTENTION] This function will be deprecated for security reason.\r
\r
- Concatenates up to a specified length one Null-terminated ASCII string to \r
- the end of another Null-terminated ASCII string, and returns the \r
+ Concatenates up to a specified length one Null-terminated ASCII string to\r
+ the end of another Null-terminated ASCII string, and returns the\r
concatenated ASCII string.\r
\r
This function concatenates two Null-terminated ASCII strings. The contents\r
while (*String != '\0') {\r
SearchStringTmp = SearchString;\r
FirstMatch = String;\r
- \r
- while ((*String == *SearchStringTmp) \r
+\r
+ while ((*String == *SearchStringTmp)\r
&& (*String != '\0')) {\r
String++;\r
SearchStringTmp++;\r
- } \r
- \r
+ }\r
+\r
if (*SearchStringTmp == '\0') {\r
return (CHAR8 *) FirstMatch;\r
}\r
If String has only pad spaces, then 0 is returned.\r
If String has no pad spaces or valid decimal digits, then 0 is returned.\r
If the number represented by String overflows according to the range defined by\r
- UINTN, then ASSERT().\r
+ UINTN, then MAX_UINTN is returned.\r
If String is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
)\r
{\r
UINTN Result;\r
- \r
- //\r
- // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
- //\r
- ASSERT (AsciiStrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == ' ') || (*String == '\t' )) {\r
- String++;\r
- }\r
\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == '0') {\r
- String++;\r
- }\r
-\r
- Result = 0;\r
-\r
- while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
- //\r
- // If the number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= ((((UINTN) ~0) - (*String - L'0')) / 10));\r
-\r
- Result = Result * 10 + (*String - '0');\r
- String++;\r
- }\r
- \r
+ AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result);\r
return Result;\r
}\r
\r
If String has only pad spaces, then 0 is returned.\r
If String has no pad spaces or valid decimal digits, then 0 is returned.\r
If the number represented by String overflows according to the range defined by\r
- UINT64, then ASSERT().\r
+ UINT64, then MAX_UINT64 is returned.\r
If String is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero, and String contains more than\r
PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
)\r
{\r
UINT64 Result;\r
- \r
- //\r
- // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
- //\r
- ASSERT (AsciiStrSize (String) != 0);\r
-\r
- //\r
- // Ignore the pad spaces (space or tab)\r
- //\r
- while ((*String == ' ') || (*String == '\t' )) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == '0') {\r
- String++;\r
- }\r
\r
- Result = 0;\r
-\r
- while (InternalAsciiIsDecimalDigitCharacter (*String)) {\r
- //\r
- // If the number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));\r
-\r
- Result = MultU64x32 (Result, 10) + (*String - '0');\r
- String++;\r
- }\r
- \r
+ AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result);\r
return Result;\r
}\r
\r
0 is returned.\r
\r
If the number represented by String overflows according to the range defined by UINTN,\r
- then ASSERT().\r
+ then MAX_UINTN is returned.\r
If String is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero,\r
and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
{\r
UINTN Result;\r
\r
- //\r
- // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
- //\r
- ASSERT (AsciiStrSize (String) != 0);\r
- \r
- //\r
- // Ignore the pad spaces (space or tab) \r
- //\r
- while ((*String == ' ') || (*String == '\t' )) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == '0') {\r
- String++;\r
- }\r
-\r
- if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
- ASSERT (*(String - 1) == '0');\r
- if (*(String - 1) != '0') {\r
- return 0;\r
- }\r
- //\r
- // Skip the 'X'\r
- //\r
- String++;\r
- }\r
-\r
- Result = 0;\r
- \r
- while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
- //\r
- // If the Hex Number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= ((((UINTN) ~0) - InternalHexCharToUintn (*String)) >> 4));\r
-\r
- Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);\r
- String++;\r
- }\r
-\r
+ AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result);\r
return Result;\r
}\r
\r
0 is returned.\r
\r
If the number represented by String overflows according to the range defined by UINT64,\r
- then ASSERT().\r
+ then MAX_UINT64 is returned.\r
If String is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero,\r
and String contains more than PcdMaximumAsciiStringLength ASCII characters not including\r
{\r
UINT64 Result;\r
\r
- //\r
- // ASSERT Strings is less long than PcdMaximumAsciiStringLength\r
- //\r
- ASSERT (AsciiStrSize (String) != 0);\r
- \r
- //\r
- // Ignore the pad spaces (space or tab) and leading Zeros\r
- //\r
- //\r
- // Ignore the pad spaces (space or tab) \r
- //\r
- while ((*String == ' ') || (*String == '\t' )) {\r
- String++;\r
- }\r
-\r
- //\r
- // Ignore leading Zeros after the spaces\r
- //\r
- while (*String == '0') {\r
- String++;\r
- }\r
-\r
- if (InternalBaseLibAsciiToUpper (*String) == 'X') {\r
- ASSERT (*(String - 1) == '0');\r
- if (*(String - 1) != '0') {\r
- return 0;\r
- }\r
- //\r
- // Skip the 'X'\r
- //\r
- String++;\r
- }\r
-\r
- Result = 0;\r
- \r
- while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {\r
- //\r
- // If the Hex Number represented by String overflows according \r
- // to the range defined by UINTN, then ASSERT().\r
- //\r
- ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4));\r
-\r
- Result = LShiftU64 (Result, 4);\r
- Result = Result + InternalAsciiHexCharToUintn (*String);\r
- String++;\r
- }\r
-\r
+ AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result);\r
return Result;\r
}\r
\r
\r
ReturnValue = Destination;\r
while (*Source != '\0') {\r
- *(Destination++) = (CHAR16) *(Source++);\r
+ *(Destination++) = (CHAR16)(UINT8) *(Source++);\r
}\r
//\r
// End the Destination with a NULL.\r
\r
#endif\r
\r
+//\r
+// The basis for Base64 encoding is RFC 4686 https://tools.ietf.org/html/rfc4648\r
+//\r
+// RFC 4686 has a number of MAY and SHOULD cases. This implementation chooses\r
+// the more restrictive versions for security concerns (see RFC 4686 section 3.3).\r
+//\r
+// A invalid character, if encountered during the decode operation, causes the data\r
+// to be rejected. In addition, the '=' padding character is only allowed at the end\r
+// of the Base64 encoded string.\r
+//\r
+#define BAD_V 99\r
+\r
+STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
+ "abcdefghijklmnopqrstuvwxyz"\r
+ "0123456789+/";\r
+\r
+STATIC UINT8 DecodingTable[] = {\r
+ //\r
+ // Valid characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\r
+ // Also, set '=' as a zero for decoding\r
+ // 0 , 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 10\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, 62, BAD_V, BAD_V, BAD_V, 63, // 20\r
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, BAD_V, BAD_V, BAD_V, 0, BAD_V, BAD_V, // 30\r
+ BAD_V, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40\r
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 50\r
+ BAD_V, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 60\r
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 70\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 80\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // 90\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // a0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // b0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // c0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // d0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, // d0\r
+ BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V, BAD_V // f0\r
+};\r
+\r
+/**\r
+ Convert binary data to a Base64 encoded ascii string based on RFC4648.\r
+\r
+ Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.\r
+ The Ascii string is produced by converting the data string specified by Source and SourceLength.\r
+\r
+ @param Source Input UINT8 data\r
+ @param SourceLength Number of UINT8 bytes of data\r
+ @param Destination Pointer to output string buffer\r
+ @param DestinationSize Size of ascii buffer. Set to 0 to get the size needed.\r
+ Caller is responsible for passing in buffer of DestinationSize\r
+\r
+ @retval RETURN_SUCCESS When ascii buffer is filled in.\r
+ @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.\r
+ @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).\r
+ @retval RETURN_BUFFER_TOO_SMALL If SourceLength is 0 and DestinationSize is <1.\r
+ @retval RETURN_BUFFER_TOO_SMALL If Destination is NULL or DestinationSize is smaller than required buffersize.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+Base64Encode (\r
+ IN CONST UINT8 *Source,\r
+ IN UINTN SourceLength,\r
+ OUT CHAR8 *Destination OPTIONAL,\r
+ IN OUT UINTN *DestinationSize\r
+ )\r
+{\r
+\r
+ UINTN RequiredSize;\r
+ UINTN Left;\r
+\r
+ //\r
+ // Check pointers, and SourceLength is valid\r
+ //\r
+ if ((Source == NULL) || (DestinationSize == NULL)) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Allow for RFC 4648 test vector 1\r
+ //\r
+ if (SourceLength == 0) {\r
+ if (*DestinationSize < 1) {\r
+ *DestinationSize = 1;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+ *DestinationSize = 1;\r
+ *Destination = '\0';\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Check if SourceLength or DestinationSize is valid\r
+ //\r
+ if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // 4 ascii per 3 bytes + NULL\r
+ //\r
+ RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;\r
+ if ((Destination == NULL) || *DestinationSize < RequiredSize) {\r
+ *DestinationSize = RequiredSize;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ Left = SourceLength;\r
+\r
+ //\r
+ // Encode 24 bits (three bytes) into 4 ascii characters\r
+ //\r
+ while (Left >= 3) {\r
+\r
+ *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2 ];\r
+ *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+ *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];\r
+ *Destination++ = EncodingTable[( Source[2] & 0x3f)];\r
+ Left -= 3;\r
+ Source += 3;\r
+ }\r
+\r
+ //\r
+ // Handle the remainder, and add padding '=' characters as necessary.\r
+ //\r
+ switch (Left) {\r
+ case 0:\r
+\r
+ //\r
+ // No bytes Left, done.\r
+ //\r
+ break;\r
+ case 1:\r
+\r
+ //\r
+ // One more data byte, two pad characters\r
+ //\r
+ *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];\r
+ *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];\r
+ *Destination++ = '=';\r
+ *Destination++ = '=';\r
+ break;\r
+ case 2:\r
+\r
+ //\r
+ // Two more data bytes, and one pad character\r
+ //\r
+ *Destination++ = EncodingTable[( Source[0] & 0xfc) >> 2];\r
+ *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+ *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];\r
+ *Destination++ = '=';\r
+ break;\r
+ }\r
+ //\r
+ // Add terminating NULL\r
+ //\r
+ *Destination = '\0';\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Convert Base64 ascii string to binary data based on RFC4648.\r
+\r
+ Produce Null-terminated binary data in the output buffer specified by Destination and DestinationSize.\r
+ The binary data is produced by converting the Base64 ascii string specified by Source and SourceLength.\r
+\r
+ @param Source Input ASCII characters\r
+ @param SourceLength Number of ASCII characters\r
+ @param Destination Pointer to output buffer\r
+ @param DestinationSize Caller is responsible for passing in buffer of at least DestinationSize.\r
+ Set 0 to get the size needed. Set to bytes stored on return.\r
+\r
+ @retval RETURN_SUCCESS When binary buffer is filled in.\r
+ @retval RETURN_INVALID_PARAMETER If Source is NULL or DestinationSize is NULL.\r
+ @retval RETURN_INVALID_PARAMETER If SourceLength or DestinationSize is bigger than (MAX_ADDRESS -(UINTN)Destination ).\r
+ @retval RETURN_INVALID_PARAMETER If there is any invalid character in input stream.\r
+ @retval RETURN_BUFFER_TOO_SMALL If buffer length is smaller than required buffer size.\r
+ **/\r
+RETURN_STATUS\r
+EFIAPI\r
+Base64Decode (\r
+ IN CONST CHAR8 *Source,\r
+ IN UINTN SourceLength,\r
+ OUT UINT8 *Destination OPTIONAL,\r
+ IN OUT UINTN *DestinationSize\r
+ )\r
+{\r
+\r
+ UINT32 Value;\r
+ CHAR8 Chr;\r
+ INTN BufferSize;\r
+ UINTN SourceIndex;\r
+ UINTN DestinationIndex;\r
+ UINTN Index;\r
+ UINTN ActualSourceLength;\r
+\r
+ //\r
+ // Check pointers are not NULL\r
+ //\r
+ if ((Source == NULL) || (DestinationSize == NULL)) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check if SourceLength or DestinationSize is valid\r
+ //\r
+ if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))){\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ ActualSourceLength = 0;\r
+ BufferSize = 0;\r
+\r
+ //\r
+ // Determine the actual number of valid characters in the string.\r
+ // All invalid characters except selected white space characters,\r
+ // will cause the Base64 string to be rejected. White space to allow\r
+ // properly formatted XML will be ignored.\r
+ //\r
+ // See section 3.3 of RFC 4648.\r
+ //\r
+ for (SourceIndex = 0; SourceIndex < SourceLength; SourceIndex++) {\r
+\r
+ //\r
+ // '=' is part of the quantum\r
+ //\r
+ if (Source[SourceIndex] == '=') {\r
+ ActualSourceLength++;\r
+ BufferSize--;\r
+\r
+ //\r
+ // Only two '=' characters can be valid.\r
+ //\r
+ if (BufferSize < -2) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ else {\r
+ Chr = Source[SourceIndex];\r
+ if (BAD_V != DecodingTable[(UINT8) Chr]) {\r
+\r
+ //\r
+ // The '=' characters are only valid at the end, so any\r
+ // valid character after an '=', will be flagged as an error.\r
+ //\r
+ if (BufferSize < 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ ActualSourceLength++;\r
+ }\r
+ else {\r
+\r
+ //\r
+ // The reset of the decoder will ignore all invalid characters allowed here.\r
+ // Ignoring selected white space is useful. In this case, the decoder will\r
+ // ignore ' ', '\t', '\n', and '\r'.\r
+ //\r
+ if ((Chr != ' ') &&(Chr != '\t') &&(Chr != '\n') &&(Chr != '\r')) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // The Base64 character string must be a multiple of 4 character quantums.\r
+ //\r
+ if (ActualSourceLength % 4 != 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ BufferSize += ActualSourceLength / 4 * 3;\r
+ if (BufferSize < 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // BufferSize is >= 0\r
+ //\r
+ if ((Destination == NULL) || (*DestinationSize < (UINTN) BufferSize)) {\r
+ *DestinationSize = BufferSize;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ //\r
+ // If no decodable characters, return a size of zero. RFC 4686 test vector 1.\r
+ //\r
+ if (ActualSourceLength == 0) {\r
+ *DestinationSize = 0;\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Input data is verified to be a multiple of 4 valid charcters. Process four\r
+ // characters at a time. Uncounted (ie. invalid) characters will be ignored.\r
+ //\r
+ for (SourceIndex = 0, DestinationIndex = 0; (SourceIndex < SourceLength) && (DestinationIndex < *DestinationSize); ) {\r
+ Value = 0;\r
+\r
+ //\r
+ // Get 24 bits of data from 4 input characters, each character representing 6 bits\r
+ //\r
+ for (Index = 0; Index < 4; Index++) {\r
+ do {\r
+ Chr = DecodingTable[(UINT8) Source[SourceIndex++]];\r
+ } while (Chr == BAD_V);\r
+ Value <<= 6;\r
+ Value |= (UINT32)Chr;\r
+ }\r
+\r
+ //\r
+ // Store 3 bytes of binary data (24 bits)\r
+ //\r
+ *Destination++ = (UINT8) (Value >> 16);\r
+ DestinationIndex++;\r
+\r
+ //\r
+ // Due to the '=' special cases for the two bytes at the end,\r
+ // we have to check the length and not store the padding data\r
+ //\r
+ if (DestinationIndex++ < *DestinationSize) {\r
+ *Destination++ = (UINT8) (Value >> 8);\r
+ }\r
+ if (DestinationIndex++ < *DestinationSize) {\r
+ *Destination++ = (UINT8) Value;\r
+ }\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
/**\r
Converts an 8-bit value to an 8-bit BCD value.\r
\r