-/** @file
- Unicode and ASCII string primatives.
-
- Copyright (c) 2006 - 2007, Intel Corporation<BR>
- All rights reserved. This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
- Module Name: String.c
-
-**/
-
-#include "BaseLibInternals.h"
-
-/**
- Copies one Null-terminated Unicode string to another Null-terminated Unicode
- string and returns the new Unicode string.
-
- This function copies the contents of the Unicode string Source to the Unicode
- string Destination, and returns Destination. If Source and Destination
- overlap, then the results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param Destination Pointer to a Null-terminated Unicode string.
- @param Source Pointer to a Null-terminated Unicode string.
-
- @return Destiantion
-
-**/
-CHAR16 *
-EFIAPI
-StrCpy (
- OUT CHAR16 *Destination,
- IN CONST CHAR16 *Source
- )
-{
- CHAR16 *ReturnValue;
-
- //
- // Destination cannot be NULL
- //
- ASSERT (Destination != NULL);
-
- //
- // Destination and source cannot overlap
- //
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
- ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
-
- ReturnValue = Destination;
- while (*Source) {
- *(Destination++) = *(Source++);
- }
- *Destination = 0;
- return ReturnValue;
-}
-
-/**
- Copies one Null-terminated Unicode string with a maximum length to another
- Null-terminated Unicode string with a maximum length and returns the new
- Unicode string.
-
- This function copies the contents of the Unicode string Source to the Unicode
- string Destination, and returns Destination. At most, Length Unicode
- characters are copied from Source to Destination. If Length is 0, then
- Destination is returned unmodified. If Length is greater that the number of
- Unicode characters in Source, then Destination is padded with Null Unicode
- characters. If Source and Destination overlap, then the results are
- undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param Destination Pointer to a Null-terminated Unicode string.
- @param Source Pointer to a Null-terminated Unicode string.
- @param Length Maximum number of Unicode characters to copy.
-
- @return Destination
-
-**/
-CHAR16 *
-EFIAPI
-StrnCpy (
- OUT CHAR16 *Destination,
- IN CONST CHAR16 *Source,
- IN UINTN Length
- )
-{
- CHAR16 *ReturnValue;
-
- if (Length == 0) {
- return Destination;
- }
-
- //
- // Destination cannot be NULL if Length is not zero
- //
- ASSERT (Destination != NULL);
-
- //
- // Destination and source cannot overlap
- // Q: Does Source have to be NULL-terminated?
- //
- ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
- ASSERT ((UINTN)(Source - Destination) >= Length);
-
- ReturnValue = Destination;
-
- while ((*Source != L'\0') && (Length > 0)) {
- *(Destination++) = *(Source++);
- Length--;
- }
-
- ZeroMem (Destination, Length * sizeof (*Destination));
- return ReturnValue;
-}
-
-/**
- Returns the length of a Null-terminated Unicode string.
-
- This function returns the number of Unicode characters in the Null-terminated
- Unicode string specified by String.
-
- If String is NULL, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @return The length of String.
-
-**/
-UINTN
-EFIAPI
-StrLen (
- IN CONST CHAR16 *String
- )
-{
- UINTN Length;
-
- ASSERT (String != NULL);
-
- for (Length = 0; *String != L'\0'; String++, Length++) {
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
- ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
- }
- }
- return Length;
-}
-
-/**
- Returns the size of a Null-terminated Unicode string in bytes, including the
- Null terminator.
-
- This function returns the size, in bytes, of the Null-terminated Unicode
- string specified by String.
-
- If String is NULL, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @return The size of String.
-
-**/
-UINTN
-EFIAPI
-StrSize (
- IN CONST CHAR16 *String
- )
-{
- return (StrLen (String) + 1) * sizeof (*String);
-}
-
-/**
- Compares two Null-terminated Unicode strings, and returns the difference
- between the first mismatched Unicode characters.
-
- This function compares the Null-terminated Unicode string FirstString to the
- Null-terminated Unicode string SecondString. If FirstString is identical to
- SecondString, then 0 is returned. Otherwise, the value returned is the first
- mismatched Unicode character in SecondString subtracted from the first
- mismatched Unicode character in FirstString.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param FirstString Pointer to a Null-terminated Unicode string.
- @param SecondString Pointer to a Null-terminated Unicode string.
-
- @retval 0 FirstString is identical to SecondString.
- @retval !=0 FirstString is not identical to SecondString.
-
-**/
-INTN
-EFIAPI
-StrCmp (
- IN CONST CHAR16 *FirstString,
- IN CONST CHAR16 *SecondString
- )
-{
- //
- // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
- //
- ASSERT (StrSize (FirstString) != 0);
- ASSERT (StrSize (SecondString) != 0);
-
- while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
- FirstString++;
- SecondString++;
- }
- return *FirstString - *SecondString;
-}
-
-/**
- Compares two Null-terminated Unicode strings with maximum lengths, and
- returns the difference between the first mismatched Unicode characters.
-
- This function compares the Null-terminated Unicode string FirstString to the
- Null-terminated Unicode string SecondString. At most, Length Unicode
- characters will be compared. If Length is 0, then 0 is returned. If
- FirstString is identical to SecondString, then 0 is returned. Otherwise, the
- value returned is the first mismatched Unicode character in SecondString
- subtracted from the first mismatched Unicode character in FirstString.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param FirstString Pointer to a Null-terminated Unicode string.
- @param SecondString Pointer to a Null-terminated Unicode string.
- @param Length Maximum number of Unicode characters to compare.
-
- @retval 0 FirstString is identical to SecondString.
- @retval !=0 FirstString is not identical to SecondString.
-
-**/
-INTN
-EFIAPI
-StrnCmp (
- IN CONST CHAR16 *FirstString,
- IN CONST CHAR16 *SecondString,
- IN UINTN Length
- )
-{
- if (Length == 0) {
- return 0;
- }
-
- //
- // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
- // Length tests are performed inside StrLen().
- //
- ASSERT (StrSize (FirstString) != 0);
- ASSERT (StrSize (SecondString) != 0);
-
- while ((*FirstString != L'\0') &&
- (*FirstString == *SecondString) &&
- (Length > 1)) {
- FirstString++;
- SecondString++;
- Length--;
- }
-
- return *FirstString - *SecondString;
-}
-
-/**
- Concatenates one Null-terminated Unicode string to another Null-terminated
- Unicode string, and returns the concatenated Unicode string.
-
- This function concatenates two Null-terminated Unicode strings. The contents
- of Null-terminated Unicode string Source are concatenated to the end of
- Null-terminated Unicode string Destination. The Null-terminated concatenated
- Unicode String is returned. If Source and Destination overlap, then the
- results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
- and Source results in a Unicode string with more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param Destination Pointer to a Null-terminated Unicode string.
- @param Source Pointer to a Null-terminated Unicode string.
-
- @return Destination
-
-**/
-CHAR16 *
-EFIAPI
-StrCat (
- IN OUT CHAR16 *Destination,
- IN CONST CHAR16 *Source
- )
-{
- StrCpy (Destination + StrLen (Destination), Source);
-
- //
- // Size of the resulting string should never be zero.
- // PcdMaximumUnicodeStringLength is tested inside StrLen().
- //
- ASSERT (StrSize (Destination) != 0);
- return Destination;
-}
-
-/**
- Concatenates one Null-terminated Unicode string with a maximum length to the
- end of another Null-terminated Unicode string, and returns the concatenated
- Unicode string.
-
- This function concatenates two Null-terminated Unicode strings. The contents
- of Null-terminated Unicode string Source are concatenated to the end of
- Null-terminated Unicode string Destination, and Destination is returned. At
- most, Length Unicode characters are concatenated from Source to the end of
- Destination, and Destination is always Null-terminated. If Length is 0, then
- Destination is returned unmodified. If Source and Destination overlap, then
- the results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
- than PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
- and Source results in a Unicode string with more than
- PcdMaximumUnicodeStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param Destination Pointer to a Null-terminated Unicode string.
- @param Source Pointer to a Null-terminated Unicode string.
- @param Length Maximum number of Unicode characters to concatenate from
- Source.
-
- @return Destination
-
-**/
-CHAR16 *
-EFIAPI
-StrnCat (
- IN OUT CHAR16 *Destination,
- IN CONST CHAR16 *Source,
- IN UINTN Length
- )
-{
- StrnCpy (Destination + StrLen (Destination), Source, Length);
-
- //
- // Size of the resulting string should never be zero.
- // PcdMaximumUnicodeStringLength is tested inside StrLen().
- //
- ASSERT (StrSize (Destination) != 0);
- return Destination;
-}
-
-/**
- Returns the first occurance of a Null-terminated Unicode sub-string
- in a Null-terminated Unicode string.
-
- This function scans the contents of the Null-terminated Unicode string
- specified by String and returns the first occurrence of SearchString.
- If SearchString is not found in String, then NULL is returned. If
- the length of SearchString is zero, then String is
- returned.
-
- If String is NULL, then ASSERT().
- If String is not aligned on a 16-bit boundary, then ASSERT().
- If SearchString is NULL, then ASSERT().
- If SearchString is not aligned on a 16-bit boundary, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and SearchString
- or String contains more than PcdMaximumUnicodeStringLength Unicode
- characters not including the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
- @param SearchString Pointer to a Null-terminated Unicode string to search for.
-
- @retval NULL If the SearchString does not appear in String.
- @retval !NULL If there is a match.
-
-**/
-CHAR16 *
-EFIAPI
-StrStr (
- IN CONST CHAR16 *String,
- IN CONST CHAR16 *SearchString
- )
-{
- CONST CHAR16 *FirstMatch;
- CONST CHAR16 *SearchStringTmp;
-
- ASSERT (String != NULL);
- ASSERT (((UINTN) String & 0x01) == 0);
- ASSERT (SearchString != NULL);
- ASSERT (((UINTN) SearchString & 0x01) == 0);
-
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length of String should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
- ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
- }
-
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length of SearchString should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
- ASSERT (StrLen (SearchString) < PcdGet32 (PcdMaximumAsciiStringLength));
- }
-
- while (*String != '\0') {
- SearchStringTmp = SearchString;
- FirstMatch = String;
-
- while ((*String == *SearchStringTmp)
- && (*SearchStringTmp != '\0')
- && (*String != '\0')) {
- String++;
- SearchStringTmp++;
- }
-
- if (*SearchStringTmp == '\0') {
- return (CHAR16 *) FirstMatch;
- }
-
- if (SearchStringTmp == SearchString) {
- //
- // If no character from SearchString match,
- // move the pointer to the String under search
- // by one character.
- //
- String++;
- }
- }
-
- return NULL;
-}
-
-/**
- Check if a Unicode character is a decimal character.
-
- This internal function checks if a Unicode character is a
- decimal character. The valid decimal character is from
- L'0' to L'9'.
-
-
- @param Char The character to check against.
-
- @retval TRUE If the Char is a decmial character.
- @retval FALSE Otherwise.
-
-**/
-STATIC
-BOOLEAN
-InternalIsDecimalDigitCharacter (
- IN CHAR16 Char
- )
-{
- return (BOOLEAN) (Char >= L'0' && Char <= L'9');
-}
-
-/**
- Convert a Unicode character to upper case only if
- it maps to a valid small-case ASCII character.
-
- This internal function only deal with Unicode character
- which maps to a valid small-case ASII character, i.e.
- L'a' to L'z'. For other Unicode character, the input character
- is returned directly.
-
-
- @param Char The character to convert.
-
- @retval LowerCharacter If the Char is with range L'a' to L'z'.
- @retval Unchanged Otherwise.
-
-**/
-STATIC
-CHAR16
-InternalCharToUpper (
- IN CHAR16 Char
- )
-{
- if (Char >= L'a' && Char <= L'z') {
- return (CHAR16) (Char - (L'a' - L'A'));
- }
-
- return Char;
-}
-
-/**
- Convert a Unicode character to numerical value.
-
- This internal function only deal with Unicode character
- which maps to a valid hexadecimal ASII character, i.e.
- L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
- Unicode character, the value returned does not make sense.
-
- @param Char The character to convert.
-
- @retval UINTN The numerical value converted.
-
-**/
-STATIC
-UINTN
-InternalHexCharToUintn (
- IN CHAR16 Char
- )
-{
- if (InternalIsDecimalDigitCharacter (Char)) {
- return Char - L'0';
- }
-
- return (UINTN) (10 + InternalCharToUpper (Char) - L'A');
-}
-
-/**
- Check if a Unicode character is a hexadecimal character.
-
- This internal function checks if a Unicode character is a
- decimal character. The valid hexadecimal character is
- L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
-
-
- @param Char The character to check against.
-
- @retval TRUE If the Char is a hexadecmial character.
- @retval FALSE Otherwise.
-
-**/
-STATIC
-BOOLEAN
-InternalIsHexaDecimalDigitCharacter (
- IN CHAR16 Char
- )
-{
-
- return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
- (Char >= L'A' && Char <= L'F') ||
- (Char >= L'a' && Char <= L'f'));
-}
-
-/**
- Convert a Null-terminated Unicode decimal string to a value of
- type UINTN.
-
- This function returns a value of type UINTN by interpreting the contents
- of the Unicode string specified by String as a decimal number. The format
- of the input Unicode string String is:
-
- [spaces] [decimal digits].
-
- The valid decimal digit character is in the range [0-9]. The
- function will ignore the pad space, which includes spaces or
- tab characters, before [decimal digits]. The running zero in the
- beginning of [decimal digits] will be ignored. Then, the function
- stops at the first character that is a not a valid decimal character
- or a Null-terminator, whichever one comes first.
-
- If String is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If String has only pad spaces, then 0 is returned.
- If String has no pad spaces or valid decimal digits,
- then 0 is returned.
- If the number represented by String overflows according
- to the range defined by UINTN, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and String contains
- more than PcdMaximumUnicodeStringLength Unicode characters not including
- the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @retval UINTN
-
-**/
-UINTN
-EFIAPI
-StrDecimalToUintn (
- IN CONST CHAR16 *String
- )
-{
- UINTN Result;
-
- ASSERT (String != NULL);
- ASSERT (((UINTN) String & 0x01) == 0);
- ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
-
- Result = 0;
-
- while (InternalIsDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||
- ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_10) &&
- (*String - L'0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)
- );
-
- Result = Result * 10 + (*String - L'0');
- String++;
- }
-
- return Result;
-}
-
-
-/**
- Convert a Null-terminated Unicode decimal string to a value of
- type UINT64.
-
- This function returns a value of type UINT64 by interpreting the contents
- of the Unicode string specified by String as a decimal number. The format
- of the input Unicode string String is:
-
- [spaces] [decimal digits].
-
- The valid decimal digit character is in the range [0-9]. The
- function will ignore the pad space, which includes spaces or
- tab characters, before [decimal digits]. The running zero in the
- beginning of [decimal digits] will be ignored. Then, the function
- stops at the first character that is a not a valid decimal character
- or a Null-terminator, whichever one comes first.
-
- If String is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If String has only pad spaces, then 0 is returned.
- If String has no pad spaces or valid decimal digits,
- then 0 is returned.
- If the number represented by String overflows according
- to the range defined by UINT64, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and String contains
- more than PcdMaximumUnicodeStringLength Unicode characters not including
- the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @retval UINT64
-
-**/
-UINT64
-EFIAPI
-StrDecimalToUint64 (
- IN CONST CHAR16 *String
- )
-{
- UINT64 Result;
-
- ASSERT (String != NULL);
- ASSERT (((UINTN) String & 0x01) == 0);
- ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
-
- Result = 0;
-
- while (InternalIsDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_10) ||
- ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_10) &&
- (*String - L'0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)
- );
-
- Result = MultU64x32 (Result, 10) + (*String - L'0');
- String++;
- }
-
- return Result;
-}
-
-/**
- Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
-
- This function returns a value of type UINTN by interpreting the contents
- of the Unicode string specified by String as a hexadecimal number.
- The format of the input Unicode string String is:
-
- [spaces][zeros][x][hexadecimal digits].
-
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
- If "x" appears in the input string, it must be prefixed with at least one 0.
- The function will ignore the pad space, which includes spaces or tab characters,
- before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
- [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
- first valid hexadecimal digit. Then, the function stops at the first character that is
- a not a valid hexadecimal character or NULL, whichever one comes first.
-
- If String is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If String has only pad spaces, then zero is returned.
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
- then zero is returned.
- If the number represented by String overflows according to the range defined by
- UINTN, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @retval UINTN
-
-**/
-UINTN
-EFIAPI
-StrHexToUintn (
- IN CONST CHAR16 *String
- )
-{
- UINTN Result;
-
- ASSERT (String != NULL);
- ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
-
- if (InternalCharToUpper (*String) == L'X') {
- ASSERT (*(String - 1) == L'0');
- if (*(String - 1) != L'0') {
- return 0;
- }
- //
- // Skip the 'X'
- //
- String++;
- }
-
- Result = 0;
-
- while (InternalIsHexaDecimalDigitCharacter (*String)) {
- //
- // If the Hex Number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||
- ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_16) &&
- (InternalHexCharToUintn (*String) <= REMINDER_MAX_UINTN_DIVIDED_BY_16))
- );
-
- Result = (Result << 4) + InternalHexCharToUintn (*String);
- String++;
- }
-
- return Result;
-}
-
-
-/**
- Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
-
- This function returns a value of type UINT64 by interpreting the contents
- of the Unicode string specified by String as a hexadecimal number.
- The format of the input Unicode string String is
-
- [spaces][zeros][x][hexadecimal digits].
-
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
- If "x" appears in the input string, it must be prefixed with at least one 0.
- The function will ignore the pad space, which includes spaces or tab characters,
- before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
- [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
- first valid hexadecimal digit. Then, the function stops at the first character that is
- a not a valid hexadecimal character or NULL, whichever one comes first.
-
- If String is NULL, then ASSERT().
- If String is not aligned in a 16-bit boundary, then ASSERT().
- If String has only pad spaces, then zero is returned.
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
- then zero is returned.
- If the number represented by String overflows according to the range defined by
- UINT64, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and String contains more than
- PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated Unicode string.
-
- @retval UINT64
-
-**/
-UINT64
-EFIAPI
-StrHexToUint64 (
- IN CONST CHAR16 *String
- )
-{
- UINT64 Result;
-
- ASSERT (String != NULL);
- ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == L' ') || (*String == L'\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == L'0') {
- String++;
- }
-
- if (InternalCharToUpper (*String) == L'X') {
- ASSERT (*(String - 1) == L'0');
- if (*(String - 1) != L'0') {
- return 0;
- }
- //
- // Skip the 'X'
- //
- String++;
- }
-
- Result = 0;
-
- while (InternalIsHexaDecimalDigitCharacter (*String)) {
- //
- // If the Hex Number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_16)||
- ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_16) &&
- (InternalHexCharToUintn (*String) <= REMINDER_MAX_UINT64_DIVIDED_BY_16))
- );
-
- Result = LShiftU64 (Result, 4);
- Result = Result + InternalHexCharToUintn (*String);
- String++;
- }
-
- return Result;
-}
-
-/**
- Check if a ASCII character is a decimal character.
-
- This internal function checks if a Unicode character is a
- decimal character. The valid decimal character is from
- '0' to '9'.
-
- @param Char The character to check against.
-
- @retval TRUE If the Char is a decmial character.
- @retval FALSE Otherwise.
-
-**/
-STATIC
-BOOLEAN
-InternalAsciiIsDecimalDigitCharacter (
- IN CHAR8 Char
- )
-{
- return (BOOLEAN) (Char >= '0' && Char <= '9');
-}
-
-/**
- Check if a ASCII character is a hexadecimal character.
-
- This internal function checks if a ASCII character is a
- decimal character. The valid hexadecimal character is
- L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
-
-
- @param Char The character to check against.
-
- @retval TRUE If the Char is a hexadecmial character.
- @retval FALSE Otherwise.
-
-**/
-STATIC
-BOOLEAN
-InternalAsciiIsHexaDecimalDigitCharacter (
- IN CHAR8 Char
- )
-{
-
- return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||
- (Char >= 'A' && Char <= 'F') ||
- (Char >= 'a' && Char <= 'f'));
-}
-
-/**
- Convert a Null-terminated Unicode string to a Null-terminated
- ASCII string and returns the ASCII string.
-
- This function converts the content of the Unicode string Source
- to the ASCII string Destination by copying the lower 8 bits of
- each Unicode character. It returns Destination. The function terminates
- the ASCII string Destination by appending a Null-terminator character
- at the end. The caller is responsible to make sure Destination points
- to a buffer with size equal or greater than (StrLen (Source) + 1) in bytes.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source is not aligned on a 16-bit boundary, then ASSERT().
- If Source and Destination overlap, then ASSERT().
-
- If any Unicode characters in Source contain non-zero value in
- the upper 8 bits, then ASSERT().
-
- If PcdMaximumUnicodeStringLength is not zero, and Source contains
- more than PcdMaximumUnicodeStringLength Unicode characters not including
- the Null-terminator, then ASSERT().
-
- If PcdMaximumAsciiStringLength is not zero, and Source contains more
- than PcdMaximumAsciiStringLength Unicode characters not including the
- Null-terminator, then ASSERT().
-
- @param Source Pointer to a Null-terminated Unicode string.
- @param Destination Pointer to a Null-terminated ASCII string.
-
- @reture Destination
-
-**/
-CHAR8 *
-EFIAPI
-UnicodeStrToAsciiStr (
- IN CONST CHAR16 *Source,
- OUT CHAR8 *Destination
- )
-{
- ASSERT (Destination != NULL);
- ASSERT (Source != NULL);
-
- //
- // Source and Destination should not overlap
- //
- ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));
- ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
-
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length of Source should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
- ASSERT (StrLen (Source) < PcdGet32 (PcdMaximumUnicodeStringLength));
- }
-
- while (*Source != '\0') {
- //
- // If any Unicode characters in Source contain
- // non-zero value in the upper 8 bits, then ASSERT().
- //
- ASSERT (*Source < 0x100);
- *(Destination++) = (CHAR8) *(Source++);
- }
-
- *Destination = '\0';
-
- return Destination;
-}
-
-
-/**
- Copies one Null-terminated ASCII string to another Null-terminated ASCII
- string and returns the new ASCII string.
-
- This function copies the contents of the ASCII string Source to the ASCII
- string Destination, and returns Destination. If Source and Destination
- overlap, then the results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and Source contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param Destination Pointer to a Null-terminated ASCII string.
- @param Source Pointer to a Null-terminated ASCII string.
-
- @return Destination
-
-**/
-CHAR8 *
-EFIAPI
-AsciiStrCpy (
- OUT CHAR8 *Destination,
- IN CONST CHAR8 *Source
- )
-{
- CHAR8 *ReturnValue;
-
- //
- // Destination cannot be NULL
- //
- ASSERT (Destination != NULL);
-
- //
- // Destination and source cannot overlap
- //
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
- ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));
-
- ReturnValue = Destination;
- while (*Source) {
- *(Destination++) = *(Source++);
- }
- *Destination = 0;
- return ReturnValue;
-}
-
-/**
- Copies one Null-terminated ASCII string with a maximum length to another
- Null-terminated ASCII string with a maximum length and returns the new ASCII
- string.
-
- This function copies the contents of the ASCII string Source to the ASCII
- string Destination, and returns Destination. At most, Length ASCII characters
- are copied from Source to Destination. If Length is 0, then Destination is
- returned unmodified. If Length is greater that the number of ASCII characters
- in Source, then Destination is padded with Null ASCII characters. If Source
- and Destination overlap, then the results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and Source contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param Destination Pointer to a Null-terminated ASCII string.
- @param Source Pointer to a Null-terminated ASCII string.
- @param Length Maximum number of ASCII characters to copy.
-
- @return Destination
-
-**/
-CHAR8 *
-EFIAPI
-AsciiStrnCpy (
- OUT CHAR8 *Destination,
- IN CONST CHAR8 *Source,
- IN UINTN Length
- )
-{
- CHAR8 *ReturnValue;
-
- if (Length == 0) {
- return Destination;
- }
-
- //
- // Destination cannot be NULL
- //
- ASSERT (Destination != NULL);
-
- //
- // Destination and source cannot overlap
- //
- ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
- ASSERT ((UINTN)(Source - Destination) >= Length);
-
- ReturnValue = Destination;
-
- while (*Source && Length > 0) {
- *(Destination++) = *(Source++);
- Length--;
- }
-
- ZeroMem (Destination, Length * sizeof (*Destination));
- return ReturnValue;
-}
-
-/**
- Returns the length of a Null-terminated ASCII string.
-
- This function returns the number of ASCII characters in the Null-terminated
- ASCII string specified by String.
-
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and String contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @return The length of String.
-
-**/
-UINTN
-EFIAPI
-AsciiStrLen (
- IN CONST CHAR8 *String
- )
-{
- UINTN Length;
-
- ASSERT (String != NULL);
-
- for (Length = 0; *String != '\0'; String++, Length++) {
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
- ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
- }
- }
- return Length;
-}
-
-/**
- Returns the size of a Null-terminated ASCII string in bytes, including the
- Null terminator.
-
- This function returns the size, in bytes, of the Null-terminated ASCII string
- specified by String.
-
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and String contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @return The size of String.
-
-**/
-UINTN
-EFIAPI
-AsciiStrSize (
- IN CONST CHAR8 *String
- )
-{
- return (AsciiStrLen (String) + 1) * sizeof (*String);
-}
-
-/**
- Compares two Null-terminated ASCII strings, and returns the difference
- between the first mismatched ASCII characters.
-
- This function compares the Null-terminated ASCII string FirstString to the
- Null-terminated ASCII string SecondString. If FirstString is identical to
- SecondString, then 0 is returned. Otherwise, the value returned is the first
- mismatched ASCII character in SecondString subtracted from the first
- mismatched ASCII character in FirstString.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and SecondString contains more
- than PcdMaximumAsciiStringLength ASCII characters not including the
- Null-terminator, then ASSERT().
-
- @param FirstString Pointer to a Null-terminated ASCII string.
- @param SecondString Pointer to a Null-terminated ASCII string.
-
- @retval 0 FirstString is identical to SecondString.
- @retval !=0 FirstString is not identical to SecondString.
-
-**/
-INTN
-EFIAPI
-AsciiStrCmp (
- IN CONST CHAR8 *FirstString,
- IN CONST CHAR8 *SecondString
- )
-{
- //
- // ASSERT both strings are less long than PcdMaximumAsciiStringLength
- //
- ASSERT (AsciiStrSize (FirstString));
- ASSERT (AsciiStrSize (SecondString));
-
- while ((*FirstString != '\0') && (*FirstString == *SecondString)) {
- FirstString++;
- SecondString++;
- }
-
- return *FirstString - *SecondString;
-}
-
-/**
- Converts a lowercase Ascii character to upper one
-
- If Chr is lowercase Ascii character, then converts it to upper one.
-
- If Value >= 0xA0, then ASSERT().
- If (Value & 0x0F) >= 0x0A, then ASSERT().
-
- @param chr one Ascii character
-
- @return The uppercase value of Ascii character
-
-**/
-STATIC
-CHAR8
-AsciiToUpper (
- IN CHAR8 Chr
- )
-{
- return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);
-}
-
-/**
- Convert a ASCII character to numerical value.
-
- This internal function only deal with Unicode character
- which maps to a valid hexadecimal ASII character, i.e.
- '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
- ASCII character, the value returned does not make sense.
-
- @param Char The character to convert.
-
- @retval UINTN The numerical value converted.
-
-**/
-STATIC
-UINTN
-InternalAsciiHexCharToUintn (
- IN CHAR8 Char
- )
-{
- if (InternalIsDecimalDigitCharacter (Char)) {
- return Char - '0';
- }
-
- return (UINTN) (10 + AsciiToUpper (Char) - 'A');
-}
-
-
-/**
- Performs a case insensitive comparison of two Null-terminated ASCII strings,
- and returns the difference between the first mismatched ASCII characters.
-
- This function performs a case insensitive comparison of the Null-terminated
- ASCII string FirstString to the Null-terminated ASCII string SecondString. If
- FirstString is identical to SecondString, then 0 is returned. Otherwise, the
- value returned is the first mismatched lower case ASCII character in
- SecondString subtracted from the first mismatched lower case ASCII character
- in FirstString.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and SecondString contains more
- than PcdMaximumAsciiStringLength ASCII characters not including the
- Null-terminator, then ASSERT().
-
- @param FirstString Pointer to a Null-terminated ASCII string.
- @param SecondString Pointer to a Null-terminated ASCII string.
-
- @retval 0 FirstString is identical to SecondString using case insensitive
- comparisons.
- @retval !=0 FirstString is not identical to SecondString using case
- insensitive comparisons.
-
-**/
-INTN
-EFIAPI
-AsciiStriCmp (
- IN CONST CHAR8 *FirstString,
- IN CONST CHAR8 *SecondString
- )
-{
- CHAR8 UpperFirstString;
- CHAR8 UpperSecondString;
-
- //
- // ASSERT both strings are less long than PcdMaximumAsciiStringLength
- //
- ASSERT (AsciiStrSize (FirstString));
- ASSERT (AsciiStrSize (SecondString));
-
- UpperFirstString = AsciiToUpper (*FirstString);
- UpperSecondString = AsciiToUpper (*SecondString);
- while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {
- FirstString++;
- SecondString++;
- UpperFirstString = AsciiToUpper (*FirstString);
- UpperSecondString = AsciiToUpper (*SecondString);
- }
-
- return UpperFirstString - UpperSecondString;
-}
-
-/**
- Compares two Null-terminated ASCII strings with maximum lengths, and returns
- the difference between the first mismatched ASCII characters.
-
- This function compares the Null-terminated ASCII string FirstString to the
- Null-terminated ASCII string SecondString. At most, Length ASCII characters
- will be compared. If Length is 0, then 0 is returned. If FirstString is
- identical to SecondString, then 0 is returned. Otherwise, the value returned
- is the first mismatched ASCII character in SecondString subtracted from the
- first mismatched ASCII character in FirstString.
-
- If FirstString is NULL, then ASSERT().
- If SecondString is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and SecondString contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param FirstString Pointer to a Null-terminated ASCII string.
- @param SecondString Pointer to a Null-terminated ASCII string.
-
- @retval 0 FirstString is identical to SecondString.
- @retval !=0 FirstString is not identical to SecondString.
-
-**/
-INTN
-EFIAPI
-AsciiStrnCmp (
- IN CONST CHAR8 *FirstString,
- IN CONST CHAR8 *SecondString,
- IN UINTN Length
- )
-{
- if (Length == 0) {
- return 0;
- }
-
- //
- // ASSERT both strings are less long than PcdMaximumAsciiStringLength
- //
- ASSERT (AsciiStrSize (FirstString));
- ASSERT (AsciiStrSize (SecondString));
-
- while ((*FirstString != '\0') &&
- (*FirstString == *SecondString) &&
- (Length > 1)) {
- FirstString++;
- SecondString++;
- Length--;
- }
- return *FirstString - *SecondString;
-}
-
-/**
- Concatenates one Null-terminated ASCII string to another Null-terminated
- ASCII string, and returns the concatenated ASCII string.
-
- This function concatenates two Null-terminated ASCII strings. The contents of
- Null-terminated ASCII string Source are concatenated to the end of Null-
- terminated ASCII string Destination. The Null-terminated concatenated ASCII
- String is returned.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and Destination contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and Source contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
- Source results in a ASCII string with more than PcdMaximumAsciiStringLength
- ASCII characters, then ASSERT().
-
- @param Destination Pointer to a Null-terminated ASCII string.
- @param Source Pointer to a Null-terminated ASCII string.
-
- @return Destination
-
-**/
-CHAR8 *
-EFIAPI
-AsciiStrCat (
- IN OUT CHAR8 *Destination,
- IN CONST CHAR8 *Source
- )
-{
- AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);
-
- //
- // Size of the resulting string should never be zero.
- // PcdMaximumUnicodeStringLength is tested inside StrLen().
- //
- ASSERT (AsciiStrSize (Destination) != 0);
- return Destination;
-}
-
-/**
- Concatenates one Null-terminated ASCII string with a maximum length to the
- end of another Null-terminated ASCII string, and returns the concatenated
- ASCII string.
-
- This function concatenates two Null-terminated ASCII strings. The contents
- of Null-terminated ASCII string Source are concatenated to the end of Null-
- terminated ASCII string Destination, and Destination is returned. At most,
- Length ASCII characters are concatenated from Source to the end of
- Destination, and Destination is always Null-terminated. If Length is 0, then
- Destination is returned unmodified. If Source and Destination overlap, then
- the results are undefined.
-
- If Destination is NULL, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and Source contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
- Source results in a ASCII string with more than PcdMaximumAsciiStringLength
- ASCII characters not including the Null-terminator, then ASSERT().
-
- @param Destination Pointer to a Null-terminated ASCII string.
- @param Source Pointer to a Null-terminated ASCII string.
- @param Length Maximum number of ASCII characters to concatenate from
- Source.
-
- @return Destination
-
-**/
-CHAR8 *
-EFIAPI
-AsciiStrnCat (
- IN OUT CHAR8 *Destination,
- IN CONST CHAR8 *Source,
- IN UINTN Length
- )
-{
- AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);
-
- //
- // Size of the resulting string should never be zero.
- // PcdMaximumUnicodeStringLength is tested inside StrLen().
- //
- ASSERT (AsciiStrSize (Destination) != 0);
- return Destination;
-}
-
-/**
- Returns the first occurance of a Null-terminated ASCII sub-string
- in a Null-terminated ASCII string.
-
- This function scans the contents of the ASCII string specified by String
- and returns the first occurrence of SearchString. If SearchString is not
- found in String, then NULL is returned. If the length of SearchString is zero,
- then String is returned.
-
- If String is NULL, then ASSERT().
- If SearchString is NULL, then ASSERT().
-
- If PcdMaximumAsciiStringLength is not zero, and SearchString or
- String contains more than PcdMaximumAsciiStringLength Unicode characters
- not including the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
- @param SearchString Pointer to a Null-terminated ASCII string to search for.
-
- @retval NULL If the SearchString does not appear in String.
- @retval !NULL If there is a match.
-
-**/
-CHAR8 *
-EFIAPI
-AsciiStrStr (
- IN CONST CHAR8 *String,
- IN CONST CHAR8 *SearchString
- )
-{
- CONST CHAR8 *FirstMatch;
- CONST CHAR8 *SearchStringTmp;
-
- ASSERT (String != NULL);
- ASSERT (SearchString != NULL);
-
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length of String should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
- ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
- }
-
- //
- // If PcdMaximumUnicodeStringLength is not zero,
- // length of SearchString should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
- ASSERT (AsciiStrLen (SearchString) < PcdGet32 (PcdMaximumAsciiStringLength));
- }
-
- while (*String != '\0') {
- SearchStringTmp = SearchString;
- FirstMatch = String;
-
- while ((*String == *SearchStringTmp)
- && (*SearchStringTmp != '\0')
- && (*String != '\0')) {
- String++;
- SearchStringTmp++;
- }
-
- if (*SearchStringTmp == '\0') {
- return (CHAR8 *) FirstMatch;
- }
-
- if (SearchStringTmp == SearchString) {
- //
- // If no character from SearchString match,
- // move the pointer to the String under search
- // by one character.
- //
- String++;
- }
-
- }
-
- return NULL;
-}
-
-/**
- Convert a Null-terminated ASCII decimal string to a value of type
- UINTN.
-
- This function returns a value of type UINTN by interpreting the contents
- of the ASCII string String as a decimal number. The format of the input
- ASCII string String is:
-
- [spaces] [decimal digits].
-
- The valid decimal digit character is in the range [0-9]. The function will
- ignore the pad space, which includes spaces or tab characters, before the digits.
- The running zero in the beginning of [decimal digits] will be ignored. Then, the
- function stops at the first character that is a not a valid decimal character or
- Null-terminator, whichever on comes first.
-
- If String has only pad spaces, then 0 is returned.
- If String has no pad spaces or valid decimal digits, then 0 is returned.
- If the number represented by String overflows according to the range defined by
- UINTN, then ASSERT().
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and String contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @retval UINTN
-
-**/
-UINTN
-EFIAPI
-AsciiStrDecimalToUintn (
- IN CONST CHAR8 *String
- )
-{
- UINTN Result;
-
- ASSERT (String != NULL);
- ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == ' ') || (*String == '\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == '0') {
- String++;
- }
-
- Result = 0;
-
- while (InternalAsciiIsDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||
- ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_10) &&
- (*String - '0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)
- );
-
- Result = Result * 10 + (*String - '0');
- String++;
- }
-
- return Result;
-}
-
-
-/**
- Convert a Null-terminated ASCII decimal string to a value of type
- UINT64.
-
- This function returns a value of type UINT64 by interpreting the contents
- of the ASCII string String as a decimal number. The format of the input
- ASCII string String is:
-
- [spaces] [decimal digits].
-
- The valid decimal digit character is in the range [0-9]. The function will
- ignore the pad space, which includes spaces or tab characters, before the digits.
- The running zero in the beginning of [decimal digits] will be ignored. Then, the
- function stops at the first character that is a not a valid decimal character or
- Null-terminator, whichever on comes first.
-
- If String has only pad spaces, then 0 is returned.
- If String has no pad spaces or valid decimal digits, then 0 is returned.
- If the number represented by String overflows according to the range defined by
- UINT64, then ASSERT().
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and String contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @retval UINT64
-
-**/
-UINT64
-EFIAPI
-AsciiStrDecimalToUint64 (
- IN CONST CHAR8 *String
- )
-{
- UINT64 Result;
-
- ASSERT (String != NULL);
- ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == ' ') || (*String == '\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == '0') {
- String++;
- }
-
- Result = 0;
-
- while (InternalAsciiIsDecimalDigitCharacter (*String)) {
- //
- // If the number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_10) ||
- ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_10) &&
- (*String - '0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)
- );
-
- Result = MultU64x32 (Result, 10) + (*String - '0');
- String++;
- }
-
- return Result;
-}
-
-/**
- Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
-
- This function returns a value of type UINTN by interpreting the contents of
- the ASCII string String as a hexadecimal number. The format of the input ASCII
- string String is:
-
- [spaces][zeros][x][hexadecimal digits].
-
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
- appears in the input string, it must be prefixed with at least one 0. The function
- will ignore the pad space, which includes spaces or tab characters, before [zeros],
- [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
- will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
- digit. Then, the function stops at the first character that is a not a valid
- hexadecimal character or Null-terminator, whichever on comes first.
-
- If String has only pad spaces, then 0 is returned.
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
- 0 is returned.
-
- If the number represented by String overflows according to the range defined by UINTN,
- then ASSERT().
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero,
- and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
- the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @retval UINTN
-
-**/
-UINTN
-EFIAPI
-AsciiStrHexToUintn (
- IN CONST CHAR8 *String
- )
-{
- UINTN Result;
-
- ASSERT (String != NULL);
- ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
-
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == ' ') || (*String == '\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == '0') {
- String++;
- }
-
- if (AsciiToUpper (*String) == 'X') {
- ASSERT (*(String - 1) == '0');
- if (*(String - 1) != '0') {
- return 0;
- }
- //
- // Skip the 'X'
- //
- String++;
- }
-
- Result = 0;
-
- while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
- //
- // If the Hex Number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||
- ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_16) &&
- (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINTN_DIVIDED_BY_16))
- );
-
- Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);
- String++;
- }
-
- return Result;
-}
-
-
-/**
- Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
-
- This function returns a value of type UINT64 by interpreting the contents of
- the ASCII string String as a hexadecimal number. The format of the input ASCII
- string String is:
-
- [spaces][zeros][x][hexadecimal digits].
-
- The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
- The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
- appears in the input string, it must be prefixed with at least one 0. The function
- will ignore the pad space, which includes spaces or tab characters, before [zeros],
- [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
- will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
- digit. Then, the function stops at the first character that is a not a valid
- hexadecimal character or Null-terminator, whichever on comes first.
-
- If String has only pad spaces, then 0 is returned.
- If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
- 0 is returned.
-
- If the number represented by String overflows according to the range defined by UINT64,
- then ASSERT().
- If String is NULL, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero,
- and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
- the Null-terminator, then ASSERT().
-
- @param String Pointer to a Null-terminated ASCII string.
-
- @retval UINT64
-
-**/
-UINT64
-EFIAPI
-AsciiStrHexToUint64 (
- IN CONST CHAR8 *String
- )
-{
- UINT64 Result;
-
- ASSERT (String != NULL);
- ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
-
- //
- // Ignore the pad spaces (space or tab) and leading Zeros
- //
- //
- // Ignore the pad spaces (space or tab)
- //
- while ((*String == ' ') || (*String == '\t')) {
- String++;
- }
-
- //
- // Ignore leading Zeros after the spaces
- //
- while (*String == '0') {
- String++;
- }
-
- if (AsciiToUpper (*String) == 'X') {
- ASSERT (*(String - 1) == '0');
- if (*(String - 1) != '0') {
- return 0;
- }
- //
- // Skip the 'X'
- //
- String++;
- }
-
- Result = 0;
-
- while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
- //
- // If the Hex Number represented by String overflows according
- // to the range defined by UINTN, then ASSERT().
- //
- ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_16) ||
- ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_16) &&
- (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINT64_DIVIDED_BY_16))
- );
-
- Result = LShiftU64 (Result, 4);
- Result = Result + InternalAsciiHexCharToUintn (*String);
- String++;
- }
-
- return Result;
-}
-
-
-/**
- Convert one Null-terminated ASCII string to a Null-terminated
- Unicode string and returns the Unicode string.
-
- This function converts the contents of the ASCII string Source to the Unicode
- string Destination, and returns Destination. The function terminates the
- Unicode string Destination by appending a Null-terminator character at the end.
- The caller is responsible to make sure Destination points to a buffer with size
- equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
-
- If Destination is NULL, then ASSERT().
- If Destination is not aligned on a 16-bit boundary, then ASSERT().
- If Source is NULL, then ASSERT().
- If Source and Destination overlap, then ASSERT().
- If PcdMaximumAsciiStringLength is not zero, and Source contains more than
- PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
- then ASSERT().
- If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
- PcdMaximumUnicodeStringLength ASCII characters not including the
- Null-terminator, then ASSERT().
-
- @param Source Pointer to a Null-terminated ASCII string.
- @param Destination Pointer to a Null-terminated Unicode string.
-
- @reture Destination
-
-**/
-CHAR16 *
-EFIAPI
-AsciiStrToUnicodeStr (
- IN CONST CHAR8 *Source,
- OUT CHAR16 *Destination
- )
-{
- ASSERT (Destination != NULL);
- ASSERT (Source != NULL);
-
- //
- // Source and Destination should not overlap
- //
- ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));
- ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));
-
- //
- // If PcdMaximumAsciiStringLength is not zero,
- // length of Source should not more than PcdMaximumUnicodeStringLength
- //
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
- ASSERT (AsciiStrLen (Source) < PcdGet32 (PcdMaximumAsciiStringLength));
- }
-
- while (*Source != '\0') {
- *(Destination++) = (CHAR16) *(Source++);
- }
- //
- // End the Destination with a NULL.
- //
- *Destination = '\0';
-
- return Destination;
-}
-
-/**
- Converts an 8-bit value to an 8-bit BCD value.
-
- Converts the 8-bit value specified by Value to BCD. The BCD value is
- returned.
-
- If Value >= 100, then ASSERT().
-
- @param Value The 8-bit value to convert to BCD. Range 0..99.
-
- @return The BCD value
-
-**/
-UINT8
-EFIAPI
-DecimalToBcd8 (
- IN UINT8 Value
- )
-{
- ASSERT (Value < 100);
- return (UINT8) (((Value / 10) << 4) | (Value % 10));
-}
-
-/**
- Converts an 8-bit BCD value to an 8-bit value.
-
- Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
- value is returned.
-
- If Value >= 0xA0, then ASSERT().
- If (Value & 0x0F) >= 0x0A, then ASSERT().
-
- @param Value The 8-bit BCD value to convert to an 8-bit value.
-
- @return The 8-bit value is returned.
-
-**/
-UINT8
-EFIAPI
-BcdToDecimal8 (
- IN UINT8 Value
- )
-{
- ASSERT (Value < 0xa0);
- ASSERT ((Value & 0xf) < 0xa);
- return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));
-}
-
-
+/** @file\r
+ Unicode and ASCII string primatives.\r
+\r
+ Copyright (c) 2006 - 2007, 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
+**/\r
+\r
+//\r
+// Include common header file for this module.\r
+//\r
+\r
+\r
+#include "BaseLibInternals.h"\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 Destination is not aligned on a 16-bit boundary, 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
+ 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
+ ASSERT (((UINTN) Destination & 0x01) == 0);\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 != 0) {\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 Length > 0 and Destination is NULL, then ASSERT().\r
+ If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length > 0 and Source is NULL, then ASSERT().\r
+ If Length > 0 and Source is not aligned on a 16-bit bounadry, 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
+\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
+ ASSERT (((UINTN) Destination & 0x01) == 0);\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
+\r
+/**\r
+ Returns the length of a Null-terminated Unicode string.\r
+\r
+ This function returns the number of Unicode characters in the Null-terminated\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
+ Null-terminator, then ASSERT().\r
+\r
+ @param String Pointer to a Null-terminated Unicode string.\r
+\r
+ @return The length of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrLen (\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ UINTN Length;\r
+\r
+ ASSERT (String != NULL);\r
+ ASSERT (((UINTN) String & 0x01) == 0);\r
+\r
+ for (Length = 0; *String != L'\0'; String++, Length++) {\r
+ //\r
+ // If PcdMaximumUnicodeStringLength is not zero,\r
+ // length should not more than PcdMaximumUnicodeStringLength\r
+ //\r
+ if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
+ ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));\r
+ }\r
+ }\r
+ return Length;\r
+}\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
+\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
+ Null-terminator, then ASSERT().\r
+\r
+ @param String Pointer to a Null-terminated Unicode string.\r
+\r
+ @return The size in bytes of String.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrSize (\r
+ IN CONST CHAR16 *String\r
+ )\r
+{\r
+ return (StrLen (String) + 1) * sizeof (*String);\r
+}\r
+\r
+/**\r
+ Compares two Null-terminated Unicode strings, and returns the difference\r
+ 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. If FirstString is identical to\r
+ SecondString, then 0 is returned. Otherwise, the value returned is the first\r
+ mismatched Unicode character in SecondString subtracted from the first\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
+ 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
+\r
+ @param FirstString Pointer to a Null-terminated Unicode string.\r
+ @param SecondString 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
+\r
+**/\r
+INTN\r
+EFIAPI\r
+StrCmp (\r
+ IN CONST CHAR16 *FirstString,\r
+ IN CONST CHAR16 *SecondString\r
+ )\r
+{\r
+ //\r
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength\r
+ //\r
+ ASSERT (StrSize (FirstString) != 0);\r
+ ASSERT (StrSize (SecondString) != 0);\r
+\r
+ while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {\r
+ FirstString++;\r
+ SecondString++;\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
+\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
+ FirstString is identical to SecondString, then 0 is returned. Otherwise, the\r
+ value returned is the first mismatched Unicode character in SecondString\r
+ subtracted from the first mismatched Unicode character in FirstString.\r
+\r
+ If Length > 0 and FirstString is NULL, then ASSERT().\r
+ If Length > 0 and FirstString is not aligned on a 16-bit bounadary, 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 bounadary, 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
+\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
+\r
+ @retval 0 FirstString is identical to SecondString.\r
+ @retval !=0 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
+ )\r
+{\r
+ if (0 == Length) {\r
+ return 0;\r
+ }\r
+\r
+ //\r
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
+ // Length tests are performed inside StrLen().\r
+ //\r
+ ASSERT (StrSize (FirstString) != 0);\r
+ ASSERT (StrSize (SecondString) != 0);\r
+\r
+ while ((*FirstString != L'\0') &&\r
+ (*FirstString == *SecondString) &&\r
+ (Length > 1)) {\r
+ FirstString++;\r
+ SecondString++;\r
+ Length--;\r
+ }\r
+\r
+ return *FirstString - *SecondString;\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
+\r
+ @param Destination Pointer to a Null-terminated Unicode string.\r
+ @param Source Pointer to a Null-terminated Unicode string.\r
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrCat (\r
+ IN OUT CHAR16 *Destination,\r
+ IN CONST CHAR16 *Source\r
+ )\r
+{\r
+ StrCpy (Destination + StrLen (Destination), Source);\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
+\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 Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().\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 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
+\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
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrnCat (\r
+ IN OUT CHAR16 *Destination,\r
+ IN CONST CHAR16 *Source,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ StrnCpy (Destination + StrLen (Destination), Source, Length);\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
+\r
+/**\r
+ Returns the first occurance of a Null-terminated Unicode sub-string \r
+ in a Null-terminated Unicode string.\r
+\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
+ @param String Pointer to a Null-terminated Unicode string.\r
+ @param SearchString Pointer to a Null-terminated Unicode string to search for.\r
+\r
+ @retval NULL If the SearchString does not appear in String.\r
+ @retval !NULL If there is a match.\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+StrStr (\r
+ IN CONST CHAR16 *String,\r
+ IN CONST CHAR16 *SearchString\r
+ )\r
+{\r
+ CONST CHAR16 *FirstMatch;\r
+ CONST CHAR16 *SearchStringTmp;\r
+\r
+ //\r
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
+ // Length tests are performed inside StrLen().\r
+ //\r
+ ASSERT (StrSize (String) != 0);\r
+ ASSERT (StrSize (SearchString) != 0);\r
+\r
+ while (*String != '\0') {\r
+ SearchStringTmp = SearchString;\r
+ FirstMatch = String;\r
+ \r
+ while ((*String == *SearchStringTmp) \r
+ && (*SearchStringTmp != '\0') \r
+ && (*String != '\0')) {\r
+ String++;\r
+ SearchStringTmp++;\r
+ } \r
+ \r
+ if ('\0' == *SearchStringTmp) {\r
+ return (CHAR16 *) FirstMatch;\r
+ }\r
+\r
+ if (SearchStringTmp == SearchString) {\r
+ //\r
+ // If no character from SearchString match,\r
+ // move the pointer to the String under search\r
+ // by one character.\r
+ //\r
+ String++;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\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
+ decimal character. The valid decimal character is from\r
+ L'0' to L'9'.\r
+\r
+\r
+ @param Char The character to check against.\r
+\r
+ @retval TRUE If the Char is a decmial character.\r
+ @retval FALSE Otherwise.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalIsDecimalDigitCharacter (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ return (BOOLEAN) (Char >= L'0' && Char <= L'9');\r
+}\r
+\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 ASII character, i.e.\r
+ L'a' to L'z'. For other Unicode character, the input character\r
+ is returned directly.\r
+\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
+InternalCharToUpper (\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
+ Convert a Unicode 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
+ 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
+\r
+ @retval UINTN The numerical value converted.\r
+\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 (UINTN) (10 + InternalCharToUpper (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 Otherwise.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+InternalIsHexaDecimalDigitCharacter (\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+\r
+ return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||\r
+ (Char >= L'A' && Char <= L'F') ||\r
+ (Char >= L'a' && Char <= L'f'));\r
+}\r
+\r
+/**\r
+ Convert a Null-terminated Unicode decimal string to a value of \r
+ 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 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 UINTN, then ASSERT().\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 Pointer to a Null-terminated Unicode string.\r
+\r
+ @retval UINTN \r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+StrDecimalToUintn (\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 ((L' ' ==*String) || (L'\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (L'0' == *String) {\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 < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||\r
+ ((QUIENT_MAX_UINTN_DIVIDED_BY_10 == Result) &&\r
+ (*String - L'0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)\r
+ );\r
+\r
+ Result = Result * 10 + (*String - L'0');\r
+ String++;\r
+ }\r
+ \r
+ return Result;\r
+}\r
+\r
+\r
+/**\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 ASSERT().\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 Pointer to a Null-terminated Unicode string.\r
+\r
+ @retval UINT64 \r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+StrDecimalToUint64 (\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 ((L' ' == *String) || (L'\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (L'0' == *String) {\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 < QUIENT_MAX_UINT64_DIVIDED_BY_10) || \r
+ ((QUIENT_MAX_UINT64_DIVIDED_BY_10 == Result) && \r
+ (*String - L'0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)\r
+ );\r
+\r
+ Result = MultU64x32 (Result, 10) + (*String - L'0');\r
+ String++;\r
+ }\r
+ \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 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 UINTN\r
+\r
+**/\r
+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 ((L' ' == *String) || (L'\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (L'0' == *String) {\r
+ String++;\r
+ }\r
+\r
+ if (InternalCharToUpper (*String) == L'X') {\r
+ ASSERT (L'0' == *(String - 1));\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 < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||\r
+ ((QUIENT_MAX_UINTN_DIVIDED_BY_16 == Result) && \r
+ (InternalHexCharToUintn (*String) <= REMINDER_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 UINT64\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 ((L' ' == *String) || (L'\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while (L'0' == *String) {\r
+ String++;\r
+ }\r
+\r
+ if (InternalCharToUpper (*String) == L'X') {\r
+ ASSERT (L'0' == *(String - 1));\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 < QUIENT_MAX_UINT64_DIVIDED_BY_16)|| \r
+ ((QUIENT_MAX_UINT64_DIVIDED_BY_16 == Result) && \r
+ (InternalHexCharToUintn (*String) <= REMINDER_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 Otherwise.\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 Otherwise.\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. The function terminates \r
+ the ASCII string Destination by appending a Null-terminator character \r
+ at the end. The caller is responsible to make sure Destination points \r
+ to a buffer with size equal or greater than (StrLen (Source) + 1) in bytes.\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 any Unicode characters in Source contain non-zero value in \r
+ the upper 8 bits, 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 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
+ 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 (0 == Length) {\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
+ 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 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 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
+AsciiToUpper (\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
+ @retval UINTN 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 + AsciiToUpper (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 = AsciiToUpper (*FirstString);\r
+ UpperSecondString = AsciiToUpper (*SecondString);\r
+ while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
+ FirstString++;\r
+ SecondString++;\r
+ UpperFirstString = AsciiToUpper (*FirstString);\r
+ UpperSecondString = AsciiToUpper (*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 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 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 to compare.\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
+AsciiStrnCmp (\r
+ IN CONST CHAR8 *FirstString,\r
+ IN CONST CHAR8 *SecondString,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ if (0 == Length) {\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
+ while ((*FirstString != '\0') &&\r
+ (*FirstString == *SecondString) &&\r
+ (Length > 1)) {\r
+ FirstString++;\r
+ SecondString++;\r
+ Length--;\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
+\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
+\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
+\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
+AsciiStrCat (\r
+ IN OUT CHAR8 *Destination,\r
+ IN CONST CHAR8 *Source\r
+ )\r
+{\r
+ AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);\r
+\r
+ //\r
+ // Size of the resulting string should never be zero.\r
+ // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+ //\r
+ ASSERT (AsciiStrSize (Destination) != 0);\r
+ return Destination;\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
+ 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 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
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrnCat (\r
+ IN OUT CHAR8 *Destination,\r
+ IN CONST CHAR8 *Source,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);\r
+\r
+ //\r
+ // Size of the resulting string should never be zero.\r
+ // PcdMaximumUnicodeStringLength is tested inside StrLen().\r
+ //\r
+ ASSERT (AsciiStrSize (Destination) != 0);\r
+ return Destination;\r
+}\r
+\r
+/**\r
+ Returns the first occurance of a Null-terminated ASCII sub-string \r
+ in a Null-terminated ASCII string.\r
+\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 String is NULL, then ASSERT().\r
+ If SearchString is NULL, then ASSERT().\r
+\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
+ @param String Pointer to a Null-terminated ASCII string.\r
+ @param SearchString Pointer to a Null-terminated ASCII string to search for.\r
+\r
+ @retval NULL If the SearchString does not appear in String.\r
+ @retval !NULL If there is a match.\r
+\r
+**/\r
+CHAR8 *\r
+EFIAPI\r
+AsciiStrStr (\r
+ IN CONST CHAR8 *String,\r
+ IN CONST CHAR8 *SearchString\r
+ )\r
+{\r
+ CONST CHAR8 *FirstMatch;\r
+ CONST CHAR8 *SearchStringTmp;\r
+\r
+ //\r
+ // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
+ //\r
+ ASSERT (AsciiStrSize (String) != 0);\r
+ ASSERT (AsciiStrSize (SearchString) != 0);\r
+\r
+ while (*String != '\0') {\r
+ SearchStringTmp = SearchString;\r
+ FirstMatch = String;\r
+ \r
+ while ((*String == *SearchStringTmp) \r
+ && (*SearchStringTmp != '\0') \r
+ && (*String != '\0')) {\r
+ String++;\r
+ SearchStringTmp++;\r
+ } \r
+ \r
+ if (*SearchStringTmp == '\0') {\r
+ return (CHAR8 *) FirstMatch;\r
+ }\r
+\r
+ if (SearchStringTmp == SearchString) {\r
+ //\r
+ // If no character from SearchString match,\r
+ // move the pointer to the String under search\r
+ // by one character.\r
+ //\r
+ String++;\r
+ }\r
+\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\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 ASSERT().\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
+ @retval UINTN \r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrDecimalToUintn (\r
+ IN CONST CHAR8 *String\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) || ('\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while ('0' == *String) {\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 < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||\r
+ ((QUIENT_MAX_UINTN_DIVIDED_BY_10 == Result) && \r
+ (*String - '0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)\r
+ );\r
+\r
+ Result = Result * 10 + (*String - '0');\r
+ String++;\r
+ }\r
+ \r
+ return Result;\r
+}\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 ASSERT().\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
+ @retval UINT64 \r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsciiStrDecimalToUint64 (\r
+ IN CONST CHAR8 *String\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) || ('\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while ('0' == *String) {\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 < QUIENT_MAX_UINT64_DIVIDED_BY_10) || \r
+ ((QUIENT_MAX_UINT64_DIVIDED_BY_10 == Result) && \r
+ (*String - '0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)\r
+ );\r
+\r
+ Result = MultU64x32 (Result, 10) + (*String - '0');\r
+ String++;\r
+ }\r
+ \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 ASSERT().\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 Pointer to a Null-terminated ASCII string.\r
+\r
+ @retval UINTN\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsciiStrHexToUintn (\r
+ IN CONST CHAR8 *String\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) || ('\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while ('0' == *String) {\r
+ String++;\r
+ }\r
+\r
+ if (AsciiToUpper (*String) == 'X') {\r
+ ASSERT ('0' == *(String - 1));\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 < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||\r
+ ((QUIENT_MAX_UINTN_DIVIDED_BY_16 == Result) && \r
+ (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINTN_DIVIDED_BY_16))\r
+ );\r
+\r
+ Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);\r
+ String++;\r
+ }\r
+\r
+ return Result;\r
+}\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 ASSERT().\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 Pointer to a Null-terminated ASCII string.\r
+\r
+ @retval UINT64\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsciiStrHexToUint64 (\r
+ IN CONST CHAR8 *String\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) and leading Zeros\r
+ //\r
+ //\r
+ // Ignore the pad spaces (space or tab) \r
+ //\r
+ while ((' ' == *String) || ('\t' == *String)) {\r
+ String++;\r
+ }\r
+\r
+ //\r
+ // Ignore leading Zeros after the spaces\r
+ //\r
+ while ('0' == *String) {\r
+ String++;\r
+ }\r
+\r
+ if (AsciiToUpper (*String) == 'X') {\r
+ ASSERT ('0' == *(String - 1));\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 < QUIENT_MAX_UINT64_DIVIDED_BY_16) ||\r
+ ((QUIENT_MAX_UINT64_DIVIDED_BY_16 == Result) && \r
+ (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINT64_DIVIDED_BY_16))\r
+ );\r
+\r
+ Result = LShiftU64 (Result, 4);\r
+ Result = Result + InternalAsciiHexCharToUintn (*String);\r
+ String++;\r
+ }\r
+\r
+ return Result;\r
+}\r
+\r
+\r
+/**\r
+ Convert one Null-terminated ASCII string to a Null-terminated \r
+ Unicode string and returns the Unicode string.\r
+\r
+ This function converts the contents of the ASCII string Source to the Unicode \r
+ string Destination, and returns Destination. The function terminates the \r
+ Unicode string Destination by appending a Null-terminator character at the end. \r
+ The caller is responsible to make sure Destination points to a buffer with size \r
+ equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.\r
+ \r
+ If Destination is NULL, then ASSERT().\r
+ If Destination is not aligned on a 16-bit boundary, 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
+ If PcdMaximumUnicodeStringLength is not zero, and Source contains more than \r
+ PcdMaximumUnicodeStringLength ASCII characters not including the \r
+ Null-terminator, then ASSERT().\r
+\r
+ @param Source Pointer to a Null-terminated ASCII string.\r
+ @param Destination Pointer to a Null-terminated Unicode string.\r
+\r
+ @return Destination\r
+\r
+**/\r
+CHAR16 *\r
+EFIAPI\r
+AsciiStrToUnicodeStr (\r
+ IN CONST CHAR8 *Source,\r
+ OUT CHAR16 *Destination\r
+ )\r
+{\r
+ CHAR16 *ReturnValue;\r
+\r
+ ASSERT (Destination != NULL);\r
+\r
+ //\r
+ // ASSERT Source is less long than PcdMaximumAsciiStringLength\r
+ //\r
+ ASSERT (AsciiStrSize (Source) != 0);\r
+\r
+ //\r
+ // Source and Destination should not overlap\r
+ //\r
+ ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));\r
+ ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));\r
+\r
+ \r
+ ReturnValue = Destination;\r
+ while (*Source != '\0') {\r
+ *(Destination++) = (CHAR16) *(Source++);\r
+ }\r
+ //\r
+ // End the Destination with a NULL.\r
+ //\r
+ *Destination = '\0';\r
+\r
+ //\r
+ // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength\r
+ //\r
+ ASSERT (StrSize (ReturnValue) != 0);\r
+\r
+ return ReturnValue;\r
+}\r
+\r
+/**\r
+ Converts an 8-bit value to an 8-bit BCD value.\r
+\r
+ Converts the 8-bit value specified by Value to BCD. The BCD value is\r
+ returned.\r
+\r
+ If Value >= 100, then ASSERT().\r
+\r
+ @param Value The 8-bit value to convert to BCD. Range 0..99.\r
+\r
+ @return The BCD value\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+DecimalToBcd8 (\r
+ IN UINT8 Value\r
+ )\r
+{\r
+ ASSERT (Value < 100);\r
+ return (UINT8) (((Value / 10) << 4) | (Value % 10));\r
+}\r
+\r
+/**\r
+ Converts an 8-bit BCD value to an 8-bit value.\r
+\r
+ Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit\r
+ value is returned.\r
+\r
+ If Value >= 0xA0, then ASSERT().\r
+ If (Value & 0x0F) >= 0x0A, then ASSERT().\r
+\r
+ @param Value The 8-bit BCD value to convert to an 8-bit value.\r
+\r
+ @return The 8-bit value is returned.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+BcdToDecimal8 (\r
+ IN UINT8 Value\r
+ )\r
+{\r
+ ASSERT (Value < 0xa0);\r
+ ASSERT ((Value & 0xf) < 0xa);\r
+ return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));\r
+}\r
+\r
+\r
+/**\r
+ Convert a nibble in the low 4 bits of a byte to a Unicode hexadecimal character.\r
+\r
+ This function converts a nibble in the low 4 bits of a byte to a Unicode hexadecimal \r
+ character For example, the nibble 0x01 and 0x0A will converted to L'1' and L'A' \r
+ respectively.\r
+\r
+ The upper nibble in the input byte will be masked off.\r
+\r
+ @param Nibble The nibble which is in the low 4 bits of the input byte.\r
+\r
+ @retval CHAR16 The Unicode hexadecimal character.\r
+ \r
+**/\r
+CHAR16\r
+NibbleToHexChar (\r
+ IN UINT8 Nibble\r
+ )\r
+{\r
+ Nibble &= 0x0F;\r
+ if (Nibble <= 0x9) {\r
+ return (CHAR16)(Nibble + L'0');\r
+ }\r
+\r
+ return (CHAR16)(Nibble - 0xA + L'A');\r
+}\r
+\r
+/** \r
+ Convert binary buffer to a Unicode String in a specified sequence. \r
+\r
+ This function converts bytes in the binary Buffer Buf to a Unicode String Str. \r
+ Each byte will be represented by two Unicode characters. For example, byte 0xA1 will \r
+ be converted into two Unicode character L'A' and L'1'. In the output String, the Unicode Character \r
+ for the Most Significant Nibble will be put before the Unicode Character for the Least Significant\r
+ Nibble. The output string for the buffer containing a single byte 0xA1 will be L"A1". \r
+ For a buffer with multiple bytes, the Unicode character produced by the first byte will be put into the \r
+ the last character in the output string. The one next to first byte will be put into the\r
+ character before the last character. This rules applies to the rest of the bytes. The Unicode\r
+ character by the last byte will be put into the first character in the output string. For example,\r
+ the input buffer for a 64-bits unsigned integrer 0x12345678abcdef1234 will be converted to\r
+ a Unicode string equal to L"12345678abcdef1234".\r
+\r
+ @param String On input, String is pointed to the buffer allocated for the convertion.\r
+ @param StringLen The Length of String buffer to hold the output String. The length must include the tailing '\0' character.\r
+ The StringLen required to convert a N bytes Buffer will be a least equal to or greater \r
+ than 2*N + 1.\r
+ @param Buffer The pointer to a input buffer.\r
+ @param BufferSizeInBytes Lenth in bytes of the input buffer.\r
+ \r
+\r
+ @retval EFI_SUCCESS The convertion is successfull. All bytes in Buffer has been convert to the corresponding\r
+ Unicode character and placed into the right place in String.\r
+ @retval EFI_BUFFER_TOO_SMALL StringSizeInBytes is smaller than 2 * N + 1the number of bytes required to\r
+ complete the convertion. \r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+BufToHexString (\r
+ IN OUT CHAR16 *String,\r
+ IN OUT UINTN *StringLen,\r
+ IN CONST UINT8 *Buffer,\r
+ IN UINTN BufferSizeInBytes\r
+ )\r
+{\r
+ UINTN Idx;\r
+ UINT8 Byte;\r
+ UINTN StrLen;\r
+\r
+ //\r
+ // Make sure string is either passed or allocate enough.\r
+ // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.\r
+ // Plus the Unicode termination character.\r
+ //\r
+ StrLen = BufferSizeInBytes * 2;\r
+ if (StrLen > ((*StringLen) - 1)) {\r
+ *StringLen = StrLen + 1;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *StringLen = StrLen + 1;\r
+ //\r
+ // Ends the string.\r
+ //\r
+ String[StrLen] = L'\0'; \r
+\r
+ for (Idx = 0; Idx < BufferSizeInBytes; Idx++) {\r
+\r
+ Byte = Buffer[Idx];\r
+ String[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);\r
+ String[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Convert a Unicode string consisting of hexadecimal characters to a output byte buffer.\r
+\r
+ This function converts a Unicode string consisting of characters in the range of Hexadecimal\r
+ character (L'0' to L'9', L'A' to L'F' and L'a' to L'f') to a output byte buffer. The function will stop\r
+ at the first non-hexadecimal character or the NULL character. The convertion process can be\r
+ simply viewed as the reverse operations defined by BufToHexString. Two Unicode characters will be \r
+ converted into one byte. The first Unicode character represents the Most Significant Nibble and the\r
+ second Unicode character represents the Least Significant Nibble in the output byte. \r
+ The first pair of Unicode characters represents the last byte in the output buffer. The second pair of Unicode \r
+ characters represent the the byte preceding the last byte. This rule applies to the rest pairs of bytes. \r
+ The last pair represent the first byte in the output buffer. \r
+\r
+ For example, a Unciode String L"12345678" will be converted into a buffer wil the following bytes \r
+ (first byte is the byte in the lowest memory address): "0x78, 0x56, 0x34, 0x12".\r
+\r
+ If String has N valid hexadecimal characters for conversion, the caller must make sure Buffer is at least \r
+ N/2 (if N is even) or (N+1)/2 (if N if odd) bytes. \r
+\r
+ @param Buffer The output buffer allocated by the caller.\r
+ @param BufferSizeInBytes On input, the size in bytes of Buffer. On output, it is updated to \r
+ contain the size of the Buffer which is actually used for the converstion.\r
+ For Unicode string with 2*N hexadecimal characters (not including the \r
+ tailing NULL character), N bytes of Buffer will be used for the output.\r
+ @param String The input hexadecimal string.\r
+ @param ConvertedStrLen The number of hexadecimal characters used to produce content in output\r
+ buffer Buffer.\r
+\r
+ @retval RETURN_BUFFER_TOO_SMALL The input BufferSizeInBytes is too small to hold the output. BufferSizeInBytes\r
+ will be updated to the size required for the converstion.\r
+ @retval RETURN_SUCCESS The convertion is successful or the first Unicode character from String\r
+ is hexadecimal. If ConvertedStrLen is not NULL, it is updated\r
+ to the number of hexadecimal character used for the converstion.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+HexStringToBuf (\r
+ OUT UINT8 *Buffer, \r
+ IN OUT UINTN *BufferSizeInBytes,\r
+ IN CONST CHAR16 *String,\r
+ OUT UINTN *ConvertedStrLen OPTIONAL\r
+ )\r
+{\r
+ UINTN HexCnt;\r
+ UINTN Idx;\r
+ UINTN BufferLength;\r
+ UINT8 Digit;\r
+ UINT8 Byte;\r
+\r
+ //\r
+ // Find out how many hex characters the string has.\r
+ //\r
+ for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, String[Idx]); Idx++, HexCnt++);\r
+\r
+ if (HexCnt == 0) {\r
+ *ConvertedStrLen = 0;\r
+ return RETURN_SUCCESS;\r
+ }\r
+ //\r
+ // Two Unicode characters make up 1 buffer byte. Round up.\r
+ //\r
+ BufferLength = (HexCnt + 1) / 2; \r
+\r
+ //\r
+ // Test if buffer is passed enough.\r
+ //\r
+ if (BufferLength > (*BufferSizeInBytes)) {\r
+ *BufferSizeInBytes = BufferLength;\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ *BufferSizeInBytes = BufferLength;\r
+\r
+ for (Idx = 0; Idx < HexCnt; Idx++) {\r
+\r
+ IsHexDigit (&Digit, String[HexCnt - 1 - Idx]);\r
+\r
+ //\r
+ // For odd charaters, write the lower nibble for each buffer byte,\r
+ // and for even characters, the upper nibble.\r
+ //\r
+ if ((Idx & 1) == 0) {\r
+ Byte = Digit;\r
+ } else {\r
+ Byte = Buffer[Idx / 2];\r
+ Byte &= 0x0F;\r
+ Byte = (UINT8) (Byte | Digit << 4);\r
+ }\r
+\r
+ Buffer[Idx / 2] = Byte;\r
+ }\r
+\r
+ if (ConvertedStrLen != NULL) {\r
+ *ConvertedStrLen = HexCnt;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Test if a Unicode character is a hexadecimal digit. If true, the input\r
+ Unicode character is converted to a byte. \r
+\r
+ This function tests if a Unicode character is a hexadecimal digit. If true, the input\r
+ Unicode character is converted to a byte. For example, Unicode character\r
+ L'A' will be converted to 0x0A. \r
+\r
+ If Digit is NULL, then ASSERT.\r
+\r
+ @retval TRUE Char is in the range of Hexadecimal number. Digit is updated\r
+ to the byte value of the number.\r
+ @retval FALSE Char is not in the range of Hexadecimal number. Digit is keep\r
+ intact.\r
+ \r
+**/\r
+BOOLEAN\r
+IsHexDigit (\r
+ OUT UINT8 *Digit,\r
+ IN CHAR16 Char\r
+ )\r
+{\r
+ ASSERT (Digit != NULL);\r
+ \r
+ if ((Char >= L'0') && (Char <= L'9')) {\r
+ *Digit = (UINT8) (Char - L'0');\r
+ return TRUE;\r
+ }\r
+\r
+ if ((Char >= L'A') && (Char <= L'F')) {\r
+ *Digit = (UINT8) (Char - L'A' + 0x0A);\r
+ return TRUE;\r
+ }\r
+\r
+ if ((Char >= L'a') && (Char <= L'f')) {\r
+ *Digit = (UINT8) (Char - L'a' + 0x0A);\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+\r