/** @file
  
  The definition of CFormPkg's member function

Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

#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;
  }

  //
  // For framework vfr file, the extension framework header will be added.
  //
  if (VfrCompatibleMode) {
	  fprintf (pFile, "  // FRAMEWORK PACKAGE HEADER Length\n");
	  PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;
	  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT32));	
	  fprintf (pFile, "\n\n  // FRAMEWORK PACKAGE HEADER Type\n");
	  PkgLength = 3;
	  _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, "  ", (CHAR8 *)&PkgLength, sizeof (UINT16));	
	} else {
	  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.ExtractFieldNameAndArrary (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 vaild 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 || VfrCompatibleMode) {
        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 Incosistent 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, };
