]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/String.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
index 6b68bb2eeca8b3fa0a087709f40b3d893a81a2ab..98e6d31463e0f20534511f3d1849765cb9b3a9f9 100644 (file)
 /** @file\r
-  Unicode and ASCII string primatives.\r
+  Unicode and ASCII string primitives.\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
+  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\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
@@ -147,10 +17,10 @@ StrnCpy (
   If String is NULL, then ASSERT().\r
   If String is not aligned on a 16-bit boundary, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
-  PcdMaximumUnicodeStringLength Unicode characters not including the \r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
   Null-terminator, then ASSERT().\r
 \r
-  @param  String  Pointer to a Null-terminated Unicode string.\r
+  @param  String  A pointer to a Null-terminated Unicode string.\r
 \r
   @return The length of String.\r
 \r
@@ -158,13 +28,13 @@ StrnCpy (
 UINTN\r
 EFIAPI\r
 StrLen (\r
-  IN      CONST CHAR16              *String\r
+  IN      CONST CHAR16  *String\r
   )\r
 {\r
-  UINTN                             Length;\r
+  UINTN  Length;\r
 \r
   ASSERT (String != NULL);\r
-  ASSERT (((UINTN) String & 0x01) == 0);\r
+  ASSERT (((UINTN)String & BIT0) == 0);\r
 \r
   for (Length = 0; *String != L'\0'; String++, Length++) {\r
     //\r
@@ -175,6 +45,7 @@ StrLen (
       ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));\r
     }\r
   }\r
+\r
   return Length;\r
 }\r
 \r
@@ -182,24 +53,24 @@ StrLen (
   Returns the size of a Null-terminated Unicode string in bytes, including the\r
   Null terminator.\r
 \r
-  This function returns the size, in bytes, of the Null-terminated Unicode\r
-  string specified by String.\r
+  This function returns the size, in bytes, of the Null-terminated Unicode string\r
+  specified by String.\r
 \r
   If String is NULL, then ASSERT().\r
   If String is not aligned on a 16-bit boundary, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and String contains more than\r
-  PcdMaximumUnicodeStringLength Unicode characters not including the \r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the\r
   Null-terminator, then ASSERT().\r
 \r
-  @param  String  Pointer to a Null-terminated Unicode string.\r
+  @param  String  A pointer to a Null-terminated Unicode string.\r
 \r
-  @return The size in bytes of String.\r
+  @return The size of String.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 StrSize (\r
-  IN      CONST CHAR16              *String\r
+  IN      CONST CHAR16  *String\r
   )\r
 {\r
   return (StrLen (String) + 1) * sizeof (*String);\r
@@ -220,24 +91,24 @@ StrSize (
   If SecondString is NULL, then ASSERT().\r
   If SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more\r
-  than PcdMaximumUnicodeStringLength Unicode characters not including the \r
+  than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
   Null-terminator, then ASSERT().\r
   If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more\r
-  than PcdMaximumUnicodeStringLength Unicode characters not including the \r
+  than PcdMaximumUnicodeStringLength Unicode characters, not including the\r
   Null-terminator, then ASSERT().\r
 \r
-  @param  FirstString   Pointer to a Null-terminated Unicode string.\r
-  @param  SecondString  Pointer to a Null-terminated Unicode string.\r
+  @param  FirstString   A pointer to a Null-terminated Unicode string.\r
+  @param  SecondString  A pointer to a Null-terminated Unicode string.\r
 \r
-  @retval 0   FirstString is identical to SecondString.\r
-  @retval !=0 FirstString is not identical to SecondString.\r
+  @retval 0      FirstString is identical to SecondString.\r
+  @return others FirstString is not identical to SecondString.\r
 \r
 **/\r
 INTN\r
 EFIAPI\r
 StrCmp (\r
-  IN      CONST CHAR16              *FirstString,\r
-  IN      CONST CHAR16              *SecondString\r
+  IN      CONST CHAR16  *FirstString,\r
+  IN      CONST CHAR16  *SecondString\r
   )\r
 {\r
   //\r
@@ -250,12 +121,13 @@ StrCmp (
     FirstString++;\r
     SecondString++;\r
   }\r
+\r
   return *FirstString - *SecondString;\r
 }\r
 \r
 /**\r
-  Compares two Null-terminated Unicode strings with maximum lengths, and\r
-  returns the difference between the first mismatched Unicode characters.\r
+  Compares up to a specified length the contents of two Null-terminated Unicode strings,\r
+  and returns the difference between the first mismatched Unicode characters.\r
 \r
   This function compares the Null-terminated Unicode string FirstString to the\r
   Null-terminated Unicode string SecondString. At most, Length Unicode\r
@@ -265,33 +137,35 @@ StrCmp (
   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 FirstString is not aligned on a 16-bit boundary, then ASSERT().\r
   If Length > 0 and SecondString is NULL, then ASSERT().\r
-  If Length > 0 and SecondString is not aligned on a 16-bit 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
+  If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than\r
+  PcdMaximumUnicodeStringLength, then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
+  then ASSERT().\r
+  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than\r
+  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,\r
+  then ASSERT().\r
 \r
-  @param  FirstString   Pointer to a Null-terminated Unicode string.\r
-  @param  SecondString  Pointer to a Null-terminated Unicode string.\r
-  @param  Length        Maximum number of Unicode characters to compare.\r
+  @param  FirstString   A pointer to a Null-terminated Unicode string.\r
+  @param  SecondString  A pointer to a Null-terminated Unicode string.\r
+  @param  Length        The maximum number of Unicode characters to compare.\r
 \r
-  @retval 0   FirstString is identical to SecondString.\r
-  @retval !=0 FirstString is not identical to SecondString.\r
+  @retval 0      FirstString is identical to SecondString.\r
+  @return others FirstString is not identical to SecondString.\r
 \r
 **/\r
 INTN\r
 EFIAPI\r
 StrnCmp (\r
-  IN      CONST CHAR16              *FirstString,\r
-  IN      CONST CHAR16              *SecondString,\r
-  IN      UINTN                     Length\r
+  IN      CONST CHAR16  *FirstString,\r
+  IN      CONST CHAR16  *SecondString,\r
+  IN      UINTN         Length\r
   )\r
 {\r
-  if (0 == Length) {\r
+  if (Length == 0) {\r
     return 0;\r
   }\r
 \r
@@ -302,9 +176,15 @@ StrnCmp (
   ASSERT (StrSize (FirstString) != 0);\r
   ASSERT (StrSize (SecondString) != 0);\r
 \r
+  if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {\r
+    ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength));\r
+  }\r
+\r
   while ((*FirstString != L'\0') &&\r
+         (*SecondString != L'\0') &&\r
          (*FirstString == *SecondString) &&\r
-         (Length > 1)) {\r
+         (Length > 1))\r
+  {\r
     FirstString++;\r
     SecondString++;\r
     Length--;\r
@@ -314,142 +194,40 @@ StrnCmp (
 }\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
+  Returns the first occurrence 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
+  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
+\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
+  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
+  @param  String          A pointer to a Null-terminated Unicode string.\r
+  @param  SearchString    A pointer to a Null-terminated Unicode string to search for.\r
 \r
   @retval NULL            If the SearchString does not appear in String.\r
-  @retval !NULL           If there is a match.\r
+  @return others          If there is a match.\r
 \r
 **/\r
 CHAR16 *\r
 EFIAPI\r
 StrStr (\r
-  IN      CONST CHAR16                *String,\r
-  IN      CONST CHAR16                *SearchString\r
+  IN      CONST CHAR16  *String,\r
+  IN      CONST CHAR16  *SearchString\r
   )\r
 {\r
-  CONST CHAR16 *FirstMatch;\r
-  CONST CHAR16 *SearchStringTmp;\r
+  CONST CHAR16  *FirstMatch;\r
+  CONST CHAR16  *SearchStringTmp;\r
 \r
   //\r
   // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.\r
@@ -458,29 +236,30 @@ StrStr (
   ASSERT (StrSize (String) != 0);\r
   ASSERT (StrSize (SearchString) != 0);\r
 \r
-  while (*String != '\0') {\r
+  if (*SearchString == L'\0') {\r
+    return (CHAR16 *)String;\r
+  }\r
+\r
+  while (*String != L'\0') {\r
     SearchStringTmp = SearchString;\r
-    FirstMatch = String;\r
-    \r
-    while ((*String == *SearchStringTmp) \r
-            && (*SearchStringTmp != '\0') \r
-            && (*String != '\0')) {\r
+    FirstMatch      = String;\r
+\r
+    while (  (*String == *SearchStringTmp)\r
+          && (*String != L'\0'))\r
+    {\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
+    if (*SearchStringTmp == L'\0') {\r
+      return (CHAR16 *)FirstMatch;\r
     }\r
+\r
+    if (*String == L'\0') {\r
+      return NULL;\r
+    }\r
+\r
+    String = FirstMatch + 1;\r
   }\r
 \r
   return NULL;\r
@@ -489,36 +268,34 @@ StrStr (
 /**\r
   Check if a Unicode character is a decimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
+  This internal function checks if a Unicode character is a\r
   decimal character. The valid decimal character is from\r
   L'0' to L'9'.\r
 \r
-\r
   @param  Char  The character to check against.\r
 \r
   @retval TRUE  If the Char is a decmial character.\r
-  @retval FALSE Otherwise.\r
+  @retval FALSE If the Char is not a decmial character.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 InternalIsDecimalDigitCharacter (\r
-  IN      CHAR16                    Char\r
+  IN      CHAR16  Char\r
   )\r
 {\r
-  return (BOOLEAN) (Char >= L'0' && Char <= L'9');\r
+  return (BOOLEAN)(Char >= L'0' && Char <= L'9');\r
 }\r
 \r
 /**\r
-  Convert a Unicode character to upper case only if \r
+  Convert a Unicode character to upper case only if\r
   it maps to a valid small-case ASCII character.\r
 \r
   This internal function only deal with Unicode character\r
-  which maps to a valid small-case ASII character, i.e.\r
+  which maps to a valid small-case ASCII character, i.e.\r
   L'a' to L'z'. For other Unicode character, the input character\r
   is returned directly.\r
 \r
-\r
   @param  Char  The character to convert.\r
 \r
   @retval LowerCharacter   If the Char is with range L'a' to L'z'.\r
@@ -527,12 +304,12 @@ InternalIsDecimalDigitCharacter (
 **/\r
 CHAR16\r
 EFIAPI\r
-InternalCharToUpper (\r
-  IN      CHAR16                    Char\r
+CharToUpper (\r
+  IN      CHAR16  Char\r
   )\r
 {\r
-  if (Char >= L'a' && Char <= L'z') {\r
-    return (CHAR16) (Char - (L'a' - L'A'));\r
+  if ((Char >= L'a') && (Char <= L'z')) {\r
+    return (CHAR16)(Char - (L'a' - L'A'));\r
   }\r
 \r
   return Char;\r
@@ -543,693 +320,338 @@ InternalCharToUpper (
 \r
   This internal function only deal with Unicode character\r
   which maps to a valid hexadecimal ASII character, i.e.\r
-  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other \r
+  L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other\r
   Unicode character, the value returned does not make sense.\r
 \r
   @param  Char  The character to convert.\r
 \r
-  @retval UINTN   The numerical value converted.\r
+  @return The numerical value converted.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 InternalHexCharToUintn (\r
-  IN      CHAR16                    Char\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
+  return (10 + CharToUpper (Char) - L'A');\r
 }\r
 \r
 /**\r
   Check if a Unicode character is a hexadecimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
-  decimal character.  The valid hexadecimal character is \r
+  This internal function checks if a Unicode character is a\r
+  decimal character.  The valid hexadecimal character is\r
   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.\r
 \r
 \r
   @param  Char  The character to check against.\r
 \r
   @retval TRUE  If the Char is a hexadecmial character.\r
-  @retval FALSE Otherwise.\r
+  @retval FALSE If the Char is not a hexadecmial character.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 InternalIsHexaDecimalDigitCharacter (\r
-  IN      CHAR16                    Char\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
+  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
+  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
+  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
+\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
+\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 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
+  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
+  If the number represented by String overflows according\r
+  to the range defined by UINTN, then MAX_UINTN is returned.\r
+\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains\r
+  more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
   the Null-terminator, then ASSERT().\r
 \r
-  @param  String                Pointer to a Null-terminated Unicode string.\r
+  @param  String      A pointer to a Null-terminated Unicode string.\r
 \r
-  @retval UINTN           \r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 StrDecimalToUintn (\r
-  IN      CONST CHAR16                *String\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
+  UINTN  Result;\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
+  StrDecimalToUintnS (String, (CHAR16 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
-\r
 /**\r
-  Convert a Null-terminated Unicode decimal string to a value of \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
+  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
+\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
+\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 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
+  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
+  If the number represented by String overflows according\r
+  to the range defined by UINT64, then MAX_UINT64 is returned.\r
+\r
+  If PcdMaximumUnicodeStringLength is not zero, and String contains\r
+  more than PcdMaximumUnicodeStringLength Unicode characters, not including\r
   the Null-terminator, then ASSERT().\r
 \r
-  @param  String                Pointer to a Null-terminated Unicode string.\r
+  @param  String          A pointer to a Null-terminated Unicode string.\r
 \r
-  @retval UINT64           \r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINT64\r
 EFIAPI\r
 StrDecimalToUint64 (\r
-  IN      CONST CHAR16                *String\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
+  UINT64  Result;\r
 \r
-    Result = MultU64x32 (Result, 10) + (*String - L'0');\r
-    String++;\r
-  }\r
-  \r
+  StrDecimalToUint64S (String, (CHAR16 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
 /**\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
+  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
+\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
+  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
+  If the number represented by String overflows according to the range defined by\r
+  UINTN, then MAX_UINTN is returned.\r
 \r
-  If PcdMaximumUnicodeStringLength is not zero, and String contains more than \r
-  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, \r
+  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
+  @param  String          A pointer to a Null-terminated Unicode string.\r
 \r
-  @retval UINTN\r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 StrHexToUintn (\r
-  IN      CONST CHAR16                *String\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
+  UINTN  Result;\r
 \r
+  StrHexToUintnS (String, (CHAR16 **)NULL, &Result);\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
+  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
+  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
+  If the number represented by String overflows according to the range defined by\r
+  UINT64, then MAX_UINT64 is returned.\r
 \r
-  If PcdMaximumUnicodeStringLength is not zero, and String contains more than \r
-  PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, \r
+  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
+  @param  String          A pointer to a Null-terminated Unicode string.\r
 \r
-  @retval UINT64\r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINT64\r
 EFIAPI\r
 StrHexToUint64 (\r
-  IN      CONST CHAR16                *String\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
+  UINT64  Result;\r
 \r
+  StrHexToUint64S (String, (CHAR16 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
 /**\r
   Check if a ASCII character is a decimal character.\r
 \r
-  This internal function checks if a Unicode character is a \r
+  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
+  @retval FALSE If the Char is not a decmial character.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 InternalAsciiIsDecimalDigitCharacter (\r
-  IN      CHAR8                     Char\r
+  IN      CHAR8  Char\r
   )\r
 {\r
-  return (BOOLEAN) (Char >= '0' && Char <= '9');\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
+  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
+  @retval FALSE If the Char is not a hexadecmial character.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
 InternalAsciiIsHexaDecimalDigitCharacter (\r
-  IN      CHAR8                    Char\r
+  IN      CHAR8  Char\r
   )\r
 {\r
-\r
-  return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||\r
-    (Char >= 'A' && Char <= 'F') ||\r
-    (Char >= 'a' && Char <= 'f'));\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
+  Returns the length of a Null-terminated ASCII string.\r
+\r
+  This function returns the number of ASCII characters in the Null-terminated\r
+  ASCII string specified by String.\r
+\r
+  If Length > 0 and Destination is NULL, then ASSERT().\r
+  If Length > 0 and Source is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero and String contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
+  then ASSERT().\r
 \r
-  @param  Source        Pointer to a Null-terminated Unicode string.\r
-  @param  Destination   Pointer to a Null-terminated ASCII string.\r
+  @param  String  A pointer to a Null-terminated ASCII string.\r
 \r
-  @return Destination\r
+  @return The length of String.\r
 \r
 **/\r
-CHAR8 *\r
+UINTN\r
 EFIAPI\r
-UnicodeStrToAsciiStr (\r
-  IN      CONST CHAR16                *Source,\r
-  OUT     CHAR8                       *Destination\r
+AsciiStrLen (\r
+  IN      CONST CHAR8  *String\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
+  UINTN  Length;\r
 \r
+  ASSERT (String != NULL);\r
 \r
-  ReturnValue = Destination;\r
-  while (*Source != '\0') {\r
+  for (Length = 0; *String != '\0'; String++, Length++) {\r
     //\r
-    // If any Unicode characters in Source contain \r
-    // non-zero value in the upper 8 bits, then ASSERT().\r
+    // If PcdMaximumUnicodeStringLength is not zero,\r
+    // length should not more than PcdMaximumUnicodeStringLength\r
     //\r
-    ASSERT (*Source < 0x100);\r
-    *(Destination++) = (CHAR8) *(Source++);\r
+    if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+      ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));\r
+    }\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
+  return Length;\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
+  Returns the size of a Null-terminated ASCII string in bytes, including the\r
+  Null terminator.\r
 \r
-  This function copies the contents of the ASCII string Source to the ASCII\r
-  string Destination, and returns Destination. If Source and Destination\r
-  overlap, then the results are undefined.\r
+  This function returns the size, in bytes, of the Null-terminated ASCII string\r
+  specified by String.\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
+  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  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
+  @param  String  A pointer to a Null-terminated ASCII string.\r
 \r
   @return The size of String.\r
 \r
@@ -1237,7 +659,7 @@ AsciiStrLen (
 UINTN\r
 EFIAPI\r
 AsciiStrSize (\r
-  IN      CONST CHAR8               *String\r
+  IN      CONST CHAR8  *String\r
   )\r
 {\r
   return (AsciiStrLen (String) + 1) * sizeof (*String);\r
@@ -1256,24 +678,24 @@ AsciiStrSize (
   If FirstString is NULL, then ASSERT().\r
   If SecondString is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
   then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
-  than PcdMaximumAsciiStringLength ASCII characters not including the\r
+  than PcdMaximumAsciiStringLength ASCII characters, not including the\r
   Null-terminator, then ASSERT().\r
 \r
-  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
-  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
+  @param  FirstString   A pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval 0   FirstString is identical to SecondString.\r
-  @retval !=0 FirstString is not identical to SecondString.\r
+  @retval ==0      FirstString is identical to SecondString.\r
+  @retval !=0      FirstString is not identical to SecondString.\r
 \r
 **/\r
 INTN\r
 EFIAPI\r
 AsciiStrCmp (\r
-  IN      CONST CHAR8               *FirstString,\r
-  IN      CONST CHAR8               *SecondString\r
+  IN      CONST CHAR8  *FirstString,\r
+  IN      CONST CHAR8  *SecondString\r
   )\r
 {\r
   //\r
@@ -1291,7 +713,7 @@ AsciiStrCmp (
 }\r
 \r
 /**\r
-  Converts a lowercase Ascii character to upper one\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
@@ -1300,16 +722,16 @@ AsciiStrCmp (
 \r
   @param  Chr   one Ascii character\r
 \r
-  @return The uppercase value of Ascii character \r
+  @return The uppercase value of Ascii character\r
 \r
 **/\r
 CHAR8\r
 EFIAPI\r
-AsciiToUpper (\r
-  IN      CHAR8                     Chr\r
+AsciiCharToUpper (\r
+  IN      CHAR8  Chr\r
   )\r
 {\r
-  return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);\r
+  return (UINT8)((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);\r
 }\r
 \r
 /**\r
@@ -1317,28 +739,27 @@ AsciiToUpper (
 \r
   This internal function only deal with Unicode character\r
   which maps to a valid hexadecimal ASII character, i.e.\r
-  '0' to '9', 'a' to 'f' or 'A' to 'F'. For other \r
+  '0' to '9', 'a' to 'f' or 'A' to 'F'. For other\r
   ASCII character, the value returned does not make sense.\r
 \r
   @param  Char  The character to convert.\r
 \r
-  @retval UINTN   The numerical value converted.\r
+  @return The numerical value converted.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 InternalAsciiHexCharToUintn (\r
-  IN      CHAR8                    Char\r
+  IN      CHAR8  Char\r
   )\r
 {\r
   if (InternalIsDecimalDigitCharacter (Char)) {\r
     return Char - '0';\r
   }\r
 \r
-  return (UINTN) (10 + AsciiToUpper (Char) - 'A');\r
+  return (10 + AsciiCharToUpper (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
@@ -1353,26 +774,26 @@ InternalAsciiHexCharToUintn (
   If FirstString is NULL, then ASSERT().\r
   If SecondString is NULL, then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
   then ASSERT().\r
   If PcdMaximumAsciiStringLength is not zero and SecondString contains more\r
-  than PcdMaximumAsciiStringLength ASCII characters not including the\r
+  than PcdMaximumAsciiStringLength ASCII characters, not including the\r
   Null-terminator, then ASSERT().\r
 \r
-  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
-  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
+  @param  FirstString   A pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval 0   FirstString is identical to SecondString using case insensitive\r
-              comparisons.\r
-  @retval !=0 FirstString is not identical to SecondString using case\r
-              insensitive comparisons.\r
+  @retval ==0    FirstString is identical to SecondString using case insensitive\r
+                 comparisons.\r
+  @retval !=0    FirstString is not identical to SecondString using case\r
+                 insensitive comparisons.\r
 \r
 **/\r
 INTN\r
 EFIAPI\r
 AsciiStriCmp (\r
-  IN      CONST CHAR8               *FirstString,\r
-  IN      CONST CHAR8               *SecondString\r
+  IN      CONST CHAR8  *FirstString,\r
+  IN      CONST CHAR8  *SecondString\r
   )\r
 {\r
   CHAR8  UpperFirstString;\r
@@ -1384,13 +805,13 @@ AsciiStriCmp (
   ASSERT (AsciiStrSize (FirstString));\r
   ASSERT (AsciiStrSize (SecondString));\r
 \r
-  UpperFirstString  = AsciiToUpper (*FirstString);\r
-  UpperSecondString = AsciiToUpper (*SecondString);\r
-  while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {\r
+  UpperFirstString  = AsciiCharToUpper (*FirstString);\r
+  UpperSecondString = AsciiCharToUpper (*SecondString);\r
+  while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {\r
     FirstString++;\r
     SecondString++;\r
-    UpperFirstString  = AsciiToUpper (*FirstString);\r
-    UpperSecondString = AsciiToUpper (*SecondString);\r
+    UpperFirstString  = AsciiCharToUpper (*FirstString);\r
+    UpperSecondString = AsciiCharToUpper (*SecondString);\r
   }\r
 \r
   return UpperFirstString - UpperSecondString;\r
@@ -1407,32 +828,34 @@ AsciiStriCmp (
   is the first mismatched ASCII character in SecondString subtracted from the\r
   first mismatched ASCII character in FirstString.\r
 \r
-  If FirstString is NULL, then ASSERT().\r
-  If SecondString is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero and FirstString contains more than\r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+  If Length > 0 and FirstString is NULL, then ASSERT().\r
+  If Length > 0 and SecondString is NULL, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and Length is greater than\r
+  PcdMaximumAsciiStringLength, then ASSERT().\r
+  If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
   then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero and SecondString contains more than\r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,\r
+  If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than\r
+  PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator,\r
   then ASSERT().\r
 \r
-  @param  FirstString   Pointer to a Null-terminated ASCII string.\r
-  @param  SecondString  Pointer to a Null-terminated ASCII string.\r
-  @param  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
+  @param  FirstString   A pointer to a Null-terminated ASCII string.\r
+  @param  SecondString  A pointer to a Null-terminated ASCII string.\r
+  @param  Length        The maximum number of ASCII characters for compare.\r
+\r
+  @retval ==0       FirstString is identical to SecondString.\r
+  @retval !=0       FirstString is not identical to SecondString.\r
 \r
 **/\r
 INTN\r
 EFIAPI\r
 AsciiStrnCmp (\r
-  IN      CONST CHAR8               *FirstString,\r
-  IN      CONST CHAR8               *SecondString,\r
-  IN      UINTN                     Length\r
+  IN      CONST CHAR8  *FirstString,\r
+  IN      CONST CHAR8  *SecondString,\r
+  IN      UINTN        Length\r
   )\r
 {\r
-  if (0 == Length) {\r
+  if (Length == 0) {\r
     return 0;\r
   }\r
 \r
@@ -1442,144 +865,56 @@ AsciiStrnCmp (
   ASSERT (AsciiStrSize (FirstString));\r
   ASSERT (AsciiStrSize (SecondString));\r
 \r
+  if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {\r
+    ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength));\r
+  }\r
+\r
   while ((*FirstString != '\0') &&\r
+         (*SecondString != '\0') &&\r
          (*FirstString == *SecondString) &&\r
-         (Length > 1)) {\r
+         (Length > 1))\r
+  {\r
     FirstString++;\r
     SecondString++;\r
     Length--;\r
   }\r
-  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
+  return *FirstString - *SecondString;\r
 }\r
 \r
 /**\r
-  Returns the first occurance of a Null-terminated ASCII sub-string \r
+  Returns the first occurrence 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
+  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
+\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
+  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
+  @param  String          A pointer to a Null-terminated ASCII string.\r
+  @param  SearchString    A pointer to a Null-terminated ASCII string to search for.\r
 \r
   @retval NULL            If the SearchString does not appear in String.\r
-  @retval !NULL           If there is a match.\r
+  @retval others          If there is a match return the first occurrence of SearchingString.\r
+                          If the length of SearchString is zero,return String.\r
 \r
 **/\r
 CHAR8 *\r
 EFIAPI\r
 AsciiStrStr (\r
-  IN      CONST CHAR8             *String,\r
-  IN      CONST CHAR8             *SearchString\r
+  IN      CONST CHAR8  *String,\r
+  IN      CONST CHAR8  *SearchString\r
   )\r
 {\r
-  CONST CHAR8 *FirstMatch;\r
-  CONST CHAR8 *SearchStringTmp;\r
+  CONST CHAR8  *FirstMatch;\r
+  CONST CHAR8  *SearchStringTmp;\r
 \r
   //\r
   // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
@@ -1587,728 +922,723 @@ AsciiStrStr (
   ASSERT (AsciiStrSize (String) != 0);\r
   ASSERT (AsciiStrSize (SearchString) != 0);\r
 \r
+  if (*SearchString == '\0') {\r
+    return (CHAR8 *)String;\r
+  }\r
+\r
   while (*String != '\0') {\r
     SearchStringTmp = SearchString;\r
-    FirstMatch = String;\r
-    \r
-    while ((*String == *SearchStringTmp) \r
-            && (*SearchStringTmp != '\0') \r
-            && (*String != '\0')) {\r
+    FirstMatch      = String;\r
+\r
+    while (  (*String == *SearchStringTmp)\r
+          && (*String != '\0'))\r
+    {\r
       String++;\r
       SearchStringTmp++;\r
-    } \r
-    \r
+    }\r
+\r
     if (*SearchStringTmp == '\0') {\r
-      return (CHAR8 *) FirstMatch;\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
+    if (*String == '\0') {\r
+      return NULL;\r
     }\r
 \r
+    String = FirstMatch + 1;\r
   }\r
 \r
   return NULL;\r
 }\r
 \r
 /**\r
-  Convert a Null-terminated ASCII decimal string to a value of type \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
+  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
+\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
+\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
+\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 the number represented by String overflows according to the range defined by\r
+  UINTN, then MAX_UINTN is returned.\r
   If String is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, and String contains more than \r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, \r
+  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
+  @param  String          A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval UINTN           \r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 AsciiStrDecimalToUintn (\r
-  IN      CONST CHAR8               *String\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
+  UINTN  Result;\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
+  AsciiStrDecimalToUintnS (String, (CHAR8 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
-\r
 /**\r
-  Convert a Null-terminated ASCII decimal string to a value of type \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
+  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
+\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
+\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
+\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 the number represented by String overflows according to the range defined by\r
+  UINT64, then MAX_UINT64 is returned.\r
   If String is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, and String contains more than \r
-  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, \r
+  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
+  @param  String          A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval UINT64           \r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINT64\r
 EFIAPI\r
 AsciiStrDecimalToUint64 (\r
-  IN      CONST CHAR8             *String\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
+  UINT64  Result;\r
 \r
-    Result = MultU64x32 (Result, 10) + (*String - '0');\r
-    String++;\r
-  }\r
-  \r
+  AsciiStrDecimalToUint64S (String, (CHAR8 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
 /**\r
   Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.\r
 \r
-  This function returns a value of type UINTN by interpreting the contents of \r
-  the ASCII string String as a hexadecimal number. The format of the input ASCII \r
+  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
+\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
+\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
+\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 the number represented by String overflows according to the range defined by UINTN,\r
+  then MAX_UINTN is returned.\r
   If String is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, \r
-  and String contains more than PcdMaximumAsciiStringLength ASCII characters not including \r
+  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
+  @param  String          A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval UINTN\r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
 AsciiStrHexToUintn (\r
-  IN      CONST CHAR8             *String\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
+  UINTN  Result;\r
 \r
+  AsciiStrHexToUintnS (String, (CHAR8 **)NULL, &Result);\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
+  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
+\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
+\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
+\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 the number represented by String overflows according to the range defined by UINT64,\r
+  then MAX_UINT64 is returned.\r
   If String is NULL, then ASSERT().\r
-  If PcdMaximumAsciiStringLength is not zero, \r
-  and String contains more than PcdMaximumAsciiStringLength ASCII characters not including \r
+  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
+  @param  String          A pointer to a Null-terminated ASCII string.\r
 \r
-  @retval UINT64\r
+  @retval Value translated from String.\r
 \r
 **/\r
 UINT64\r
 EFIAPI\r
 AsciiStrHexToUint64 (\r
-  IN      CONST CHAR8             *String\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
+  UINT64  Result;\r
 \r
+  AsciiStrHexToUint64S (String, (CHAR8 **)NULL, &Result);\r
   return Result;\r
 }\r
 \r
+STATIC CHAR8  EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
+                                "abcdefghijklmnopqrstuvwxyz"\r
+                                "0123456789+/";\r
 \r
 /**\r
-  Convert 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
+  Convert binary data to a Base64 encoded ascii string based on RFC4648.\r
 \r
-  @param  Source        Pointer to a Null-terminated ASCII string.\r
-  @param  Destination   Pointer to a Null-terminated Unicode string.\r
+  Produce a Null-terminated Ascii string in the output buffer specified by Destination and DestinationSize.\r
+  The Ascii string is produced by converting the data string specified by Source and SourceLength.\r
 \r
-  @return Destination\r
+  @param Source            Input UINT8 data\r
+  @param SourceLength      Number of UINT8 bytes of data\r
+  @param Destination       Pointer to output string buffer\r
+  @param DestinationSize   Size of ascii buffer. Set to 0 to get the size needed.\r
+                           Caller is responsible for passing in buffer of DestinationSize\r
+\r
+  @retval RETURN_SUCCESS             When ascii buffer is filled in.\r
+  @retval RETURN_INVALID_PARAMETER   If Source is NULL or DestinationSize is NULL.\r
+  @retval RETURN_INVALID_PARAMETER   If SourceLength or DestinationSize is bigger than (MAX_ADDRESS - (UINTN)Destination).\r
+  @retval RETURN_BUFFER_TOO_SMALL    If SourceLength is 0 and DestinationSize is <1.\r
+  @retval RETURN_BUFFER_TOO_SMALL    If Destination is NULL or DestinationSize is smaller than required buffersize.\r
 \r
 **/\r
-CHAR16 *\r
+RETURN_STATUS\r
 EFIAPI\r
-AsciiStrToUnicodeStr (\r
-  IN      CONST CHAR8               *Source,\r
-  OUT     CHAR16                    *Destination\r
+Base64Encode (\r
+  IN  CONST UINT8  *Source,\r
+  IN        UINTN  SourceLength,\r
+  OUT       CHAR8  *Destination   OPTIONAL,\r
+  IN OUT    UINTN  *DestinationSize\r
   )\r
 {\r
-  CHAR16                            *ReturnValue;\r
-\r
-  ASSERT (Destination != NULL);\r
+  UINTN  RequiredSize;\r
+  UINTN  Left;\r
 \r
   //\r
-  // ASSERT Source is less long than PcdMaximumAsciiStringLength\r
+  // Check pointers, and SourceLength is valid\r
   //\r
-  ASSERT (AsciiStrSize (Source) != 0);\r
+  if ((Source == NULL) || (DestinationSize == NULL)) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
-  // Source and Destination should not overlap\r
+  // Allow for RFC 4648 test vector 1\r
   //\r
-  ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));\r
-  ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));\r
+  if (SourceLength == 0) {\r
+    if (*DestinationSize < 1) {\r
+      *DestinationSize = 1;\r
+      return RETURN_BUFFER_TOO_SMALL;\r
+    }\r
 \r
\r
-  ReturnValue = Destination;\r
-  while (*Source != '\0') {\r
-    *(Destination++) = (CHAR16) *(Source++);\r
+    *DestinationSize = 1;\r
+    *Destination     = '\0';\r
+    return RETURN_SUCCESS;\r
   }\r
+\r
   //\r
-  // End the Destination with a NULL.\r
+  // Check if SourceLength or  DestinationSize is valid\r
   //\r
-  *Destination = '\0';\r
+  if ((SourceLength >= (MAX_ADDRESS - (UINTN)Source)) || (*DestinationSize >= (MAX_ADDRESS - (UINTN)Destination))) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
-  // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength\r
+  // 4 ascii per 3 bytes + NULL\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
+  RequiredSize = ((SourceLength + 2) / 3) * 4 + 1;\r
+  if ((Destination == NULL) || (*DestinationSize < RequiredSize)) {\r
+    *DestinationSize = RequiredSize;\r
+    return RETURN_BUFFER_TOO_SMALL;\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
+  Left = SourceLength;\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
+  // Encode 24 bits (three bytes) into 4 ascii characters\r
   //\r
-  StrLen = BufferSizeInBytes * 2;\r
-  if (StrLen > ((*StringLen) - 1)) {\r
-    *StringLen = StrLen + 1;\r
-    return RETURN_BUFFER_TOO_SMALL;\r
+  while (Left >= 3) {\r
+    *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
+    *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+    *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2) + ((Source[2] & 0xc0) >> 6)];\r
+    *Destination++ = EncodingTable[(Source[2] & 0x3f)];\r
+    Left          -= 3;\r
+    Source        += 3;\r
   }\r
 \r
-  *StringLen = StrLen + 1;\r
   //\r
-  // Ends the string.\r
+  // Handle the remainder, and add padding '=' characters as necessary.\r
   //\r
-  String[StrLen] = L'\0'; \r
+  switch (Left) {\r
+    case 0:\r
 \r
-  for (Idx = 0; Idx < BufferSizeInBytes; Idx++) {\r
+      //\r
+      // No bytes Left, done.\r
+      //\r
+      break;\r
+    case 1:\r
+\r
+      //\r
+      // One more data byte, two pad characters\r
+      //\r
+      *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
+      *Destination++ = EncodingTable[((Source[0] & 0x03) << 4)];\r
+      *Destination++ = '=';\r
+      *Destination++ = '=';\r
+      break;\r
+    case 2:\r
 \r
-    Byte = Buffer[Idx];\r
-    String[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);\r
-    String[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));\r
+      //\r
+      // Two more data bytes, and one pad character\r
+      //\r
+      *Destination++ = EncodingTable[(Source[0] & 0xfc) >> 2];\r
+      *Destination++ = EncodingTable[((Source[0] & 0x03) << 4) + ((Source[1] & 0xf0) >> 4)];\r
+      *Destination++ = EncodingTable[((Source[1] & 0x0f) << 2)];\r
+      *Destination++ = '=';\r
+      break;\r
   }\r
 \r
+  //\r
+  // Add terminating NULL\r
+  //\r
+  *Destination = '\0';\r
   return RETURN_SUCCESS;\r
 }\r
 \r
-\r
 /**\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
+  Decode Base64 ASCII encoded data to 8-bit binary representation, based on\r
+  RFC4648.\r
+\r
+  Decoding occurs according to "Table 1: The Base 64 Alphabet" in RFC4648.\r
+\r
+  Whitespace is ignored at all positions:\r
+  - 0x09 ('\t') horizontal tab\r
+  - 0x0A ('\n') new line\r
+  - 0x0B ('\v') vertical tab\r
+  - 0x0C ('\f') form feed\r
+  - 0x0D ('\r') carriage return\r
+  - 0x20 (' ')  space\r
+\r
+  The minimum amount of required padding (with ASCII 0x3D, '=') is tolerated\r
+  and enforced at the end of the Base64 ASCII encoded data, and only there.\r
+\r
+  Other characters outside of the encoding alphabet cause the function to\r
+  reject the Base64 ASCII encoded data.\r
+\r
+  @param[in] Source               Array of CHAR8 elements containing the Base64\r
+                                  ASCII encoding. May be NULL if SourceSize is\r
+                                  zero.\r
+\r
+  @param[in] SourceSize           Number of CHAR8 elements in Source.\r
+\r
+  @param[out] Destination         Array of UINT8 elements receiving the decoded\r
+                                  8-bit binary representation. Allocated by the\r
+                                  caller. May be NULL if DestinationSize is\r
+                                  zero on input. If NULL, decoding is\r
+                                  performed, but the 8-bit binary\r
+                                  representation is not stored. If non-NULL and\r
+                                  the function returns an error, the contents\r
+                                  of Destination are indeterminate.\r
+\r
+  @param[in,out] DestinationSize  On input, the number of UINT8 elements that\r
+                                  the caller allocated for Destination. On\r
+                                  output, if the function returns\r
+                                  RETURN_SUCCESS or RETURN_BUFFER_TOO_SMALL,\r
+                                  the number of UINT8 elements that are\r
+                                  required for decoding the Base64 ASCII\r
+                                  representation. If the function returns a\r
+                                  value different from both RETURN_SUCCESS and\r
+                                  RETURN_BUFFER_TOO_SMALL, then DestinationSize\r
+                                  is indeterminate on output.\r
+\r
+  @retval RETURN_SUCCESS            SourceSize CHAR8 elements at Source have\r
+                                    been decoded to on-output DestinationSize\r
+                                    UINT8 elements at Destination. Note that\r
+                                    RETURN_SUCCESS covers the case when\r
+                                    DestinationSize is zero on input, and\r
+                                    Source decodes to zero bytes (due to\r
+                                    containing at most ignored whitespace).\r
+\r
+  @retval RETURN_BUFFER_TOO_SMALL   The input value of DestinationSize is not\r
+                                    large enough for decoding SourceSize CHAR8\r
+                                    elements at Source. The required number of\r
+                                    UINT8 elements has been stored to\r
+                                    DestinationSize.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  DestinationSize is NULL.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  Source is NULL, but SourceSize is not zero.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  Destination is NULL, but DestinationSize is\r
+                                    not zero on input.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  Source is non-NULL, and (Source +\r
+                                    SourceSize) would wrap around MAX_ADDRESS.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  Destination is non-NULL, and (Destination +\r
+                                    DestinationSize) would wrap around\r
+                                    MAX_ADDRESS, as specified on input.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  None of Source and Destination are NULL,\r
+                                    and CHAR8[SourceSize] at Source overlaps\r
+                                    UINT8[DestinationSize] at Destination, as\r
+                                    specified on input.\r
+\r
+  @retval RETURN_INVALID_PARAMETER  Invalid CHAR8 element encountered in\r
+                                    Source.\r
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-HexStringToBuf (\r
-  OUT          UINT8                    *Buffer,   \r
-  IN OUT       UINTN                    *BufferSizeInBytes,\r
-  IN     CONST CHAR16                   *String,\r
-  OUT          UINTN                    *ConvertedStrLen  OPTIONAL\r
+Base64Decode (\r
+  IN     CONST CHAR8  *Source          OPTIONAL,\r
+  IN     UINTN        SourceSize,\r
+  OUT    UINT8        *Destination     OPTIONAL,\r
+  IN OUT UINTN        *DestinationSize\r
   )\r
 {\r
-  UINTN       HexCnt;\r
-  UINTN       Idx;\r
-  UINTN       BufferLength;\r
-  UINT8       Digit;\r
-  UINT8       Byte;\r
+  BOOLEAN  PaddingMode;\r
+  UINTN    SixBitGroupsConsumed;\r
+  UINT32   Accumulator;\r
+  UINTN    OriginalDestinationSize;\r
+  UINTN    SourceIndex;\r
+  CHAR8    SourceChar;\r
+  UINT32   Base64Value;\r
+  UINT8    DestinationOctet;\r
+\r
+  if (DestinationSize == NULL) {\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
-  // Find out how many hex characters the string has.\r
+  // Check Source array validity.\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
+  if (Source == NULL) {\r
+    if (SourceSize > 0) {\r
+      //\r
+      // At least one CHAR8 element at NULL Source.\r
+      //\r
+      return RETURN_INVALID_PARAMETER;\r
+    }\r
+  } else if (SourceSize > MAX_ADDRESS - (UINTN)Source) {\r
+    //\r
+    // Non-NULL Source, but it wraps around.\r
+    //\r
+    return RETURN_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
-  // Two Unicode characters make up 1 buffer byte. Round up.\r
+  // Check Destination array validity.\r
   //\r
-  BufferLength = (HexCnt + 1) / 2; \r
+  if (Destination == NULL) {\r
+    if (*DestinationSize > 0) {\r
+      //\r
+      // At least one UINT8 element at NULL Destination.\r
+      //\r
+      return RETURN_INVALID_PARAMETER;\r
+    }\r
+  } else if (*DestinationSize > MAX_ADDRESS - (UINTN)Destination) {\r
+    //\r
+    // Non-NULL Destination, but it wraps around.\r
+    //\r
+    return RETURN_INVALID_PARAMETER;\r
+  }\r
 \r
   //\r
-  // Test if  buffer is passed enough.\r
+  // Check for overlap.\r
   //\r
-  if (BufferLength > (*BufferSizeInBytes)) {\r
-    *BufferSizeInBytes = BufferLength;\r
-    return RETURN_BUFFER_TOO_SMALL;\r
+  if ((Source != NULL) && (Destination != NULL)) {\r
+    //\r
+    // Both arrays have been provided, and we know from earlier that each array\r
+    // is valid in itself.\r
+    //\r
+    if ((UINTN)Source + SourceSize <= (UINTN)Destination) {\r
+      //\r
+      // Source array precedes Destination array, OK.\r
+      //\r
+    } else if ((UINTN)Destination + *DestinationSize <= (UINTN)Source) {\r
+      //\r
+      // Destination array precedes Source array, OK.\r
+      //\r
+    } else {\r
+      //\r
+      // Overlap.\r
+      //\r
+      return RETURN_INVALID_PARAMETER;\r
+    }\r
   }\r
 \r
-  *BufferSizeInBytes = BufferLength;\r
+  //\r
+  // Decoding loop setup.\r
+  //\r
+  PaddingMode             = FALSE;\r
+  SixBitGroupsConsumed    = 0;\r
+  Accumulator             = 0;\r
+  OriginalDestinationSize = *DestinationSize;\r
+  *DestinationSize        = 0;\r
 \r
-  for (Idx = 0; Idx < HexCnt; Idx++) {\r
+  //\r
+  // Decoding loop.\r
+  //\r
+  for (SourceIndex = 0; SourceIndex < SourceSize; SourceIndex++) {\r
+    SourceChar = Source[SourceIndex];\r
 \r
-    IsHexDigit (&Digit, String[HexCnt - 1 - Idx]);\r
+    //\r
+    // Whitespace is ignored at all positions (regardless of padding mode).\r
+    //\r
+    if ((SourceChar == '\t') || (SourceChar == '\n') || (SourceChar == '\v') ||\r
+        (SourceChar == '\f') || (SourceChar == '\r') || (SourceChar == ' '))\r
+    {\r
+      continue;\r
+    }\r
 \r
     //\r
-    // For odd charaters, write the lower nibble for each buffer byte,\r
-    // and for even characters, the upper nibble.\r
+    // If we're in padding mode, accept another padding character, as long as\r
+    // that padding character completes the quantum. This completes case (2)\r
+    // from RFC4648, Chapter 4. "Base 64 Encoding":\r
+    //\r
+    // (2) The final quantum of encoding input is exactly 8 bits; here, the\r
+    //     final unit of encoded output will be two characters followed by two\r
+    //     "=" padding characters.\r
     //\r
-    if ((Idx & 1) == 0) {\r
-      Byte = Digit;\r
+    if (PaddingMode) {\r
+      if ((SourceChar == '=') && (SixBitGroupsConsumed == 3)) {\r
+        SixBitGroupsConsumed = 0;\r
+        continue;\r
+      }\r
+\r
+      return RETURN_INVALID_PARAMETER;\r
+    }\r
+\r
+    //\r
+    // When not in padding mode, decode Base64Value based on RFC4648, "Table 1:\r
+    // The Base 64 Alphabet".\r
+    //\r
+    if (('A' <= SourceChar) && (SourceChar <= 'Z')) {\r
+      Base64Value = SourceChar - 'A';\r
+    } else if (('a' <= SourceChar) && (SourceChar <= 'z')) {\r
+      Base64Value = 26 + (SourceChar - 'a');\r
+    } else if (('0' <= SourceChar) && (SourceChar <= '9')) {\r
+      Base64Value = 52 + (SourceChar - '0');\r
+    } else if (SourceChar == '+') {\r
+      Base64Value = 62;\r
+    } else if (SourceChar == '/') {\r
+      Base64Value = 63;\r
+    } else if (SourceChar == '=') {\r
+      //\r
+      // Enter padding mode.\r
+      //\r
+      PaddingMode = TRUE;\r
+\r
+      if (SixBitGroupsConsumed == 2) {\r
+        //\r
+        // If we have consumed two 6-bit groups from the current quantum before\r
+        // encountering the first padding character, then this is case (2) from\r
+        // RFC4648, Chapter 4. "Base 64 Encoding". Bump SixBitGroupsConsumed,\r
+        // and we'll enforce another padding character.\r
+        //\r
+        SixBitGroupsConsumed = 3;\r
+      } else if (SixBitGroupsConsumed == 3) {\r
+        //\r
+        // If we have consumed three 6-bit groups from the current quantum\r
+        // before encountering the first padding character, then this is case\r
+        // (3) from RFC4648, Chapter 4. "Base 64 Encoding". The quantum is now\r
+        // complete.\r
+        //\r
+        SixBitGroupsConsumed = 0;\r
+      } else {\r
+        //\r
+        // Padding characters are not allowed at the first two positions of a\r
+        // quantum.\r
+        //\r
+        return RETURN_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Wherever in a quantum we enter padding mode, we enforce the padding\r
+      // bits pending in the accumulator -- from the last 6-bit group just\r
+      // preceding the padding character -- to be zero. Refer to RFC4648,\r
+      // Chapter 3.5. "Canonical Encoding".\r
+      //\r
+      if (Accumulator != 0) {\r
+        return RETURN_INVALID_PARAMETER;\r
+      }\r
+\r
+      //\r
+      // Advance to the next source character.\r
+      //\r
+      continue;\r
     } else {\r
-      Byte = Buffer[Idx / 2];\r
-      Byte &= 0x0F;\r
-      Byte = (UINT8) (Byte | Digit << 4);\r
+      //\r
+      // Other characters outside of the encoding alphabet are rejected.\r
+      //\r
+      return RETURN_INVALID_PARAMETER;\r
     }\r
 \r
-    Buffer[Idx / 2] = Byte;\r
+    //\r
+    // Feed the bits of the current 6-bit group of the quantum to the\r
+    // accumulator.\r
+    //\r
+    Accumulator = (Accumulator << 6) | Base64Value;\r
+    SixBitGroupsConsumed++;\r
+    switch (SixBitGroupsConsumed) {\r
+      case 1:\r
+        //\r
+        // No octet to spill after consuming the first 6-bit group of the\r
+        // quantum; advance to the next source character.\r
+        //\r
+        continue;\r
+      case 2:\r
+        //\r
+        // 12 bits accumulated (6 pending + 6 new); prepare for spilling an\r
+        // octet. 4 bits remain pending.\r
+        //\r
+        DestinationOctet = (UINT8)(Accumulator >> 4);\r
+        Accumulator     &= 0xF;\r
+        break;\r
+      case 3:\r
+        //\r
+        // 10 bits accumulated (4 pending + 6 new); prepare for spilling an\r
+        // octet. 2 bits remain pending.\r
+        //\r
+        DestinationOctet = (UINT8)(Accumulator >> 2);\r
+        Accumulator     &= 0x3;\r
+        break;\r
+      default:\r
+        ASSERT (SixBitGroupsConsumed == 4);\r
+        //\r
+        // 8 bits accumulated (2 pending + 6 new); prepare for spilling an octet.\r
+        // The quantum is complete, 0 bits remain pending.\r
+        //\r
+        DestinationOctet     = (UINT8)Accumulator;\r
+        Accumulator          = 0;\r
+        SixBitGroupsConsumed = 0;\r
+        break;\r
+    }\r
+\r
+    //\r
+    // Store the decoded octet if there's room left. Increment\r
+    // (*DestinationSize) unconditionally.\r
+    //\r
+    if (*DestinationSize < OriginalDestinationSize) {\r
+      ASSERT (Destination != NULL);\r
+      Destination[*DestinationSize] = DestinationOctet;\r
+    }\r
+\r
+    (*DestinationSize)++;\r
+\r
+    //\r
+    // Advance to the next source character.\r
+    //\r
   }\r
 \r
-  if (ConvertedStrLen != NULL) {\r
-    *ConvertedStrLen = HexCnt;\r
+  //\r
+  // If Source terminates mid-quantum, then Source is invalid.\r
+  //\r
+  if (SixBitGroupsConsumed != 0) {\r
+    return RETURN_INVALID_PARAMETER;\r
   }\r
 \r
-  return RETURN_SUCCESS;\r
-}\r
+  //\r
+  // Done.\r
+  //\r
+  if (*DestinationSize <= OriginalDestinationSize) {\r
+    return RETURN_SUCCESS;\r
+  }\r
 \r
+  return RETURN_BUFFER_TOO_SMALL;\r
+}\r
 \r
 /**\r
-  Test if  a Unicode character is a hexadecimal digit. If true, the input\r
-  Unicode character is converted to a byte. \r
+  Converts an 8-bit value to an 8-bit BCD value.\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
+  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
-  If Digit is NULL, then ASSERT.\r
+  @param  Value The 8-bit value to convert to BCD. Range 0..99.\r
+\r
+  @return The BCD value.\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
+UINT8\r
+EFIAPI\r
+DecimalToBcd8 (\r
+  IN      UINT8  Value\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
+  ASSERT (Value < 100);\r
+  return (UINT8)(((Value / 10) << 4) | (Value % 10));\r
+}\r
 \r
-  if ((Char >= L'A') && (Char <= L'F')) {\r
-    *Digit = (UINT8) (Char - L'A' + 0x0A);\r
-    return TRUE;\r
-  }\r
+/**\r
+  Converts an 8-bit BCD value to an 8-bit value.\r
 \r
-  if ((Char >= L'a') && (Char <= L'f')) {\r
-    *Digit = (UINT8) (Char - L'a' + 0x0A);\r
-    return TRUE;\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
-  return FALSE;\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