/** @file\r
- Unicode string primatives.\r
+ Unicode and ASCII string primitives.\r
\r
- Copyright (c) 2006, Intel Corporation<BR>\r
- All rights reserved. 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
-\r
- Module Name: String.c\r
-\r
-**/\r
-\r
-/**\r
- Copies one Null-terminated Unicode string to another Null-terminated Unicode\r
- string and returns the new Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the \r
- Null-terminator, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
-\r
- @return Destiantion\r
-\r
-**/\r
-CHAR16 *\r
-EFIAPI\r
-StrCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) > StrLen (Source));\r
-\r
- ReturnValue = Destination;\r
- while (*Source) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
-}\r
-\r
-/**\r
- Copies one Null-terminated Unicode string with a maximum length to another\r
- Null-terminated Unicode string with a maximum length and returns the new\r
- Unicode string.\r
-\r
- This function copies the contents of the Unicode string Source to the Unicode\r
- string Destination, and returns Destination. At most, Length Unicode\r
- characters are copied from Source to Destination. If Length is 0, then\r
- Destination is returned unmodified. If Length is greater that the number of\r
- Unicode characters in Source, then Destination is padded with Null Unicode\r
- characters. If Source and Destination overlap, then the results are\r
- undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the \r
- Null-terminator, then ASSERT().\r
-\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to copy.\r
-\r
- @return Destination\r
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
-CHAR16 *\r
-EFIAPI\r
-StrnCpy (\r
- OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source,\r
- IN UINTN Length\r
- )\r
-{\r
- CHAR16 *ReturnValue;\r
-\r
- if (Length == 0) {\r
- return Destination;\r
- }\r
-\r
- //\r
- // Destination cannot be NULL if Length is not zero\r
- //\r
- ASSERT (Destination != NULL);\r
-\r
- //\r
- // Destination and source cannot overlap\r
- // Q: Does Source have to be NULL-terminated?\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) >= Length);\r
\r
- ReturnValue = Destination;\r
-\r
- while ((*Source != L'\0') && (Length > 0)) {\r
- *(Destination++) = *(Source++);\r
- Length--;\r
- }\r
-\r
- ZeroMem (Destination, Length * sizeof (*Destination));\r
- return ReturnValue;\r
-}\r
+#include "BaseLibInternals.h"\r
\r
/**\r
Returns the length of a Null-terminated Unicode string.\r
Unicode string specified by String.\r
\r
If String is NULL, then ASSERT().\r
+ If String is not aligned on a 16-bit boundary, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the \r
+ PcdMaximumUnicodeStringLength Unicode characters, not including the\r
Null-terminator, then ASSERT().\r
\r
- @param String Pointer to a Null-terminated Unicode string.\r
+ @param String A pointer to a Null-terminated Unicode string.\r
\r
@return The length of String.\r
\r
UINTN\r
EFIAPI\r
StrLen (\r
- IN CONST CHAR16 *String\r
+ IN CONST CHAR16 *String\r
)\r
{\r
- UINTN Length;\r
+ UINTN Length;\r
\r
ASSERT (String != NULL);\r
+ ASSERT (((UINTN)String & BIT0) == 0);\r
\r
for (Length = 0; *String != L'\0'; String++, Length++) {\r
//\r
ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));\r
}\r
}\r
+\r
return Length;\r
}\r
\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\r
- string specified by 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
+ If String is not aligned on a 16-bit boundary, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the \r
+ PcdMaximumUnicodeStringLength Unicode characters, not including the\r
Null-terminator, then ASSERT().\r
\r
- @param String Pointer to a Null-terminated Unicode string.\r
+ @param String A pointer to a Null-terminated Unicode string.\r
\r
@return The size of String.\r
\r
UINTN\r
EFIAPI\r
StrSize (\r
- IN CONST CHAR16 *String\r
+ IN CONST CHAR16 *String\r
)\r
{\r
return (StrLen (String) + 1) * sizeof (*String);\r
mismatched Unicode character in FirstString.\r
\r
If FirstString is NULL, then ASSERT().\r
+ If FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
If SecondString is NULL, then ASSERT().\r
+ If SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the \r
+ than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
Null-terminator, then ASSERT().\r
If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the \r
+ than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
Null-terminator, then ASSERT().\r
\r
- @param FirstString Pointer to a Null-terminated Unicode string.\r
- @param SecondString Pointer to a Null-terminated Unicode string.\r
+ @param FirstString A pointer to a Null-terminated Unicode string.\r
+ @param SecondString A pointer to a Null-terminated Unicode string.\r
\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
+ @retval 0 FirstString is identical to SecondString.\r
+ @return others FirstString is not identical to SecondString.\r
\r
**/\r
INTN\r
EFIAPI\r
StrCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString\r
+ IN CONST CHAR16 *FirstString,\r
+ IN CONST CHAR16 *SecondString\r
)\r
{\r
//\r
FirstString++;\r
SecondString++;\r
}\r
+\r
return *FirstString - *SecondString;\r
}\r
\r
/**\r
- Compares two Null-terminated Unicode strings with maximum lengths, and\r
- returns the difference between the first mismatched Unicode characters.\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
This function compares the Null-terminated Unicode string FirstString to the\r
Null-terminated Unicode string SecondString. At most, Length Unicode\r
value returned is the first mismatched Unicode character in SecondString\r
subtracted from the first mismatched Unicode character in FirstString.\r
\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
+ If Length > 0 and FirstString is NULL, then ASSERT().\r
+ If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length > 0 and SecondString is NULL, then ASSERT().\r
+ If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
+ If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
+ PcdMaximumUnicodeStringLength, then ASSERT().\r
+ If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than\r
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
+ then ASSERT().\r
+ If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than\r
+ PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
+ then ASSERT().\r
\r
- @param FirstString Pointer to a Null-terminated Unicode string.\r
- @param SecondString Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to compare.\r
+ @param FirstString A pointer to a Null-terminated Unicode string.\r
+ @param SecondString A pointer to a Null-terminated Unicode string.\r
+ @param Length The maximum number of Unicode characters to compare.\r
\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
+ @retval 0 FirstString is identical to SecondString.\r
+ @return others FirstString is not identical to SecondString.\r
\r
**/\r
INTN\r
EFIAPI\r
StrnCmp (\r
- IN CONST CHAR16 *FirstString,\r
- IN CONST CHAR16 *SecondString,\r
- IN UINTN Length\r
+ IN CONST CHAR16 *FirstString,\r
+ IN CONST CHAR16 *SecondString,\r
+ IN UINTN Length\r
)\r
{\r
if (Length == 0) {\r
ASSERT (StrSize (FirstString) != 0);\r
ASSERT (StrSize (SecondString) != 0);\r
\r
+ if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
+ ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));\r
+ }\r
+\r
while ((*FirstString != L'\0') &&\r
+ (*SecondString != L'\0') &&\r
(*FirstString == *SecondString) &&\r
- (Length > 1)) {\r
+ (Length > 1))\r
+ {\r
FirstString++;\r
SecondString++;\r
Length--;\r
}\r
\r
/**\r
- Concatenates one Null-terminated Unicode string to another Null-terminated\r
- Unicode string, and returns the concatenated Unicode string.\r
-\r
- This function concatenates two Null-terminated Unicode strings. The contents\r
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination. The Null-terminated concatenated\r
- Unicode String is returned. If Source and Destination overlap, then the\r
- results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
- and Source results in a Unicode string with more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
+ Returns the first occurrence of a Null-terminated Unicode sub-string\r
+ in a Null-terminated Unicode string.\r
\r
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
+ This function scans the contents of the Null-terminated Unicode string\r
+ specified by String and returns the first occurrence of SearchString.\r
+ If SearchString is not found in String, then NULL is returned. If\r
+ the length of SearchString is zero, then String is\r
+ returned.\r
+\r
+ If String is NULL, then ASSERT().\r
+ If String is not aligned on a 16-bit boundary, then ASSERT().\r
+ If SearchString is NULL, then ASSERT().\r
+ If SearchString is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+ If PcdMaximumUnicodeStringLength is not zero, and SearchString\r
+ or String contains more than PcdMaximumUnicodeStringLength Unicode\r
+ characters, not including the Null-terminator, then ASSERT().\r
\r
- @return Destination\r
+ @param String A pointer to a Null-terminated Unicode string.\r
+ @param SearchString A pointer to a Null-terminated Unicode string to search for.\r
+\r
+ @retval NULL If the SearchString does not appear in String.\r
+ @return others If there is a match.\r
\r
**/\r
CHAR16 *\r
EFIAPI\r
-StrCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source\r
+StrStr (\r
+ IN CONST CHAR16 *String,\r
+ IN CONST CHAR16 *SearchString\r
)\r
{\r
- StrCpy (Destination + StrLen (Destination), Source);\r
+ CONST CHAR16 *FirstMatch;\r
+ CONST CHAR16 *SearchStringTmp;\r
\r
//\r
- // Size of the resulting string should never be zero.\r
- // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
+ // Length tests are performed inside StrLen().\r
//\r
- ASSERT (StrSize (Destination) != 0);\r
- return Destination;\r
+ ASSERT (StrSize (String) != 0);\r
+ ASSERT (StrSize (SearchString) != 0);\r
+\r
+ if (*SearchString == L'\0') {\r
+ return (CHAR16 *)String;\r
+ }\r
+\r
+ while (*String != L'\0') {\r
+ SearchStringTmp = SearchString;\r
+ FirstMatch = String;\r
+\r
+ while ( (*String == *SearchStringTmp)\r
+ && (*String != L'\0'))\r
+ {\r
+ String++;\r
+ SearchStringTmp++;\r
+ }\r
+\r
+ if (*SearchStringTmp == L'\0') {\r
+ return (CHAR16 *)FirstMatch;\r
+ }\r
+\r
+ if (*String == L'\0') {\r
+ return NULL;\r
+ }\r
+\r
+ String = FirstMatch + 1;\r
+ }\r
+\r
+ return NULL;\r
}\r
\r
/**\r
- Concatenates one Null-terminated Unicode string with a maximum length to the\r
- end 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
- of Null-terminated Unicode string Source are concatenated to the end of\r
- Null-terminated Unicode string Destination, and Destination is returned. At\r
- most, Length Unicode characters are concatenated from Source to the end of\r
- Destination, and Destination is always Null-terminated. If Length is 0, then\r
- Destination is returned unmodified. If Source and Destination overlap, then\r
- the results are undefined.\r
-\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If Source and Destination overlap, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more\r
- than PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination\r
- and Source results in a Unicode string with more than\r
- PcdMaximumUnicodeStringLength Unicode characters not including the\r
- Null-terminator, then ASSERT().\r
+ Check if a Unicode character is a decimal character.\r
+\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
- @param Destination Pointer to a Null-terminated Unicode string.\r
- @param Source Pointer to a Null-terminated Unicode string.\r
- @param Length Maximum number of Unicode characters to concatenate from\r
- Source.\r
+ @param Char The character to check against.\r
\r
- @return Destination\r
+ @retval TRUE If the Char is a decmial character.\r
+ @retval FALSE If the Char is not a decmial character.\r
\r
**/\r
-CHAR16 *\r
+BOOLEAN\r
EFIAPI\r
-StrnCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CONST CHAR16 *Source,\r
- IN UINTN Length\r
+InternalIsDecimalDigitCharacter (\r
+ IN CHAR16 Char\r
)\r
{\r
- StrnCpy (Destination + StrLen (Destination), Source, Length);\r
+ return (BOOLEAN)(Char >= L'0' && Char <= L'9');\r
+}\r
\r
- //\r
- // Size of the resulting string should never be zero.\r
- // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
- //\r
- ASSERT (StrSize (Destination) != 0);\r
- return Destination;\r
+/**\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
+ which maps to a valid small-case ASCII character, i.e.\r
+ L'a' to L'z'. For other Unicode character, the input character\r
+ is returned directly.\r
+\r
+ @param Char The character to convert.\r
+\r
+ @retval LowerCharacter If the Char is with range L'a' to L'z'.\r
+ @retval Unchanged Otherwise.\r
+\r
+**/\r
+CHAR16\r
+EFIAPI\r
+CharToUpper (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ if ((Char >= L'a') && (Char <= L'z')) {\r
+ return (CHAR16)(Char - (L'a' - L'A'));\r
+ }\r
+\r
+ return Char;\r
}\r
\r
/**\r
- Copies one Null-terminated ASCII string to another Null-terminated ASCII\r
- string and returns the new ASCII string.\r
+ Convert a Unicode character to numerical value.\r
\r
- This function copies the contents of the ASCII string Source to the ASCII\r
- string Destination, and returns Destination. If Source and Destination\r
- overlap, then the results are undefined.\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
+ Unicode character, the value returned does not make sense.\r
\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 Source contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
- then ASSERT().\r
+ @param Char The character to convert.\r
\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
+ @return The numerical value converted.\r
\r
- @return Destination\r
+**/\r
+UINTN\r
+EFIAPI\r
+InternalHexCharToUintn (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ if (InternalIsDecimalDigitCharacter (Char)) {\r
+ return Char - L'0';\r
+ }\r
+\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
+ L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
+\r
+\r
+ @param Char The character to check against.\r
+\r
+ @retval TRUE If the Char is a hexadecmial character.\r
+ @retval FALSE If the Char is not a hexadecmial character.\r
\r
**/\r
-CHAR8 *\r
+BOOLEAN\r
EFIAPI\r
-AsciiStrCpy (\r
- OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source\r
+InternalIsHexaDecimalDigitCharacter (\r
+ IN CHAR16 Char\r
)\r
{\r
- CHAR8 *ReturnValue;\r
+ return (BOOLEAN)(InternalIsDecimalDigitCharacter (Char) ||\r
+ (Char >= L'A' && Char <= L'F') ||\r
+ (Char >= L'a' && Char <= L'f'));\r
+}\r
\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
+/**\r
+ Convert a Null-terminated Unicode decimal string to a value of\r
+ type UINTN.\r
\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));\r
+ This function returns a value of type UINTN by interpreting the contents\r
+ of the Unicode string specified by String as a decimal number. The format\r
+ of the input Unicode string String is:\r
\r
- ReturnValue = Destination;\r
- while (*Source) {\r
- *(Destination++) = *(Source++);\r
- }\r
- *Destination = 0;\r
- return ReturnValue;\r
+ [spaces] [decimal digits].\r
+\r
+ The valid decimal digit character is in the range [0-9]. The\r
+ function will ignore the pad space, which includes spaces or\r
+ tab characters, before [decimal digits]. The running zero in the\r
+ beginning of [decimal digits] will be ignored. Then, the function\r
+ stops at the first character that is a not a valid decimal character\r
+ or a Null-terminator, whichever one comes first.\r
+\r
+ If String is NULL, then ASSERT().\r
+ If String is not aligned in a 16-bit boundary, then ASSERT().\r
+ If String has only pad spaces, then 0 is returned.\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 MAX_UINTN is returned.\r
+\r
+ If PcdMaximumUnicodeStringLength is not zero, and String contains\r
+ more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
+ the Null-terminator, then ASSERT().\r
+\r
+ @param String A pointer to a Null-terminated Unicode string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrDecimalToUintn (\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINTN Result;\r
+\r
+ StrDecimalToUintnS (String, (CHAR16 **)NULL, &Result);\r
+ return Result;\r
}\r
\r
/**\r
- Copies one Null-terminated ASCII string with a maximum length to another\r
- Null-terminated ASCII string with a maximum length and returns the new ASCII\r
- string.\r
-\r
- This function copies the contents of the ASCII string Source to the ASCII\r
- string Destination, and returns Destination. At most, Length ASCII characters\r
- are copied from Source to Destination. If Length is 0, then Destination is\r
- returned unmodified. If Length is greater that the number of ASCII characters\r
- in Source, then Destination is padded with Null ASCII characters. If Source\r
- and Destination overlap, then the results are undefined.\r
-\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 Source contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+ Convert a Null-terminated Unicode decimal string to a value of\r
+ type UINT64.\r
+\r
+ This function returns a value of type UINT64 by interpreting the contents\r
+ of the Unicode string specified by String as a decimal number. The format\r
+ of the input Unicode string String is:\r
+\r
+ [spaces] [decimal digits].\r
+\r
+ The valid decimal digit character is in the range [0-9]. The\r
+ function will ignore the pad space, which includes spaces or\r
+ tab characters, before [decimal digits]. The running zero in the\r
+ beginning of [decimal digits] will be ignored. Then, the function\r
+ stops at the first character that is a not a valid decimal character\r
+ or a Null-terminator, whichever one comes first.\r
+\r
+ If String is NULL, then ASSERT().\r
+ If String is not aligned in a 16-bit boundary, then ASSERT().\r
+ If String has only pad spaces, then 0 is returned.\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 MAX_UINT64 is returned.\r
+\r
+ If PcdMaximumUnicodeStringLength is not zero, and String contains\r
+ more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
+ the Null-terminator, then ASSERT().\r
+\r
+ @param String A pointer to a Null-terminated Unicode string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+StrDecimalToUint64 (\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINT64 Result;\r
+\r
+ StrDecimalToUint64S (String, (CHAR16 **)NULL, &Result);\r
+ return Result;\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.\r
+\r
+ This function returns a value of type UINTN by interpreting the contents\r
+ of the Unicode string specified by String as a hexadecimal number.\r
+ The format of the input Unicode string String is:\r
+\r
+ [spaces][zeros][x][hexadecimal digits].\r
+\r
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
+ If "x" appears in the input string, it must be prefixed with at least one 0.\r
+ The function will ignore the pad space, which includes spaces or tab characters,\r
+ before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
+ [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
+ first valid hexadecimal digit. Then, the function stops at the first character that is\r
+ a not a valid hexadecimal character or NULL, whichever one comes first.\r
+\r
+ If String is NULL, then ASSERT().\r
+ If String is not aligned in a 16-bit boundary, then ASSERT().\r
+ If String has only pad spaces, then zero is returned.\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 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
then ASSERT().\r
\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
- @param Length Maximum number of ASCII characters to copy.\r
+ @param String A pointer to a Null-terminated Unicode string.\r
\r
- @return Destination\r
+ @retval Value translated from String.\r
\r
**/\r
-CHAR8 *\r
+UINTN\r
EFIAPI\r
-AsciiStrnCpy (\r
- OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source,\r
- IN UINTN Length\r
+StrHexToUintn (\r
+ IN CONST CHAR16 *String\r
)\r
{\r
- CHAR8 *ReturnValue;\r
+ UINTN Result;\r
\r
- if (Length == 0) {\r
- return Destination;\r
- }\r
+ StrHexToUintnS (String, (CHAR16 **)NULL, &Result);\r
+ return Result;\r
+}\r
\r
- //\r
- // Destination cannot be NULL\r
- //\r
- ASSERT (Destination != NULL);\r
+/**\r
+ Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.\r
\r
- //\r
- // Destination and source cannot overlap\r
- //\r
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));\r
- ASSERT ((UINTN)(Source - Destination) >= Length);\r
+ This function returns a value of type UINT64 by interpreting the contents\r
+ of the Unicode string specified by String as a hexadecimal number.\r
+ The format of the input Unicode string String is\r
\r
- ReturnValue = Destination;\r
+ [spaces][zeros][x][hexadecimal digits].\r
\r
- while (*Source && Length > 0) {\r
- *(Destination++) = *(Source++);\r
- Length--;\r
- }\r
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.\r
+ If "x" appears in the input string, it must be prefixed with at least one 0.\r
+ The function will ignore the pad space, which includes spaces or tab characters,\r
+ before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or\r
+ [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the\r
+ first valid hexadecimal digit. Then, the function stops at the first character that is\r
+ a not a valid hexadecimal character or NULL, whichever one comes first.\r
+\r
+ If String is NULL, then ASSERT().\r
+ If String is not aligned in a 16-bit boundary, then ASSERT().\r
+ If String has only pad spaces, then zero is returned.\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 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
+ then ASSERT().\r
\r
- ZeroMem (Destination, Length * sizeof (*Destination));\r
- return ReturnValue;\r
+ @param String A pointer to a Null-terminated Unicode string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+StrHexToUint64 (\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINT64 Result;\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
+ decimal character. The valid decimal character is from\r
+ '0' to '9'.\r
+\r
+ @param Char The character to check against.\r
+\r
+ @retval TRUE If the Char is a decmial character.\r
+ @retval FALSE If the Char is not a decmial character.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalAsciiIsDecimalDigitCharacter (\r
+ IN CHAR8 Char\r
+ )\r
+{\r
+ return (BOOLEAN)(Char >= '0' && Char <= '9');\r
+}\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
+ L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
+\r
+\r
+ @param Char The character to check against.\r
+\r
+ @retval TRUE If the Char is a hexadecmial character.\r
+ @retval FALSE If the Char is not a hexadecmial character.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalAsciiIsHexaDecimalDigitCharacter (\r
+ IN CHAR8 Char\r
+ )\r
+{\r
+ return (BOOLEAN)(InternalAsciiIsDecimalDigitCharacter (Char) ||\r
+ (Char >= 'A' && Char <= 'F') ||\r
+ (Char >= 'a' && Char <= 'f'));\r
}\r
\r
/**\r
This function returns the number of ASCII characters in the Null-terminated\r
ASCII string specified by String.\r
\r
- If String is NULL, then ASSERT().\r
+ If Length > 0 and Destination is NULL, then ASSERT().\r
+ If Length > 0 and Source 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
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
\r
- @param String Pointer to a Null-terminated ASCII string.\r
+ @param String A pointer to a Null-terminated ASCII string.\r
\r
@return The length of String.\r
\r
UINTN\r
EFIAPI\r
AsciiStrLen (\r
- IN CONST CHAR8 *String\r
+ IN CONST CHAR8 *String\r
)\r
{\r
- UINTN Length;\r
+ UINTN Length;\r
\r
ASSERT (String != NULL);\r
\r
ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));\r
}\r
}\r
+\r
return Length;\r
}\r
\r
\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
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
\r
- @param String Pointer to a Null-terminated ASCII string.\r
+ @param String A pointer to a Null-terminated ASCII string.\r
\r
@return The size of String.\r
\r
UINTN\r
EFIAPI\r
AsciiStrSize (\r
- IN CONST CHAR8 *String\r
+ IN CONST CHAR8 *String\r
)\r
{\r
return (AsciiStrLen (String) + 1) * sizeof (*String);\r
If FirstString is NULL, then ASSERT().\r
If SecondString is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
- than PcdMaximumAsciiStringLength ASCII characters not including the\r
+ than PcdMaximumAsciiStringLength ASCII characters, not including the\r
Null-terminator, then ASSERT().\r
\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\r
+ @param FirstString A pointer to a Null-terminated ASCII string.\r
+ @param SecondString A pointer to a Null-terminated ASCII string.\r
\r
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
+ @retval ==0 FirstString is identical to SecondString.\r
+ @retval !=0 FirstString is not identical to SecondString.\r
\r
**/\r
INTN\r
EFIAPI\r
AsciiStrCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString\r
+ IN CONST CHAR8 *FirstString,\r
+ IN CONST CHAR8 *SecondString\r
)\r
{\r
//\r
return *FirstString - *SecondString;\r
}\r
\r
-STATIC\r
+/**\r
+ Converts a lowercase Ascii character to upper one.\r
+\r
+ If Chr is lowercase Ascii character, then converts it to upper one.\r
+\r
+ If Value >= 0xA0, then ASSERT().\r
+ If (Value & 0x0F) >= 0x0A, then ASSERT().\r
+\r
+ @param Chr one Ascii character\r
+\r
+ @return The uppercase value of Ascii character\r
+\r
+**/\r
CHAR8\r
EFIAPI\r
-AsciiToUpper (\r
- IN CHAR8 Chr\r
+AsciiCharToUpper (\r
+ IN CHAR8 Chr\r
+ )\r
+{\r
+ return (UINT8)((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);\r
+}\r
+\r
+/**\r
+ Convert a ASCII character to numerical value.\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
+ ASCII character, the value returned does not make sense.\r
+\r
+ @param Char The character to convert.\r
+\r
+ @return The numerical value converted.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+InternalAsciiHexCharToUintn (\r
+ IN CHAR8 Char\r
)\r
{\r
- return (Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr;\r
+ if (InternalIsDecimalDigitCharacter (Char)) {\r
+ return Char - '0';\r
+ }\r
+\r
+ return (10 + AsciiCharToUpper (Char) - 'A');\r
}\r
\r
/**\r
If FirstString is NULL, then ASSERT().\r
If SecondString is NULL, then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
- than PcdMaximumAsciiStringLength ASCII characters not including the\r
+ than PcdMaximumAsciiStringLength ASCII characters, not including the\r
Null-terminator, then ASSERT().\r
\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\r
+ @param FirstString A pointer to a Null-terminated ASCII string.\r
+ @param SecondString A pointer to a Null-terminated ASCII string.\r
\r
- @retval 0 FirstString is identical to SecondString using case insensitive\r
- comparisons.\r
- @retval !=0 FirstString is not identical to SecondString using case\r
- insensitive comparisons.\r
+ @retval ==0 FirstString is identical to SecondString using case insensitive\r
+ comparisons.\r
+ @retval !=0 FirstString is not identical to SecondString using case\r
+ insensitive comparisons.\r
\r
**/\r
INTN\r
EFIAPI\r
AsciiStriCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString\r
+ IN CONST CHAR8 *FirstString,\r
+ IN CONST CHAR8 *SecondString\r
)\r
{\r
+ CHAR8 UpperFirstString;\r
+ CHAR8 UpperSecondString;\r
+\r
//\r
// ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
//\r
ASSERT (AsciiStrSize (FirstString));\r
ASSERT (AsciiStrSize (SecondString));\r
\r
- while ((*FirstString != '\0') &&\r
- (AsciiToUpper (*FirstString) == AsciiToUpper (*SecondString))) {\r
+ UpperFirstString = AsciiCharToUpper (*FirstString);\r
+ UpperSecondString = AsciiCharToUpper (*SecondString);\r
+ while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {\r
FirstString++;\r
SecondString++;\r
+ UpperFirstString = AsciiCharToUpper (*FirstString);\r
+ UpperSecondString = AsciiCharToUpper (*SecondString);\r
}\r
\r
- return AsciiToUpper (*FirstString) - AsciiToUpper (*SecondString);\r
+ return UpperFirstString - UpperSecondString;\r
}\r
\r
/**\r
is the first mismatched ASCII character in SecondString subtracted from the\r
first mismatched ASCII character in FirstString.\r
\r
- If FirstString is NULL, then ASSERT().\r
- If SecondString is NULL, then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\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
+ PcdMaximumAsciiStringLength, then ASSERT().\r
+ If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than\r
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero and SecondString contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+ If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than\r
+ PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
then ASSERT().\r
\r
- @param FirstString Pointer to a Null-terminated ASCII string.\r
- @param SecondString Pointer to a Null-terminated ASCII string.\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
- @retval 0 FirstString is identical to SecondString.\r
- @retval !=0 FirstString is not identical to SecondString.\r
+ @retval ==0 FirstString is identical to SecondString.\r
+ @retval !=0 FirstString is not identical to SecondString.\r
\r
**/\r
INTN\r
EFIAPI\r
AsciiStrnCmp (\r
- IN CONST CHAR8 *FirstString,\r
- IN CONST CHAR8 *SecondString,\r
- IN UINTN Length\r
+ IN CONST CHAR8 *FirstString,\r
+ IN CONST CHAR8 *SecondString,\r
+ IN UINTN Length\r
)\r
{\r
+ if (Length == 0) {\r
+ return 0;\r
+ }\r
+\r
//\r
// ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
//\r
ASSERT (AsciiStrSize (FirstString));\r
ASSERT (AsciiStrSize (SecondString));\r
\r
+ if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+ ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));\r
+ }\r
+\r
while ((*FirstString != '\0') &&\r
+ (*SecondString != '\0') &&\r
(*FirstString == *SecondString) &&\r
- (Length > 1)) {\r
+ (Length > 1))\r
+ {\r
FirstString++;\r
SecondString++;\r
Length--;\r
}\r
+\r
return *FirstString - *SecondString;\r
}\r
\r
/**\r
- Concatenates one Null-terminated ASCII string to another Null-terminated\r
- ASCII string, and returns the concatenated ASCII string.\r
+ Returns the first occurrence of a Null-terminated ASCII sub-string\r
+ in a Null-terminated ASCII string.\r
\r
- This function concatenates two Null-terminated ASCII strings. The contents of\r
- Null-terminated ASCII string Source are concatenated to the end of Null-\r
- terminated ASCII string Destination. The Null-terminated concatenated ASCII\r
- String is returned.\r
+ This function scans the contents of the ASCII string specified by String\r
+ and returns the first occurrence of SearchString. If SearchString is not\r
+ found in String, then NULL is returned. If the length of SearchString is zero,\r
+ then String is returned.\r
\r
- If Destination is NULL, then ASSERT().\r
- If Source is NULL, then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero and Destination contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
- then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero and Source contains more than\r
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
- then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero and concatenating Destination and\r
- Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
- ASCII characters, then ASSERT().\r
+ If String is NULL, then ASSERT().\r
+ If SearchString is NULL, then ASSERT().\r
\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
+ If PcdMaximumAsciiStringLength is not zero, and SearchString or\r
+ String contains more than PcdMaximumAsciiStringLength Unicode characters\r
+ not including the Null-terminator, then ASSERT().\r
\r
- @return Destination\r
+ @param String A pointer to a Null-terminated ASCII string.\r
+ @param SearchString A pointer to a Null-terminated ASCII string to search for.\r
+\r
+ @retval NULL If the SearchString does not appear in String.\r
+ @retval others If there is a match return the first occurrence of SearchingString.\r
+ If the length of SearchString is zero,return String.\r
\r
**/\r
CHAR8 *\r
EFIAPI\r
-AsciiStrCat (\r
- IN OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source\r
+AsciiStrStr (\r
+ IN CONST CHAR8 *String,\r
+ IN CONST CHAR8 *SearchString\r
)\r
{\r
- AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);\r
+ CONST CHAR8 *FirstMatch;\r
+ CONST CHAR8 *SearchStringTmp;\r
\r
//\r
- // Size of the resulting string should never be zero.\r
- // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+ // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
//\r
- ASSERT (AsciiStrSize (Destination) != 0);\r
- return Destination;\r
+ ASSERT (AsciiStrSize (String) != 0);\r
+ ASSERT (AsciiStrSize (SearchString) != 0);\r
+\r
+ if (*SearchString == '\0') {\r
+ return (CHAR8 *)String;\r
+ }\r
+\r
+ while (*String != '\0') {\r
+ SearchStringTmp = SearchString;\r
+ FirstMatch = String;\r
+\r
+ while ( (*String == *SearchStringTmp)\r
+ && (*String != '\0'))\r
+ {\r
+ String++;\r
+ SearchStringTmp++;\r
+ }\r
+\r
+ if (*SearchStringTmp == '\0') {\r
+ return (CHAR8 *)FirstMatch;\r
+ }\r
+\r
+ if (*String == '\0') {\r
+ return NULL;\r
+ }\r
+\r
+ String = FirstMatch + 1;\r
+ }\r
+\r
+ return NULL;\r
}\r
\r
/**\r
- Concatenates one Null-terminated ASCII string with a maximum length to the\r
- end of another Null-terminated ASCII string, and returns the concatenated\r
- ASCII string.\r
-\r
- This function concatenates two Null-terminated ASCII strings. The contents\r
- of Null-terminated ASCII string Source are concatenated to the end of Null-\r
- terminated ASCII string Destination, and Destination is returned. At most,\r
- Length ASCII characters are concatenated from Source to the end of\r
- Destination, and Destination is always Null-terminated. If Length is 0, then\r
- Destination is returned unmodified. If Source and Destination overlap, then\r
- the results are undefined.\r
-\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 Destination contains more than\r
+ Convert a Null-terminated ASCII decimal string to a value of type\r
+ UINTN.\r
+\r
+ This function returns a value of type UINTN by interpreting the contents\r
+ of the ASCII string String as a decimal number. The format of the input\r
+ ASCII string String is:\r
+\r
+ [spaces] [decimal digits].\r
+\r
+ The valid decimal digit character is in the range [0-9]. The function will\r
+ ignore the pad space, which includes spaces or tab characters, before the digits.\r
+ The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
+ function stops at the first character that is a not a valid decimal character or\r
+ Null-terminator, whichever on comes first.\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 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
then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero, and Source contains more than\r
+\r
+ @param String A pointer to a Null-terminated ASCII string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrDecimalToUintn (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ UINTN Result;\r
+\r
+ AsciiStrDecimalToUintnS (String, (CHAR8 **)NULL, &Result);\r
+ return Result;\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated ASCII decimal string to a value of type\r
+ UINT64.\r
+\r
+ This function returns a value of type UINT64 by interpreting the contents\r
+ of the ASCII string String as a decimal number. The format of the input\r
+ ASCII string String is:\r
+\r
+ [spaces] [decimal digits].\r
+\r
+ The valid decimal digit character is in the range [0-9]. The function will\r
+ ignore the pad space, which includes spaces or tab characters, before the digits.\r
+ The running zero in the beginning of [decimal digits] will be ignored. Then, the\r
+ function stops at the first character that is a not a valid decimal character or\r
+ Null-terminator, whichever on comes first.\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 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
then ASSERT().\r
- If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and\r
- Source results in a ASCII string with more than PcdMaximumAsciiStringLength\r
- ASCII characters not including the Null-terminator, then ASSERT().\r
\r
- @param Destination Pointer to a Null-terminated ASCII string.\r
- @param Source Pointer to a Null-terminated ASCII string.\r
- @param Length Maximum number of ASCII characters to concatenate from\r
- Source.\r
+ @param String A pointer to a Null-terminated ASCII string.\r
\r
- @return Destination\r
+ @retval Value translated from String.\r
\r
**/\r
-CHAR8 *\r
+UINT64\r
+EFIAPI\r
+AsciiStrDecimalToUint64 (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ UINT64 Result;\r
+\r
+ AsciiStrDecimalToUint64S (String, (CHAR8 **)NULL, &Result);\r
+ return Result;\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.\r
+\r
+ This function returns a value of type UINTN by interpreting the contents of\r
+ the ASCII string String as a hexadecimal number. The format of the input ASCII\r
+ string String is:\r
+\r
+ [spaces][zeros][x][hexadecimal digits].\r
+\r
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
+ appears in the input string, it must be prefixed with at least one 0. The function\r
+ will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
+ [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
+ will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
+ digit. Then, the function stops at the first character that is a not a valid\r
+ hexadecimal character or Null-terminator, whichever on comes first.\r
+\r
+ If String has only pad spaces, then 0 is returned.\r
+ If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
+ 0 is returned.\r
+\r
+ If the number represented by String overflows according to the range defined by UINTN,\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
+ the Null-terminator, then ASSERT().\r
+\r
+ @param String A pointer to a Null-terminated ASCII string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrHexToUintn (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ UINTN Result;\r
+\r
+ AsciiStrHexToUintnS (String, (CHAR8 **)NULL, &Result);\r
+ return Result;\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.\r
+\r
+ This function returns a value of type UINT64 by interpreting the contents of\r
+ the ASCII string String as a hexadecimal number. The format of the input ASCII\r
+ string String is:\r
+\r
+ [spaces][zeros][x][hexadecimal digits].\r
+\r
+ The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].\r
+ The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"\r
+ appears in the input string, it must be prefixed with at least one 0. The function\r
+ will ignore the pad space, which includes spaces or tab characters, before [zeros],\r
+ [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]\r
+ will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal\r
+ digit. Then, the function stops at the first character that is a not a valid\r
+ hexadecimal character or Null-terminator, whichever on comes first.\r
+\r
+ If String has only pad spaces, then 0 is returned.\r
+ If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then\r
+ 0 is returned.\r
+\r
+ If the number represented by String overflows according to the range defined by UINT64,\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
+ the Null-terminator, then ASSERT().\r
+\r
+ @param String A pointer to a Null-terminated ASCII string.\r
+\r
+ @retval Value translated from String.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsciiStrHexToUint64 (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ UINT64 Result;\r
+\r
+ AsciiStrHexToUint64S (String, (CHAR8 **)NULL, &Result);\r
+ return Result;\r
+}\r
+\r
+STATIC CHAR8 EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
+ "abcdefghijklmnopqrstuvwxyz"\r
+ "0123456789+/";\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
-AsciiStrnCat (\r
- IN OUT CHAR8 *Destination,\r
- IN CONST CHAR8 *Source,\r
- IN UINTN Length\r
+Base64Encode (\r
+ IN CONST UINT8 *Source,\r
+ IN UINTN SourceLength,\r
+ OUT CHAR8 *Destination OPTIONAL,\r
+ IN OUT UINTN *DestinationSize\r
)\r
{\r
- AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);\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
+\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
+ *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
+ //\r
+ // Add terminating NULL\r
+ //\r
+ *Destination = '\0';\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Decode Base64 ASCII encoded data to 8-bit binary representation, based on\r
+ RFC4648.\r
+\r
+ Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.\r
+\r
+ Whitespace is ignored at all positions:\r
+ - 0x09 ('\t') horizontal tab\r
+ - 0x0A ('\n') new line\r
+ - 0x0B ('\v') vertical tab\r
+ - 0x0C ('\f') form feed\r
+ - 0x0D ('\r') carriage return\r
+ - 0x20 (' ') space\r
+\r
+ The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated\r
+ and enforced at the end of the Base64 ASCII encoded data, and only there.\r
+\r
+ Other characters outside of the encoding alphabet cause the function to\r
+ reject the Base64 ASCII encoded data.\r
+\r
+ @param[in] Source Array of CHAR8 elements containing the Base64\r
+ ASCII encoding. May be NULL if SourceSize is\r
+ zero.\r
+\r
+ @param[in] SourceSize Number of CHAR8 elements in Source.\r
+\r
+ @param[out] Destination Array of UINT8 elements receiving the decoded\r
+ 8-bit binary representation. Allocated by the\r
+ caller. May be NULL if DestinationSize is\r
+ zero on input. If NULL, decoding is\r
+ performed, but the 8-bit binary\r
+ representation is not stored. If non-NULL and\r
+ the function returns an error, the contents\r
+ of Destination are indeterminate.\r
+\r
+ @param[in,out] DestinationSize On input, the number of UINT8 elements that\r
+ the caller allocated for Destination. On\r
+ output, if the function returns\r
+ RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,\r
+ the number of UINT8 elements that are\r
+ required for decoding the Base64 ASCII\r
+ representation. If the function returns a\r
+ value different from both RETURN_SUCCESS and\r
+ RETURN_BUFFER_TOO_SMALL, then DestinationSize\r
+ is indeterminate on output.\r
+\r
+ @retval RETURN_SUCCESS SourceSize CHAR8 elements at Source have\r
+ been decoded to on-output DestinationSize\r
+ UINT8 elements at Destination. Note that\r
+ RETURN_SUCCESS covers the case when\r
+ DestinationSize is zero on input, and\r
+ Source decodes to zero bytes (due to\r
+ containing at most ignored whitespace).\r
+\r
+ @retval RETURN_BUFFER_TOO_SMALL The input value of DestinationSize is not\r
+ large enough for decoding SourceSize CHAR8\r
+ elements at Source. The required number of\r
+ UINT8 elements has been stored to\r
+ DestinationSize.\r
+\r
+ @retval RETURN_INVALID_PARAMETER DestinationSize is NULL.\r
+\r
+ @retval RETURN_INVALID_PARAMETER Source is NULL, but SourceSize is not zero.\r
+\r
+ @retval RETURN_INVALID_PARAMETER Destination is NULL, but DestinationSize is\r
+ not zero on input.\r
+\r
+ @retval RETURN_INVALID_PARAMETER Source is non-NULL, and (Source +\r
+ SourceSize) would wrap around MAX_ADDRESS.\r
+\r
+ @retval RETURN_INVALID_PARAMETER Destination is non-NULL, and (Destination +\r
+ DestinationSize) would wrap around\r
+ MAX_ADDRESS, as specified on input.\r
+\r
+ @retval RETURN_INVALID_PARAMETER None of Source and Destination are NULL,\r
+ and CHAR8[SourceSize] at Source overlaps\r
+ UINT8[DestinationSize] at Destination, as\r
+ specified on input.\r
+\r
+ @retval RETURN_INVALID_PARAMETER Invalid CHAR8 element encountered in\r
+ Source.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+Base64Decode (\r
+ IN CONST CHAR8 *Source OPTIONAL,\r
+ IN UINTN SourceSize,\r
+ OUT UINT8 *Destination OPTIONAL,\r
+ IN OUT UINTN *DestinationSize\r
+ )\r
+{\r
+ BOOLEAN PaddingMode;\r
+ UINTN SixBitGroupsConsumed;\r
+ UINT32 Accumulator;\r
+ UINTN OriginalDestinationSize;\r
+ UINTN SourceIndex;\r
+ CHAR8 SourceChar;\r
+ UINT32 Base64Value;\r
+ UINT8 DestinationOctet;\r
+\r
+ if (DestinationSize == NULL) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check Source array validity.\r
+ //\r
+ if (Source == NULL) {\r
+ if (SourceSize > 0) {\r
+ //\r
+ // At least one CHAR8 element at NULL Source.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ } else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {\r
+ //\r
+ // Non-NULL Source, but it wraps around.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check Destination array validity.\r
+ //\r
+ if (Destination == NULL) {\r
+ if (*DestinationSize > 0) {\r
+ //\r
+ // At least one UINT8 element at NULL Destination.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ } else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {\r
+ //\r
+ // Non-NULL Destination, but it wraps around.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check for overlap.\r
+ //\r
+ if ((Source != NULL) && (Destination != NULL)) {\r
+ //\r
+ // Both arrays have been provided, and we know from earlier that each array\r
+ // is valid in itself.\r
+ //\r
+ if ((UINTN)Source + SourceSize <= (UINTN)Destination) {\r
+ //\r
+ // Source array precedes Destination array, OK.\r
+ //\r
+ } else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {\r
+ //\r
+ // Destination array precedes Source array, OK.\r
+ //\r
+ } else {\r
+ //\r
+ // Overlap.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+ }\r
\r
//\r
- // Size of the resulting string should never be zero.\r
- // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+ // Decoding loop setup.\r
+ //\r
+ PaddingMode = FALSE;\r
+ SixBitGroupsConsumed = 0;\r
+ Accumulator = 0;\r
+ OriginalDestinationSize = *DestinationSize;\r
+ *DestinationSize = 0;\r
+\r
//\r
- ASSERT (AsciiStrSize (Destination) != 0);\r
- return Destination;\r
+ // Decoding loop.\r
+ //\r
+ for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {\r
+ SourceChar = Source[SourceIndex];\r
+\r
+ //\r
+ // Whitespace is ignored at all positions (regardless of padding mode).\r
+ //\r
+ if ((SourceChar == '\t') || (SourceChar == '\n') || (SourceChar == '\v') ||\r
+ (SourceChar == '\f') || (SourceChar == '\r') || (SourceChar == ' '))\r
+ {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // If we're in padding mode, accept another padding character, as long as\r
+ // that padding character completes the quantum. This completes case (2)\r
+ // from RFC4648, Chapter 4. "Base 64 Encoding":\r
+ //\r
+ // (2) The final quantum of encoding input is exactly 8 bits; here, the\r
+ // final unit of encoded output will be two characters followed by two\r
+ // "=" padding characters.\r
+ //\r
+ if (PaddingMode) {\r
+ if ((SourceChar == '=') && (SixBitGroupsConsumed == 3)) {\r
+ SixBitGroupsConsumed = 0;\r
+ continue;\r
+ }\r
+\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:\r
+ // The Base 64 Alphabet".\r
+ //\r
+ if (('A' <= SourceChar) && (SourceChar <= 'Z')) {\r
+ Base64Value = SourceChar - 'A';\r
+ } else if (('a' <= SourceChar) && (SourceChar <= 'z')) {\r
+ Base64Value = 26 + (SourceChar - 'a');\r
+ } else if (('0' <= SourceChar) && (SourceChar <= '9')) {\r
+ Base64Value = 52 + (SourceChar - '0');\r
+ } else if (SourceChar == '+') {\r
+ Base64Value = 62;\r
+ } else if (SourceChar == '/') {\r
+ Base64Value = 63;\r
+ } else if (SourceChar == '=') {\r
+ //\r
+ // Enter padding mode.\r
+ //\r
+ PaddingMode = TRUE;\r
+\r
+ if (SixBitGroupsConsumed == 2) {\r
+ //\r
+ // If we have consumed two 6-bit groups from the current quantum before\r
+ // encountering the first padding character, then this is case (2) from\r
+ // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,\r
+ // and we'll enforce another padding character.\r
+ //\r
+ SixBitGroupsConsumed = 3;\r
+ } else if (SixBitGroupsConsumed == 3) {\r
+ //\r
+ // If we have consumed three 6-bit groups from the current quantum\r
+ // before encountering the first padding character, then this is case\r
+ // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now\r
+ // complete.\r
+ //\r
+ SixBitGroupsConsumed = 0;\r
+ } else {\r
+ //\r
+ // Padding characters are not allowed at the first two positions of a\r
+ // quantum.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Wherever in a quantum we enter padding mode, we enforce the padding\r
+ // bits pending in the accumulator -- from the last 6-bit group just\r
+ // preceding the padding character -- to be zero. Refer to RFC4648,\r
+ // Chapter 3.5. "Canonical Encoding".\r
+ //\r
+ if (Accumulator != 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Advance to the next source character.\r
+ //\r
+ continue;\r
+ } else {\r
+ //\r
+ // Other characters outside of the encoding alphabet are rejected.\r
+ //\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Feed the bits of the current 6-bit group of the quantum to the\r
+ // accumulator.\r
+ //\r
+ Accumulator = (Accumulator << 6) | Base64Value;\r
+ SixBitGroupsConsumed++;\r
+ switch (SixBitGroupsConsumed) {\r
+ case 1:\r
+ //\r
+ // No octet to spill after consuming the first 6-bit group of the\r
+ // quantum; advance to the next source character.\r
+ //\r
+ continue;\r
+ case 2:\r
+ //\r
+ // 12 bits accumulated (6 pending + 6 new); prepare for spilling an\r
+ // octet. 4 bits remain pending.\r
+ //\r
+ DestinationOctet = (UINT8)(Accumulator >> 4);\r
+ Accumulator &= 0xF;\r
+ break;\r
+ case 3:\r
+ //\r
+ // 10 bits accumulated (4 pending + 6 new); prepare for spilling an\r
+ // octet. 2 bits remain pending.\r
+ //\r
+ DestinationOctet = (UINT8)(Accumulator >> 2);\r
+ Accumulator &= 0x3;\r
+ break;\r
+ default:\r
+ ASSERT (SixBitGroupsConsumed == 4);\r
+ //\r
+ // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.\r
+ // The quantum is complete, 0 bits remain pending.\r
+ //\r
+ DestinationOctet = (UINT8)Accumulator;\r
+ Accumulator = 0;\r
+ SixBitGroupsConsumed = 0;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Store the decoded octet if there's room left. Increment\r
+ // (*DestinationSize) unconditionally.\r
+ //\r
+ if (*DestinationSize < OriginalDestinationSize) {\r
+ ASSERT (Destination != NULL);\r
+ Destination[*DestinationSize] = DestinationOctet;\r
+ }\r
+\r
+ (*DestinationSize)++;\r
+\r
+ //\r
+ // Advance to the next source character.\r
+ //\r
+ }\r
+\r
+ //\r
+ // If Source terminates mid-quantum, then Source is invalid.\r
+ //\r
+ if (SixBitGroupsConsumed != 0) {\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Done.\r
+ //\r
+ if (*DestinationSize <= OriginalDestinationSize) {\r
+ return RETURN_SUCCESS;\r
+ }\r
+\r
+ return RETURN_BUFFER_TOO_SMALL;\r
}\r
\r
/**\r
\r
@param Value The 8-bit value to convert to BCD. Range 0..99.\r
\r
- @return The BCD value\r
+ @return The BCD value.\r
\r
**/\r
UINT8\r
EFIAPI\r
DecimalToBcd8 (\r
- IN UINT8 Value\r
+ IN UINT8 Value\r
)\r
{\r
ASSERT (Value < 100);\r
- return ((Value / 10) << 4) | (Value % 10);\r
+ return (UINT8)(((Value / 10) << 4) | (Value % 10));\r
}\r
\r
/**\r
UINT8\r
EFIAPI\r
BcdToDecimal8 (\r
- IN UINT8 Value\r
+ IN UINT8 Value\r
)\r
{\r
ASSERT (Value < 0xa0);\r
ASSERT ((Value & 0xf) < 0xa);\r
- return (Value >> 4) * 10 + (Value & 0xf);\r
+ return (UINT8)((Value >> 4) * 10 + (Value & 0xf));\r
}\r