/** @file

  The definition of CFormPkg's member function

Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "stdio.h"
#include "assert.h"
#include "VfrFormPkg.h"

/*
 * The definition of CFormPkg's member function
 */

SPendingAssign::SPendingAssign (
  IN CHAR8  *Key,
  IN VOID   *Addr,
  IN UINT32 Len,
  IN UINT32 LineNo,
  IN CONST CHAR8  *Msg
  )
{
  mKey    = NULL;
  mAddr   = Addr;
  mLen    = Len;
  mFlag   = PENDING;
  mLineNo = LineNo;
  mMsg    = NULL;
  mNext   = NULL;
  if (Key != NULL) {
    mKey = new CHAR8[strlen (Key) + 1];
    if (mKey != NULL) {
      strcpy (mKey, Key);
    }
  }

  if (Msg != NULL) {
    mMsg = new CHAR8[strlen (Msg) + 1];
    if (mMsg != NULL) {
      strcpy (mMsg, Msg);
    }
  }
}

SPendingAssign::~SPendingAssign (
  VOID
  )
{
  if (mKey != NULL) {
    delete[] mKey;
  }
  mAddr   = NULL;
  mLen    = 0;
  mLineNo = 0;
  if (mMsg != NULL) {
    delete[] mMsg;
  }
  mNext   = NULL;
}

VOID
SPendingAssign::SetAddrAndLen (
  IN VOID   *Addr,
  IN UINT32 LineNo
  )
{
  mAddr   = Addr;
  mLineNo = LineNo;
}

VOID
SPendingAssign::AssignValue (
  IN VOID   *Addr,
  IN UINT32 Len
  )
{
  memmove (mAddr, Addr, (mLen < Len ? mLen : Len));
  mFlag = ASSIGNED;
}

CHAR8 *
SPendingAssign::GetKey (
  VOID
  )
{
  return mKey;
}

CFormPkg::CFormPkg (
  IN UINT32 BufferSize
  )
{
  CHAR8       *BufferStart;
  CHAR8       *BufferEnd;
  SBufferNode *Node;

  mPkgLength           = 0;
  mBufferSize          = 0;
  mBufferNodeQueueHead = NULL;
  mBufferNodeQueueTail = NULL;
  mCurrBufferNode      = NULL;
  mReadBufferNode      = NULL;
  mReadBufferOffset    = 0;
  PendingAssignList    = NULL;

  Node = new SBufferNode;
  if (Node == NULL) {
    return ;
  }
  BufferStart = new CHAR8[BufferSize];
  if (BufferStart == NULL) {
    delete Node;
    return;
  }
  BufferEnd   = BufferStart + BufferSize;

  memset (BufferStart, 0, BufferSize);
  Node->mBufferStart   = BufferStart;
  Node->mBufferEnd     = BufferEnd;
  Node->mBufferFree    = BufferStart;
  Node->mNext          = NULL;

  mBufferSize          = BufferSize;
  mBufferNodeQueueHead = Node;
  mBufferNodeQueueTail = Node;
  mCurrBufferNode      = Node;
}

CFormPkg::~CFormPkg ()
{
  SBufferNode    *pBNode;
  SPendingAssign *pPNode;

  while (mBufferNodeQueueHead != NULL) {
    pBNode = mBufferNodeQueueHead;
    mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;
    if (pBNode->mBufferStart != NULL) {
      delete[] pBNode->mBufferStart;
      delete pBNode;
    }
  }
  mBufferNodeQueueTail = NULL;
  mCurrBufferNode      = NULL;

  while (PendingAssignList != NULL) {
    pPNode = PendingAssignList;
    PendingAssignList = PendingAssignList->mNext;
    delete pPNode;
  }
  PendingAssignList = NULL;
}

SBufferNode *
CFormPkg::CreateNewNode (
  VOID
  )
{
  SBufferNode *Node;

  Node = new SBufferNode;
  if (Node == NULL) {
    return NULL;
  }

  Node->mBufferStart = new CHAR8[mBufferSize];
  if (Node->mBufferStart == NULL) {
    delete Node;
    return NULL;
  } else {
    memset (Node->mBufferStart, 0, mBufferSize);
    Node->mBufferEnd  = Node->mBufferStart + mBufferSize;
    Node->mBufferFree = Node->mBufferStart;
    Node->mNext       = NULL;
  }

  return Node;
}

CHAR8 *
CFormPkg::IfrBinBufferGet (
  IN UINT32 Len
  )
{
  CHAR8       *BinBuffer = NULL;
  SBufferNode *Node      = NULL;

  if ((Len == 0) || (Len > mBufferSize)) {
    return NULL;
  }

  if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {
    BinBuffer = mCurrBufferNode->mBufferFree;
    mCurrBufferNode->mBufferFree += Len;
  } else {
    Node = CreateNewNode ();
    if (Node == NULL) {
      return NULL;
    }

    if (mBufferNodeQueueTail == NULL) {
      mBufferNodeQueueHead = mBufferNodeQueueTail = Node;
    } else {
      mBufferNodeQueueTail->mNext = Node;
      mBufferNodeQueueTail = Node;
    }
    mCurrBufferNode = Node;

    //
    // Now try again.
    //
    BinBuffer = mCurrBufferNode->mBufferFree;
    mCurrBufferNode->mBufferFree += Len;
  }

  mPkgLength += Len;

  return BinBuffer;
}

inline
UINT32
CFormPkg::GetPkgLength (
  VOID
  )
{
  return mPkgLength;
}

VOID
CFormPkg::Open (
  VOID
  )
{
  mReadBufferNode   = mBufferNodeQueueHead;
  mReadBufferOffset = 0;
}

VOID
CFormPkg::Close (
  VOID
  )
{
  mReadBufferNode   = NULL;
  mReadBufferOffset = 0;
}

UINT32
CFormPkg::Read (
  IN CHAR8     *Buffer,
  IN UINT32    Size
  )
{
  UINT32       Index;

  if ((Size == 0) || (Buffer == NULL)) {
    return 0;
  }

  if (mReadBufferNode == NULL) {
    return 0;
  }

  for (Index = 0; Index < Size; Index++) {
    if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {
      Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];
    } else {
      if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {
        return Index;
      } else {
        mReadBufferOffset = 0;
        Index --;
      }
    }
  }

  return Size;
}

EFI_VFR_RETURN_CODE
CFormPkg::BuildPkgHdr (
  OUT EFI_HII_PACKAGE_HEADER **PkgHdr
  )
{
  if (PkgHdr == NULL) {
    return VFR_RETURN_FATAL_ERROR;
  }

  if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {
    return VFR_RETURN_OUT_FOR_RESOURCES;
  }

  (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;
  (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);

  return VFR_RETURN_SUCCESS;
}

EFI_VFR_RETURN_CODE
CFormPkg::BuildPkg (
  OUT PACKAGE_DATA &TBuffer
  )
{

  CHAR8  *Temp;
  UINT32 Size;
  CHAR8  Buffer[1024];

  if (TBuffer.Buffer != NULL) {
    delete TBuffer.Buffer;
  }

  TBuffer.Size = mPkgLength;
  TBuffer.Buffer = NULL;
  if (TBuffer.Size != 0) {
    TBuffer.Buffer = new CHAR8[TBuffer.Size];
  } else {
    return VFR_RETURN_SUCCESS;
  }

  Temp = TBuffer.Buffer;
  Open ();
  while ((Size = Read (Buffer, 1024)) != 0) {
    memcpy (Temp, Buffer, Size);
    Temp += Size;
  }
  Close ();
  return VFR_RETURN_SUCCESS;
}


EFI_VFR_RETURN_CODE
CFormPkg::BuildPkg (
  IN FILE  *Output,
  IN PACKAGE_DATA *PkgData
  )
{
  EFI_VFR_RETURN_CODE     Ret;
  CHAR8                   Buffer[1024];
  UINT32                  Size;
  EFI_HII_PACKAGE_HEADER  *PkgHdr;

  if (Output == NULL) {
    return VFR_RETURN_FATAL_ERROR;
  }

  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    return Ret;
  }
  fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);
  delete PkgHdr;

  if (PkgData == NULL) {
    Open ();
    while ((Size = Read (Buffer, 1024)) != 0) {
      fwrite (Buffer, Size, 1, Output);
    }
    Close ();
  } else {
    fwrite (PkgData->Buffer, PkgData->Size, 1, Output);
  }

  return VFR_RETURN_SUCCESS;
}

VOID
CFormPkg::_WRITE_PKG_LINE (
  IN FILE         *pFile,
  IN UINT32       LineBytes,
  IN CONST CHAR8  *LineHeader,
  IN CHAR8        *BlkBuf,
  IN UINT32       BlkSize
  )
{
  UINT32    Index;

  if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    return;
  }

  for (Index = 0; Index < BlkSize; Index++) {
    if ((Index % LineBytes) == 0) {
      fprintf (pFile, "\n%s", LineHeader);
    }
    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
  }
}

VOID
CFormPkg::_WRITE_PKG_END (
  IN FILE         *pFile,
  IN UINT32       LineBytes,
  IN CONST CHAR8  *LineHeader,
  IN CHAR8        *BlkBuf,
  IN UINT32       BlkSize
  )
{
  UINT32    Index;

  if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
    return;
  }

  for (Index = 0; Index < BlkSize - 1; Index++) {
    if ((Index % LineBytes) == 0) {
      fprintf (pFile, "\n%s", LineHeader);
    }
    fprintf (pFile, "0x%02X,  ", (UINT8)BlkBuf[Index]);
  }

  if ((Index % LineBytes) == 0) {
    fprintf (pFile, "\n%s", LineHeader);
  }
  fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
}

#define BYTES_PRE_LINE 0x10
UINT32   gAdjustOpcodeOffset = 0;
BOOLEAN  gNeedAdjustOpcode   = FALSE;
UINT32   gAdjustOpcodeLen    = 0;

EFI_VFR_RETURN_CODE
CFormPkg::GenCFile (
  IN CHAR8 *BaseName,
  IN FILE *pFile,
  IN PACKAGE_DATA *PkgData
  )
{
  EFI_VFR_RETURN_CODE          Ret;
  CHAR8                        Buffer[BYTES_PRE_LINE * 8];
  EFI_HII_PACKAGE_HEADER       *PkgHdr;
  UINT32                       PkgLength  = 0;
  UINT32                       ReadSize   = 0;

  if ((BaseName == NULL) || (pFile == NULL)) {
    return VFR_RETURN_FATAL_ERROR;
  }

  fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);

  if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {
    return Ret;
  }


  fprintf (pFile, "  // ARRAY LENGTH\n");
  PkgLength = PkgHdr->Length + sizeof (UINT32);
  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT32));

  fprintf (pFile, "\n\n  // PACKAGE HEADER\n");
  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));
  PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);

  fprintf (pFile, "\n\n  // PACKAGE DATA\n");

  if (PkgData == NULL) {
    Open ();
    while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {
      PkgLength += ReadSize;
      if (PkgLength < PkgHdr->Length) {
        _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
      } else {
        _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", Buffer, ReadSize);
      }
    }
    Close ();
  } else {
    if (PkgData->Size % BYTES_PRE_LINE != 0) {
      PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);
      _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer, PkgLength);
      _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);
    } else {
      PkgLength = PkgData->Size - BYTES_PRE_LINE;
      _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer, PkgLength);
      _WRITE_PKG_END (pFile, BYTES_PRE_LINE, "  ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);
    }
  }

  delete PkgHdr;
  fprintf (pFile, "\n};\n");

  return VFR_RETURN_SUCCESS;
}

EFI_VFR_RETURN_CODE
CFormPkg::AssignPending (
  IN CHAR8  *Key,
  IN VOID   *ValAddr,
  IN UINT32 ValLen,
  IN UINT32 LineNo,
  IN CONST CHAR8  *Msg
  )
{
  SPendingAssign *pNew;

  pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);
  if (pNew == NULL) {
    return VFR_RETURN_OUT_FOR_RESOURCES;
  }

  pNew->mNext       = PendingAssignList;
  PendingAssignList = pNew;
  return VFR_RETURN_SUCCESS;
}

VOID
CFormPkg::DoPendingAssign (
  IN CHAR8  *Key,
  IN VOID   *ValAddr,
  IN UINT32 ValLen
  )
{
  SPendingAssign *pNode;

  if ((Key == NULL) || (ValAddr == NULL)) {
    return;
  }

  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    if (strcmp (pNode->mKey, Key) == 0) {
      pNode->AssignValue (ValAddr, ValLen);
    }
  }
}

bool
CFormPkg::HavePendingUnassigned (
  VOID
  )
{
  SPendingAssign *pNode;

  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mFlag == PENDING) {
      return TRUE;
    }
  }

  return FALSE;
}

VOID
CFormPkg::PendingAssignPrintAll (
  VOID
  )
{
  SPendingAssign *pNode;

  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mFlag == PENDING) {
      gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);
    }
  }
}

SBufferNode *
CFormPkg::GetBinBufferNodeForAddr (
  IN CHAR8              *BinBuffAddr
  )
{
  SBufferNode *TmpNode;

  TmpNode = mBufferNodeQueueHead;

  while (TmpNode != NULL) {
    if (TmpNode->mBufferStart <= BinBuffAddr && TmpNode->mBufferFree >= BinBuffAddr) {
      return TmpNode;
    }

    TmpNode = TmpNode->mNext;
  }

  return NULL;
}

SBufferNode *
CFormPkg::GetNodeBefore(
  IN SBufferNode *CurrentNode
  )
{
  SBufferNode *FirstNode   = mBufferNodeQueueHead;
  SBufferNode *LastNode    = mBufferNodeQueueHead;

  while (FirstNode != NULL) {
    if (FirstNode == CurrentNode) {
      break;
    }

    LastNode    = FirstNode;
    FirstNode   = FirstNode->mNext;
  }

  if (FirstNode == NULL) {
    LastNode = NULL;
  }

  return LastNode;
}

EFI_VFR_RETURN_CODE
CFormPkg::InsertNodeBefore(
  IN SBufferNode *CurrentNode,
  IN SBufferNode *NewNode
  )
{
  SBufferNode *LastNode = GetNodeBefore (CurrentNode);

  if (LastNode == NULL) {
    return VFR_RETURN_MISMATCHED;
  }

  NewNode->mNext = LastNode->mNext;
  LastNode->mNext = NewNode;

  return VFR_RETURN_SUCCESS;
}

CHAR8 *
CFormPkg::GetBufAddrBaseOnOffset (
  IN UINT32      Offset
  )
{
  SBufferNode *TmpNode;
  UINT32      TotalBufLen;
  UINT32      CurrentBufLen;

  TotalBufLen = 0;

  for (TmpNode = mBufferNodeQueueHead; TmpNode != NULL; TmpNode = TmpNode->mNext) {
    CurrentBufLen = TmpNode->mBufferFree - TmpNode->mBufferStart;
    if (Offset >= TotalBufLen && Offset < TotalBufLen + CurrentBufLen) {
      return TmpNode->mBufferStart + (Offset - TotalBufLen);
    }

    TotalBufLen += CurrentBufLen;
  }

  return NULL;
}

EFI_VFR_RETURN_CODE
CFormPkg::AdjustDynamicInsertOpcode (
  IN CHAR8              *InserPositionAddr,
  IN CHAR8              *InsertOpcodeAddr,
  IN BOOLEAN            CreateOpcodeAfterParsingVfr
  )
{
  SBufferNode *InserPositionNode;
  SBufferNode *InsertOpcodeNode;
  SBufferNode *NewRestoreNodeBegin;
  SBufferNode *NewRestoreNodeEnd;
  SBufferNode *NewLastEndNode;
  SBufferNode *TmpNode;
  UINT32      NeedRestoreCodeLen;

  NewRestoreNodeEnd = NULL;

  InserPositionNode  = GetBinBufferNodeForAddr(InserPositionAddr);
  InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);
  assert (InserPositionNode != NULL);
  assert (InsertOpcodeNode  != NULL);

  if (InserPositionNode == InsertOpcodeNode) {
    //
    // Create New Node to save the restore opcode.
    //
    NeedRestoreCodeLen = InsertOpcodeAddr - InserPositionAddr;
    gAdjustOpcodeLen   = NeedRestoreCodeLen;
    NewRestoreNodeBegin = CreateNewNode ();
    if (NewRestoreNodeBegin == NULL) {
      return VFR_RETURN_OUT_FOR_RESOURCES;
    }
    memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;

    //
    // Override the restore buffer data.
    //
    memmove (InserPositionAddr, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
    InsertOpcodeNode->mBufferFree -= NeedRestoreCodeLen;
    memset (InsertOpcodeNode->mBufferFree, 0, NeedRestoreCodeLen);
  } else {
    //
    // Create New Node to save the restore opcode.
    //
    NeedRestoreCodeLen = InserPositionNode->mBufferFree - InserPositionAddr;
    gAdjustOpcodeLen   = NeedRestoreCodeLen;
    NewRestoreNodeBegin = CreateNewNode ();
    if (NewRestoreNodeBegin == NULL) {
      return VFR_RETURN_OUT_FOR_RESOURCES;
    }
    memcpy (NewRestoreNodeBegin->mBufferFree, InserPositionAddr, NeedRestoreCodeLen);
    NewRestoreNodeBegin->mBufferFree += NeedRestoreCodeLen;
    //
    // Override the restore buffer data.
    //
    InserPositionNode->mBufferFree -= NeedRestoreCodeLen;
    //
    // Link the restore data to new node.
    //
    NewRestoreNodeBegin->mNext = InserPositionNode->mNext;

    //
    // Count the Adjust opcode len.
    //
    TmpNode = InserPositionNode->mNext;
    while (TmpNode != InsertOpcodeNode) {
      gAdjustOpcodeLen += TmpNode->mBufferFree - TmpNode->mBufferStart;
      TmpNode = TmpNode->mNext;
    }

    //
    // Create New Node to save the last node of restore opcode.
    //
    NeedRestoreCodeLen = InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;
    gAdjustOpcodeLen  += NeedRestoreCodeLen;
    if (NeedRestoreCodeLen > 0) {
      NewRestoreNodeEnd = CreateNewNode ();
      if (NewRestoreNodeEnd == NULL) {
        return VFR_RETURN_OUT_FOR_RESOURCES;
      }
      memcpy (NewRestoreNodeEnd->mBufferFree, InsertOpcodeNode->mBufferStart, NeedRestoreCodeLen);
      NewRestoreNodeEnd->mBufferFree += NeedRestoreCodeLen;
      //
      // Override the restore buffer data.
      //
      memmove (InsertOpcodeNode->mBufferStart, InsertOpcodeAddr, InsertOpcodeNode->mBufferFree - InsertOpcodeAddr);
      InsertOpcodeNode->mBufferFree -= InsertOpcodeAddr - InsertOpcodeNode->mBufferStart;

      //
      // Insert the last restore data node.
      //
      TmpNode = GetNodeBefore (InsertOpcodeNode);
      assert (TmpNode != NULL);

      if (TmpNode == InserPositionNode) {
        NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;
      } else {
        TmpNode->mNext = NewRestoreNodeEnd;
      }
      //
      // Connect the dynamic opcode node to the node after InserPositionNode.
      //
      InserPositionNode->mNext = InsertOpcodeNode;
    }
  }

  if (CreateOpcodeAfterParsingVfr) {
    //
    // Th new opcodes were created after Parsing Vfr file,
    // so the content in mBufferNodeQueueTail must be the new created opcodes.
    // So connet the  NewRestoreNodeBegin to the tail and update the tail node.
    //
    mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
    if (NewRestoreNodeEnd != NULL) {
      mBufferNodeQueueTail = NewRestoreNodeEnd;
    } else {
      mBufferNodeQueueTail = NewRestoreNodeBegin;
    }
  } else {
    if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart > 2) {
      //
      // End form set opcode all in the mBufferNodeQueueTail node.
      //
      NewLastEndNode = CreateNewNode ();
      if (NewLastEndNode == NULL) {
        return VFR_RETURN_OUT_FOR_RESOURCES;
      }
      NewLastEndNode->mBufferStart[0] = 0x29;
      NewLastEndNode->mBufferStart[1] = 0x02;
      NewLastEndNode->mBufferFree += 2;

      mBufferNodeQueueTail->mBufferFree -= 2;

      mBufferNodeQueueTail->mNext = NewRestoreNodeBegin;
      if (NewRestoreNodeEnd != NULL) {
        NewRestoreNodeEnd->mNext = NewLastEndNode;
      } else {
        NewRestoreNodeBegin->mNext = NewLastEndNode;
      }

      mBufferNodeQueueTail = NewLastEndNode;
    } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {
      TmpNode = GetNodeBefore(mBufferNodeQueueTail);
      assert (TmpNode != NULL);

      TmpNode->mNext = NewRestoreNodeBegin;
      if (NewRestoreNodeEnd != NULL) {
        NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;
      } else {
        NewRestoreNodeBegin->mNext = mBufferNodeQueueTail;
      }
    }
  }
  mCurrBufferNode = mBufferNodeQueueTail;
  return VFR_RETURN_SUCCESS;
}

EFI_VFR_RETURN_CODE
CFormPkg::DeclarePendingQuestion (
  IN CVfrVarDataTypeDB   &lCVfrVarDataTypeDB,
  IN CVfrDataStorage     &lCVfrDataStorage,
  IN CVfrQuestionDB      &lCVfrQuestionDB,
  IN EFI_GUID            *LocalFormSetGuid,
  IN UINT32              LineNo,
  OUT CHAR8              **InsertOpcodeAddr
  )
{
  SPendingAssign *pNode;
  CHAR8          *VarStr;
  UINT32         ArrayIdx;
  CHAR8          FName[MAX_NAME_LEN];
  CHAR8          *SName;
  CHAR8          *NewStr;
  UINT32         ShrinkSize = 0;
  EFI_VFR_RETURN_CODE  ReturnCode;
  EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;
  UINT8    LFlags;
  UINT32   MaxValue;
  CIfrGuid *GuidObj = NULL;

  //
  // Declare all questions as Numeric in DisableIf True
  //
  // DisableIf
  CIfrDisableIf DIObj;
  DIObj.SetLineNo (LineNo);
  *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();

  //TrueOpcode
  CIfrTrue TObj (LineNo);

  // Declare Numeric qeustion for each undefined question.
  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mFlag == PENDING) {
      EFI_VARSTORE_INFO Info;
      EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;
      //
      // Register this question, assume it is normal question, not date or time question
      //
      VarStr = pNode->mKey;
      ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);
      if (ReturnCode != VFR_RETURN_SUCCESS) {
        gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
        return ReturnCode;
      }

#ifdef VFREXP_DEBUG
      printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);
#endif
      //
      // Get Question Info, framework vfr VarName == StructName
      //
      ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrayIdx (VarStr, FName, ArrayIdx);
      if (ReturnCode != VFR_RETURN_SUCCESS) {
        gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");
        return ReturnCode;
      }
      //
      // Get VarStoreType
      //
      ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);
      if (ReturnCode != VFR_RETURN_SUCCESS) {
        gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");
        return ReturnCode;
      }
      VarStoreType = lCVfrDataStorage.GetVarStoreType (Info.mVarStoreId);

      if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {
        ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);
      } else {
        if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
          ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);
        } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {
          VarStr = pNode->mKey;
          //convert VarStr with store name to VarStr with structure name
          ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);
          if (ReturnCode == VFR_RETURN_SUCCESS) {
            NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];
            NewStr[0] = '\0';
            strcpy (NewStr, SName);
            strcat (NewStr, VarStr + strlen (FName));
            ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);
            delete[] NewStr;
          }
        } else {
          ReturnCode = VFR_RETURN_UNSUPPORTED;
        }
      }
      if (ReturnCode != VFR_RETURN_SUCCESS) {
        gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
        return ReturnCode;
      }
      //
      // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.
      //
      if (Info.mIsBitVar) {
        GuidObj = new CIfrGuid(0);
        GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);
        GuidObj->SetLineNo(LineNo);
      }

      CIfrNumeric CNObj;
      CNObj.SetLineNo (LineNo);
      CNObj.SetPrompt (0x0);
      CNObj.SetHelp (0x0);
      CNObj.SetQuestionId (QId);
      CNObj.SetVarStoreInfo (&Info);

      //
      // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.
      //
      if (Info.mIsBitVar) {
        MaxValue = (1 << Info.mVarTotalSize) -1;
        CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);
        ShrinkSize = 12;
        LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);
        CNObj.SetFlagsForBitField (0, LFlags);
      } else {
        //
        // Numeric doesn't support BOOLEAN data type.
        // BOOLEAN type has the same data size to UINT8.
        //
        if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {
          Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
        }
        CNObj.SetFlags (0, Info.mVarType);
        //
        // Use maximum value not to limit the valid value for the undefined question.
        //
        switch (Info.mVarType) {
        case EFI_IFR_TYPE_NUM_SIZE_64:
          CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);
          ShrinkSize = 0;
          break;
        case EFI_IFR_TYPE_NUM_SIZE_32:
          CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);
          ShrinkSize = 12;
          break;
        case EFI_IFR_TYPE_NUM_SIZE_16:
          CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);
          ShrinkSize = 18;
          break;
        case EFI_IFR_TYPE_NUM_SIZE_8:
          CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);
          ShrinkSize = 21;
          break;
        default:
          break;
        }
      }
      CNObj.ShrinkBinSize (ShrinkSize);

      //
      // For undefined Efi VarStore type question
      // Append the extended guided opcode to contain VarName
      //
      if (VarStoreType == EFI_VFR_VARSTORE_EFI) {
        CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);
        CVNObj.SetLineNo (LineNo);
      }

      //
      // End for Numeric
      //
      CIfrEnd CEObj;
      CEObj.SetLineNo (LineNo);
      //
      // End for Guided opcode
      //
      if (GuidObj != NULL) {
        CIfrEnd CEObjGuid;
        CEObjGuid.SetLineNo (LineNo);
        GuidObj->SetScope(1);
        delete GuidObj;
        GuidObj = NULL;
      }
    }
  }

  //
  // End for DisableIf
  //
  CIfrEnd SEObj;
  SEObj.SetLineNo (LineNo);

  return VFR_RETURN_SUCCESS;
}

CFormPkg gCFormPkg;

SIfrRecord::SIfrRecord (
  VOID
  )
{
  mIfrBinBuf = NULL;
  mBinBufLen = 0;
  mLineNo    = 0xFFFFFFFF;
  mOffset    = 0xFFFFFFFF;
  mNext      = NULL;
}

SIfrRecord::~SIfrRecord (
  VOID
  )
{
  if (mIfrBinBuf != NULL) {
    //delete mIfrBinBuf;
    mIfrBinBuf = NULL;
  }
  mLineNo      = 0xFFFFFFFF;
  mOffset      = 0xFFFFFFFF;
  mBinBufLen   = 0;
  mNext        = NULL;
}

CIfrRecordInfoDB::CIfrRecordInfoDB (
  VOID
  )
{
  mSwitch            = TRUE;
  mRecordCount       = EFI_IFR_RECORDINFO_IDX_START;
  mIfrRecordListHead = NULL;
  mIfrRecordListTail = NULL;
  mAllDefaultTypeCount = 0;
  for (UINT8 i = 0; i < EFI_HII_MAX_SUPPORT_DEFAULT_TYPE; i++) {
    mAllDefaultIdArray[i] = 0xffff;
  }
}

CIfrRecordInfoDB::~CIfrRecordInfoDB (
  VOID
  )
{
  SIfrRecord *pNode;

  while (mIfrRecordListHead != NULL) {
    pNode = mIfrRecordListHead;
    mIfrRecordListHead = mIfrRecordListHead->mNext;
    delete pNode;
  }
}

SIfrRecord *
CIfrRecordInfoDB::GetRecordInfoFromIdx (
  IN UINT32 RecordIdx
  )
{
  UINT32     Idx;
  SIfrRecord *pNode = NULL;

  if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {
    return NULL;
  }

  for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;
       (Idx != RecordIdx) && (pNode != NULL);
       Idx++, pNode = pNode->mNext)
  ;

  return pNode;
}

UINT32
CIfrRecordInfoDB::IfrRecordRegister (
  IN UINT32 LineNo,
  IN CHAR8  *IfrBinBuf,
  IN UINT8  BinBufLen,
  IN UINT32 Offset
  )
{
  SIfrRecord *pNew;

  if (mSwitch == FALSE) {
    return EFI_IFR_RECORDINFO_IDX_INVALUD;
  }

  if ((pNew = new SIfrRecord) == NULL) {
    return EFI_IFR_RECORDINFO_IDX_INVALUD;
  }

  if (mIfrRecordListHead == NULL) {
    mIfrRecordListHead = pNew;
    mIfrRecordListTail = pNew;
  } else {
    mIfrRecordListTail->mNext = pNew;
    mIfrRecordListTail = pNew;
  }
  mRecordCount++;

  return mRecordCount;
}

VOID
CIfrRecordInfoDB::IfrRecordInfoUpdate (
  IN UINT32 RecordIdx,
  IN UINT32 LineNo,
  IN CHAR8  *BinBuf,
  IN UINT8  BinBufLen,
  IN UINT32 Offset
  )
{
  SIfrRecord *pNode;
  SIfrRecord *Prev;

  if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {
    return;
  }

  if (LineNo == 0) {
    //
    // Line number is not specified explicitly, try to use line number of previous opcode
    //
    Prev = GetRecordInfoFromIdx (RecordIdx - 1);
    if (Prev != NULL) {
      LineNo = Prev->mLineNo;
    }
  }

  pNode->mLineNo    = LineNo;
  pNode->mOffset    = Offset;
  pNode->mBinBufLen = BinBufLen;
  pNode->mIfrBinBuf = BinBuf;

}

VOID
CIfrRecordInfoDB::IfrRecordOutput (
  OUT PACKAGE_DATA &TBuffer
  )
{
  CHAR8      *Temp;
  SIfrRecord *pNode;

  if (TBuffer.Buffer != NULL) {
    delete[] TBuffer.Buffer;
  }

  TBuffer.Size = 0;
  TBuffer.Buffer = NULL;


  if (mSwitch == FALSE) {
    return;
  }

  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    TBuffer.Size += pNode->mBinBufLen;
  }

  if (TBuffer.Size != 0) {
    TBuffer.Buffer = new CHAR8[TBuffer.Size];
  } else {
    return;
  }

  Temp = TBuffer.Buffer;

  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mIfrBinBuf != NULL) {
      memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);
      Temp += pNode->mBinBufLen;
    }
  }

  return;
}

VOID
CIfrRecordInfoDB::IfrRecordOutput (
  IN FILE   *File,
  IN UINT32 LineNo
  )
{
  SIfrRecord *pNode;
  UINT8      Index;
  UINT32     TotalSize;

  if (mSwitch == FALSE) {
    return;
  }

  if (File == NULL) {
    return;
  }

  TotalSize = 0;

  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mLineNo == LineNo || LineNo == 0) {
      fprintf (File, ">%08X: ", pNode->mOffset);
      TotalSize += pNode->mBinBufLen;
      if (pNode->mIfrBinBuf != NULL) {
        for (Index = 0; Index < pNode->mBinBufLen; Index++) {
          fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));
        }
      }
      fprintf (File, "\n");
    }
  }

  if (LineNo == 0) {
    fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);
  }
}

//
// for framework vfr file
// adjust opcode sequence for uefi IFR format
// adjust inconsistent and varstore into the right position.
//
BOOLEAN
CIfrRecordInfoDB::CheckQuestionOpCode (
  IN UINT8 OpCode
  )
{
  switch (OpCode) {
  case EFI_IFR_CHECKBOX_OP:
  case EFI_IFR_NUMERIC_OP:
  case EFI_IFR_PASSWORD_OP:
  case EFI_IFR_ONE_OF_OP:
  case EFI_IFR_ACTION_OP:
  case EFI_IFR_STRING_OP:
  case EFI_IFR_DATE_OP:
  case EFI_IFR_TIME_OP:
  case EFI_IFR_ORDERED_LIST_OP:
  case EFI_IFR_REF_OP:
    return TRUE;
  default:
    return FALSE;
  }
}

BOOLEAN
CIfrRecordInfoDB::CheckIdOpCode (
  IN UINT8 OpCode
  )
{
  switch (OpCode) {
  case EFI_IFR_EQ_ID_VAL_OP:
  case EFI_IFR_EQ_ID_ID_OP:
  case EFI_IFR_EQ_ID_VAL_LIST_OP:
  case EFI_IFR_QUESTION_REF1_OP:
    return TRUE;
  default:
    return FALSE;
  }
}

EFI_QUESTION_ID
CIfrRecordInfoDB::GetOpcodeQuestionId (
  IN EFI_IFR_OP_HEADER *OpHead
  )
{
  EFI_IFR_QUESTION_HEADER *QuestionHead;

  QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);

  return QuestionHead->QuestionId;
}

SIfrRecord *
CIfrRecordInfoDB::GetRecordInfoFromOffset (
  IN UINT32 Offset
  )
{
  SIfrRecord *pNode = NULL;

  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mOffset == Offset) {
      return pNode;
    }
  }

  return pNode;
}

/**
  Add just the op code position.

  Case1 (CreateOpcodeAfterParsingVfr == FALSE): The dynamic opcodes were created before the formset opcode,
  so pDynamicOpcodeNodes is before mIfrRecordListTail.

  From

  |mIfrRecordListHead + ...+ pAdjustNode + pDynamicOpcodeNodes + mIfrRecordListTail|

  To

  |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode + mIfrRecordListTail|

  Case2 (CreateOpcodeAfterParsingVfr == TRUE): The dynamic opcodes were created after paring the vfr file,
  so new records are appennded to the end of OriginalIfrRecordListTail.

  From

  |mIfrRecordListHead + ...+ pAdjustNode +  ... + OriginalIfrRecordListTail + pDynamicOpcodeNodes|

  To

  |mIfrRecordListHead + ...+ pDynamicOpcodeNodes + pAdjustNode +  ... + OriginalIfrRecordListTail|


  @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.

**/
BOOLEAN
CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
  IN BOOLEAN  CreateOpcodeAfterParsingVfr
  )
{
  UINT32             OpcodeOffset;
  SIfrRecord         *pNode, *pPreNode;
  SIfrRecord         *pAdjustNode, *pNodeBeforeAdjust;
  SIfrRecord         *pNodeBeforeDynamic;

  pPreNode            = NULL;
  pAdjustNode         = NULL;
  pNodeBeforeDynamic  = NULL;
  OpcodeOffset        = 0;

  //
  // Base on the gAdjustOpcodeOffset and gAdjustOpcodeLen to find the pAdjustNod, the node before pAdjustNode,
  // and the node before pDynamicOpcodeNode.
  //
  for (pNode = mIfrRecordListHead; pNode!= NULL; pNode = pNode->mNext) {
    if (OpcodeOffset == gAdjustOpcodeOffset) {
      pAdjustNode       = pNode;
      pNodeBeforeAdjust = pPreNode;
    } else if (OpcodeOffset == gAdjustOpcodeOffset + gAdjustOpcodeLen) {
      pNodeBeforeDynamic = pPreNode;
    }
    if (pNode->mNext != NULL) {
      pPreNode = pNode;
    }
    OpcodeOffset += pNode->mBinBufLen;
  }

  //
  // Check the nodes whether exist.
  //
  if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {
    return FALSE;
  }

  //
  // Adjust the node. pPreNode save the Node before mIfrRecordListTail
  //
  pNodeBeforeAdjust->mNext = pNodeBeforeDynamic->mNext;
  if (CreateOpcodeAfterParsingVfr) {
    //
    // mIfrRecordListTail is the end of pDynamicNode (Case2).
    //
    mIfrRecordListTail->mNext = pAdjustNode;
    mIfrRecordListTail = pNodeBeforeDynamic;
    mIfrRecordListTail->mNext = NULL;
  } else {
    //
    //pPreNode is the end of pDynamicNode(Case1).
    //
    pPreNode->mNext = pAdjustNode;
    pNodeBeforeDynamic->mNext = mIfrRecordListTail;
  }

  return TRUE;
}

/**
  Update the record info(the position in the record list, offset and mIfrBinBuf) for new created record.

  @param CreateOpcodeAfterParsingVfr     Whether create the dynamic opcode after parsing the VFR file.

**/
VOID
CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
  IN BOOLEAN  CreateOpcodeAfterParsingVfr
  )
{
  SIfrRecord          *pRecord;

  //
  // Base on the original offset info to update the record list.
  //
  if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {
    gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");
  }

  //
  // Base on the opcode binary length to recalculate the offset for each opcode.
  //
  IfrAdjustOffsetForRecord();

  //
  // Base on the offset to find the binary address.
  //
  pRecord = GetRecordInfoFromOffset(gAdjustOpcodeOffset);
  while (pRecord != NULL) {
    pRecord->mIfrBinBuf = gCFormPkg.GetBufAddrBaseOnOffset(pRecord->mOffset);
    pRecord = pRecord->mNext;
  }
}


VOID
CIfrRecordInfoDB::IfrAdjustOffsetForRecord (
  VOID
  )
{
  UINT32             OpcodeOffset;
  SIfrRecord         *pNode;

  OpcodeOffset = 0;
  for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {
    pNode->mOffset = OpcodeOffset;
    OpcodeOffset += pNode->mBinBufLen;
  }
}

EFI_VFR_RETURN_CODE
CIfrRecordInfoDB::IfrRecordAdjust (
  VOID
  )
{
  SIfrRecord *pNode, *preNode;
  SIfrRecord *uNode, *tNode;
  EFI_IFR_OP_HEADER  *OpHead, *tOpHead;
  EFI_QUESTION_ID    QuestionId;
  UINT32             StackCount;
  UINT32             QuestionScope;
  CHAR8              ErrorMsg[MAX_STRING_LEN] = {0, };
  EFI_VFR_RETURN_CODE  Status;

  //
  // Init local variable
  //
  Status = VFR_RETURN_SUCCESS;
  pNode = mIfrRecordListHead;
  preNode = pNode;
  QuestionScope = 0;
  while (pNode != NULL) {
    OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;

    //
    // make sure the inconsistent opcode in question scope
    //
    if (QuestionScope > 0) {
      QuestionScope += OpHead->Scope;
      if (OpHead->OpCode == EFI_IFR_END_OP) {
        QuestionScope --;
      }
    }

    if (CheckQuestionOpCode (OpHead->OpCode)) {
      QuestionScope = 1;
    }
    //
    // for the inconsistent opcode not in question scope, adjust it
    //
    if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {
      //
      // for inconsistent opcode not in question scope
      //

      //
      // Count inconsistent opcode Scope
      //
      StackCount = OpHead->Scope;
      QuestionId = EFI_QUESTION_ID_INVALID;
      tNode = pNode;
      while (tNode != NULL && StackCount > 0) {
        tNode = tNode->mNext;
        tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;
        //
        // Calculate Scope Number
        //
        StackCount += tOpHead->Scope;
        if (tOpHead->OpCode == EFI_IFR_END_OP) {
          StackCount --;
        }
        //
        // by IdEqual opcode to get QuestionId
        //
        if (QuestionId == EFI_QUESTION_ID_INVALID &&
            CheckIdOpCode (tOpHead->OpCode)) {
          QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);
        }
      }
      if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {
        //
        // report error; not found
        //
        sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);
        gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
        Status = VFR_RETURN_MISMATCHED;
        break;
      }
      //
      // extract inconsistent opcode list
      // pNode is Inconsistent opcode, tNode is End Opcode
      //

      //
      // insert inconsistent opcode list into the right question scope by questionid
      //
      for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {
        tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;
        if (CheckQuestionOpCode (tOpHead->OpCode) &&
            (QuestionId == GetOpcodeQuestionId (tOpHead))) {
          break;
        }
      }
      //
      // insert inconsistent opcode list and check LATE_CHECK flag
      //
      if (uNode != NULL) {
        if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {
          //
          // if LATE_CHECK flag is set, change inconsistent to nosumbit
          //
          OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;
        }

        //
        // skip the default storage for Date and Time
        //
        if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {
          uNode = uNode->mNext;
        }

        preNode->mNext = tNode->mNext;
        tNode->mNext = uNode->mNext;
        uNode->mNext = pNode;
        //
        // reset pNode to head list, scan the whole list again.
        //
        pNode = mIfrRecordListHead;
        preNode = pNode;
        QuestionScope = 0;
        continue;
      } else {
        //
        // not found matched question id, report error
        //
        sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);
        gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);
        Status = VFR_RETURN_MISMATCHED;
        break;
      }
    } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP ||
               OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {
      //
      // for new added group of varstore opcode
      //
      tNode = pNode;
      while (tNode->mNext != NULL) {
        tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;
        if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP &&
            tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {
          break;
        }
        tNode = tNode->mNext;
      }

      if (tNode->mNext == NULL) {
        //
        // invalid IfrCode, IfrCode end by EndOpCode
        //
        gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");
        Status = VFR_RETURN_MISMATCHED;
        break;
      }

      if (tOpHead->OpCode != EFI_IFR_END_OP) {
          //
          // not new added varstore, which are not needed to be adjust.
          //
          preNode = tNode;
          pNode   = tNode->mNext;
          continue;
      } else {
        //
        // move new added varstore opcode to the position befor form opcode
        // varstore opcode between pNode and tNode
        //

        //
        // search form opcode from begin
        //
        for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {
          tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;
          if (tOpHead->OpCode == EFI_IFR_FORM_OP) {
            break;
          }
        }
        //
        // Insert varstore opcode beform form opcode if form opcode is found
        //
        if (uNode->mNext != NULL) {
          preNode->mNext = tNode->mNext;
          tNode->mNext = uNode->mNext;
          uNode->mNext = pNode;
          //
          // reset pNode to head list, scan the whole list again.
          //
          pNode = mIfrRecordListHead;
          preNode = pNode;
          QuestionScope = 0;
          continue;
        } else {
          //
          // not found form, continue scan IfrRecord list
          //
          preNode = tNode;
          pNode   = tNode->mNext;
          continue;
        }
      }
    }
    //
    // next node
    //
    preNode = pNode;
    pNode = pNode->mNext;
  }

  //
  // Update Ifr Opcode Offset
  //
  if (Status == VFR_RETURN_SUCCESS) {
    IfrAdjustOffsetForRecord ();
  }
  return Status;
}

/**
  When the Varstore of the question is EFI_VFR_VARSTORE_BUFFER and the default value is not
  given by expression, should save the default info for the Buffer VarStore.

  @param  DefaultId           The default id.
  @param  pQuestionNode       Point to the question opcode node.
  @param  Value               The default value.
**/
VOID
CIfrRecordInfoDB::IfrAddDefaultToBufferConfig (
  IN  UINT16                  DefaultId,
  IN  SIfrRecord              *pQuestionNode,
  IN  EFI_IFR_TYPE_VALUE      Value
  )
{
  CHAR8                   *VarStoreName = NULL;
  EFI_VFR_VARSTORE_TYPE    VarStoreType  = EFI_VFR_VARSTORE_INVALID;
  EFI_GUID                 *VarGuid      = NULL;
  EFI_VARSTORE_INFO        VarInfo;
  EFI_IFR_QUESTION_HEADER  *QuestionHead;
  EFI_IFR_OP_HEADER        *pQuestionOpHead;

  pQuestionOpHead = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
  QuestionHead    = (EFI_IFR_QUESTION_HEADER *) (pQuestionOpHead + 1);

  //
  // Get the Var Store name and type.
  //
  gCVfrDataStorage.GetVarStoreName (QuestionHead->VarStoreId, &VarStoreName);
  VarGuid= gCVfrDataStorage.GetVarStoreGuid (QuestionHead->VarStoreId);
  VarStoreType = gCVfrDataStorage.GetVarStoreType (QuestionHead->VarStoreId);

  //
  // Only for Buffer storage need to save the default info in the storage.
  // Other type storage, just return.
  //
  if (VarStoreType != EFI_VFR_VARSTORE_BUFFER) {
    return;
  } else {
    VarInfo.mInfo.mVarOffset = QuestionHead->VarStoreInfo.VarOffset;
    VarInfo.mVarStoreId = QuestionHead->VarStoreId;
  }

  //
  // Get the buffer storage info about this question.
  //
  gCVfrDataStorage.GetBufferVarStoreFieldInfo (&VarInfo);

  //
  // Add action.
  //
  gCVfrDefaultStore.BufferVarStoreAltConfigAdd (
    DefaultId,
    VarInfo,
    VarStoreName,
    VarGuid,
    VarInfo.mVarType,
    Value
    );
}

/**
  Record the number and default id of all defaultstore opcode.

**/
VOID
CIfrRecordInfoDB::IfrGetDefaultStoreInfo (
  VOID
  )
{
  SIfrRecord             *pNode;
  EFI_IFR_OP_HEADER      *pOpHead;
  EFI_IFR_DEFAULTSTORE   *DefaultStore;

  pNode                = mIfrRecordListHead;
  mAllDefaultTypeCount = 0;

  while (pNode != NULL) {
    pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;

    if (pOpHead->OpCode == EFI_IFR_DEFAULTSTORE_OP){
      DefaultStore = (EFI_IFR_DEFAULTSTORE *) pNode->mIfrBinBuf;
      mAllDefaultIdArray[mAllDefaultTypeCount++] = DefaultStore->DefaultId;
    }
    pNode = pNode->mNext;
  }
}

/**
  Create new default opcode record.

  @param    Size            The new default opcode size.
  @param    DefaultId       The new default id.
  @param    Type            The new default type.
  @param    LineNo          The line number of the new record.
  @param    Value           The new default value.

**/
VOID
CIfrRecordInfoDB::IfrCreateDefaultRecord(
  IN UINT8               Size,
  IN UINT16              DefaultId,
  IN UINT8               Type,
  IN UINT32              LineNo,
  IN EFI_IFR_TYPE_VALUE  Value
  )
{
  CIfrDefault   *DObj;
  CIfrDefault2  *DObj2;

  DObj  = NULL;
  DObj2 = NULL;

  if (Type == EFI_IFR_TYPE_OTHER) {
    DObj2 = new CIfrDefault2 (Size);
    DObj2->SetDefaultId(DefaultId);
    DObj2->SetType(Type);
    DObj2->SetLineNo(LineNo);
    DObj2->SetScope (1);
    delete DObj2;
  } else {
    DObj = new CIfrDefault (Size);
    DObj->SetDefaultId(DefaultId);
    DObj->SetType(Type);
    DObj->SetLineNo(LineNo);
    DObj->SetValue (Value);
    delete DObj;
  }
}

/**
  Create new default opcode for question base on the QuestionDefaultInfo.

  @param  pQuestionNode              Point to the question opcode Node.
  @param  QuestionDefaultInfo        Point to the QuestionDefaultInfo for current question.

**/
VOID
CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
  IN  SIfrRecord              *pQuestionNode,
  IN  QuestionDefaultRecord   *QuestionDefaultInfo
  )
{
  EFI_IFR_OP_HEADER      *pOpHead;
  EFI_IFR_DEFAULT        *Default;
  SIfrRecord             *pSNode;
  SIfrRecord             *pENode;
  SIfrRecord             *pDefaultNode;
  CIfrObj                *Obj;
  CHAR8                  *ObjBinBuf;
  UINT8                  ScopeCount;
  UINT8                  OpcodeNumber;
  UINT8                  OpcodeCount;
  UINT8                  DefaultSize;
  EFI_IFR_ONE_OF_OPTION  *DefaultOptionOpcode;
  EFI_IFR_TYPE_VALUE     CheckBoxDefaultValue;

  CheckBoxDefaultValue.b = 1;
  pOpHead                = (EFI_IFR_OP_HEADER *) pQuestionNode->mIfrBinBuf;
  ScopeCount             = 0;
  OpcodeCount            = 0;
  Obj                    = NULL;

  //
  // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
  //
  gAdjustOpcodeOffset = pQuestionNode->mNext->mOffset;
  //
  // Case 1:
  // For oneof, the default with smallest default id is given by the option flag.
  // So create the missing defaults base on the oneof option value(mDefaultValueRecord).
  //
  if (pOpHead->OpCode == EFI_IFR_ONE_OF_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
    DefaultOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)QuestionDefaultInfo->mDefaultValueRecord->mIfrBinBuf;
    DefaultSize = QuestionDefaultInfo->mDefaultValueRecord->mBinBufLen - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value);
    DefaultSize += OFFSET_OF (EFI_IFR_DEFAULT, Value);
    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
        IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], DefaultOptionOpcode->Type, pQuestionNode->mLineNo, DefaultOptionOpcode->Value);
        //
        // Save the new created default in the buffer storage.
        //
        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, DefaultOptionOpcode->Value);
      }
    }
    return;
  }

  //
  // Case2:
  // For checkbox, the default with smallest default id is given by the question flag.
  // And create the missing defaults with true value.
  //
  if (pOpHead-> OpCode == EFI_IFR_CHECKBOX_OP && !QuestionDefaultInfo->mIsDefaultOpcode) {
    DefaultSize = OFFSET_OF (EFI_IFR_DEFAULT, Value) + sizeof (BOOLEAN);
    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
        IfrCreateDefaultRecord (DefaultSize, mAllDefaultIdArray[i], EFI_IFR_TYPE_BOOLEAN, pQuestionNode->mLineNo, CheckBoxDefaultValue);
        //
        // Save the new created default.
        //
        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, CheckBoxDefaultValue);
      }
    }
    return;
  }

  //
  // Case3:
  // The default with smallest default id is given by the default opcode.
  // So create the missing defaults base on the value in the default opcode.
  //

  //
  // pDefaultNode point to the mDefaultValueRecord in QuestionDefaultInfo.
  //
  pDefaultNode = QuestionDefaultInfo->mDefaultValueRecord;
  Default = (EFI_IFR_DEFAULT *)pDefaultNode->mIfrBinBuf;
  //
  // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
  //
  gAdjustOpcodeOffset = pDefaultNode->mNext->mOffset;

  if (Default->Type == EFI_IFR_TYPE_OTHER) {
    //
    // EFI_IFR_DEFAULT_2 opcode.
    //
    // Point to the first expression opcode.
    //
    pSNode = pDefaultNode->mNext;
    pENode = NULL;
    ScopeCount++;
    //
    // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)
    //
    while (pSNode != NULL && pSNode->mNext != NULL && ScopeCount != 0) {
      pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
      if (pOpHead->Scope == 1) {
        ScopeCount++;
      }
      if (pOpHead->OpCode == EFI_IFR_END_OP) {
        ScopeCount--;
      }
      pENode = pSNode;
      pSNode = pSNode->mNext;
      OpcodeCount++;
    }

    assert (pSNode);
    assert (pENode);

    //
    // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.
    //
    gAdjustOpcodeOffset = pSNode->mOffset;
    //
    // Create new default opcode node for missing default.
    //
    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
      OpcodeNumber = OpcodeCount;
      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
        IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pENode->mLineNo, Default->Value);
        //
        // Point to the first expression opcode node.
        //
        pSNode = pDefaultNode->mNext;
        //
        // Create the expression opcode and end opcode for the new created EFI_IFR_DEFAULT_2 opcode.
        //
        while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {
          pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
          Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);
          assert (Obj != NULL);
          Obj->SetLineNo (pSNode->mLineNo);
          ObjBinBuf = Obj->GetObjBinAddr<CHAR8>();
          memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);
          delete Obj;
          pSNode = pSNode->mNext;
        }
      }
    }
  } else {
    //
    // EFI_IFR_DEFAULT opcode.
    //
    // Create new default opcode node for missing default.
    //
    for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
      if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
        IfrCreateDefaultRecord (Default->Header.Length, mAllDefaultIdArray[i], Default->Type, pDefaultNode->mLineNo, Default->Value);
        //
        // Save the new created default in the buffer storage..
        //
        IfrAddDefaultToBufferConfig (mAllDefaultIdArray[i], pQuestionNode, Default->Value);
      }
    }
  }
}

/**
  Parse the default information in a question, get the QuestionDefaultInfo.

  @param  pQuestionNode          Point to the question record Node.
  @param  QuestionDefaultInfo    On return, point to the QuestionDefaultInfo.
**/
VOID
CIfrRecordInfoDB::IfrParseDefaulInfoInQuestion(
  IN  SIfrRecord              *pQuestionNode,
  OUT QuestionDefaultRecord   *QuestionDefaultInfo
  )
{
  SIfrRecord              *pSNode;
  EFI_IFR_ONE_OF_OPTION   *OneofOptionOpcode;
  EFI_IFR_OP_HEADER       *pSOpHead;
  EFI_IFR_CHECKBOX        *CheckBoxOpcode;
  EFI_IFR_DEFAULT         *DefaultOpcode;
  BOOLEAN                 IsOneOfOpcode;
  UINT16                  SmallestDefaultId;
  UINT8                   ScopeCount;

  SmallestDefaultId  = 0xffff;
  IsOneOfOpcode      = FALSE;
  ScopeCount         = 0;
  pSNode             = pQuestionNode;

  //
  // Parse all the opcodes in the Question.
  //
  while (pSNode != NULL) {
    pSOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;
    //
    // For a question, its scope bit must be set, the scope exists until it reaches a corresponding EFI_IFR_END_OP.
    // Scopes may be nested within other scopes.
    // When finishing parsing a question, the scope count must be zero.
    //
    if (pSOpHead->Scope == 1) {
      ScopeCount++;
    }
    if (pSOpHead->OpCode == EFI_IFR_END_OP) {
      ScopeCount--;
    }
    //
    // Check whether finishing parsing a question.
    //
    if (ScopeCount == 0) {
      break;
    }

    //
    // Record the default information in the question.
    //
    switch (pSOpHead->OpCode) {
    case EFI_IFR_ONE_OF_OP:
      IsOneOfOpcode = TRUE;
      break;
    case EFI_IFR_CHECKBOX_OP:
      //
      // The default info of check box may be given by flag.
      // So need to check the flag of check box.
      //
      CheckBoxOpcode = (EFI_IFR_CHECKBOX *)pSNode->mIfrBinBuf;
      if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT) != 0) {
        //
        // Check whether need to update the smallest default id.
        //
        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
        }
        //
        // Update the QuestionDefaultInfo.
        //
        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
              QuestionDefaultInfo->mDefaultNumber ++;
              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
            }
            break;
          }
        }
      }
      if ((CheckBoxOpcode->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) != 0) {
        //
        // Check whether need to update the smallest default id.
        //
        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
        }
        //
        // Update the QuestionDefaultInfo.
        //
        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
              QuestionDefaultInfo->mDefaultNumber ++;
              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
            }
            break;
          }
        }
      }
      break;
    case EFI_IFR_ONE_OF_OPTION_OP:
      if (!IsOneOfOpcode) {
        //
        // Only check the option in oneof.
        //
        break;
      }
      OneofOptionOpcode = (EFI_IFR_ONE_OF_OPTION *)pSNode->mIfrBinBuf;
      if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT) != 0) {
        //
        // The option is used as the standard default.
        // Check whether need to update the smallest default id and QuestionDefaultInfo.
        //
        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
          QuestionDefaultInfo->mDefaultValueRecord = pSNode;
        }
        //
        // Update the IsDefaultIdExist array in QuestionDefaultInfo.
        //
        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_STANDARD) {
            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
              QuestionDefaultInfo->mDefaultNumber ++;
              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
            }
            break;
          }
        }
      }
      if ((OneofOptionOpcode->Flags & EFI_IFR_OPTION_DEFAULT_MFG) != 0) {
        //
        // This option is used as the manufacture default.
        // Check whether need to update the smallest default id and QuestionDefaultInfo.
        //
        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
          QuestionDefaultInfo->mDefaultValueRecord = pSNode;
        }
        //
        // Update the QuestionDefaultInfo.
        //
        for (UINT8 i = 0; i < mAllDefaultTypeCount; i++) {
          if (mAllDefaultIdArray[i] == EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
            if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
              QuestionDefaultInfo->mDefaultNumber ++;
              QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
            }
            break;
          }
        }
      }
      break;
    case EFI_IFR_DEFAULT_OP:
      DefaultOpcode = (EFI_IFR_DEFAULT *) pSNode->mIfrBinBuf;
      //
      // Check whether need to update the smallest default id and QuestionDefaultInfo.
      //
      if (SmallestDefaultId >= DefaultOpcode->DefaultId ) {
        SmallestDefaultId = DefaultOpcode->DefaultId;
        QuestionDefaultInfo->mDefaultValueRecord= pSNode;
        QuestionDefaultInfo->mIsDefaultOpcode= TRUE;
      }
      //
      // Update the QuestionDefaultInfo.
      //
      for (UINT8 i = 0; i < mAllDefaultTypeCount; i++){
        if (mAllDefaultIdArray[i] == ((EFI_IFR_DEFAULT *)pSNode->mIfrBinBuf)->DefaultId) {
          if (!QuestionDefaultInfo->mIsDefaultIdExist[i]) {
            QuestionDefaultInfo->mDefaultNumber ++;
            QuestionDefaultInfo->mIsDefaultIdExist[i] = TRUE;
          }
          break;
        }
      }
      break;
    default:
      break;
    }
    //
    // Parse next opcode in this question.
    //
    pSNode = pSNode->mNext;
  }
}

/**
  Check or add default for question if need.

  This function will check the default info for question.
  If the question has default, but the default number < defaultstore opcode number.
  will do following two action :

  1. if (AutoDefault) will add default for question to support all kinds of defaults.
  2. if (CheckDefault) will generate an error to tell user the question misses some default value.

  We assume that the two options can not be TRUE at same time.
  If they are TRUE at same time, only do the action corresponding to AutoDefault option.

  @param  AutoDefault          Add default for question if needed
  @param  CheckDefault         Check the default info, if missing default, generates an error.

**/
VOID
CIfrRecordInfoDB::IfrCheckAddDefaultRecord (
  BOOLEAN  AutoDefault,
  BOOLEAN  CheckDefault
  )
{
  SIfrRecord            *pNode;
  SIfrRecord            *pTailNode;
  SIfrRecord            *pStartAdjustNode;
  EFI_IFR_OP_HEADER     *pOpHead;
  QuestionDefaultRecord  QuestionDefaultInfo;
  UINT8                  MissingDefaultCount;
  CHAR8                  Msg[MAX_STRING_LEN] = {0, };

  pNode               = mIfrRecordListHead;

  //
  // Record the number and default id of all defaultstore opcode.
  //
  IfrGetDefaultStoreInfo ();

  while (pNode != NULL) {
    pOpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;
    //
    // Check whether is question opcode.
    //
    if (CheckQuestionOpCode (pOpHead->OpCode)) {
      //
      // Initialize some local variables here, because they vary with question.
      // Record the mIfrRecordListTail for each question, because may create default node for question after mIfrRecordListTail.
      //
      memset (&QuestionDefaultInfo, 0, sizeof (QuestionDefaultRecord));
      pTailNode = mIfrRecordListTail;
      //
      // Get the QuestionDefaultInfo for current question.
      //
      IfrParseDefaulInfoInQuestion (pNode, &QuestionDefaultInfo);

      if (QuestionDefaultInfo.mDefaultNumber != mAllDefaultTypeCount && QuestionDefaultInfo.mDefaultNumber != 0) {
        if (AutoDefault) {
          //
          // Create default for question which misses default.
          //
          IfrCreateDefaultForQuestion (pNode, &QuestionDefaultInfo);

          //
          // Adjust the buffer content.
          // pStartAdjustNode->mIfrBinBuf points to the insert position.
          // pTailNode->mNext->mIfrBinBuf points to the inset opcodes.
          //
          pStartAdjustNode =GetRecordInfoFromOffset (gAdjustOpcodeOffset);
          gCFormPkg.AdjustDynamicInsertOpcode (pStartAdjustNode->mIfrBinBuf, pTailNode->mNext->mIfrBinBuf, TRUE);

          //
          // Update the record info.
          //
          IfrUpdateRecordInfoForDynamicOpcode (TRUE);
        } else if (CheckDefault) {
          //
          // Generate an error for question which misses default.
          //
          MissingDefaultCount = mAllDefaultTypeCount - QuestionDefaultInfo.mDefaultNumber;
          sprintf (Msg, "The question misses %d default, the question's opcode is %d", MissingDefaultCount, pOpHead->OpCode);
          gCVfrErrorHandle.PrintMsg (pNode->mLineNo, NULL, "Error", Msg);
        }
      }
    }
    //
    // parse next opcode.
    //
    pNode = pNode->mNext;
  }
}

CIfrRecordInfoDB gCIfrRecordInfoDB;

VOID
CIfrObj::_EMIT_PENDING_OBJ (
  VOID
  )
{
  CHAR8  *ObjBinBuf = NULL;

  //
  // do nothing
  //
  if (!mDelayEmit || !gCreateOp) {
    return;
  }

  mPkgOffset = gCFormPkg.GetPkgLength ();
  //
  // update data buffer to package data
  //
  ObjBinBuf  = gCFormPkg.IfrBinBufferGet (mObjBinLen);
  if (ObjBinBuf != NULL) {
    memmove (ObjBinBuf, mObjBinBuf, mObjBinLen);
  }

  //
  // update bin buffer to package data buffer
  //
  if (mObjBinBuf != NULL) {
    delete[] mObjBinBuf;
    mObjBinBuf = ObjBinBuf;
  }

  mDelayEmit = FALSE;
}

/*
 * The definition of CIfrObj's member function
 */
static struct {
  UINT8  mSize;
  UINT8  mScope;
} gOpcodeSizesScopeTable[] = {
  { 0, 0 },                                    // EFI_IFR_INVALID - 0x00
  { sizeof (EFI_IFR_FORM), 1 },                // EFI_IFR_FORM_OP
  { sizeof (EFI_IFR_SUBTITLE), 1 },            // EFI_IFR_SUBTITLE_OP
  { sizeof (EFI_IFR_TEXT), 0 },                // EFI_IFR_TEXT_OP
  { sizeof (EFI_IFR_IMAGE), 0 },               // EFI_IFR_IMAGE_OP
  { sizeof (EFI_IFR_ONE_OF), 1 },              // EFI_IFR_ONE_OF_OP - 0x05
  { sizeof (EFI_IFR_CHECKBOX), 1},             // EFI_IFR_CHECKBOX_OP
  { sizeof (EFI_IFR_NUMERIC), 1 },             // EFI_IFR_NUMERIC_OP
  { sizeof (EFI_IFR_PASSWORD), 1 },            // EFI_IFR_PASSWORD_OP
  { sizeof (EFI_IFR_ONE_OF_OPTION), 0 },       // EFI_IFR_ONE_OF_OPTION_OP
  { sizeof (EFI_IFR_SUPPRESS_IF), 1 },         // EFI_IFR_SUPPRESS_IF - 0x0A
  { sizeof (EFI_IFR_LOCKED), 0 },              // EFI_IFR_LOCKED_OP
  { sizeof (EFI_IFR_ACTION), 1 },              // EFI_IFR_ACTION_OP
  { sizeof (EFI_IFR_RESET_BUTTON), 1 },        // EFI_IFR_RESET_BUTTON_OP
  { sizeof (EFI_IFR_FORM_SET), 1 },            // EFI_IFR_FORM_SET_OP -0xE
  { sizeof (EFI_IFR_REF), 0 },                 // EFI_IFR_REF_OP
  { sizeof (EFI_IFR_NO_SUBMIT_IF), 1},         // EFI_IFR_NO_SUBMIT_IF_OP -0x10
  { sizeof (EFI_IFR_INCONSISTENT_IF), 1 },     // EFI_IFR_INCONSISTENT_IF_OP
  { sizeof (EFI_IFR_EQ_ID_VAL), 0 },           // EFI_IFR_EQ_ID_VAL_OP
  { sizeof (EFI_IFR_EQ_ID_ID), 0 },            // EFI_IFR_EQ_ID_ID_OP
  { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 },      // EFI_IFR_EQ_ID_LIST_OP - 0x14
  { sizeof (EFI_IFR_AND), 0 },                 // EFI_IFR_AND_OP
  { sizeof (EFI_IFR_OR), 0 },                  // EFI_IFR_OR_OP
  { sizeof (EFI_IFR_NOT), 0 },                 // EFI_IFR_NOT_OP
  { sizeof (EFI_IFR_RULE), 1 },                // EFI_IFR_RULE_OP
  { sizeof (EFI_IFR_GRAY_OUT_IF), 1 },         // EFI_IFR_GRAYOUT_IF_OP - 0x19
  { sizeof (EFI_IFR_DATE), 1 },                // EFI_IFR_DATE_OP
  { sizeof (EFI_IFR_TIME), 1 },                // EFI_IFR_TIME_OP
  { sizeof (EFI_IFR_STRING), 1 },              // EFI_IFR_STRING_OP
  { sizeof (EFI_IFR_REFRESH), 0 },             // EFI_IFR_REFRESH_OP
  { sizeof (EFI_IFR_DISABLE_IF), 1 },          // EFI_IFR_DISABLE_IF_OP - 0x1E
  { 0, 0 },                                    // 0x1F
  { sizeof (EFI_IFR_TO_LOWER), 0 },            // EFI_IFR_TO_LOWER_OP - 0x20
  { sizeof (EFI_IFR_TO_UPPER), 0 },            // EFI_IFR_TO_UPPER_OP - 0x21
  { sizeof (EFI_IFR_MAP), 1 },                 // EFI_IFR_MAP - 0x22
  { sizeof (EFI_IFR_ORDERED_LIST), 1 },        // EFI_IFR_ORDERED_LIST_OP - 0x23
  { sizeof (EFI_IFR_VARSTORE), 0 },            // EFI_IFR_VARSTORE_OP
  { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP
  { sizeof (EFI_IFR_VARSTORE_EFI), 0 },        // EFI_IFR_VARSTORE_EFI_OP
  { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 },     // EFI_IFR_VARSTORE_DEVICE_OP
  { sizeof (EFI_IFR_VERSION), 0 },             // EFI_IFR_VERSION_OP - 0x28
  { sizeof (EFI_IFR_END), 0 },                 // EFI_IFR_END_OP
  { sizeof (EFI_IFR_MATCH), 0 },               // EFI_IFR_MATCH_OP - 0x2A
  { sizeof (EFI_IFR_GET), 0 },                 // EFI_IFR_GET - 0x2B
  { sizeof (EFI_IFR_SET), 0 },                 // EFI_IFR_SET - 0x2C
  { sizeof (EFI_IFR_READ), 0 },                // EFI_IFR_READ - 0x2D
  { sizeof (EFI_IFR_WRITE), 0 },               // EFI_IFR_WRITE - 0x2E
  { sizeof (EFI_IFR_EQUAL), 0 },               // EFI_IFR_EQUAL_OP - 0x2F
  { sizeof (EFI_IFR_NOT_EQUAL), 0 },           // EFI_IFR_NOT_EQUAL_OP
  { sizeof (EFI_IFR_GREATER_THAN), 0 },        // EFI_IFR_GREATER_THAN_OP
  { sizeof (EFI_IFR_GREATER_EQUAL), 0 },       // EFI_IFR_GREATER_EQUAL_OP
  { sizeof (EFI_IFR_LESS_THAN), 0 },           // EFI_IFR_LESS_THAN_OP
  { sizeof (EFI_IFR_LESS_EQUAL), 0 },          // EFI_IFR_LESS_EQUAL_OP - 0x34
  { sizeof (EFI_IFR_BITWISE_AND), 0 },         // EFI_IFR_BITWISE_AND_OP
  { sizeof (EFI_IFR_BITWISE_OR), 0 },          // EFI_IFR_BITWISE_OR_OP
  { sizeof (EFI_IFR_BITWISE_NOT), 0 },         // EFI_IFR_BITWISE_NOT_OP
  { sizeof (EFI_IFR_SHIFT_LEFT), 0 },          // EFI_IFR_SHIFT_LEFT_OP
  { sizeof (EFI_IFR_SHIFT_RIGHT), 0 },         // EFI_IFR_SHIFT_RIGHT_OP
  { sizeof (EFI_IFR_ADD), 0 },                 // EFI_IFR_ADD_OP - 0x3A
  { sizeof (EFI_IFR_SUBTRACT), 0 },            // EFI_IFR_SUBTRACT_OP
  { sizeof (EFI_IFR_MULTIPLY), 0 },            // EFI_IFR_MULTIPLY_OP
  { sizeof (EFI_IFR_DIVIDE), 0 },              // EFI_IFR_DIVIDE_OP
  { sizeof (EFI_IFR_MODULO), 0 },              // EFI_IFR_MODULO_OP - 0x3E
  { sizeof (EFI_IFR_RULE_REF), 0 },            // EFI_IFR_RULE_REF_OP
  { sizeof (EFI_IFR_QUESTION_REF1), 0 },       // EFI_IFR_QUESTION_REF1_OP
  { sizeof (EFI_IFR_QUESTION_REF2), 0 },       // EFI_IFR_QUESTION_REF2_OP - 0x41
  { sizeof (EFI_IFR_UINT8), 0},                // EFI_IFR_UINT8
  { sizeof (EFI_IFR_UINT16), 0},               // EFI_IFR_UINT16
  { sizeof (EFI_IFR_UINT32), 0},               // EFI_IFR_UINT32
  { sizeof (EFI_IFR_UINT64), 0},               // EFI_IFR_UTNT64
  { sizeof (EFI_IFR_TRUE), 0 },                // EFI_IFR_TRUE_OP - 0x46
  { sizeof (EFI_IFR_FALSE), 0 },               // EFI_IFR_FALSE_OP
  { sizeof (EFI_IFR_TO_UINT), 0 },             // EFI_IFR_TO_UINT_OP
  { sizeof (EFI_IFR_TO_STRING), 0 },           // EFI_IFR_TO_STRING_OP
  { sizeof (EFI_IFR_TO_BOOLEAN), 0 },          // EFI_IFR_TO_BOOLEAN_OP
  { sizeof (EFI_IFR_MID), 0 },                 // EFI_IFR_MID_OP
  { sizeof (EFI_IFR_FIND), 0 },                // EFI_IFR_FIND_OP
  { sizeof (EFI_IFR_TOKEN), 0 },               // EFI_IFR_TOKEN_OP
  { sizeof (EFI_IFR_STRING_REF1), 0 },         // EFI_IFR_STRING_REF1_OP - 0x4E
  { sizeof (EFI_IFR_STRING_REF2), 0 },         // EFI_IFR_STRING_REF2_OP
  { sizeof (EFI_IFR_CONDITIONAL), 0 },         // EFI_IFR_CONDITIONAL_OP
  { sizeof (EFI_IFR_QUESTION_REF3), 0 },       // EFI_IFR_QUESTION_REF3_OP
  { sizeof (EFI_IFR_ZERO), 0 },                // EFI_IFR_ZERO_OP
  { sizeof (EFI_IFR_ONE), 0 },                 // EFI_IFR_ONE_OP
  { sizeof (EFI_IFR_ONES), 0 },                // EFI_IFR_ONES_OP
  { sizeof (EFI_IFR_UNDEFINED), 0 },           // EFI_IFR_UNDEFINED_OP
  { sizeof (EFI_IFR_LENGTH), 0 },              // EFI_IFR_LENGTH_OP
  { sizeof (EFI_IFR_DUP), 0 },                 // EFI_IFR_DUP_OP - 0x57
  { sizeof (EFI_IFR_THIS), 0 },                // EFI_IFR_THIS_OP
  { sizeof (EFI_IFR_SPAN), 0 },                // EFI_IFR_SPAN_OP
  { sizeof (EFI_IFR_VALUE), 1 },               // EFI_IFR_VALUE_OP
  { sizeof (EFI_IFR_DEFAULT), 0 },             // EFI_IFR_DEFAULT_OP
  { sizeof (EFI_IFR_DEFAULTSTORE), 0 },        // EFI_IFR_DEFAULTSTORE_OP - 0x5C
  { sizeof (EFI_IFR_FORM_MAP), 1},             // EFI_IFR_FORM_MAP_OP - 0x5D
  { sizeof (EFI_IFR_CATENATE), 0 },            // EFI_IFR_CATENATE_OP
  { sizeof (EFI_IFR_GUID), 0 },                // EFI_IFR_GUID_OP
  { sizeof (EFI_IFR_SECURITY), 0 },            // EFI_IFR_SECURITY_OP - 0x60
  { sizeof (EFI_IFR_MODAL_TAG), 0},            // EFI_IFR_MODAL_TAG_OP - 0x61
  { sizeof (EFI_IFR_REFRESH_ID), 0},           // EFI_IFR_REFRESH_ID_OP - 0x62
  { sizeof (EFI_IFR_WARNING_IF), 1},           // EFI_IFR_WARNING_IF_OP - 0x63
  { sizeof (EFI_IFR_MATCH2), 0 },              // EFI_IFR_MATCH2_OP - 0x64
};

#ifdef CIFROBJ_DEUBG
static struct {
  CHAR8 *mIfrName;
} gIfrObjPrintDebugTable[] = {
  "EFI_IFR_INVALID",    "EFI_IFR_FORM",                 "EFI_IFR_SUBTITLE",      "EFI_IFR_TEXT",            "EFI_IFR_IMAGE",         "EFI_IFR_ONE_OF",
  "EFI_IFR_CHECKBOX",   "EFI_IFR_NUMERIC",              "EFI_IFR_PASSWORD",      "EFI_IFR_ONE_OF_OPTION",   "EFI_IFR_SUPPRESS_IF",   "EFI_IFR_LOCKED",
  "EFI_IFR_ACTION",     "EFI_IFR_RESET_BUTTON",         "EFI_IFR_FORM_SET",      "EFI_IFR_REF",             "EFI_IFR_NO_SUBMIT_IF",  "EFI_IFR_INCONSISTENT_IF",
  "EFI_IFR_EQ_ID_VAL",  "EFI_IFR_EQ_ID_ID",             "EFI_IFR_EQ_ID_LIST",    "EFI_IFR_AND",             "EFI_IFR_OR",            "EFI_IFR_NOT",
  "EFI_IFR_RULE",       "EFI_IFR_GRAY_OUT_IF",          "EFI_IFR_DATE",          "EFI_IFR_TIME",            "EFI_IFR_STRING",        "EFI_IFR_REFRESH",
  "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID",              "EFI_IFR_TO_LOWER",      "EFI_IFR_TO_UPPER",        "EFI_IFR_MAP",           "EFI_IFR_ORDERED_LIST",
  "EFI_IFR_VARSTORE",   "EFI_IFR_VARSTORE_NAME_VALUE",  "EFI_IFR_VARSTORE_EFI",  "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION",       "EFI_IFR_END",
  "EFI_IFR_MATCH",      "EFI_IFR_GET",                  "EFI_IFR_SET",           "EFI_IFR_READ",            "EFI_IFR_WRITE",         "EFI_IFR_EQUAL",
  "EFI_IFR_NOT_EQUAL",  "EFI_IFR_GREATER_THAN",         "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN",       "EFI_IFR_LESS_EQUAL",    "EFI_IFR_BITWISE_AND",
  "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT",          "EFI_IFR_SHIFT_LEFT",    "EFI_IFR_SHIFT_RIGHT",     "EFI_IFR_ADD",           "EFI_IFR_SUBTRACT",
  "EFI_IFR_MULTIPLY",   "EFI_IFR_DIVIDE",               "EFI_IFR_MODULO",        "EFI_IFR_RULE_REF",        "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",
  "EFI_IFR_UINT8",      "EFI_IFR_UINT16",               "EFI_IFR_UINT32",        "EFI_IFR_UINT64",          "EFI_IFR_TRUE",          "EFI_IFR_FALSE",
  "EFI_IFR_TO_UINT",    "EFI_IFR_TO_STRING",            "EFI_IFR_TO_BOOLEAN",    "EFI_IFR_MID",             "EFI_IFR_FIND",          "EFI_IFR_TOKEN",
  "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2",          "EFI_IFR_CONDITIONAL",   "EFI_IFR_QUESTION_REF3",   "EFI_IFR_ZERO",          "EFI_IFR_ONE",
  "EFI_IFR_ONES",       "EFI_IFR_UNDEFINED",            "EFI_IFR_LENGTH",        "EFI_IFR_DUP",             "EFI_IFR_THIS",          "EFI_IFR_SPAN",
  "EFI_IFR_VALUE",      "EFI_IFR_DEFAULT",              "EFI_IFR_DEFAULTSTORE",  "EFI_IFR_FORM_MAP",        "EFI_IFR_CATENATE",      "EFI_IFR_GUID",
  "EFI_IFR_SECURITY",   "EFI_IFR_MODAL_TAG",            "EFI_IFR_REFRESH_ID",    "EFI_IFR_WARNING_IF",      "EFI_IFR_MATCH2",
};

VOID
CIFROBJ_DEBUG_PRINT (
  IN UINT8 OpCode
  )
{
  printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);
}
#else

#define CIFROBJ_DEBUG_PRINT(OpCode)

#endif

BOOLEAN gCreateOp = TRUE;

CIfrObj::CIfrObj (
  IN  UINT8   OpCode,
  OUT CHAR8   **IfrObj,
  IN  UINT8   ObjBinLen,
  IN  BOOLEAN DelayEmit
  )
{
  mDelayEmit   = DelayEmit;
  mPkgOffset   = gCFormPkg.GetPkgLength ();
  mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;
  mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];
  mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;
  mLineNo      = 0;

  assert (mObjBinBuf != NULL);

  if (IfrObj != NULL) {
    *IfrObj    = mObjBinBuf;
  }

  CIFROBJ_DEBUG_PRINT (OpCode);
}

CIfrObj::~CIfrObj (
  VOID
  )
{
  if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {
    _EMIT_PENDING_OBJ ();
  }

  gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);
}

/*
 * The definition of CIfrObj's member function
 */
UINT8 gScopeCount = 0;

CIfrOpHeader::CIfrOpHeader (
  IN UINT8 OpCode,
  IN VOID *StartAddr,
  IN UINT8 Length
  ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)
{
  mHeader->OpCode = OpCode;
  mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;
  mHeader->Scope  = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;
}

CIfrOpHeader::CIfrOpHeader (
  IN CIfrOpHeader &OpHdr
  )
{
  mHeader = OpHdr.mHeader;
}

UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };
