+UINTN\r
+EFIAPI\r
+StrHexToUintn (\r
+ IN CONST CHAR16 *String\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
+ 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 < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) ||\r
+ ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) && \r
+ (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16))\r
+ );\r
+\r
+ Result = (Result << 4) + InternalHexCharToUintn (*String);\r
+ String++;\r
+ }\r
+\r
+ return Result;\r
+}\r
+\r
+\r
+/**\r
+ Convert a Null-terminated Unicode hexadecimal string to a value of 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 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
+ UINT64, then ASSERT().\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 String 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
+ //\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 < QUOTIENT_MAX_UINT64_DIVIDED_BY_16)|| \r
+ ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) && \r
+ (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16))\r
+ );\r
+\r
+ Result = LShiftU64 (Result, 4);\r
+ Result = Result + InternalHexCharToUintn (*String);\r
+ String++;\r
+ }\r
+\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
+\r
+ return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||\r
+ (Char >= 'A' && Char <= 'F') ||\r
+ (Char >= 'a' && Char <= 'f'));\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated Unicode string to a Null-terminated\r
+ ASCII string and returns the ASCII string.\r
+\r
+ This function converts the content of the Unicode string Source\r
+ to the ASCII string Destination by copying the lower 8 bits of\r
+ each Unicode character. It returns Destination.\r
+\r
+ If any Unicode characters in Source contain non-zero value in\r
+ the upper 8 bits, then ASSERT().\r
+\r
+ If Destination is NULL, then ASSERT().\r
+ If Source is NULL, then ASSERT().\r
+ If Source is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Source and Destination overlap, then ASSERT().\r
+\r
+ If PcdMaximumUnicodeStringLength is not zero, and Source contains\r
+ more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
+ the Null-terminator, then ASSERT().\r
+\r
+ If PcdMaximumAsciiStringLength is not zero, and Source contains more\r
+ than PcdMaximumAsciiStringLength Unicode characters, not including the\r
+ Null-terminator, then ASSERT().\r
+\r
+ @param Source Pointer to a Null-terminated Unicode string.\r
+ @param Destination Pointer to a Null-terminated ASCII string.\r
+\r
+ @return Destination.\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+UnicodeStrToAsciiStr (\r
+ IN CONST CHAR16 *Source,\r
+ OUT CHAR8 *Destination\r
+ )\r
+{\r
+ CHAR8 *ReturnValue;\r
+\r
+ ASSERT (Destination != NULL);\r
+\r
+ //\r
+ // ASSERT if Source is long than PcdMaximumUnicodeStringLength.\r
+ // Length tests are performed inside StrLen().\r
+ //\r
+ ASSERT (StrSize (Source) != 0);\r
+\r
+ //\r
+ // Source and Destination should not overlap\r
+ //\r
+ ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));\r
+ ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));\r
+\r
+\r
+ ReturnValue = Destination;\r
+ while (*Source != '\0') {\r
+ //\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
+ *(Destination++) = (CHAR8) *(Source++);\r
+ }\r
+\r
+ *Destination = '\0';\r
+\r
+ //\r
+ // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.\r
+ // Length tests are performed inside AsciiStrLen().\r
+ //\r
+ ASSERT (AsciiStrSize (ReturnValue) != 0);\r
+\r
+ return ReturnValue;\r
+}\r
+\r
+\r
+/**\r
+ Copies one Null-terminated ASCII string to another Null-terminated ASCII\r
+ string and returns the new ASCII string.\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
+\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
+\r
+ @param Destination Pointer to a Null-terminated ASCII string.\r
+ @param Source Pointer to a Null-terminated ASCII string.\r
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrCpy (\r
+ OUT CHAR8 *Destination,\r
+ IN CONST CHAR8 *Source\r
+ )\r
+{\r
+ CHAR8 *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) > AsciiStrLen (Source));\r
+ ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));\r
+\r
+ ReturnValue = Destination;\r
+ while (*Source != 0) {\r
+ *(Destination++) = *(Source++);\r
+ }\r
+ *Destination = 0;\r
+ return ReturnValue;\r
+}\r
+\r
+/**\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
+ 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 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
+ 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
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrnCpy (\r
+ OUT CHAR8 *Destination,\r
+ IN CONST CHAR8 *Source,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ CHAR8 *ReturnValue;\r
+\r
+ if (Length == 0) {\r
+ return Destination;\r
+ }\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) > AsciiStrLen (Source));\r
+ ASSERT ((UINTN)(Source - Destination) >= Length);\r
+\r
+ if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+ ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));\r
+ }\r
+\r
+ ReturnValue = Destination;\r
+\r
+ while (*Source != 0 && Length > 0) {\r
+ *(Destination++) = *(Source++);\r
+ Length--;\r
+ }\r
+\r
+ ZeroMem (Destination, Length * sizeof (*Destination));\r
+ return ReturnValue;\r
+}\r
+\r
+/**\r
+ Returns the length of a Null-terminated ASCII string.\r
+\r
+ This function returns the number of ASCII characters in the Null-terminated\r
+ ASCII string specified by String.\r
+\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
+ then ASSERT().\r
+\r
+ @param String Pointer to a Null-terminated ASCII string.\r
+\r
+ @return The length of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrLen (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ UINTN Length;\r
+\r
+ ASSERT (String != NULL);\r
+\r
+ for (Length = 0; *String != '\0'; String++, Length++) {\r
+ //\r
+ // If PcdMaximumUnicodeStringLength is not zero,\r
+ // length should not more than PcdMaximumUnicodeStringLength\r
+ //\r
+ if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+ ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));\r
+ }\r
+ }\r
+ return Length;\r
+}\r
+\r
+/**\r
+ Returns the size of a Null-terminated ASCII string in bytes, including the\r
+ Null terminator.\r
+\r
+ This function returns the size, in bytes, of the Null-terminated ASCII string\r
+ specified by String.\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
+ then ASSERT().\r
+\r
+ @param String Pointer to a Null-terminated ASCII string.\r
+\r
+ @return The size of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrSize (\r
+ IN CONST CHAR8 *String\r
+ )\r
+{\r
+ return (AsciiStrLen (String) + 1) * sizeof (*String);\r
+}\r
+\r
+/**\r
+ Compares two Null-terminated ASCII strings, and returns the difference\r
+ between the first mismatched ASCII characters.\r
+\r
+ This function compares the Null-terminated ASCII string FirstString to the\r
+ Null-terminated ASCII string SecondString. If FirstString is identical to\r
+ SecondString, then 0 is returned. Otherwise, the value returned is the first\r
+ mismatched ASCII character in SecondString subtracted from the first\r
+ 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
+ then ASSERT().\r
+ If PcdMaximumAsciiStringLength is not zero and SecondString contains more\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
+\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
+ )\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') && (*FirstString == *SecondString)) {\r
+ FirstString++;\r
+ SecondString++;\r
+ }\r
+\r
+ return *FirstString - *SecondString;\r
+}\r
+\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
+InternalBaseLibAsciiToUpper (\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
+ if (InternalIsDecimalDigitCharacter (Char)) {\r
+ return Char - '0';\r
+ }\r
+\r
+ return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A');\r
+}\r
+\r
+\r
+/**\r
+ Performs a case insensitive comparison of two Null-terminated ASCII strings,\r
+ and returns the difference between the first mismatched ASCII characters.\r
+\r
+ This function performs a case insensitive comparison of the Null-terminated\r
+ ASCII string FirstString to the Null-terminated ASCII string SecondString. If\r
+ FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
+ value returned is the first mismatched lower case ASCII character in\r
+ SecondString subtracted from the first mismatched lower case ASCII character\r
+ 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
+ then ASSERT().\r
+ If PcdMaximumAsciiStringLength is not zero and SecondString contains more\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
+\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
+ )\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
+ UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);\r
+ UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
+ while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
+ FirstString++;\r
+ SecondString++;\r
+ UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString);\r
+ UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString);\r
+ }\r
+\r
+ return UpperFirstString - UpperSecondString;\r
+}\r
+\r
+/**\r
+ Compares two Null-terminated ASCII strings with maximum lengths, and returns\r
+ the difference between the first mismatched ASCII characters.\r
+\r
+ This function compares the Null-terminated ASCII string FirstString to the\r
+ Null-terminated ASCII string SecondString. At most, Length ASCII characters\r
+ will be compared. If Length is 0, then 0 is returned. If FirstString is\r
+ identical to SecondString, then 0 is returned. Otherwise, the value returned\r
+ is the first mismatched ASCII character in SecondString subtracted from the\r
+ first mismatched ASCII character in FirstString.\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
+ 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
+ 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 Length 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
+\r
+**/\r
+INTN\r