/** @file
Common basic Library Functions

Copyright (c) 2004 - 2025, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifdef __GNUC__
#include <unistd.h>
#else
#include <direct.h>
#endif
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"

#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status)  \
  do { \
    ASSERT (Expression); \
    if (!(Expression)) { \
      return Status; \
    } \
  } while (FALSE)

/**
  Set Buffer to zero for Size bytes.

  @param Buffer  Memory to set.
  @param Size    Number of bytes to set
**/
VOID
PeiZeroMem (
  IN VOID   *Buffer,
  IN UINTN  Size
  )
{
  INT8  *Ptr;

  Ptr = Buffer;
  while (Size--) {
    *(Ptr++) = 0;
  }
}

/**
  Copy Length bytes from Source to Destination.

  @param Destination Target of copy
  @param Source      Place to copy from
  @param Length      Number of bytes to copy
**/
VOID
PeiCopyMem (
  IN VOID   *Destination,
  IN VOID   *Source,
  IN UINTN  Length
  )
{
  CHAR8 *Destination8;
  CHAR8 *Source8;

  Destination8  = Destination;
  Source8       = Source;
  while (Length--) {
    *(Destination8++) = *(Source8++);
  }
}

VOID
ZeroMem (
  IN VOID   *Buffer,
  IN UINTN  Size
  )
{
  PeiZeroMem (Buffer, Size);
}

VOID
CopyMem (
  IN VOID   *Destination,
  IN VOID   *Source,
  IN UINTN  Length
  )
{
  PeiCopyMem (Destination, Source, Length);
}

/**
  Compares to GUIDs

  @param Guid1 guid to compare
  @param Guid2 guid to compare

  @retval =  0  if Guid1 == Guid2
  @retval != 0  if Guid1 != Guid2
**/
INTN
CompareGuid (
  IN EFI_GUID     *Guid1,
  IN EFI_GUID     *Guid2
  )
{
  INT32 *g1;
  INT32 *g2;
  INT32 r;

  //
  // Compare 32 bits at a time
  //
  g1  = (INT32 *) Guid1;
  g2  = (INT32 *) Guid2;

  r   = g1[0] - g2[0];
  r |= g1[1] - g2[1];
  r |= g1[2] - g2[2];
  r |= g1[3] - g2[3];

  return r;
}

/**
  This function opens a file and reads it into a memory buffer.  The function
  will allocate the memory buffer and returns the size of the buffer.

  @param InputFileName     The name of the file to read.
  @param InputFileImage    A pointer to the memory buffer.
  @param BytesRead         The size of the memory buffer.

  @retval EFI_SUCCESS              The function completed successfully.
  @retval EFI_INVALID_PARAMETER    One of the input parameters was invalid.
  @retval EFI_ABORTED              An error occurred.
  @retval EFI_OUT_OF_RESOURCES     No resource to complete operations.
**/
EFI_STATUS
GetFileImage (
  IN CHAR8    *InputFileName,
  OUT CHAR8   **InputFileImage,
  OUT UINT32  *BytesRead
  )
{
  FILE    *InputFile;
  UINT32  FileSize;

  //
  // Verify input parameters.
  //
  if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Open the file and copy contents into a memory buffer.
  //
  //
  // Open the file
  //
  InputFile = fopen (LongFilePath (InputFileName), "rb");
  if (InputFile == NULL) {
    Error (NULL, 0, 0001, "Error opening the input file", InputFileName);
    return EFI_ABORTED;
  }
  //
  // Go to the end so that we can determine the file size
  //
  if (fseek (InputFile, 0, SEEK_END)) {
    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
    fclose (InputFile);
    return EFI_ABORTED;
  }
  //
  // Get the file size
  //
  FileSize = ftell (InputFile);
  if (FileSize == -1) {
    Error (NULL, 0, 0003, "Error parsing the input file", InputFileName);
    fclose (InputFile);
    return EFI_ABORTED;
  }
  //
  // Allocate a buffer
  //
  *InputFileImage = malloc (FileSize);
  if (*InputFileImage == NULL) {
    fclose (InputFile);
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Reset to the beginning of the file
  //
  if (fseek (InputFile, 0, SEEK_SET)) {
    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
    fclose (InputFile);
    free (*InputFileImage);
    *InputFileImage = NULL;
    return EFI_ABORTED;
  }
  //
  // Read all of the file contents.
  //
  *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);
  if (*BytesRead != sizeof (UINT8) * FileSize) {
    Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
    fclose (InputFile);
    free (*InputFileImage);
    *InputFileImage = NULL;
    return EFI_ABORTED;
  }
  //
  // Close the file
  //
  fclose (InputFile);

  return EFI_SUCCESS;
}

/**
  This function opens a file and writes OutputFileImage into the file.

  @param OutputFileName     The name of the file to write.
  @param OutputFileImage    A pointer to the memory buffer.
  @param BytesToWrite       The size of the memory buffer.

  @retval EFI_SUCCESS              The function completed successfully.
  @retval EFI_INVALID_PARAMETER    One of the input parameters was invalid.
  @retval EFI_ABORTED              An error occurred.
  @retval EFI_OUT_OF_RESOURCES     No resource to complete operations.
**/
EFI_STATUS
PutFileImage (
  IN CHAR8    *OutputFileName,
  IN CHAR8    *OutputFileImage,
  IN UINT32   BytesToWrite
  )
{
  FILE    *OutputFile;
  UINT32  BytesWrote;

  //
  // Verify input parameters.
  //
  if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Open the file and copy contents into a memory buffer.
  //
  //
  // Open the file
  //
  OutputFile = fopen (LongFilePath (OutputFileName), "wb");
  if (OutputFile == NULL) {
    Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);
    return EFI_ABORTED;
  }

  //
  // Write all of the file contents.
  //
  BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile);
  if (BytesWrote != sizeof (UINT8) * BytesToWrite) {
    Error (NULL, 0, 0002, "Error writing the output file", OutputFileName);
    fclose (OutputFile);
    return EFI_ABORTED;
  }
  //
  // Close the file
  //
  fclose (OutputFile);

  return EFI_SUCCESS;
}

/**
  This function calculates the value needed for a valid UINT8 checksum

  @param Buffer      Pointer to buffer containing byte data of component.
  @param Size        Size of the buffer

  @return The 8 bit checksum value needed.
**/
UINT8
CalculateChecksum8 (
  IN UINT8        *Buffer,
  IN UINTN        Size
  )
{
  return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));
}

/**
  This function calculates the UINT8 sum for the requested region.

  @param Buffer      Pointer to buffer containing byte data of component.
  @param Size      Size of the buffer

  @return The 8 bit checksum value needed.
**/
UINT8
CalculateSum8 (
  IN UINT8  *Buffer,
  IN UINTN  Size
  )
{
  UINTN Index;
  UINT8 Sum;

  Sum = 0;

  //
  // Perform the byte sum for buffer
  //
  for (Index = 0; Index < Size; Index++) {
    Sum = (UINT8) (Sum + Buffer[Index]);
  }

  return Sum;
}

/**
  This function calculates the value needed for a valid UINT16 checksum

  @param Buffer      Pointer to buffer containing byte data of component.
  @param Size        Size of the buffer

  @return The 16 bit checksum value needed.
**/
UINT16
CalculateChecksum16 (
  IN UINT16       *Buffer,
  IN UINTN        Size
  )
{
  return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));
}

/**
  This function calculates the UINT16 sum for the requested region.

  @param Buffer      Pointer to buffer containing byte data of component.
  @param Size        Size of the buffer

  @return The 16 bit checksum
**/
UINT16
CalculateSum16 (
  IN UINT16       *Buffer,
  IN UINTN        Size
  )
{
  UINTN   Index;
  UINT16  Sum;

  Sum = 0;

  //
  // Perform the word sum for buffer
  //
  for (Index = 0; Index < Size; Index++) {
    Sum = (UINT16) (Sum + Buffer[Index]);
  }

  return (UINT16) Sum;
}

/**
  This function prints a GUID to STDOUT.

  @param Guid    Pointer to a GUID to print.

  @retval EFI_SUCCESS             The GUID was printed.
  @retval EFI_INVALID_PARAMETER   The input was NULL.
**/
EFI_STATUS
PrintGuid (
  IN EFI_GUID *Guid
  )
{
  if (Guid == NULL) {
    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
    return EFI_INVALID_PARAMETER;
  }

  printf (
    "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
    (unsigned) Guid->Data1,
    Guid->Data2,
    Guid->Data3,
    Guid->Data4[0],
    Guid->Data4[1],
    Guid->Data4[2],
    Guid->Data4[3],
    Guid->Data4[4],
    Guid->Data4[5],
    Guid->Data4[6],
    Guid->Data4[7]
    );
  return EFI_SUCCESS;
}

/**
  This function prints a GUID to a buffer

  @param Guid      Pointer to a GUID to print.
  @param Buffer    Pointer to a user-provided buffer to print to
  @param BufferLen Size of the Buffer
  @param Uppercase If use upper case.

  @retval EFI_SUCCESS             The GUID was printed.
  @retval EFI_INVALID_PARAMETER   The input was NULL.
  @retval EFI_BUFFER_TOO_SMALL    The input buffer was not big enough
**/
EFI_STATUS
PrintGuidToBuffer (
  IN EFI_GUID     *Guid,
  IN OUT UINT8    *Buffer,
  IN UINT32       BufferLen,
  IN BOOLEAN      Uppercase
  )
{
  if (Guid == NULL) {
    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
    return EFI_INVALID_PARAMETER;
  }

  if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {
    Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
    return EFI_BUFFER_TOO_SMALL;
  }

  if (Uppercase) {
    sprintf (
      (CHAR8 *)Buffer,
      "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
      (unsigned) Guid->Data1,
      Guid->Data2,
      Guid->Data3,
      Guid->Data4[0],
      Guid->Data4[1],
      Guid->Data4[2],
      Guid->Data4[3],
      Guid->Data4[4],
      Guid->Data4[5],
      Guid->Data4[6],
      Guid->Data4[7]
      );
  } else {
    sprintf (
      (CHAR8 *)Buffer,
      "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
      (unsigned) Guid->Data1,
      Guid->Data2,
      Guid->Data3,
      Guid->Data4[0],
      Guid->Data4[1],
      Guid->Data4[2],
      Guid->Data4[3],
      Guid->Data4[4],
      Guid->Data4[5],
      Guid->Data4[6],
      Guid->Data4[7]
      );
  }

  return EFI_SUCCESS;
}

#ifdef __GNUC__

#ifndef _WIN32
size_t _filelength(int fd)
{
  struct stat stat_buf;
  fstat(fd, &stat_buf);
  return stat_buf.st_size;
}

#ifndef __CYGWIN__
char *strlwr(char *s)
{
  char *p = s;
  for(;*s;s++) {
    *s = tolower(*s);
  }
  return p;
}
#endif
#endif
#endif

#define WINDOWS_EXTENSION_PATH "\\\\?\\"
#define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"

//
// Global data to store full file path. It is not required to be free.
//
CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];

/**
  Convert FileName to the long file path, which can support larger than 260 length.

  @param FileName         FileName.

  @return LongFilePath      A pointer to the converted long file path.
**/
CHAR8 *
LongFilePath (
 IN CHAR8 *FileName
 )
{
#ifdef __GNUC__
  //
  // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
  // unix has no limitation on file path. Just return FileName.
  //
  return FileName;
#else
  CHAR8 *RootPath;
  CHAR8 *PathPointer;
  CHAR8 *NextPointer;

  PathPointer = (CHAR8 *) FileName;

  if (FileName != NULL) {
    //
    // Add the extension string first to support long file path.
    //
    mCommonLibFullPath[0] = 0;
    strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);

    if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {
      //
      // network path like \\server\share to \\?\UNC\server\share
      //
      strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);
      FileName ++;
    } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {
      //
      // Relative file path. Convert it to absolute path.
      //
      RootPath = getcwd (NULL, 0);
      if (RootPath != NULL) {
        if (strlen (mCommonLibFullPath) + strlen (RootPath) > MAX_LONG_FILE_PATH - 1) {
          Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
          free (RootPath);
          return NULL;
        }
        strncat (mCommonLibFullPath, RootPath, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
        if (FileName[0] != '\\' && FileName[0] != '/') {
          if (strlen (mCommonLibFullPath) + 1 > MAX_LONG_FILE_PATH - 1) {
            Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
            free (RootPath);
            return NULL;
          }
          //
          // Attach directory separator
          //
          strncat (mCommonLibFullPath, "\\", MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
        }
        free (RootPath);
      }
    }

    //
    // Construct the full file path
    //
    if (strlen (mCommonLibFullPath) + strlen (FileName) > MAX_LONG_FILE_PATH - 1) {
      Error (NULL, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName);
      return NULL;
    }
    strncat (mCommonLibFullPath, FileName, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);

    //
    // Convert directory separator '/' to '\\'
    //
    PathPointer = (CHAR8 *) mCommonLibFullPath;
    do {
      if (*PathPointer == '/') {
        *PathPointer = '\\';
      }
    } while (*PathPointer ++ != '\0');

    //
    // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
    //
    if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {
      *(PathPointer + 2) = '\0';
      strncat (mCommonLibFullPath, PathPointer + 3, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
    }

    //
    // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
    //
    while ((PathPointer = strstr (mCommonLibFullPath, ".\\")) != NULL) {
      *PathPointer = '\0';
      strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
    }

    //
    // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
    //
    while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {
      *PathPointer = '\0';
      strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
    }

    //
    // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
    //
    while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {
      NextPointer = PathPointer + 3;
      do {
        PathPointer --;
      } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');

      if (*PathPointer == '\\') {
        //
        // Skip one directory
        //
        *PathPointer = '\0';
        strncat (mCommonLibFullPath, NextPointer, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
      } else {
        //
        // No directory is found. Just break.
        //
        break;
      }
    }

    PathPointer = mCommonLibFullPath;
  }

  return PathPointer;
#endif
}

CHAR16
InternalCharToUpper (
        CHAR16                    Char
  )
{
  if (Char >= L'a' && Char <= L'z') {
    return (CHAR16) (Char - (L'a' - L'A'));
  }

  return Char;
}

UINTN
StrnLenS (
   CONST CHAR16              *String,
   UINTN                     MaxSize
  )
{
  UINTN     Length;

  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
  //
  if ((String == NULL) || (MaxSize == 0)) {
    return 0;
  }

  Length = 0;
  while (String[Length] != 0) {
    if (Length >= MaxSize - 1) {
      return MaxSize;
    }
    Length++;
  }
  return Length;
}


VOID *
InternalAllocatePool (
   UINTN   AllocationSize
  )
{
  VOID * Memory;

  Memory = malloc(AllocationSize);
  ASSERT(Memory != NULL);
  return Memory;
}


VOID *
InternalReallocatePool (
   UINTN            OldSize,
   UINTN            NewSize,
   VOID             *OldBuffer  OPTIONAL
  )
{
  VOID  *NewBuffer;

  NewBuffer = AllocateZeroPool (NewSize);
  if (NewBuffer != NULL && OldBuffer != NULL) {
    memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
    free(OldBuffer);
  }
  return NewBuffer;
}

VOID *
ReallocatePool (
   UINTN  OldSize,
   UINTN  NewSize,
   VOID   *OldBuffer  OPTIONAL
  )
{
  return InternalReallocatePool (OldSize, NewSize, OldBuffer);
}

/**
  Returns the length of a Null-terminated Unicode string.

  This function returns the number of Unicode characters in the Null-terminated
  Unicode string specified by String.

  If String is NULL, then ASSERT().
  If String is not aligned on a 16-bit boundary, then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  PcdMaximumUnicodeStringLength Unicode characters, not including the
  Null-terminator, then ASSERT().

  @param  String  A pointer to a Null-terminated Unicode string.

  @return The length of String.

**/
UINTN
StrLen (
  CONST CHAR16              *String
  )
{
  UINTN   Length;

  ASSERT (String != NULL);
  ASSERT (((UINTN) String & BIT0) == 0);

  for (Length = 0; *String != L'\0'; String++, Length++) {
    //
    // If PcdMaximumUnicodeStringLength is not zero,
    // length should not more than PcdMaximumUnicodeStringLength
    //
  }
  return Length;
}

BOOLEAN
InternalSafeStringIsOverlap (
  IN VOID    *Base1,
  IN UINTN   Size1,
  IN VOID    *Base2,
  IN UINTN   Size2
  )
{
  if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
      (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
    return TRUE;
  }
  return FALSE;
}

BOOLEAN
InternalSafeStringNoStrOverlap (
  IN CHAR16  *Str1,
  IN UINTN   Size1,
  IN CHAR16  *Str2,
  IN UINTN   Size2
  )
{
  return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
}

/**
  Convert a Null-terminated Unicode decimal string to a value of type UINT64.

  This function outputs a value of type UINT64 by interpreting the contents of
  the Unicode string specified by String as a decimal number. The format of the
  input Unicode string String is:

                  [spaces] [decimal digits].

  The valid decimal digit character is in the range [0-9]. The function will
  ignore the pad space, which includes spaces or tab characters, before
  [decimal digits]. The running zero in the beginning of [decimal digits] will
  be ignored. Then, the function stops at the first character that is a not a
  valid decimal character or a Null-terminator, whichever one comes first.

  If String is NULL, then ASSERT().
  If Data is NULL, then ASSERT().
  If String is not aligned in a 16-bit boundary, then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  PcdMaximumUnicodeStringLength Unicode characters, not including the
  Null-terminator, then ASSERT().

  If String has no valid decimal digits in the above format, then 0 is stored
  at the location pointed to by Data.
  If the number represented by String exceeds the range defined by UINT64, then
  MAX_UINT64 is stored at the location pointed to by Data.

  If EndPointer is not NULL, a pointer to the character that stopped the scan
  is stored at the location pointed to by EndPointer. If String has no valid
  decimal digits right after the optional pad spaces, the value of String is
  stored at the location pointed to by EndPointer.

  @param  String                   Pointer to a Null-terminated Unicode string.
  @param  EndPointer               Pointer to character that stops scan.
  @param  Data                     Pointer to the converted value.

  @retval RETURN_SUCCESS           Value is translated from String.
  @retval RETURN_INVALID_PARAMETER If String is NULL.
                                   If Data is NULL.
                                   If PcdMaximumUnicodeStringLength is not
                                   zero, and String contains more than
                                   PcdMaximumUnicodeStringLength Unicode
                                   characters, not including the
                                   Null-terminator.
  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
                                   the range defined by UINT64.

**/
RETURN_STATUS
StrDecimalToUint64S (
    CONST CHAR16             *String,
         CHAR16             **EndPointer,  OPTIONAL
         UINT64             *Data
  )
{
  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. Neither String nor Data shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);

  //
  // 2. The length of String shall not be greater than RSIZE_MAX.
  //
  if (RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }

  if (EndPointer != NULL) {
    *EndPointer = (CHAR16 *) String;
  }

  //
  // Ignore the pad spaces (space or tab)
  //
  while ((*String == L' ') || (*String == L'\t')) {
    String++;
  }

  //
  // Ignore leading Zeros after the spaces
  //
  while (*String == L'0') {
    String++;
  }

  *Data = 0;

  while (InternalIsDecimalDigitCharacter (*String)) {
    //
    // If the number represented by String overflows according to the range
    // defined by UINT64, then MAX_UINT64 is stored in *Data and
    // RETURN_UNSUPPORTED is returned.
    //
    if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
      *Data = MAX_UINT64;
      if (EndPointer != NULL) {
        *EndPointer = (CHAR16 *) String;
      }
      return RETURN_UNSUPPORTED;
    }

    *Data = (*Data) * 10 + (*String - L'0');
    String++;
  }

  if (EndPointer != NULL) {
    *EndPointer = (CHAR16 *) String;
  }
  return RETURN_SUCCESS;
}

/**
  Convert a Null-terminated Unicode hexadecimal string to a value of type
  UINT64.

  This function outputs a value of type UINT64 by interpreting the contents of
  the Unicode string specified by String as a hexadecimal number. The format of
  the input Unicode string String is:

                  [spaces][zeros][x][hexadecimal digits].

  The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
  The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
  If "x" appears in the input string, it must be prefixed with at least one 0.
  The function will ignore the pad space, which includes spaces or tab
  characters, before [zeros], [x] or [hexadecimal digit]. The running zero
  before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
  after [x] or the first valid hexadecimal digit. Then, the function stops at
  the first character that is a not a valid hexadecimal character or NULL,
  whichever one comes first.

  If String is NULL, then ASSERT().
  If Data is NULL, then ASSERT().
  If String is not aligned in a 16-bit boundary, then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  PcdMaximumUnicodeStringLength Unicode characters, not including the
  Null-terminator, then ASSERT().

  If String has no valid hexadecimal digits in the above format, then 0 is
  stored at the location pointed to by Data.
  If the number represented by String exceeds the range defined by UINT64, then
  MAX_UINT64 is stored at the location pointed to by Data.

  If EndPointer is not NULL, a pointer to the character that stopped the scan
  is stored at the location pointed to by EndPointer. If String has no valid
  hexadecimal digits right after the optional pad spaces, the value of String
  is stored at the location pointed to by EndPointer.

  @param  String                   Pointer to a Null-terminated Unicode string.
  @param  EndPointer               Pointer to character that stops scan.
  @param  Data                     Pointer to the converted value.

  @retval RETURN_SUCCESS           Value is translated from String.
  @retval RETURN_INVALID_PARAMETER If String is NULL.
                                   If Data is NULL.
                                   If PcdMaximumUnicodeStringLength is not
                                   zero, and String contains more than
                                   PcdMaximumUnicodeStringLength Unicode
                                   characters, not including the
                                   Null-terminator.
  @retval RETURN_UNSUPPORTED       If the number represented by String exceeds
                                   the range defined by UINT64.

**/
RETURN_STATUS
StrHexToUint64S (
    CONST CHAR16             *String,
         CHAR16             **EndPointer,  OPTIONAL
         UINT64             *Data
  )
{
  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. Neither String nor Data shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);

  //
  // 2. The length of String shall not be greater than RSIZE_MAX.
  //
  if (RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }

  if (EndPointer != NULL) {
    *EndPointer = (CHAR16 *) String;
  }

  //
  // Ignore the pad spaces (space or tab)
  //
  while ((*String == L' ') || (*String == L'\t')) {
    String++;
  }

  //
  // Ignore leading Zeros after the spaces
  //
  while (*String == L'0') {
    String++;
  }

  if (InternalCharToUpper (*String) == L'X') {
    if (*(String - 1) != L'0') {
      *Data = 0;
      return RETURN_SUCCESS;
    }
    //
    // Skip the 'X'
    //
    String++;
  }

  *Data = 0;

  while (InternalIsHexaDecimalDigitCharacter (*String)) {
    //
    // If the number represented by String overflows according to the range
    // defined by UINT64, then MAX_UINT64 is stored in *Data and
    // RETURN_UNSUPPORTED is returned.
    //
    if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
      *Data = MAX_UINT64;
      if (EndPointer != NULL) {
        *EndPointer = (CHAR16 *) String;
      }
      return RETURN_UNSUPPORTED;
    }

    *Data =  ((*Data) << 4) + InternalHexCharToUintn (*String);
    String++;
  }

  if (EndPointer != NULL) {
    *EndPointer = (CHAR16 *) String;
  }
  return RETURN_SUCCESS;
}

UINT64
StrDecimalToUint64 (
  CONST CHAR16              *String
  )
{
  UINT64     Result;

  StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
  return Result;
}


UINT64
StrHexToUint64 (
  CONST CHAR16             *String
  )
{
  UINT64    Result;

  StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
  return Result;
}

UINTN
StrSize (
  CONST CHAR16              *String
  )
{
  return (StrLen (String) + 1) * sizeof (*String);
}


UINT64
ReadUnaligned64 (
   CONST UINT64              *Buffer
  )
{
  ASSERT (Buffer != NULL);

  return *Buffer;
}

UINT64
WriteUnaligned64 (
   UINT64                    *Buffer,
   UINT64                    Value
  )
{
  ASSERT (Buffer != NULL);

  return *Buffer = Value;
}


EFI_GUID *
CopyGuid (
   EFI_GUID         *DestinationGuid,
   CONST EFI_GUID  *SourceGuid
  )
{
  WriteUnaligned64 (
    (UINT64*)DestinationGuid,
    ReadUnaligned64 ((CONST UINT64*)SourceGuid)
    );
  WriteUnaligned64 (
    (UINT64*)DestinationGuid + 1,
    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
    );
  return DestinationGuid;
}

UINT16
SwapBytes16 (
  UINT16                    Value
  )
{
  return (UINT16) ((Value<< 8) | (Value>> 8));
}


UINT32
SwapBytes32 (
  UINT32                    Value
  )
{
  UINT32  LowerBytes;
  UINT32  HigherBytes;

  LowerBytes  = (UINT32) SwapBytes16 ((UINT16) Value);
  HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
  return (LowerBytes << 16 | HigherBytes);
}

BOOLEAN
InternalIsDecimalDigitCharacter (
  CHAR16                    Char
  )
{
  return (BOOLEAN) (Char >= L'0' && Char <= L'9');
}

VOID *
InternalAllocateCopyPool (
   UINTN            AllocationSize,
   CONST VOID       *Buffer
  )
{
  VOID  *Memory;

  ASSERT (Buffer != NULL);

  Memory = malloc (AllocationSize);
  if (Memory != NULL) {
     Memory = memcpy (Memory, Buffer, AllocationSize);
  }
  return Memory;
}

BOOLEAN
InternalIsHexaDecimalDigitCharacter (
  CHAR16                    Char
  )
{

  return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
    (Char >= L'A' && Char <= L'F') ||
    (Char >= L'a' && Char <= L'f'));
}

UINTN
InternalHexCharToUintn (
        CHAR16                    Char
  )
{
  if (InternalIsDecimalDigitCharacter (Char)) {
    return Char - L'0';
  }

  return (10 + InternalCharToUpper (Char) - L'A');
}


/**
  Convert a Null-terminated Unicode hexadecimal string to a byte array.

  This function outputs a byte array by interpreting the contents of
  the Unicode string specified by String in hexadecimal format. The format of
  the input Unicode string String is:

                  [XX]*

  X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
  The function decodes every two hexadecimal digit characters as one byte. The
  decoding stops after Length of characters and outputs Buffer containing
  (Length / 2) bytes.

  If String is not aligned in a 16-bit boundary, then ASSERT().

  If String is NULL, then ASSERT().

  If Buffer is NULL, then ASSERT().

  If Length is not multiple of 2, then ASSERT().

  If PcdMaximumUnicodeStringLength is not zero and Length is greater than
  PcdMaximumUnicodeStringLength, then ASSERT().

  If MaxBufferSize is less than (Length / 2), then ASSERT().

  @param  String                   Pointer to a Null-terminated Unicode string.
  @param  Length                   The number of Unicode characters to decode.
  @param  Buffer                   Pointer to the converted bytes array.
  @param  MaxBufferSize            The maximum size of Buffer.

  @retval RETURN_SUCCESS           Buffer is translated from String.
  @retval RETURN_INVALID_PARAMETER If String is NULL.
                                   If Data is NULL.
                                   If Length is not multiple of 2.
                                   If PcdMaximumUnicodeStringLength is not zero,
                                    and Length is greater than
                                    PcdMaximumUnicodeStringLength.
  @retval RETURN_UNSUPPORTED       If Length of characters from String contain
                                    a character that is not valid hexadecimal
                                    digit characters, or a Null-terminator.
  @retval RETURN_BUFFER_TOO_SMALL  If MaxBufferSize is less than (Length / 2).
**/
RETURN_STATUS
StrHexToBytes (
   CONST CHAR16       *String,
   UINTN              Length,
   UINT8              *Buffer,
   UINTN              MaxBufferSize
  )
{
  UINTN                  Index;

  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. None of String or Buffer shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);

  //
  // 2. Length shall not be greater than RSIZE_MAX.
  //
  if (RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }

  //
  // 3. Length shall not be odd.
  //
  SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);

  //
  // 4. MaxBufferSize shall equal to or greater than Length / 2.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);

  //
  // 5. String shall not contains invalid hexadecimal digits.
  //
  for (Index = 0; Index < Length; Index++) {
    if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
      break;
    }
  }
  if (Index != Length) {
    return RETURN_UNSUPPORTED;
  }

  //
  // Convert the hex string to bytes.
  //
  for(Index = 0; Index < Length; Index++) {

    //
    // For even characters, write the upper nibble for each buffer byte,
    // and for even characters, the lower nibble.
    //
    if ((Index & BIT0) == 0) {
      Buffer[Index / 2]  = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
    } else {
      Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
    }
  }
  return RETURN_SUCCESS;
}

/**
  Convert a Null-terminated Unicode GUID string to a value of type
  EFI_GUID.

  This function outputs a GUID value by interpreting the contents of
  the Unicode string specified by String. The format of the input
  Unicode string String consists of 36 characters, as follows:

                  aabbccdd-eeff-gghh-iijj-kkllmmnnoopp

  The pairs aa - pp are two characters in the range [0-9], [a-f] and
  [A-F], with each pair representing a single byte hexadecimal value.

  The mapping between String and the EFI_GUID structure is as follows:
                  aa          Data1[24:31]
                  bb          Data1[16:23]
                  cc          Data1[8:15]
                  dd          Data1[0:7]
                  ee          Data2[8:15]
                  ff          Data2[0:7]
                  gg          Data3[8:15]
                  hh          Data3[0:7]
                  ii          Data4[0:7]
                  jj          Data4[8:15]
                  kk          Data4[16:23]
                  ll          Data4[24:31]
                  mm          Data4[32:39]
                  nn          Data4[40:47]
                  oo          Data4[48:55]
                  pp          Data4[56:63]

  If String is NULL, then ASSERT().
  If Guid is NULL, then ASSERT().
  If String is not aligned in a 16-bit boundary, then ASSERT().

  @param  String                   Pointer to a Null-terminated Unicode string.
  @param  Guid                     Pointer to the converted GUID.

  @retval RETURN_SUCCESS           Guid is translated from String.
  @retval RETURN_INVALID_PARAMETER If String is NULL.
                                   If Data is NULL.
  @retval RETURN_UNSUPPORTED       If String is not as the above format.

**/
RETURN_STATUS
StrToGuid (
   CONST CHAR16       *String,
   EFI_GUID           *Guid
  )
{
  RETURN_STATUS          Status;
  EFI_GUID               LocalGuid;

  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. None of String or Guid shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);

  //
  // Get aabbccdd in big-endian.
  //
  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
    return RETURN_UNSUPPORTED;
  }
  //
  // Convert big-endian to little-endian.
  //
  LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
  String += 2 * sizeof (LocalGuid.Data1) + 1;

  //
  // Get eeff in big-endian.
  //
  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
    return RETURN_UNSUPPORTED;
  }
  //
  // Convert big-endian to little-endian.
  //
  LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
  String += 2 * sizeof (LocalGuid.Data2) + 1;

  //
  // Get gghh in big-endian.
  //
  Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
  if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
    return RETURN_UNSUPPORTED;
  }
  //
  // Convert big-endian to little-endian.
  //
  LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
  String += 2 * sizeof (LocalGuid.Data3) + 1;

  //
  // Get iijj.
  //
  Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
  if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
    return RETURN_UNSUPPORTED;
  }
  String += 2 * 2 + 1;

  //
  // Get kkllmmnnoopp.
  //
  Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
  if (RETURN_ERROR (Status)) {
    return RETURN_UNSUPPORTED;
  }

  CopyGuid (Guid, &LocalGuid);
  return RETURN_SUCCESS;
}

/**
  Compares up to a specified length the contents of two Null-terminated Unicode strings,
  and returns the difference between the first mismatched Unicode characters.

  This function compares the Null-terminated Unicode string FirstString to the
  Null-terminated Unicode string SecondString. At most, Length Unicode
  characters will be compared. If Length is 0, then 0 is returned. If
  FirstString is identical to SecondString, then 0 is returned. Otherwise, the
  value returned is the first mismatched Unicode character in SecondString
  subtracted from the first mismatched Unicode character in FirstString.

  If Length > 0 and FirstString is NULL, then ASSERT().
  If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
  If Length > 0 and SecondString is NULL, then ASSERT().
  If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
  PcdMaximumUnicodeStringLength, then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
  then ASSERT().
  If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
  PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
  then ASSERT().

  @param  FirstString   A pointer to a Null-terminated Unicode string.
  @param  SecondString  A pointer to a Null-terminated Unicode string.
  @param  Length        The maximum number of Unicode characters to compare.

  @retval 0      FirstString is identical to SecondString.
  @return others FirstString is not identical to SecondString.

**/
INTN
StrnCmp (
        CONST CHAR16              *FirstString,
        CONST CHAR16              *SecondString,
        UINTN                     Length
  )
{
  if (Length == 0) {
    return 0;
  }

  //
  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
  // Length tests are performed inside StrLen().
  //
  ASSERT (StrSize (FirstString) != 0);
  ASSERT (StrSize (SecondString) != 0);

  while ((*FirstString != L'\0') &&
         (*SecondString != L'\0') &&
         (*FirstString == *SecondString) &&
         (Length > 1)) {
    FirstString++;
    SecondString++;
    Length--;
  }

  return *FirstString - *SecondString;
}

VOID *
AllocateCopyPool (
   UINTN       AllocationSize,
   CONST VOID  *Buffer
  )
{
  return InternalAllocateCopyPool (AllocationSize, Buffer);
}

INTN
StrCmp (
  CONST CHAR16              *FirstString,
  CONST CHAR16              *SecondString
  )
{
  //
  // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
  //
  ASSERT (StrSize (FirstString) != 0);
  ASSERT (StrSize (SecondString) != 0);

  while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
    FirstString++;
    SecondString++;
  }
  return *FirstString - *SecondString;
}

UINT64
SwapBytes64 (
  UINT64                    Value
  )
{
  return InternalMathSwapBytes64 (Value);
}

UINT64
InternalMathSwapBytes64 (
  UINT64                    Operand
  )
{
  UINT64  LowerBytes;
  UINT64  HigherBytes;

  LowerBytes  = (UINT64) SwapBytes32 ((UINT32) Operand);
  HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));

  return (LowerBytes << 32 | HigherBytes);
}

RETURN_STATUS
StrToIpv4Address (
  CONST CHAR16       *String,
  CHAR16             **EndPointer,
  EFI_IPv4_ADDRESS       *Address,
  UINT8              *PrefixLength
  )
{
  RETURN_STATUS          Status;
  UINTN                  AddressIndex;
  UINT64                 Uint64;
  EFI_IPv4_ADDRESS       LocalAddress;
  UINT8                  LocalPrefixLength;
  CHAR16                 *Pointer;

  LocalPrefixLength = MAX_UINT8;
  LocalAddress.Addr[0] = 0;

  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. None of String or Guid shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);

  for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
    if (!InternalIsDecimalDigitCharacter (*Pointer)) {
      //
      // D or P contains invalid characters.
      //
      break;
    }

    //
    // Get D or P.
    //
    Status = StrDecimalToUint64S ((CONST CHAR16 *) Pointer, &Pointer, &Uint64);
    if (RETURN_ERROR (Status)) {
      return RETURN_UNSUPPORTED;
    }
    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
      //
      // It's P.
      //
      if (Uint64 > 32) {
        return RETURN_UNSUPPORTED;
      }
      LocalPrefixLength = (UINT8) Uint64;
    } else {
      //
      // It's D.
      //
      if (Uint64 > MAX_UINT8) {
        return RETURN_UNSUPPORTED;
      }
      LocalAddress.Addr[AddressIndex] = (UINT8) Uint64;
      AddressIndex++;
    }

    //
    // Check the '.' or '/', depending on the AddressIndex.
    //
    if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
      if (*Pointer == L'/') {
        //
        // '/P' is in the String.
        // Skip "/" and get P in next loop.
        //
        Pointer++;
      } else {
        //
        // '/P' is not in the String.
        //
        break;
      }
    } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
      if (*Pointer == L'.') {
        //
        // D should be followed by '.'
        //
        Pointer++;
      } else {
        return RETURN_UNSUPPORTED;
      }
    }
  }

  if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
    return RETURN_UNSUPPORTED;
  }

  memcpy (Address, &LocalAddress, sizeof (*Address));
  if (PrefixLength != NULL) {
    *PrefixLength = LocalPrefixLength;
  }
  if (EndPointer != NULL) {
    *EndPointer = Pointer;
  }

  return RETURN_SUCCESS;
}

RETURN_STATUS
StrToIpv6Address (
  CONST CHAR16       *String,
  CHAR16             **EndPointer,
  EFI_IPv6_ADDRESS   *Address,
  UINT8              *PrefixLength
  )
{
  RETURN_STATUS          Status;
  UINTN                  AddressIndex;
  UINT64                 Uint64;
  EFI_IPv6_ADDRESS       LocalAddress;
  UINT8                  LocalPrefixLength;
  CONST CHAR16           *Pointer;
  CHAR16                 *End;
  UINTN                  CompressStart;
  BOOLEAN                ExpectPrefix;

  LocalPrefixLength = MAX_UINT8;
  CompressStart     = ARRAY_SIZE (Address->Addr);
  ExpectPrefix      = FALSE;

  ASSERT (((UINTN) String & BIT0) == 0);

  //
  // 1. None of String or Guid shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);

  for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
      if (*Pointer != L':') {
        //
        // ":" or "/" should be followed by digit characters.
        //
        return RETURN_UNSUPPORTED;
      }

      //
      // Meet second ":" after previous ":" or "/"
      // or meet first ":" in the beginning of String.
      //
      if (ExpectPrefix) {
        //
        // ":" shall not be after "/"
        //
        return RETURN_UNSUPPORTED;
      }

      if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
        //
        // "::" can only appear once.
        // "::" can only appear when address is not full length.
        //
        return RETURN_UNSUPPORTED;
      } else {
        //
        // Remember the start of zero compressing.
        //
        CompressStart = AddressIndex;
        Pointer++;

        if (CompressStart == 0) {
          if (*Pointer != L':') {
            //
            // Single ":" shall not be in the beginning of String.
            //
            return RETURN_UNSUPPORTED;
          }
          Pointer++;
        }
      }
    }

    if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
      if (*Pointer == L'/') {
        //
        // Might be optional "/P" after "::".
        //
        if (CompressStart != AddressIndex) {
          return RETURN_UNSUPPORTED;
        }
      } else {
        break;
      }
    } else {
      if (!ExpectPrefix) {
        //
        // Get X.
        //
        Status = StrHexToUint64S (Pointer, &End, &Uint64);
        if (RETURN_ERROR (Status) || End - Pointer > 4) {
          //
          // Number of hexadecimal digit characters is no more than 4.
          //
          return RETURN_UNSUPPORTED;
        }
        Pointer = End;
        //
        // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
        //
        ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
        LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uint64 >> 8);
        LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uint64;
        AddressIndex += 2;
      } else {
        //
        // Get P, then exit the loop.
        //
        Status = StrDecimalToUint64S (Pointer, &End, &Uint64);
        if (RETURN_ERROR (Status) || End == Pointer || Uint64 > 128) {
          //
          // Prefix length should not exceed 128.
          //
          return RETURN_UNSUPPORTED;
        }
        LocalPrefixLength = (UINT8) Uint64;
        Pointer = End;
        break;
      }
    }

    //
    // Skip ':' or "/"
    //
    if (*Pointer == L'/') {
      ExpectPrefix = TRUE;
    } else if (*Pointer == L':') {
      if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
        //
        // Meet additional ":" after all 8 16-bit address
        //
        break;
      }
    } else {
      //
      // Meet other character that is not "/" or ":" after all 8 16-bit address
      //
      break;
    }
    Pointer++;
  }

  if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
    (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
      ) {
    //
    // Full length of address shall not have compressing zeros.
    // Non-full length of address shall have compressing zeros.
    //
    return RETURN_UNSUPPORTED;
  }
  memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
  if (AddressIndex > CompressStart) {
    memset (&Address->Addr[CompressStart], 0,  ARRAY_SIZE (Address->Addr) - AddressIndex);
    memcpy (
      &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
      &LocalAddress.Addr[CompressStart],
      AddressIndex - CompressStart
      );
  }

  if (PrefixLength != NULL) {
    *PrefixLength = LocalPrefixLength;
  }
  if (EndPointer != NULL) {
    *EndPointer = (CHAR16 *) Pointer;
  }

  return RETURN_SUCCESS;
}


RETURN_STATUS
UnicodeStrToAsciiStrS (
  CONST CHAR16              *Source,
  CHAR8                     *Destination,
  UINTN                     DestMax
  )
{
  UINTN            SourceLen;

  ASSERT (((UINTN) Source & BIT0) == 0);

  //
  // 1. Neither Destination nor Source shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

  //
  // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
  //
  if (ASCII_RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }
  if (RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }

  //
  // 3. DestMax shall not equal zero.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

  //
  // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
  //
  SourceLen = StrnLenS (Source, DestMax);
  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

  //
  // 5. Copying shall not take place between objects that overlap.
  //
  SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);

  //
  // convert string
  //
  while (*Source != '\0') {
    //
    // If any Unicode characters in Source contain
    // non-zero value in the upper 8 bits, then ASSERT().
    //
    ASSERT (*Source < 0x100);
    *(Destination++) = (CHAR8) *(Source++);
  }
  *Destination = '\0';

  return RETURN_SUCCESS;
}

RETURN_STATUS
StrCpyS (
  CHAR16       *Destination,
  UINTN        DestMax,
  CONST CHAR16 *Source
  )
{
  UINTN            SourceLen;

  ASSERT (((UINTN) Destination & BIT0) == 0);
  ASSERT (((UINTN) Source & BIT0) == 0);

  //
  // 1. Neither Destination nor Source shall be a null pointer.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
  SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);

  //
  // 2. DestMax shall not be greater than RSIZE_MAX.
  //
  if (RSIZE_MAX != 0) {
    SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  }

  //
  // 3. DestMax shall not equal zero.
  //
  SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);

  //
  // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
  //
  SourceLen = StrnLenS (Source, DestMax);
  SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);

  //
  // 5. Copying shall not take place between objects that overlap.
  //
  SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);

  //
  // The StrCpyS function copies the string pointed to by Source (including the terminating
  // null character) into the array pointed to by Destination.
  //
  while (*Source != 0) {
    *(Destination++) = *(Source++);
  }
  *Destination = 0;

  return RETURN_SUCCESS;
}

VOID *
AllocateZeroPool (
  UINTN  AllocationSize
  )
{
  VOID * Memory;
  Memory = malloc(AllocationSize);
  ASSERT (Memory != NULL);
  if (Memory == NULL) {
    fprintf(stderr, "Not memory for malloc\n");
  }
  memset(Memory, 0, AllocationSize);
  return Memory;
}

VOID *
AllocatePool (
  UINTN  AllocationSize
  )
{
  return InternalAllocatePool (AllocationSize);
}

UINT16
WriteUnaligned16 (
  UINT16                    *Buffer,
  UINT16                    Value
  )
{
  ASSERT (Buffer != NULL);

  return *Buffer = Value;
}

UINT16
ReadUnaligned16 (
  CONST UINT16              *Buffer
  )
{
  ASSERT (Buffer != NULL);

  return *Buffer;
}
/**
  Return whether the integer string is a hex string.

  @param Str             The integer string

  @retval TRUE   Hex string
  @retval FALSE  Decimal string

**/
BOOLEAN
IsHexStr (
   CHAR16   *Str
  )
{
  //
  // skip preceding white space
  //
  while ((*Str != 0) && *Str == L' ') {
    Str ++;
  }
  //
  // skip preceding zeros
  //
  while ((*Str != 0) && *Str == L'0') {
    Str ++;
  }

  return (BOOLEAN) (*Str == L'x' || *Str == L'X');
}

/**

  Convert integer string to uint.

  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.

  @return A UINTN value represented by Str

**/
UINTN
Strtoi (
   CHAR16  *Str
  )
{
  if (IsHexStr (Str)) {
    return (UINTN)StrHexToUint64 (Str);
  } else {
    return (UINTN)StrDecimalToUint64 (Str);
  }
}

/**

  Convert integer string to 64 bit data.

  @param Str             The integer string. If leading with "0x" or "0X", it's hexadecimal.
  @param Data            A pointer to the UINT64 value represented by Str

**/
VOID
Strtoi64 (
    CHAR16  *Str,
   UINT64  *Data
  )
{
  if (IsHexStr (Str)) {
    *Data = StrHexToUint64 (Str);
  } else {
    *Data = StrDecimalToUint64 (Str);
  }
}

/**
  Converts a Unicode string to ASCII string.

  @param Str             The equivalent Unicode string
  @param AsciiStr        On input, it points to destination ASCII string buffer; on output, it points
                         to the next ASCII string next to it

**/
VOID
StrToAscii (
       CHAR16 *Str,
    CHAR8  **AsciiStr
  )
{
  CHAR8 *Dest;

  Dest = *AsciiStr;
  while (!IS_NULL (*Str)) {
    *(Dest++) = (CHAR8) *(Str++);
  }
  *Dest = 0;

  //
  // Return the string next to it
  //
  *AsciiStr = Dest + 1;
}

/**
  Gets current sub-string from a string list, before return
  the list header is moved to next sub-string. The sub-string is separated
  by the specified character. For example, the separator is ',', the string
  list is "2,0,3", it returns "2", the remain list move to "0,3"

  @param  List        A string list separated by the specified separator
  @param  Separator   The separator character

  @return A pointer to the current sub-string

**/
CHAR16 *
SplitStr (
    CHAR16 **List,
       CHAR16 Separator
  )
{
  CHAR16  *Str;
  CHAR16  *ReturnStr;

  Str = *List;
  ReturnStr = Str;

  if (IS_NULL (*Str)) {
    return ReturnStr;
  }

  //
  // Find first occurrence of the separator
  //
  while (!IS_NULL (*Str)) {
    if (*Str == Separator) {
      break;
    }
    Str++;
  }

  if (*Str == Separator) {
    //
    // Find a sub-string, terminate it
    //
    *Str = L'\0';
    Str++;
  }

  //
  // Move to next sub-string
  //
  *List = Str;
  return ReturnStr;
}
