REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			1645 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1645 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Unicode and ASCII string primitives.
 | |
| 
 | |
|   Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "BaseLibInternals.h"
 | |
| 
 | |
| /**
 | |
|   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 String is not aligned on a 16-bit boundary, then ASSERT().
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
 | |
|   PcdMaximumUnicodeStringLength Unicode characters, not including the
 | |
|   Null-terminator, then ASSERT().
 | |
| 
 | |
|   @param  String  A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @return The length of String.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| StrLen (
 | |
|   IN      CONST CHAR16  *String
 | |
|   )
 | |
| {
 | |
|   UINTN  Length;
 | |
| 
 | |
|   ASSERT (String != NULL);
 | |
|   ASSERT (((UINTN)String & BIT0) == 0);
 | |
| 
 | |
|   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 String is not aligned on a 16-bit boundary, then ASSERT().
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
 | |
|   PcdMaximumUnicodeStringLength Unicode characters, not including the
 | |
|   Null-terminator, then ASSERT().
 | |
| 
 | |
|   @param  String  A 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 FirstString is not aligned on a 16-bit boundary, then ASSERT().
 | |
|   If SecondString is NULL, then ASSERT().
 | |
|   If SecondString is not aligned on a 16-bit boundary, 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   A pointer to a Null-terminated Unicode string.
 | |
|   @param  SecondString  A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @retval 0      FirstString is identical to SecondString.
 | |
|   @return others 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 up to a specified length the contents of 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. 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 Length > 0 and FirstString is NULL, then ASSERT().
 | |
|   If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
 | |
|   If Length > 0 and SecondString is NULL, then ASSERT().
 | |
|   If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
 | |
|   PcdMaximumUnicodeStringLength, 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   A pointer to a Null-terminated Unicode string.
 | |
|   @param  SecondString  A pointer to a Null-terminated Unicode string.
 | |
|   @param  Length        The maximum number of Unicode characters to compare.
 | |
| 
 | |
|   @retval 0      FirstString is identical to SecondString.
 | |
|   @return others 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);
 | |
| 
 | |
|   if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
 | |
|     ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));
 | |
|   }
 | |
| 
 | |
|   while ((*FirstString != L'\0') &&
 | |
|          (*SecondString != L'\0') &&
 | |
|          (*FirstString == *SecondString) &&
 | |
|          (Length > 1))
 | |
|   {
 | |
|     FirstString++;
 | |
|     SecondString++;
 | |
|     Length--;
 | |
|   }
 | |
| 
 | |
|   return *FirstString - *SecondString;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Returns the first occurrence 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          A pointer to a Null-terminated Unicode string.
 | |
|   @param  SearchString    A pointer to a Null-terminated Unicode string to search for.
 | |
| 
 | |
|   @retval NULL            If the SearchString does not appear in String.
 | |
|   @return others          If there is a match.
 | |
| 
 | |
| **/
 | |
| CHAR16 *
 | |
| EFIAPI
 | |
| StrStr (
 | |
|   IN      CONST CHAR16  *String,
 | |
|   IN      CONST CHAR16  *SearchString
 | |
|   )
 | |
| {
 | |
|   CONST CHAR16  *FirstMatch;
 | |
|   CONST CHAR16  *SearchStringTmp;
 | |
| 
 | |
|   //
 | |
|   // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
 | |
|   // Length tests are performed inside StrLen().
 | |
|   //
 | |
|   ASSERT (StrSize (String) != 0);
 | |
|   ASSERT (StrSize (SearchString) != 0);
 | |
| 
 | |
|   if (*SearchString == L'\0') {
 | |
|     return (CHAR16 *)String;
 | |
|   }
 | |
| 
 | |
|   while (*String != L'\0') {
 | |
|     SearchStringTmp = SearchString;
 | |
|     FirstMatch      = String;
 | |
| 
 | |
|     while (  (*String == *SearchStringTmp)
 | |
|           && (*String != L'\0'))
 | |
|     {
 | |
|       String++;
 | |
|       SearchStringTmp++;
 | |
|     }
 | |
| 
 | |
|     if (*SearchStringTmp == L'\0') {
 | |
|       return (CHAR16 *)FirstMatch;
 | |
|     }
 | |
| 
 | |
|     if (*String == L'\0') {
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     String = FirstMatch + 1;
 | |
|   }
 | |
| 
 | |
|   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 If the Char is not a decmial character.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| 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 ASCII 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.
 | |
| 
 | |
| **/
 | |
| CHAR16
 | |
| EFIAPI
 | |
| CharToUpper (
 | |
|   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.
 | |
| 
 | |
|   @return The numerical value converted.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| InternalHexCharToUintn (
 | |
|   IN      CHAR16  Char
 | |
|   )
 | |
| {
 | |
|   if (InternalIsDecimalDigitCharacter (Char)) {
 | |
|     return Char - L'0';
 | |
|   }
 | |
| 
 | |
|   return (10 + CharToUpper (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 If the Char is not a hexadecmial character.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| 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 MAX_UINTN is returned.
 | |
| 
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains
 | |
|   more than PcdMaximumUnicodeStringLength Unicode characters, not including
 | |
|   the Null-terminator, then ASSERT().
 | |
| 
 | |
|   @param  String      A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| StrDecimalToUintn (
 | |
|   IN      CONST CHAR16  *String
 | |
|   )
 | |
| {
 | |
|   UINTN  Result;
 | |
| 
 | |
|   StrDecimalToUintnS (String, (CHAR16 **)NULL, &Result);
 | |
|   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 MAX_UINT64 is returned.
 | |
| 
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains
 | |
|   more than PcdMaximumUnicodeStringLength Unicode characters, not including
 | |
|   the Null-terminator, then ASSERT().
 | |
| 
 | |
|   @param  String          A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINT64
 | |
| EFIAPI
 | |
| StrDecimalToUint64 (
 | |
|   IN      CONST CHAR16  *String
 | |
|   )
 | |
| {
 | |
|   UINT64  Result;
 | |
| 
 | |
|   StrDecimalToUint64S (String, (CHAR16 **)NULL, &Result);
 | |
|   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 MAX_UINTN is returned.
 | |
| 
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
 | |
|   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
 | |
|   then ASSERT().
 | |
| 
 | |
|   @param  String          A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| StrHexToUintn (
 | |
|   IN      CONST CHAR16  *String
 | |
|   )
 | |
| {
 | |
|   UINTN  Result;
 | |
| 
 | |
|   StrHexToUintnS (String, (CHAR16 **)NULL, &Result);
 | |
|   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 MAX_UINT64 is returned.
 | |
| 
 | |
|   If PcdMaximumUnicodeStringLength is not zero, and String contains more than
 | |
|   PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
 | |
|   then ASSERT().
 | |
| 
 | |
|   @param  String          A pointer to a Null-terminated Unicode string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINT64
 | |
| EFIAPI
 | |
| StrHexToUint64 (
 | |
|   IN      CONST CHAR16  *String
 | |
|   )
 | |
| {
 | |
|   UINT64  Result;
 | |
| 
 | |
|   StrHexToUint64S (String, (CHAR16 **)NULL, &Result);
 | |
|   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 If the Char is not a decmial character.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| 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 If the Char is not a hexadecmial character.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| EFIAPI
 | |
| InternalAsciiIsHexaDecimalDigitCharacter (
 | |
|   IN      CHAR8  Char
 | |
|   )
 | |
| {
 | |
|   return (BOOLEAN)(InternalAsciiIsDecimalDigitCharacter (Char) ||
 | |
|                    (Char >= 'A' && Char <= 'F') ||
 | |
|                    (Char >= 'a' && Char <= 'f'));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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 Length > 0 and Destination is NULL, then ASSERT().
 | |
|   If Length > 0 and Source 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  A 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  A 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   A pointer to a Null-terminated ASCII string.
 | |
|   @param  SecondString  A 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
 | |
| 
 | |
| **/
 | |
| CHAR8
 | |
| EFIAPI
 | |
| AsciiCharToUpper (
 | |
|   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.
 | |
| 
 | |
|   @return The numerical value converted.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| InternalAsciiHexCharToUintn (
 | |
|   IN      CHAR8  Char
 | |
|   )
 | |
| {
 | |
|   if (InternalIsDecimalDigitCharacter (Char)) {
 | |
|     return Char - '0';
 | |
|   }
 | |
| 
 | |
|   return (10 + AsciiCharToUpper (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   A pointer to a Null-terminated ASCII string.
 | |
|   @param  SecondString  A 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  = AsciiCharToUpper (*FirstString);
 | |
|   UpperSecondString = AsciiCharToUpper (*SecondString);
 | |
|   while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {
 | |
|     FirstString++;
 | |
|     SecondString++;
 | |
|     UpperFirstString  = AsciiCharToUpper (*FirstString);
 | |
|     UpperSecondString = AsciiCharToUpper (*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 Length > 0 and FirstString is NULL, then ASSERT().
 | |
|   If Length > 0 and SecondString is NULL, then ASSERT().
 | |
|   If PcdMaximumAsciiStringLength is not zero, and Length is greater than
 | |
|   PcdMaximumAsciiStringLength, 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   A pointer to a Null-terminated ASCII string.
 | |
|   @param  SecondString  A pointer to a Null-terminated ASCII string.
 | |
|   @param  Length        The maximum number of ASCII characters for compare.
 | |
| 
 | |
|   @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));
 | |
| 
 | |
|   if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
 | |
|     ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));
 | |
|   }
 | |
| 
 | |
|   while ((*FirstString != '\0') &&
 | |
|          (*SecondString != '\0') &&
 | |
|          (*FirstString == *SecondString) &&
 | |
|          (Length > 1))
 | |
|   {
 | |
|     FirstString++;
 | |
|     SecondString++;
 | |
|     Length--;
 | |
|   }
 | |
| 
 | |
|   return *FirstString - *SecondString;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Returns the first occurrence 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          A pointer to a Null-terminated ASCII string.
 | |
|   @param  SearchString    A pointer to a Null-terminated ASCII string to search for.
 | |
| 
 | |
|   @retval NULL            If the SearchString does not appear in String.
 | |
|   @retval others          If there is a match return the first occurrence of SearchingString.
 | |
|                           If the length of SearchString is zero,return String.
 | |
| 
 | |
| **/
 | |
| CHAR8 *
 | |
| EFIAPI
 | |
| AsciiStrStr (
 | |
|   IN      CONST CHAR8  *String,
 | |
|   IN      CONST CHAR8  *SearchString
 | |
|   )
 | |
| {
 | |
|   CONST CHAR8  *FirstMatch;
 | |
|   CONST CHAR8  *SearchStringTmp;
 | |
| 
 | |
|   //
 | |
|   // ASSERT both strings are less long than PcdMaximumAsciiStringLength
 | |
|   //
 | |
|   ASSERT (AsciiStrSize (String) != 0);
 | |
|   ASSERT (AsciiStrSize (SearchString) != 0);
 | |
| 
 | |
|   if (*SearchString == '\0') {
 | |
|     return (CHAR8 *)String;
 | |
|   }
 | |
| 
 | |
|   while (*String != '\0') {
 | |
|     SearchStringTmp = SearchString;
 | |
|     FirstMatch      = String;
 | |
| 
 | |
|     while (  (*String == *SearchStringTmp)
 | |
|           && (*String != '\0'))
 | |
|     {
 | |
|       String++;
 | |
|       SearchStringTmp++;
 | |
|     }
 | |
| 
 | |
|     if (*SearchStringTmp == '\0') {
 | |
|       return (CHAR8 *)FirstMatch;
 | |
|     }
 | |
| 
 | |
|     if (*String == '\0') {
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     String = FirstMatch + 1;
 | |
|   }
 | |
| 
 | |
|   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 MAX_UINTN is returned.
 | |
|   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          A pointer to a Null-terminated ASCII string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| AsciiStrDecimalToUintn (
 | |
|   IN      CONST CHAR8  *String
 | |
|   )
 | |
| {
 | |
|   UINTN  Result;
 | |
| 
 | |
|   AsciiStrDecimalToUintnS (String, (CHAR8 **)NULL, &Result);
 | |
|   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 MAX_UINT64 is returned.
 | |
|   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          A pointer to a Null-terminated ASCII string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINT64
 | |
| EFIAPI
 | |
| AsciiStrDecimalToUint64 (
 | |
|   IN      CONST CHAR8  *String
 | |
|   )
 | |
| {
 | |
|   UINT64  Result;
 | |
| 
 | |
|   AsciiStrDecimalToUint64S (String, (CHAR8 **)NULL, &Result);
 | |
|   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 MAX_UINTN is returned.
 | |
|   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          A pointer to a Null-terminated ASCII string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINTN
 | |
| EFIAPI
 | |
| AsciiStrHexToUintn (
 | |
|   IN      CONST CHAR8  *String
 | |
|   )
 | |
| {
 | |
|   UINTN  Result;
 | |
| 
 | |
|   AsciiStrHexToUintnS (String, (CHAR8 **)NULL, &Result);
 | |
|   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 MAX_UINT64 is returned.
 | |
|   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          A pointer to a Null-terminated ASCII string.
 | |
| 
 | |
|   @retval Value translated from String.
 | |
| 
 | |
| **/
 | |
| UINT64
 | |
| EFIAPI
 | |
| AsciiStrHexToUint64 (
 | |
|   IN      CONST CHAR8  *String
 | |
|   )
 | |
| {
 | |
|   UINT64  Result;
 | |
| 
 | |
|   AsciiStrHexToUint64S (String, (CHAR8 **)NULL, &Result);
 | |
|   return Result;
 | |
| }
 | |
| 
 | |
| STATIC CHAR8  EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | |
|                                 "abcdefghijklmnopqrstuvwxyz"
 | |
|                                 "0123456789+/";
 | |
| 
 | |
| /**
 | |
|   Convert binary data to a Base64 encoded ascii string based on RFC4648.
 | |
| 
 | |
|   Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.
 | |
|   The Ascii string is produced by converting the data string specified by Source and SourceLength.
 | |
| 
 | |
|   @param Source            Input UINT8 data
 | |
|   @param SourceLength      Number of UINT8 bytes of data
 | |
|   @param Destination       Pointer to output string buffer
 | |
|   @param DestinationSize   Size of ascii buffer. Set to 0 to get the size needed.
 | |
|                            Caller is responsible for passing in buffer of DestinationSize
 | |
| 
 | |
|   @retval RETURN_SUCCESS             When ascii buffer is filled in.
 | |
|   @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.
 | |
|   @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).
 | |
|   @retval RETURN_BUFFER_TOO_SMALL    If SourceLength is 0 and DestinationSize is <1.
 | |
|   @retval RETURN_BUFFER_TOO_SMALL    If Destination is NULL or DestinationSize is smaller than required buffersize.
 | |
| 
 | |
| **/
 | |
| RETURN_STATUS
 | |
| EFIAPI
 | |
| Base64Encode (
 | |
|   IN  CONST UINT8  *Source,
 | |
|   IN        UINTN  SourceLength,
 | |
|   OUT       CHAR8  *Destination   OPTIONAL,
 | |
|   IN OUT    UINTN  *DestinationSize
 | |
|   )
 | |
| {
 | |
|   UINTN  RequiredSize;
 | |
|   UINTN  Left;
 | |
| 
 | |
|   //
 | |
|   // Check pointers, and SourceLength is valid
 | |
|   //
 | |
|   if ((Source == NULL) || (DestinationSize == NULL)) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Allow for RFC 4648 test vector 1
 | |
|   //
 | |
|   if (SourceLength == 0) {
 | |
|     if (*DestinationSize < 1) {
 | |
|       *DestinationSize = 1;
 | |
|       return RETURN_BUFFER_TOO_SMALL;
 | |
|     }
 | |
| 
 | |
|     *DestinationSize = 1;
 | |
|     *Destination     = '\0';
 | |
|     return RETURN_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Check if SourceLength or  DestinationSize is valid
 | |
|   //
 | |
|   if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // 4 ascii per 3 bytes + NULL
 | |
|   //
 | |
|   RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;
 | |
|   if ((Destination == NULL) || (*DestinationSize < RequiredSize)) {
 | |
|     *DestinationSize = RequiredSize;
 | |
|     return RETURN_BUFFER_TOO_SMALL;
 | |
|   }
 | |
| 
 | |
|   Left = SourceLength;
 | |
| 
 | |
|   //
 | |
|   // Encode 24 bits (three bytes) into 4 ascii characters
 | |
|   //
 | |
|   while (Left >= 3) {
 | |
|     *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];
 | |
|     *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
 | |
|     *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];
 | |
|     *Destination++ = EncodingTable[(Source[2] & 0x3f)];
 | |
|     Left          -= 3;
 | |
|     Source        += 3;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Handle the remainder, and add padding '=' characters as necessary.
 | |
|   //
 | |
|   switch (Left) {
 | |
|     case 0:
 | |
| 
 | |
|       //
 | |
|       // No bytes Left, done.
 | |
|       //
 | |
|       break;
 | |
|     case 1:
 | |
| 
 | |
|       //
 | |
|       // One more data byte, two pad characters
 | |
|       //
 | |
|       *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];
 | |
|       *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];
 | |
|       *Destination++ = '=';
 | |
|       *Destination++ = '=';
 | |
|       break;
 | |
|     case 2:
 | |
| 
 | |
|       //
 | |
|       // Two more data bytes, and one pad character
 | |
|       //
 | |
|       *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];
 | |
|       *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];
 | |
|       *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];
 | |
|       *Destination++ = '=';
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Add terminating NULL
 | |
|   //
 | |
|   *Destination = '\0';
 | |
|   return RETURN_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Decode Base64 ASCII encoded data to 8-bit binary representation, based on
 | |
|   RFC4648.
 | |
| 
 | |
|   Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.
 | |
| 
 | |
|   Whitespace is ignored at all positions:
 | |
|   - 0x09 ('\t') horizontal tab
 | |
|   - 0x0A ('\n') new line
 | |
|   - 0x0B ('\v') vertical tab
 | |
|   - 0x0C ('\f') form feed
 | |
|   - 0x0D ('\r') carriage return
 | |
|   - 0x20 (' ')  space
 | |
| 
 | |
|   The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated
 | |
|   and enforced at the end of the Base64 ASCII encoded data, and only there.
 | |
| 
 | |
|   Other characters outside of the encoding alphabet cause the function to
 | |
|   reject the Base64 ASCII encoded data.
 | |
| 
 | |
|   @param[in] Source               Array of CHAR8 elements containing the Base64
 | |
|                                   ASCII encoding. May be NULL if SourceSize is
 | |
|                                   zero.
 | |
| 
 | |
|   @param[in] SourceSize           Number of CHAR8 elements in Source.
 | |
| 
 | |
|   @param[out] Destination         Array of UINT8 elements receiving the decoded
 | |
|                                   8-bit binary representation. Allocated by the
 | |
|                                   caller. May be NULL if DestinationSize is
 | |
|                                   zero on input. If NULL, decoding is
 | |
|                                   performed, but the 8-bit binary
 | |
|                                   representation is not stored. If non-NULL and
 | |
|                                   the function returns an error, the contents
 | |
|                                   of Destination are indeterminate.
 | |
| 
 | |
|   @param[in,out] DestinationSize  On input, the number of UINT8 elements that
 | |
|                                   the caller allocated for Destination. On
 | |
|                                   output, if the function returns
 | |
|                                   RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,
 | |
|                                   the number of UINT8 elements that are
 | |
|                                   required for decoding the Base64 ASCII
 | |
|                                   representation. If the function returns a
 | |
|                                   value different from both RETURN_SUCCESS and
 | |
|                                   RETURN_BUFFER_TOO_SMALL, then DestinationSize
 | |
|                                   is indeterminate on output.
 | |
| 
 | |
|   @retval RETURN_SUCCESS            SourceSize CHAR8 elements at Source have
 | |
|                                     been decoded to on-output DestinationSize
 | |
|                                     UINT8 elements at Destination. Note that
 | |
|                                     RETURN_SUCCESS covers the case when
 | |
|                                     DestinationSize is zero on input, and
 | |
|                                     Source decodes to zero bytes (due to
 | |
|                                     containing at most ignored whitespace).
 | |
| 
 | |
|   @retval RETURN_BUFFER_TOO_SMALL   The input value of DestinationSize is not
 | |
|                                     large enough for decoding SourceSize CHAR8
 | |
|                                     elements at Source. The required number of
 | |
|                                     UINT8 elements has been stored to
 | |
|                                     DestinationSize.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  DestinationSize is NULL.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  Source is NULL, but SourceSize is not zero.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  Destination is NULL, but DestinationSize is
 | |
|                                     not zero on input.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  Source is non-NULL, and (Source +
 | |
|                                     SourceSize) would wrap around MAX_ADDRESS.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  Destination is non-NULL, and (Destination +
 | |
|                                     DestinationSize) would wrap around
 | |
|                                     MAX_ADDRESS, as specified on input.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  None of Source and Destination are NULL,
 | |
|                                     and CHAR8[SourceSize] at Source overlaps
 | |
|                                     UINT8[DestinationSize] at Destination, as
 | |
|                                     specified on input.
 | |
| 
 | |
|   @retval RETURN_INVALID_PARAMETER  Invalid CHAR8 element encountered in
 | |
|                                     Source.
 | |
| **/
 | |
| RETURN_STATUS
 | |
| EFIAPI
 | |
| Base64Decode (
 | |
|   IN     CONST CHAR8  *Source          OPTIONAL,
 | |
|   IN     UINTN        SourceSize,
 | |
|   OUT    UINT8        *Destination     OPTIONAL,
 | |
|   IN OUT UINTN        *DestinationSize
 | |
|   )
 | |
| {
 | |
|   BOOLEAN  PaddingMode;
 | |
|   UINTN    SixBitGroupsConsumed;
 | |
|   UINT32   Accumulator;
 | |
|   UINTN    OriginalDestinationSize;
 | |
|   UINTN    SourceIndex;
 | |
|   CHAR8    SourceChar;
 | |
|   UINT32   Base64Value;
 | |
|   UINT8    DestinationOctet;
 | |
| 
 | |
|   if (DestinationSize == NULL) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Check Source array validity.
 | |
|   //
 | |
|   if (Source == NULL) {
 | |
|     if (SourceSize > 0) {
 | |
|       //
 | |
|       // At least one CHAR8 element at NULL Source.
 | |
|       //
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|     }
 | |
|   } else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {
 | |
|     //
 | |
|     // Non-NULL Source, but it wraps around.
 | |
|     //
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Check Destination array validity.
 | |
|   //
 | |
|   if (Destination == NULL) {
 | |
|     if (*DestinationSize > 0) {
 | |
|       //
 | |
|       // At least one UINT8 element at NULL Destination.
 | |
|       //
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|     }
 | |
|   } else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {
 | |
|     //
 | |
|     // Non-NULL Destination, but it wraps around.
 | |
|     //
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Check for overlap.
 | |
|   //
 | |
|   if ((Source != NULL) && (Destination != NULL)) {
 | |
|     //
 | |
|     // Both arrays have been provided, and we know from earlier that each array
 | |
|     // is valid in itself.
 | |
|     //
 | |
|     if ((UINTN)Source + SourceSize <= (UINTN)Destination) {
 | |
|       //
 | |
|       // Source array precedes Destination array, OK.
 | |
|       //
 | |
|     } else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {
 | |
|       //
 | |
|       // Destination array precedes Source array, OK.
 | |
|       //
 | |
|     } else {
 | |
|       //
 | |
|       // Overlap.
 | |
|       //
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Decoding loop setup.
 | |
|   //
 | |
|   PaddingMode             = FALSE;
 | |
|   SixBitGroupsConsumed    = 0;
 | |
|   Accumulator             = 0;
 | |
|   OriginalDestinationSize = *DestinationSize;
 | |
|   *DestinationSize        = 0;
 | |
| 
 | |
|   //
 | |
|   // Decoding loop.
 | |
|   //
 | |
|   for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {
 | |
|     SourceChar = Source[SourceIndex];
 | |
| 
 | |
|     //
 | |
|     // Whitespace is ignored at all positions (regardless of padding mode).
 | |
|     //
 | |
|     if ((SourceChar == '\t') || (SourceChar == '\n') || (SourceChar == '\v') ||
 | |
|         (SourceChar == '\f') || (SourceChar == '\r') || (SourceChar == ' '))
 | |
|     {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // If we're in padding mode, accept another padding character, as long as
 | |
|     // that padding character completes the quantum. This completes case (2)
 | |
|     // from RFC4648, Chapter 4. "Base 64 Encoding":
 | |
|     //
 | |
|     // (2) The final quantum of encoding input is exactly 8 bits; here, the
 | |
|     //     final unit of encoded output will be two characters followed by two
 | |
|     //     "=" padding characters.
 | |
|     //
 | |
|     if (PaddingMode) {
 | |
|       if ((SourceChar == '=') && (SixBitGroupsConsumed == 3)) {
 | |
|         SixBitGroupsConsumed = 0;
 | |
|         continue;
 | |
|       }
 | |
| 
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:
 | |
|     // The Base 64 Alphabet".
 | |
|     //
 | |
|     if (('A' <= SourceChar) && (SourceChar <= 'Z')) {
 | |
|       Base64Value = SourceChar - 'A';
 | |
|     } else if (('a' <= SourceChar) && (SourceChar <= 'z')) {
 | |
|       Base64Value = 26 + (SourceChar - 'a');
 | |
|     } else if (('0' <= SourceChar) && (SourceChar <= '9')) {
 | |
|       Base64Value = 52 + (SourceChar - '0');
 | |
|     } else if (SourceChar == '+') {
 | |
|       Base64Value = 62;
 | |
|     } else if (SourceChar == '/') {
 | |
|       Base64Value = 63;
 | |
|     } else if (SourceChar == '=') {
 | |
|       //
 | |
|       // Enter padding mode.
 | |
|       //
 | |
|       PaddingMode = TRUE;
 | |
| 
 | |
|       if (SixBitGroupsConsumed == 2) {
 | |
|         //
 | |
|         // If we have consumed two 6-bit groups from the current quantum before
 | |
|         // encountering the first padding character, then this is case (2) from
 | |
|         // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,
 | |
|         // and we'll enforce another padding character.
 | |
|         //
 | |
|         SixBitGroupsConsumed = 3;
 | |
|       } else if (SixBitGroupsConsumed == 3) {
 | |
|         //
 | |
|         // If we have consumed three 6-bit groups from the current quantum
 | |
|         // before encountering the first padding character, then this is case
 | |
|         // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now
 | |
|         // complete.
 | |
|         //
 | |
|         SixBitGroupsConsumed = 0;
 | |
|       } else {
 | |
|         //
 | |
|         // Padding characters are not allowed at the first two positions of a
 | |
|         // quantum.
 | |
|         //
 | |
|         return RETURN_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Wherever in a quantum we enter padding mode, we enforce the padding
 | |
|       // bits pending in the accumulator -- from the last 6-bit group just
 | |
|       // preceding the padding character -- to be zero. Refer to RFC4648,
 | |
|       // Chapter 3.5. "Canonical Encoding".
 | |
|       //
 | |
|       if (Accumulator != 0) {
 | |
|         return RETURN_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Advance to the next source character.
 | |
|       //
 | |
|       continue;
 | |
|     } else {
 | |
|       //
 | |
|       // Other characters outside of the encoding alphabet are rejected.
 | |
|       //
 | |
|       return RETURN_INVALID_PARAMETER;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Feed the bits of the current 6-bit group of the quantum to the
 | |
|     // accumulator.
 | |
|     //
 | |
|     Accumulator = (Accumulator << 6) | Base64Value;
 | |
|     SixBitGroupsConsumed++;
 | |
|     switch (SixBitGroupsConsumed) {
 | |
|       case 1:
 | |
|         //
 | |
|         // No octet to spill after consuming the first 6-bit group of the
 | |
|         // quantum; advance to the next source character.
 | |
|         //
 | |
|         continue;
 | |
|       case 2:
 | |
|         //
 | |
|         // 12 bits accumulated (6 pending + 6 new); prepare for spilling an
 | |
|         // octet. 4 bits remain pending.
 | |
|         //
 | |
|         DestinationOctet = (UINT8)(Accumulator >> 4);
 | |
|         Accumulator     &= 0xF;
 | |
|         break;
 | |
|       case 3:
 | |
|         //
 | |
|         // 10 bits accumulated (4 pending + 6 new); prepare for spilling an
 | |
|         // octet. 2 bits remain pending.
 | |
|         //
 | |
|         DestinationOctet = (UINT8)(Accumulator >> 2);
 | |
|         Accumulator     &= 0x3;
 | |
|         break;
 | |
|       default:
 | |
|         ASSERT (SixBitGroupsConsumed == 4);
 | |
|         //
 | |
|         // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.
 | |
|         // The quantum is complete, 0 bits remain pending.
 | |
|         //
 | |
|         DestinationOctet     = (UINT8)Accumulator;
 | |
|         Accumulator          = 0;
 | |
|         SixBitGroupsConsumed = 0;
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Store the decoded octet if there's room left. Increment
 | |
|     // (*DestinationSize) unconditionally.
 | |
|     //
 | |
|     if (*DestinationSize < OriginalDestinationSize) {
 | |
|       ASSERT (Destination != NULL);
 | |
|       Destination[*DestinationSize] = DestinationOctet;
 | |
|     }
 | |
| 
 | |
|     (*DestinationSize)++;
 | |
| 
 | |
|     //
 | |
|     // Advance to the next source character.
 | |
|     //
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // If Source terminates mid-quantum, then Source is invalid.
 | |
|   //
 | |
|   if (SixBitGroupsConsumed != 0) {
 | |
|     return RETURN_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Done.
 | |
|   //
 | |
|   if (*DestinationSize <= OriginalDestinationSize) {
 | |
|     return RETURN_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   return RETURN_BUFFER_TOO_SMALL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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));
 | |
| }
 |