/** @file
  
  The definition of CFormPkg's member function

Copyright (c) 2004 - 2016, 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;
  mBufferNodeQueueHead = NULL;
  mCurrBufferNode      = 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;

  //
  // Declare all questions as Numeric in DisableIf True
  //
  // DisableIf
  CIfrDisableIf DIObj;
  DIObj.SetLineNo (LineNo);
  *InsertOpcodeAddr = DIObj.GetObjBinAddr ();
  
  //TrueOpcode
  CIfrTrue TObj (LineNo);

  // Declare Numeric qeustion for each undefined question.
  for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {
    if (pNode->mFlag == PENDING) {
      CIfrNumeric CNObj;
      EFI_VARSTORE_INFO Info; 
      EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;

      CNObj.SetLineNo (LineNo);
      CNObj.SetPrompt (0x0);
      CNObj.SetHelp (0x0);

      //
      // 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) {
          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);
            delete[] NewStr;
          }
        } else {
          ReturnCode = VFR_RETURN_UNSUPPORTED;
        }
      }
      if (ReturnCode != VFR_RETURN_SUCCESS) {
        gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);
        return ReturnCode;
      }

      CNObj.SetQuestionId (QId);
      CNObj.SetVarStoreInfo (&Info);
      //
      // 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 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();
          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;

  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, };
