/** @file
  This library parses the INI configuration file.

  The INI file format is:
    ================
    [SectionName]
    EntryName=EntryValue
    ================

    Where:
      1) SectionName is an ASCII string. The valid format is [A-Za-z0-9_]+
      2) EntryName is an ASCII string. The valid format is [A-Za-z0-9_]+
      3) EntryValue can be:
         3.1) an ASCII String. The valid format is [A-Za-z0-9_]+
         3.2) a GUID. The valid format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where x is [A-Fa-f0-9]
         3.3) a decimal value. The valid format is [0-9]+
         3.4) a hexadecimal value. The valid format is 0x[A-Fa-f0-9]+
      4) '#' or ';' can be used as comment at anywhere.
      5) TAB(0x20) or SPACE(0x9) can be used as separator.
      6) LF(\n, 0xA) or CR(\r, 0xD) can be used as line break.

  Caution: This module requires additional review when modified.
  This driver will have external input - INI data file.

  OpenIniFile(), PreProcessDataFile(), ProfileGetSection(), ProfileGetEntry()
  will receive untrusted input and do basic validation.

  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#define IS_HYPHEN(a)  ((a) == '-')
#define IS_NULL(a)    ((a) == '\0')

// This is default allocation. Reallocation will happen if it is not enough.
#define MAX_LINE_LENGTH  512

typedef struct _INI_SECTION_ITEM SECTION_ITEM;
struct _INI_SECTION_ITEM {
  CHAR8           *PtrSection;
  UINTN           SecNameLen;
  CHAR8           *PtrEntry;
  CHAR8           *PtrValue;
  SECTION_ITEM    *PtrNext;
};

typedef struct _INI_COMMENT_LINE COMMENT_LINE;
struct _INI_COMMENT_LINE {
  CHAR8           *PtrComment;
  COMMENT_LINE    *PtrNext;
};

typedef struct {
  SECTION_ITEM    *SectionHead;
  COMMENT_LINE    *CommentHead;
} INI_PARSING_LIB_CONTEXT;

/**
  Return if the digital char is valid.

  @param[in] DigitalChar    The digital char to be checked.
  @param[in] IncludeHex     If it include HEX char.

  @retval TRUE   The digital char is valid.
  @retval FALSE  The digital char is invalid.
**/
BOOLEAN
IsValidDigitalChar (
  IN CHAR8    DigitalChar,
  IN BOOLEAN  IncludeHex
  )
{
  if ((DigitalChar >= '0') && (DigitalChar <= '9')) {
    return TRUE;
  }

  if (IncludeHex) {
    if ((DigitalChar >= 'a') && (DigitalChar <= 'f')) {
      return TRUE;
    }

    if ((DigitalChar >= 'A') && (DigitalChar <= 'F')) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Return if the name char is valid.

  @param[in] NameChar    The name char to be checked.

  @retval TRUE   The name char is valid.
  @retval FALSE  The name char is invalid.
**/
BOOLEAN
IsValidNameChar (
  IN CHAR8  NameChar
  )
{
  if ((NameChar >= 'a') && (NameChar <= 'z')) {
    return TRUE;
  }

  if ((NameChar >= 'A') && (NameChar <= 'Z')) {
    return TRUE;
  }

  if ((NameChar >= '0') && (NameChar <= '9')) {
    return TRUE;
  }

  if (NameChar == '_') {
    return TRUE;
  }

  return FALSE;
}

/**
  Return if the digital string is valid.

  @param[in] Digital        The digital to be checked.
  @param[in] Length         The length of digital string in bytes.
  @param[in] IncludeHex     If it include HEX char.

  @retval TRUE   The digital string is valid.
  @retval FALSE  The digital string is invalid.
**/
BOOLEAN
IsValidDigital (
  IN CHAR8    *Digital,
  IN UINTN    Length,
  IN BOOLEAN  IncludeHex
  )
{
  UINTN  Index;

  for (Index = 0; Index < Length; Index++) {
    if (!IsValidDigitalChar (Digital[Index], IncludeHex)) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Return if the decimal string is valid.

  @param[in] Decimal The decimal string to be checked.
  @param[in] Length  The length of decimal string in bytes.

  @retval TRUE   The decimal string is valid.
  @retval FALSE  The decimal string is invalid.
**/
BOOLEAN
IsValidDecimalString (
  IN CHAR8  *Decimal,
  IN UINTN  Length
  )
{
  return IsValidDigital (Decimal, Length, FALSE);
}

/**
  Return if the hexadecimal string is valid.

  @param[in] Hex     The hexadecimal string to be checked.
  @param[in] Length  The length of hexadecimal string in bytes.

  @retval TRUE   The hexadecimal string is valid.
  @retval FALSE  The hexadecimal string is invalid.
**/
BOOLEAN
IsValidHexString (
  IN CHAR8  *Hex,
  IN UINTN  Length
  )
{
  if (Length <= 2) {
    return FALSE;
  }

  if (Hex[0] != '0') {
    return FALSE;
  }

  if ((Hex[1] != 'x') && (Hex[1] != 'X')) {
    return FALSE;
  }

  return IsValidDigital (&Hex[2], Length - 2, TRUE);
}

/**
  Return if the name string is valid.

  @param[in] Name    The name to be checked.
  @param[in] Length  The length of name string in bytes.

  @retval TRUE   The name string is valid.
  @retval FALSE  The name string is invalid.
**/
BOOLEAN
IsValidName (
  IN CHAR8  *Name,
  IN UINTN  Length
  )
{
  UINTN  Index;

  for (Index = 0; Index < Length; Index++) {
    if (!IsValidNameChar (Name[Index])) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Return if the value string is valid GUID.

  @param[in] Value   The value to be checked.
  @param[in] Length  The length of value string in bytes.

  @retval TRUE   The value string is valid GUID.
  @retval FALSE  The value string is invalid GUID.
**/
BOOLEAN
IsValidGuid (
  IN CHAR8  *Value,
  IN UINTN  Length
  )
{
  if (Length != sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") - 1) {
    return FALSE;
  }

  if (!IS_HYPHEN (Value[8])) {
    return FALSE;
  }

  if (!IS_HYPHEN (Value[13])) {
    return FALSE;
  }

  if (!IS_HYPHEN (Value[18])) {
    return FALSE;
  }

  if (!IS_HYPHEN (Value[23])) {
    return FALSE;
  }

  if (!IsValidDigital (&Value[0], 8, TRUE)) {
    return FALSE;
  }

  if (!IsValidDigital (&Value[9], 4, TRUE)) {
    return FALSE;
  }

  if (!IsValidDigital (&Value[14], 4, TRUE)) {
    return FALSE;
  }

  if (!IsValidDigital (&Value[19], 4, TRUE)) {
    return FALSE;
  }

  if (!IsValidDigital (&Value[24], 12, TRUE)) {
    return FALSE;
  }

  return TRUE;
}

/**
  Return if the value string is valid.

  @param[in] Value    The value to be checked.
  @param[in] Length  The length of value string in bytes.

  @retval TRUE   The name string is valid.
  @retval FALSE  The name string is invalid.
**/
BOOLEAN
IsValidValue (
  IN CHAR8  *Value,
  IN UINTN  Length
  )
{
  if (IsValidName (Value, Length) || IsValidGuid (Value, Length)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Dump an INI config file context.

  @param[in] Context         INI Config file context.
**/
VOID
DumpIniSection (
  IN VOID  *Context
  )
{
  INI_PARSING_LIB_CONTEXT  *IniContext;
  SECTION_ITEM             *PtrSection;
  SECTION_ITEM             *Section;

  if (Context == NULL) {
    return;
  }

  IniContext = Context;
  Section    = IniContext->SectionHead;

  while (Section != NULL) {
    PtrSection = Section;
    Section    = Section->PtrNext;
    if (PtrSection->PtrSection != NULL) {
      DEBUG ((DEBUG_VERBOSE, "Section - %a\n", PtrSection->PtrSection));
    }

    if (PtrSection->PtrEntry != NULL) {
      DEBUG ((DEBUG_VERBOSE, "  Entry - %a\n", PtrSection->PtrEntry));
    }

    if (PtrSection->PtrValue != NULL) {
      DEBUG ((DEBUG_VERBOSE, "  Value - %a\n", PtrSection->PtrValue));
    }
  }
}

/**
  Copy one line data from buffer data to the line buffer.

  @param[in]      Buffer          Buffer data.
  @param[in]      BufferSize      Buffer Size.
  @param[in, out] LineBuffer      Line buffer to store the found line data.
  @param[in, out] LineSize        On input, size of the input line buffer.
                                  On output, size of the actual line buffer.

  @retval EFI_BUFFER_TOO_SMALL  The size of input line buffer is not enough.
  @retval EFI_SUCCESS           Copy line data into the line buffer.

**/
EFI_STATUS
ProfileGetLine (
  IN      UINT8  *Buffer,
  IN      UINTN  BufferSize,
  IN OUT  UINT8  *LineBuffer,
  IN OUT  UINTN  *LineSize
  )
{
  UINTN  Length;
  UINT8  *PtrBuf;
  UINTN  PtrEnd;

  PtrBuf = Buffer;
  PtrEnd = (UINTN)Buffer + BufferSize;

  //
  // 0x0D indicates a line break. Otherwise there is no line break
  //
  while ((UINTN)PtrBuf < PtrEnd) {
    if ((*PtrBuf == 0x0D) || (*PtrBuf == 0x0A)) {
      break;
    }

    PtrBuf++;
  }

  if ((UINTN)PtrBuf >= (PtrEnd - 1)) {
    //
    // The buffer ends without any line break
    // or it is the last character of the buffer
    //
    Length = BufferSize;
  } else if (*(PtrBuf + 1) == 0x0A) {
    //
    // Further check if a 0x0A follows. If yes, count 0xA
    //
    Length = (UINTN)PtrBuf - (UINTN)Buffer + 2;
  } else {
    Length = (UINTN)PtrBuf - (UINTN)Buffer + 1;
  }

  if (Length > (*LineSize)) {
    *LineSize = Length;
    return EFI_BUFFER_TOO_SMALL;
  }

  SetMem (LineBuffer, *LineSize, 0x0);
  *LineSize = Length;
  CopyMem (LineBuffer, Buffer, Length);

  return EFI_SUCCESS;
}

/**
  Trim Buffer by removing all CR, LF, TAB, and SPACE chars in its head and tail.

  @param[in, out] Buffer          On input,  buffer data to be trimmed.
                                  On output, the trimmed buffer.
  @param[in, out] BufferSize      On input,  size of original buffer data.
                                  On output, size of the trimmed buffer.

**/
VOID
ProfileTrim (
  IN OUT  UINT8  *Buffer,
  IN OUT  UINTN  *BufferSize
  )
{
  UINTN  Length;
  UINT8  *PtrBuf;
  UINT8  *PtrEnd;

  if (*BufferSize == 0) {
    return;
  }

  //
  // Trim the tail first, include CR, LF, TAB, and SPACE.
  //
  Length = *BufferSize;
  PtrBuf = (UINT8 *)((UINTN)Buffer + Length - 1);
  while (PtrBuf >= Buffer) {
    if (  (*PtrBuf != 0x0D) && (*PtrBuf != 0x0A)
       && (*PtrBuf != 0x20) && (*PtrBuf != 0x09))
    {
      break;
    }

    PtrBuf--;
  }

  //
  // all spaces, a blank line, return directly;
  //
  if (PtrBuf < Buffer) {
    *BufferSize = 0;
    return;
  }

  Length = (UINTN)PtrBuf - (UINTN)Buffer + 1;
  PtrEnd = PtrBuf;
  PtrBuf = Buffer;

  //
  // Now skip the heading CR, LF, TAB and SPACE
  //
  while (PtrBuf <= PtrEnd) {
    if (  (*PtrBuf != 0x0D) && (*PtrBuf != 0x0A)
       && (*PtrBuf != 0x20) && (*PtrBuf != 0x09))
    {
      break;
    }

    PtrBuf++;
  }

  //
  // If no heading CR, LF, TAB or SPACE, directly return
  //
  if (PtrBuf == Buffer) {
    *BufferSize = Length;
    return;
  }

  *BufferSize = (UINTN)PtrEnd - (UINTN)PtrBuf + 1;

  //
  // The first Buffer..PtrBuf characters are CR, LF, TAB or SPACE.
  // Now move out all these characters.
  //
  while (PtrBuf <= PtrEnd) {
    *Buffer = *PtrBuf;
    Buffer++;
    PtrBuf++;
  }

  return;
}

/**
  Insert new comment item into comment head.

  @param[in]      Buffer          Comment buffer to be added.
  @param[in]      BufferSize      Size of comment buffer.
  @param[in, out] CommentHead     Comment Item head entry.

  @retval EFI_OUT_OF_RESOURCES   No enough memory is allocated.
  @retval EFI_SUCCESS            New comment item is inserted.

**/
EFI_STATUS
ProfileGetComments (
  IN      UINT8         *Buffer,
  IN      UINTN         BufferSize,
  IN OUT  COMMENT_LINE  **CommentHead
  )
{
  COMMENT_LINE  *CommentItem;

  CommentItem = NULL;
  CommentItem = AllocatePool (sizeof (COMMENT_LINE));
  if (CommentItem == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CommentItem->PtrNext = *CommentHead;
  *CommentHead         = CommentItem;

  //
  // Add a trailing '\0'
  //
  CommentItem->PtrComment = AllocatePool (BufferSize + 1);
  if (CommentItem->PtrComment == NULL) {
    FreePool (CommentItem);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (CommentItem->PtrComment, Buffer, BufferSize);
  *(CommentItem->PtrComment + BufferSize) = '\0';

  return EFI_SUCCESS;
}

/**
  Add new section item into Section head.

  @param[in]      Buffer          Section item data buffer.
  @param[in]      BufferSize      Size of section item.
  @param[in, out] SectionHead     Section item head entry.

  @retval EFI_OUT_OF_RESOURCES   No enough memory is allocated.
  @retval EFI_SUCCESS            Section item is NULL or Section item is added.

**/
EFI_STATUS
ProfileGetSection (
  IN      UINT8         *Buffer,
  IN      UINTN         BufferSize,
  IN OUT  SECTION_ITEM  **SectionHead
  )
{
  SECTION_ITEM  *SectionItem;
  UINTN         Length;
  UINT8         *PtrBuf;
  UINT8         *PtrEnd;

  ASSERT (BufferSize >= 1);
  //
  // The first character of Buffer is '[', now we want for ']'
  //
  PtrEnd = (UINT8 *)((UINTN)Buffer + BufferSize - 1);
  PtrBuf = (UINT8 *)((UINTN)Buffer + 1);
  while (PtrBuf <= PtrEnd) {
    if (*PtrBuf == ']') {
      break;
    }

    PtrBuf++;
  }

  if (PtrBuf > PtrEnd) {
    //
    // Not found. Invalid line
    //
    return EFI_NOT_FOUND;
  }

  if (PtrBuf <= Buffer + 1) {
    // Empty name
    return EFI_NOT_FOUND;
  }

  //
  // excluding the heading '[' and tailing ']'
  //
  Length = PtrBuf - Buffer - 1;
  ProfileTrim (
    Buffer + 1,
    &Length
    );

  //
  // Invalid line if the section name is null
  //
  if (Length == 0) {
    return EFI_NOT_FOUND;
  }

  if (!IsValidName ((CHAR8 *)Buffer + 1, Length)) {
    return EFI_INVALID_PARAMETER;
  }

  SectionItem = AllocatePool (sizeof (SECTION_ITEM));
  if (SectionItem == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  SectionItem->PtrSection = NULL;
  SectionItem->SecNameLen = Length;
  SectionItem->PtrEntry   = NULL;
  SectionItem->PtrValue   = NULL;
  SectionItem->PtrNext    = *SectionHead;
  *SectionHead            = SectionItem;

  //
  // Add a trailing '\0'
  //
  SectionItem->PtrSection = AllocatePool (Length + 1);
  if (SectionItem->PtrSection == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // excluding the heading '['
  //
  CopyMem (SectionItem->PtrSection, Buffer + 1, Length);
  *(SectionItem->PtrSection + Length) = '\0';

  return EFI_SUCCESS;
}

/**
  Add new section entry and entry value into Section head.

  @param[in]      Buffer          Section entry data buffer.
  @param[in]      BufferSize      Size of section entry.
  @param[in, out] SectionHead     Section item head entry.

  @retval EFI_OUT_OF_RESOURCES   No enough memory is allocated.
  @retval EFI_SUCCESS            Section entry is added.
  @retval EFI_NOT_FOUND          Section entry is not found.
  @retval EFI_INVALID_PARAMETER  Section entry is invalid.

**/
EFI_STATUS
ProfileGetEntry (
  IN      UINT8         *Buffer,
  IN      UINTN         BufferSize,
  IN OUT  SECTION_ITEM  **SectionHead
  )
{
  EFI_STATUS    Status;
  SECTION_ITEM  *SectionItem;
  SECTION_ITEM  *PtrSection;
  UINTN         Length;
  UINT8         *PtrBuf;
  UINT8         *PtrEnd;

  Status = EFI_SUCCESS;
  PtrBuf = Buffer;
  PtrEnd = (UINT8 *)((UINTN)Buffer + BufferSize - 1);

  //
  // First search for '='
  //
  while (PtrBuf <= PtrEnd) {
    if (*PtrBuf == '=') {
      break;
    }

    PtrBuf++;
  }

  if (PtrBuf > PtrEnd) {
    //
    // Not found. Invalid line
    //
    return EFI_NOT_FOUND;
  }

  if (PtrBuf <= Buffer) {
    // Empty name
    return EFI_NOT_FOUND;
  }

  //
  // excluding the tailing '='
  //
  Length = PtrBuf - Buffer;
  ProfileTrim (
    Buffer,
    &Length
    );

  //
  // Invalid line if the entry name is null
  //
  if (Length == 0) {
    return EFI_NOT_FOUND;
  }

  if (!IsValidName ((CHAR8 *)Buffer, Length)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Omit this line if no section header has been found before
  //
  if (*SectionHead == NULL) {
    return Status;
  }

  PtrSection = *SectionHead;

  SectionItem = AllocatePool (sizeof (SECTION_ITEM));
  if (SectionItem == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  SectionItem->PtrSection = NULL;
  SectionItem->PtrEntry   = NULL;
  SectionItem->PtrValue   = NULL;
  SectionItem->SecNameLen = PtrSection->SecNameLen;
  SectionItem->PtrNext    = *SectionHead;
  *SectionHead            = SectionItem;

  //
  // SectionName, add a trailing '\0'
  //
  SectionItem->PtrSection = AllocatePool (PtrSection->SecNameLen + 1);
  if (SectionItem->PtrSection == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (SectionItem->PtrSection, PtrSection->PtrSection, PtrSection->SecNameLen + 1);

  //
  // EntryName, add a trailing '\0'
  //
  SectionItem->PtrEntry = AllocatePool (Length + 1);
  if (SectionItem->PtrEntry == NULL) {
    FreePool (SectionItem->PtrSection);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (SectionItem->PtrEntry, Buffer, Length);
  *(SectionItem->PtrEntry + Length) = '\0';

  //
  // Next search for '#' or ';'
  //
  PtrBuf = PtrBuf + 1;
  Buffer = PtrBuf;
  while (PtrBuf <= PtrEnd) {
    if ((*PtrBuf == '#') || (*PtrBuf == ';')) {
      break;
    }

    PtrBuf++;
  }

  if (PtrBuf <= Buffer) {
    // Empty name
    FreePool (SectionItem->PtrEntry);
    FreePool (SectionItem->PtrSection);
    return EFI_NOT_FOUND;
  }

  Length = PtrBuf - Buffer;
  ProfileTrim (
    Buffer,
    &Length
    );

  //
  // Invalid line if the entry value is null
  //
  if (Length == 0) {
    FreePool (SectionItem->PtrEntry);
    FreePool (SectionItem->PtrSection);
    return EFI_NOT_FOUND;
  }

  if (!IsValidValue ((CHAR8 *)Buffer, Length)) {
    FreePool (SectionItem->PtrEntry);
    FreePool (SectionItem->PtrSection);
    return EFI_INVALID_PARAMETER;
  }

  //
  // EntryValue, add a trailing '\0'
  //
  SectionItem->PtrValue = AllocatePool (Length + 1);
  if (SectionItem->PtrValue == NULL) {
    FreePool (SectionItem->PtrEntry);
    FreePool (SectionItem->PtrSection);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (SectionItem->PtrValue, Buffer, Length);
  *(SectionItem->PtrValue + Length) = '\0';

  return EFI_SUCCESS;
}

/**
  Free all comment entry and section entry.

  @param[in] Section         Section entry list.
  @param[in] Comment         Comment entry list.

**/
VOID
FreeAllList (
  IN      SECTION_ITEM  *Section,
  IN      COMMENT_LINE  *Comment
  )
{
  SECTION_ITEM  *PtrSection;
  COMMENT_LINE  *PtrComment;

  while (Section != NULL) {
    PtrSection = Section;
    Section    = Section->PtrNext;
    if (PtrSection->PtrEntry != NULL) {
      FreePool (PtrSection->PtrEntry);
    }

    if (PtrSection->PtrSection != NULL) {
      FreePool (PtrSection->PtrSection);
    }

    if (PtrSection->PtrValue != NULL) {
      FreePool (PtrSection->PtrValue);
    }

    FreePool (PtrSection);
  }

  while (Comment != NULL) {
    PtrComment = Comment;
    Comment    = Comment->PtrNext;
    if (PtrComment->PtrComment != NULL) {
      FreePool (PtrComment->PtrComment);
    }

    FreePool (PtrComment);
  }

  return;
}

/**
  Get section entry value.

  @param[in]  Section         Section entry list.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] EntryValue      Point to the got entry value.

  @retval EFI_NOT_FOUND  Section is not found.
  @retval EFI_SUCCESS    Section entry value is got.

**/
EFI_STATUS
UpdateGetProfileString (
  IN      SECTION_ITEM  *Section,
  IN      CHAR8         *SectionName,
  IN      CHAR8         *EntryName,
  OUT     CHAR8         **EntryValue
  )
{
  *EntryValue = NULL;

  while (Section != NULL) {
    if (AsciiStrCmp ((CONST CHAR8 *)Section->PtrSection, (CONST CHAR8 *)SectionName) == 0) {
      if (Section->PtrEntry != NULL) {
        if (AsciiStrCmp ((CONST CHAR8 *)Section->PtrEntry, (CONST CHAR8 *)EntryName) == 0) {
          break;
        }
      }
    }

    Section = Section->PtrNext;
  }

  if (Section == NULL) {
    return EFI_NOT_FOUND;
  }

  *EntryValue = Section->PtrValue;

  return EFI_SUCCESS;
}

/**
  Pre process config data buffer into Section entry list and Comment entry list.

  @param[in]      DataBuffer      Config raw file buffer.
  @param[in]      BufferSize      Size of raw buffer.
  @param[in, out] SectionHead     Pointer to the section entry list.
  @param[in, out] CommentHead     Pointer to the comment entry list.

  @retval EFI_OUT_OF_RESOURCES  No enough memory is allocated.
  @retval EFI_SUCCESS           Config data buffer is preprocessed.
  @retval EFI_NOT_FOUND         Config data buffer is invalid, because Section or Entry is not found.
  @retval EFI_INVALID_PARAMETER Config data buffer is invalid, because Section or Entry is invalid.

**/
EFI_STATUS
PreProcessDataFile (
  IN      UINT8         *DataBuffer,
  IN      UINTN         BufferSize,
  IN OUT  SECTION_ITEM  **SectionHead,
  IN OUT  COMMENT_LINE  **CommentHead
  )
{
  EFI_STATUS  Status;
  CHAR8       *Source;
  CHAR8       *CurrentPtr;
  CHAR8       *BufferEnd;
  CHAR8       *PtrLine;
  UINTN       LineLength;
  UINTN       SourceLength;
  UINTN       MaxLineLength;

  *SectionHead  = NULL;
  *CommentHead  = NULL;
  BufferEnd     = (CHAR8 *)((UINTN)DataBuffer + BufferSize);
  CurrentPtr    = (CHAR8 *)DataBuffer;
  MaxLineLength = MAX_LINE_LENGTH;
  Status        = EFI_SUCCESS;

  PtrLine = AllocatePool (MaxLineLength);
  if (PtrLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  while (CurrentPtr < BufferEnd) {
    Source       = CurrentPtr;
    SourceLength = (UINTN)BufferEnd - (UINTN)CurrentPtr;
    LineLength   = MaxLineLength;
    //
    // With the assumption that line length is less than 512
    // characters. Otherwise BUFFER_TOO_SMALL will be returned.
    //
    Status = ProfileGetLine (
               (UINT8 *)Source,
               SourceLength,
               (UINT8 *)PtrLine,
               &LineLength
               );
    if (EFI_ERROR (Status)) {
      if (Status == EFI_BUFFER_TOO_SMALL) {
        //
        // If buffer too small, re-allocate the buffer according
        // to the returned LineLength and try again.
        //
        FreePool (PtrLine);
        PtrLine = NULL;
        PtrLine = AllocatePool (LineLength);
        if (PtrLine == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }

        SourceLength = LineLength;
        Status       = ProfileGetLine (
                         (UINT8 *)Source,
                         SourceLength,
                         (UINT8 *)PtrLine,
                         &LineLength
                         );
        if (EFI_ERROR (Status)) {
          break;
        }

        MaxLineLength = LineLength;
      } else {
        break;
      }
    }

    CurrentPtr = (CHAR8 *)((UINTN)CurrentPtr + LineLength);

    //
    // Line got. Trim the line before processing it.
    //
    ProfileTrim (
      (UINT8 *)PtrLine,
      &LineLength
      );

    //
    // Blank line
    //
    if (LineLength == 0) {
      continue;
    }

    if ((PtrLine[0] == '#') || (PtrLine[0] == ';')) {
      Status = ProfileGetComments (
                 (UINT8 *)PtrLine,
                 LineLength,
                 CommentHead
                 );
    } else if (PtrLine[0] == '[') {
      Status = ProfileGetSection (
                 (UINT8 *)PtrLine,
                 LineLength,
                 SectionHead
                 );
    } else {
      Status = ProfileGetEntry (
                 (UINT8 *)PtrLine,
                 LineLength,
                 SectionHead
                 );
    }

    if (EFI_ERROR (Status)) {
      break;
    }
  }

  //
  // Free buffer
  //
  FreePool (PtrLine);

  return Status;
}

/**
  Open an INI config file and return a context.

  @param[in] DataBuffer      Config raw file buffer.
  @param[in] BufferSize      Size of raw buffer.

  @return       Config data buffer is opened and context is returned.
  @retval NULL  No enough memory is allocated.
  @retval NULL  Config data buffer is invalid.
**/
VOID *
EFIAPI
OpenIniFile (
  IN      UINT8  *DataBuffer,
  IN      UINTN  BufferSize
  )
{
  EFI_STATUS               Status;
  INI_PARSING_LIB_CONTEXT  *IniContext;

  if ((DataBuffer == NULL) || (BufferSize == 0)) {
    return NULL;
  }

  IniContext = AllocateZeroPool (sizeof (INI_PARSING_LIB_CONTEXT));
  if (IniContext == NULL) {
    return NULL;
  }

  //
  // First process the data buffer and get all sections and entries
  //
  Status = PreProcessDataFile (
             DataBuffer,
             BufferSize,
             &IniContext->SectionHead,
             &IniContext->CommentHead
             );
  if (EFI_ERROR (Status)) {
    FreePool (IniContext);
    return NULL;
  }

  DEBUG_CODE_BEGIN ();
  DumpIniSection (IniContext);
  DEBUG_CODE_END ();
  return IniContext;
}

/**
  Get section entry string value.

  @param[in]  Context         INI Config file context.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] EntryValue      Point to the got entry string value.

  @retval EFI_SUCCESS    Section entry string value is got.
  @retval EFI_NOT_FOUND  Section is not found.
**/
EFI_STATUS
EFIAPI
GetStringFromDataFile (
  IN      VOID   *Context,
  IN      CHAR8  *SectionName,
  IN      CHAR8  *EntryName,
  OUT     CHAR8  **EntryValue
  )
{
  INI_PARSING_LIB_CONTEXT  *IniContext;
  EFI_STATUS               Status;

  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (EntryValue == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  IniContext = Context;

  *EntryValue = NULL;
  Status      = UpdateGetProfileString (
                  IniContext->SectionHead,
                  SectionName,
                  EntryName,
                  EntryValue
                  );
  return Status;
}

/**
  Get section entry GUID value.

  @param[in]  Context         INI Config file context.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] Guid            Point to the got GUID value.

  @retval EFI_SUCCESS    Section entry GUID value is got.
  @retval EFI_NOT_FOUND  Section is not found.
**/
EFI_STATUS
EFIAPI
GetGuidFromDataFile (
  IN      VOID      *Context,
  IN      CHAR8     *SectionName,
  IN      CHAR8     *EntryName,
  OUT     EFI_GUID  *Guid
  )
{
  CHAR8          *Value;
  EFI_STATUS     Status;
  RETURN_STATUS  RStatus;

  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Guid == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetStringFromDataFile (
             Context,
             SectionName,
             EntryName,
             &Value
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  ASSERT (Value != NULL);
  RStatus = AsciiStrToGuid (Value, Guid);
  if (RETURN_ERROR (RStatus) || (Value[GUID_STRING_LENGTH] != '\0')) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Get section entry decimal UINTN value.

  @param[in]  Context         INI Config file context.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] Data            Point to the got decimal UINTN value.

  @retval EFI_SUCCESS    Section entry decimal UINTN value is got.
  @retval EFI_NOT_FOUND  Section is not found.
**/
EFI_STATUS
EFIAPI
GetDecimalUintnFromDataFile (
  IN      VOID   *Context,
  IN      CHAR8  *SectionName,
  IN      CHAR8  *EntryName,
  OUT     UINTN  *Data
  )
{
  CHAR8       *Value;
  EFI_STATUS  Status;

  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetStringFromDataFile (
             Context,
             SectionName,
             EntryName,
             &Value
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  ASSERT (Value != NULL);
  if (!IsValidDecimalString (Value, AsciiStrLen (Value))) {
    return EFI_NOT_FOUND;
  }

  *Data = AsciiStrDecimalToUintn (Value);
  return EFI_SUCCESS;
}

/**
  Get section entry hexadecimal UINTN value.

  @param[in]  Context         INI Config file context.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] Data            Point to the got hexadecimal UINTN value.

  @retval EFI_SUCCESS    Section entry hexadecimal UINTN value is got.
  @retval EFI_NOT_FOUND  Section is not found.
**/
EFI_STATUS
EFIAPI
GetHexUintnFromDataFile (
  IN      VOID   *Context,
  IN      CHAR8  *SectionName,
  IN      CHAR8  *EntryName,
  OUT     UINTN  *Data
  )
{
  CHAR8       *Value;
  EFI_STATUS  Status;

  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetStringFromDataFile (
             Context,
             SectionName,
             EntryName,
             &Value
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  ASSERT (Value != NULL);
  if (!IsValidHexString (Value, AsciiStrLen (Value))) {
    return EFI_NOT_FOUND;
  }

  *Data = AsciiStrHexToUintn (Value);
  return EFI_SUCCESS;
}

/**
  Get section entry hexadecimal UINT64 value.

  @param[in]  Context         INI Config file context.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] Data            Point to the got hexadecimal UINT64 value.

  @retval EFI_SUCCESS    Section entry hexadecimal UINT64 value is got.
  @retval EFI_NOT_FOUND  Section is not found.
**/
EFI_STATUS
EFIAPI
GetHexUint64FromDataFile (
  IN      VOID    *Context,
  IN      CHAR8   *SectionName,
  IN      CHAR8   *EntryName,
  OUT     UINT64  *Data
  )
{
  CHAR8       *Value;
  EFI_STATUS  Status;

  if ((Context == NULL) || (SectionName == NULL) || (EntryName == NULL) || (Data == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetStringFromDataFile (
             Context,
             SectionName,
             EntryName,
             &Value
             );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  ASSERT (Value != NULL);
  if (!IsValidHexString (Value, AsciiStrLen (Value))) {
    return EFI_NOT_FOUND;
  }

  *Data = AsciiStrHexToUint64 (Value);
  return EFI_SUCCESS;
}

/**
  Close an INI config file and free the context.

  @param[in] Context         INI Config file context.
**/
VOID
EFIAPI
CloseIniFile (
  IN      VOID  *Context
  )
{
  INI_PARSING_LIB_CONTEXT  *IniContext;

  if (Context == NULL) {
    return;
  }

  IniContext = Context;
  FreeAllList (IniContext->SectionHead, IniContext->CommentHead);

  return;
}
