/****************************************************************************

  module      : vbd900.cpp

  -------------------------------------------------------------------------

  responsible : AlexanderK

  special area: BD_Object_Constants_And_Types
  description : 


  version     : 7.2.0.0
  last changed: 2001-03-02  13:11
  see also    : 

  -------------------------------------------------------------------------

  copyright:    (c) 1998-2004 SAP AG



    ========== licence begin  GPL
    Copyright (c) 1998-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


*****************************************************************************/


/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include "gbd900.h"
#include "gbd910.h"
 
#include "hgg01.h"
#include "hgg01_1.h"
#include "hgg06.h"
#include "SAPDB/SAPDBCommon/SAPDB_RangeCode.hpp" // Kernel_move_and_fill
#include "hgg10.h"

#if COMPILEMODE_MEO00 >= SLOW_MEO00 
#include "hta99.h"
#endif

#include "KernelCommon/Kernel_OpMsg.hpp"        /* PTS 1114951 FF 2002-04-19 */

/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/

#define HUNDERT_PERCENT   100

/*===========================================================================*
 *  LOCAL FUNCTIONS (CODE)                                                   *
 *===========================================================================*/

static void
bd900_NewDumpPage (tgg00_VfFileref      &HostFile,
				   tsp00_Int4            BufferSize,
				   tsp00_Page           &Buffer,
				   tsp00_Int4           &OutPno,
				   tsp00_Int4           &OutPos,
				   tsp00_VfReturn       &HostError,
				   tsp00_ErrText        &ErrText,
				   const tsp00_Int2     &DumpCode,  
				   char *                DumpMark,
                   tgg00_BasisError      MoveError)
{

	/* start at a new dump page */
	g01new_dump_page (HostFile, Buffer, OutPno, OutPos, HostError, ErrText);
    if (vf_ok != HostError) return;
	
	SAPDB_RangeMove( __FILE__, 1,    
		DUMPMARKSIZE_BD900, BufferSize, DumpMark, 1,
		Buffer, OutPos, DUMPMARKSIZE_BD900 , MoveError);
    if ( e_ok == MoveError )
    {
        OutPos += DUMPMARKSIZE_BD900;

        SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &DumpCode, sizeof(DumpCode));
        OutPos         += sizeof(DumpCode);
    }
}

/*===========================================================================*
 *  IMPLEMENTATION OF METHODS DECLARED IN gbd900.h                           * 
 *===========================================================================*/

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjFileInfo                                             */
/*---------------------------------------------------------------------------*/

SAPDB_OStream& operator<<(SAPDB_OStream& os, const cbd900_ObjFileInfo& fileinfo)
{
    int ix;
    tsp00_Line line;
    int        linelen = 0;
    fileinfo.ofiTransNo.gg90AppendToLine (linelen, line);
    line[linelen] = 0;

#if defined(BIT64) 
    struct {
        SAPDB_UInt8 m_alloc;
        SAPDB_UInt  m_Capacity;
        SAPDB_UInt  m_Size;
        SAPDB_UInt8 m_ArrayPtr;
    } vector;
#else
    struct {
        SAPDB_UInt  m_alloc;
        SAPDB_UInt  m_Capacity;
        SAPDB_UInt  m_Size;
        SAPDB_UInt  m_ArrayPtr;
    } vector;
#endif

    memcpy( &vector, &fileinfo.ofiKeyRoots_bd900, sizeof(vector));

    os << "RecreateIndex:" << fileinfo.ofiRecreateIndex_bd900
        << " #KeyPart:" << fileinfo.ofiNumKeyPartitions_bd900
        << " bErrReCreIdx:" << fileinfo.ofiRecreateIndexError_bd900
        << " #MaxChain:" << fileinfo.ofiMaxChain_bd900
        << " #MaxObjPerPage:" << fileinfo.ofiMaxObjPerPageCnt_bd900
        << " MaxObjBodySize:" << fileinfo.ofiMaxObjBodySize_bd900
        << " keyroot-vector-alloc-addr:" << vector.m_alloc
        << " keyroot-vector-capacity:" << vector.m_Capacity
        << " keyroot-vector-size:" << vector.m_Size
        << " keyroot-vector-arrayptr:" << vector.m_ArrayPtr;
    for ( ix=0; ix < fileinfo.GetKeyPartitionCount(); ix++ )
        os << " KeyRoot:" << ix << fileinfo.ofiKeyRoots_bd900[ix];

    os << " Root:" << fileinfo.ofiRoot_bd900
        << " IsVar:" << fileinfo.ofiFileIsForVarObj_bd900
        << " RelFile:" << fileinfo.ofiRelFileIsReq_bd900
        << " Filler1:" << fileinfo.ofiFiller1_bd900
        << " DropFile:" << fileinfo.ofiDropFile_bd900
        << " TransNo:"  << line
        << " Filler2:" << fileinfo.ofiFiller2_bd900
        << fileinfo.ofiChain_bd900[0];
    return os;
};

externCpp void 
cbd900_ObjFileInfo::bd900DumpFileInfo (               
									   tgg00_VfFileref    &HostFile,
									   tsp00_Uint4         BufferSize,
									   tsp00_Page         &Buffer,
									   tsp00_Int4         &OutPno,
									   tsp00_Int4         &OutPos,
									   tsp00_VfReturn     &HostError,
									   tsp00_ErrText      &ErrText,
									   tsp00_Int2         &ElemsOnThisPage,
									   tsp00_Int4         &NumElemPos,
									   tsp00_Int4          FileNo,
									   tsp00_Int4          ContFileNo,
									   tsp00_Int2          DumpCode,
									   char               *DumpMark,
                                       tgg00_BasisError   &MoveError)
{
    ROUTINE_DBG_MEO00 ("bd900DumpFileInfo");

    MoveError = e_ok;
	tsp00_Int4  iChain;
	tsp00_Int4  NumObjKeyFiles = GetKeyPartitionCount();
	tsp00_PageNo KeyRootPageNo;

	/* check if the complete dump still fits into the    */ 
	/* current dump page. if not a new dump page is used */
	const tsp00_Uint4 LastBufferPosToUse = (OutPos - 1 
		+ sizeof (FileNo)
		+ sizeof (ContFileNo)
        // + sizeof (ofiCurrChain_bd900)        PTS 1134645
        + sizeof (ofiRecreateIndex_bd900)         //  PTS 1134645
        + sizeof (ofiNumKeyPartitions_bd900)      //  PTS 1134645
        + sizeof (ofiRecreateIndexError_bd900)    //  PTS 1134645
        + sizeof (ofiMaxChain_bd900) 
        + sizeof (ofiMaxObjPerPageCnt_bd900)
        + sizeof (ofiMaxObjBodySize_bd900)
        + sizeof (ofiRoot_bd900)
		+ sizeof (NumObjKeyFiles) +  NumObjKeyFiles * sizeof(KeyRootPageNo)
		+ sizeof (ofiFileIsForVarObj_bd900)
		+ sizeof (ofiRelFileIsReq_bd900)
		+ ofiMaxChain_bd900 * 
		  (sizeof (cbd900_ObjChainInfo) + sizeof (iChain))) ;

    if (LastBufferPosToUse > BufferSize)
	{
        SAPDB_MemCopyNoCheck (Buffer + NumElemPos - 1, &ElemsOnThisPage, sizeof(ElemsOnThisPage));
        
		bd900_NewDumpPage (HostFile, BufferSize, Buffer, OutPno, OutPos, HostError,
			ErrText, DumpCode, DumpMark, MoveError);
        if ( e_ok != MoveError ) return;
			
		NumElemPos      = OutPos;
	    ElemsOnThisPage = 0;
	    OutPos          += sizeof (ElemsOnThisPage);
    }
	
	++ElemsOnThisPage;
	SAPDB_MemCopyNoCheck (Buffer + NumElemPos - 1, &ElemsOnThisPage, sizeof(ElemsOnThisPage));
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &FileNo, sizeof(FileNo));
	OutPos         += sizeof(FileNo);

	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ContFileNo, sizeof(ContFileNo));
	OutPos         += sizeof(ContFileNo);
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiMaxChain_bd900, sizeof(ofiMaxChain_bd900));
	OutPos         += sizeof(ofiMaxChain_bd900);
	
    //SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiCurrChain_bd900, sizeof(ofiCurrChain_bd900)); PTS 1134645
    //OutPos         += sizeof(ofiCurrChain_bd900);
    SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiRecreateIndex_bd900, sizeof(ofiRecreateIndex_bd900));           //  PTS 1134645
    OutPos         += sizeof(ofiRecreateIndex_bd900);

    SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiNumKeyPartitions_bd900, sizeof(ofiNumKeyPartitions_bd900));     //  PTS 1134645
    OutPos         += sizeof(ofiNumKeyPartitions_bd900);

    SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiRecreateIndexError_bd900, sizeof(ofiRecreateIndexError_bd900)); //  PTS 1134645
    OutPos         += sizeof(ofiRecreateIndexError_bd900);
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiMaxObjPerPageCnt_bd900, sizeof(ofiMaxObjPerPageCnt_bd900));
	OutPos         += sizeof(ofiMaxObjPerPageCnt_bd900);
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiMaxObjBodySize_bd900, sizeof(ofiMaxObjBodySize_bd900));
	OutPos         += sizeof(ofiMaxObjBodySize_bd900);
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiRoot_bd900, sizeof(ofiRoot_bd900));
	OutPos         += sizeof(ofiRoot_bd900);
	
    if ( NumObjKeyFiles > 16 )
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg 
            << "bd900DumpFileInfo: NumObjKeyFiles:" << NumObjKeyFiles
            << " invalid!"
            << " root" << ofiRoot_bd900
            << " fileno:" << FileNo;
        NumObjKeyFiles = 16;
    }
    SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &NumObjKeyFiles, sizeof(NumObjKeyFiles));
	OutPos         += sizeof(NumObjKeyFiles);
	
    for (tsp00_Int4 iKeyFile=0; iKeyFile<NumObjKeyFiles; ++iKeyFile)
    {
        KeyRootPageNo = ofiKeyRoots_bd900[iKeyFile];
        /* PTS 1114951 FF 2002-04-19 check if buffer is big enough */
        if (((OutPos + sizeof(KeyRootPageNo)) < BufferSize ) &&
            (iKeyFile < 32))
        {
            SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &KeyRootPageNo, sizeof(KeyRootPageNo));
            OutPos         += sizeof(KeyRootPageNo);
        }
        else 
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg 
                << "bd900DumpFileInfo: not enough space within dump-buffer ! ofiKeyRoots_bd900="   
                << NumObjKeyFiles;
            break;
        }
    }
    
    /* PTS 1114951 FF 2002-04-19 check if buffer is big enough */
    if ((OutPos + sizeof(ofiFileIsForVarObj_bd900) + sizeof(ofiRelFileIsReq_bd900)) < BufferSize )
    {
        SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiFileIsForVarObj_bd900, sizeof(ofiFileIsForVarObj_bd900));
        OutPos         += sizeof(ofiFileIsForVarObj_bd900);
        
        SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &ofiRelFileIsReq_bd900, sizeof(ofiRelFileIsReq_bd900));
        OutPos         += sizeof(ofiRelFileIsReq_bd900);
    }

	// --- CHAIN STATE ---
	
    if ( MAX_NUM_CHAINS_PER_CONTAINER_BD900 < ofiMaxChain_bd900 )
    {
        Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
        opErrMsg 
            << "bd900DumpFileInfo: ofiMaxChain_bd900:" << NumObjKeyFiles
            << " invalid!"
            << " root" << ofiRoot_bd900
            << " fileno:" << FileNo;
        ofiMaxChain_bd900 = MAX_NUM_CHAINS_PER_CONTAINER_BD900;
    }

	for (iChain = 0; iChain < ofiMaxChain_bd900; ++iChain)
	{
        /* PTS 1114951 FF 2002-04-19 check if buffer is big enough */
        if (((OutPos + sizeof(iChain)) < BufferSize ) &&
            (iChain <= MAX_NUM_CHAINS_PER_CONTAINER_BD900))
        {
            SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &iChain, sizeof(iChain));
            OutPos         += sizeof(iChain);
        }
        else 
        {
            Kernel_OpError  opErrMsg( csp3_bd_msg, csp3_n_obj );
            opErrMsg 
                << "bd900DumpFileInfo: not enough space within dump-buffer ! ofiMaxChain_bd900="   
                << ofiMaxChain_bd900;
            break;
        }		
		operator[](iChain).bd900DumpChainInfo (BufferSize, Buffer, OutPos);
	}   
}

/*---------------------------------------------------------------------------*/

externCpp void 
cbd900_ObjFileInfo::bd900ResetFileInfo ()
{
  ROUTINE_DBG_MEO00 ("bd900ResetFileInfo");

  ofiRoot_bd900             = NIL_PAGE_NO_GG00;
  // ofiCurrChain_bd900     = 0;        PTS 1134645
  ofiRecreateIndex_bd900    = false; // PTS 1134645
  ofiNumKeyPartitions_bd900 = 0;	  /*PTS 1134645*/
  ofiRecreateIndexError_bd900 = e_ok; /*PTS 1134645*/
  ofiMaxChain_bd900         = 0;
  ofiMaxObjPerPageCnt_bd900 = 0;
  ofiMaxObjBodySize_bd900   = 0;
  ofiRelFileIsReq_bd900     = false;
  ofiFileIsForVarObj_bd900  = false;
  ofiFiller1_bd900          = false;
  ofiDropFile_bd900         = false;   // PTS 1119647 FF 2002-DEC-05
  gg06SetNilTrans(ofiTransNo);         // PTS 1119647 FF 2002-DEC-05
  ofiFiller2_bd900          = 0;       // PTS 1119647 FF 2002-DEC-05

  for (SAPDB_UInt iKeyFile=0; iKeyFile<GetKeyPartitionCount(); ++iKeyFile)
    ofiKeyRoots_bd900[iKeyFile] = NIL_PAGE_NO_GG00;

  for (int iChain=0; iChain < MAX_NUM_CHAINS_PER_CONTAINER_BD900; ++iChain)
    ofiChain_bd900[iChain].bd900ResetChainInfo();
}

/*---------------------------------------------------------------------------*/

externCpp tsp00_Int4 
cbd900_ObjFileInfo::bd900NumAllPages() const
{
  ROUTINE_DBG_MEO00 ("bd900NumAllPages");

  int        iChain; 
  tsp00_Int4 AllPageInFileCnt = 0;

  /* go trough all subroots of the file and sum up the number of  pages */
  for (iChain=0; iChain < ofiMaxChain_bd900; ++iChain)
    AllPageInFileCnt +=  ofiChain_bd900[iChain].ociAllPageCnt_bd900;

  return AllPageInFileCnt;
}

/*---------------------------------------------------------------------------*/

externCpp tsp00_Longreal // tsp00_Int4 PTS 1114534 FF 2002-02-28
cbd900_ObjFileInfo::bd900NumOccPages() const
{
  ROUTINE_DBG_MEO00 ("bd900NumOccPages");

  int            iChain;
  tsp00_Longreal OccPageInFileCnt = 0; // tsp00_Int4 PTS 1114534

  /* go trough all subroots of the file and sum up the number of  pages */
  for (iChain=0; iChain<= ofiMaxChain_bd900-1; ++iChain)
  {
    if ((ofiMaxObjPerPageCnt_bd900                 > 0)  && 
      (ofiChain_bd900[iChain].ociAllObjCnt_bd900 > 0))  //PTS 1103239 AK 08-09-1999
    {
      // tsp00_Int4 PTS 1114034
      OccPageInFileCnt += STATIC_CAST(tsp00_Longreal,ofiChain_bd900[iChain].ociAllObjCnt_bd900)
        /ofiMaxObjPerPageCnt_bd900;
    }
  }
		
	return (OccPageInFileCnt*HUNDERT_PERCENT); // tsp00_Int4 PTS 1114534
}

/*---------------------------------------------------------------------------*/

externCpp void
cbd900_ObjFileInfo::bd900GetNumOfActiveGCs (tsp00_Int4 & NumReqGC,
                                            tsp00_Int4 & NumActiveGC) 
{	
  int  iChain;

  /* calculate number of chains which request a GC service */
  if (ofiRelFileIsReq_bd900)
  {
    NumReqGC = ofiMaxChain_bd900;

    for (iChain=0; iChain<ofiMaxChain_bd900; ++iChain) 
    {
      if (NIL_PAGE_NO_GG00 == operator[](iChain).ociSubRoot_bd900 )
        --NumReqGC;
    }
  }

	/* calculate number of chains where the GC is activ */
	NumActiveGC = 0;
	for (iChain=0; iChain<ofiMaxChain_bd900; ++iChain) 
	{		
		if (NIL_GC_INDEX_BD900 != operator[](iChain).ociCurrActivGC_bd900)
			++NumActiveGC;
	}
}

/*---------------------------------------------------------------------------*/

void 
cbd900_ObjFileInfo::bd900SetFileInfo (tbd_current_tree     &Current,
									  tbd_node_ptrs        &NptrsRoot,
									  tsp00_Int4            MaxObjBodySize,
									  tsp00_Int4            MaxObjPerPageCnt)
{      
  int                 iChain;
  cbd900_RootPageInfo RootPageInfo (NptrsRoot);

  bd900ResetFileInfo();
  ofiRoot_bd900             = NptrsRoot.np_ptr()->nd_id();
  ofiMaxChain_bd900         = RootPageInfo.bd900NumChains();
  // ofiCurrChain_bd900     = 0;        PTS 1134645
  ofiMaxObjPerPageCnt_bd900 = MaxObjPerPageCnt;
  ofiMaxObjBodySize_bd900   = MaxObjBodySize;
  ofiFileIsForVarObj_bd900  = (pt2VarObject_egg00 == NptrsRoot.np_ptr()->nd_pt2());
  ofiRelFileIsReq_bd900     = RootPageInfo.bd900FileIsDeleted(); /* PTS 1106900 Alexander Kley 09/06/2000 */
  ofiDropFile_bd900         = RootPageInfo.bd900FileIsDeleted(); /* 1128266 PTS FF 2004-03-05             */
  ofiFiller1_bd900          = false;
  tsp00_Int4 NumObjKeyFiles = RootPageInfo.bd900NumObjKeyFiles();
  /* this is necessary to be compatible with elder */ 
  /* releases (see CRS 1109486 AK 01/03/2001       */
  /* even after migration this may be wrong, because of coding errors FF 2003-Apr-02 */
  /* therefore still patch to 1                                                      */
  if ((NptrsRoot.np_ptr()->nd_obj_key_len() > 0) && (NumObjKeyFiles == 0))
    NumObjKeyFiles = 1;

# if COMPILEMODE_MEO00 >= QUICK_MEO00
  if ((NptrsRoot.np_ptr()->nd_obj_key_len() == 0) && (NumObjKeyFiles > 0))
    g01abort (csp3_bd_msg, csp3_n_obj, "bd900SetFInfo:OddKeyFile",  NumObjKeyFiles);

  /* allocate memory for the vector containing the roots of the key files */
  /* first check that the vector is still empty                           */
  if ( 0 != ofiKeyRoots_bd900.GetCapacity())
    g01abort (csp3_bd_msg, csp3_n_obj, "bd900SetFI:KeyRootsExist",  ofiKeyRoots_bd900.GetCapacity());
# endif

  ofiNumKeyPartitions_bd900 = NumObjKeyFiles; /*PTS 1134645*/
  if (!ofiKeyRoots_bd900.Resize(NumObjKeyFiles))
  {
    Current.curr_trans->trError_gg00 = e_sysbuf_storage_exceeded;
    g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj,
      "bd900SetFI: NoMoreMemory",  Current.curr_trans->trError_gg00);
    g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj,
      "bd900SetFI: FileNo      ",  NptrsRoot.np_ptr()->nd_obj_file_no());
    g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_obj,
      "bd900SetFI: NumKeyRoots ",  NumObjKeyFiles);
    return;
  }

  for (iChain=0; iChain < RootPageInfo.bd900NumChains(); ++iChain)
  {
    cbd910_SubRootNode NptrsSubRoot (Current, RootPageInfo.bd900SubRoot(iChain), nr_for_read);
    ofiChain_bd900[iChain].bd900SetChainInfo (NptrsSubRoot);

    /* note: that since the current objectfileinfo is not yet inserted */
    /* into the directory some of the checks would report errors       */
    NptrsSubRoot.bd910ReleasePage();
  }

  for (iChain=RootPageInfo.bd900NumChains(); iChain < MAX_NUM_CHAINS_PER_CONTAINER_BD900; ++iChain)
    ofiChain_bd900[iChain].bd900ResetChainInfo();
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjFileDir                                              */
/*---------------------------------------------------------------------------*/
 
void
cbd900_ObjFileDir::bd900DumpObjFileDir (tgg00_VfFileref      &HostFile,
                                        tsp00_Int4            BufferSize,
                                        tsp00_Page           &Buffer,
                                        tsp00_Int4           &OutPno,
                                        tsp00_Int4           &OutPos,
                                        tsp00_VfReturn       &HostError,
                                        tsp00_ErrText        &ErrText,
                                        tgg00_BasisError     &MoveError)
{
    ROUTINE_DBG_MEO00 ("bd900DumpObjFileDir");
     
    tsp00_Int2        DumpCodeFileDir    = 250;
	tsp00_Int2        DumpCodeFileInfo   = 251;
    char              DumpMarkFileDir[]  = "B90OFDIR"; 
	char              DumpMarkFileInfo[] = "B90OFINF";
    MoveError  = e_ok;

    // OutPos is handled as a Pascal (!) Position
    // only for C-Routines 1 must be subtracted
			
    HostError.becomes(vf_ok);
	bd900_NewDumpPage (HostFile, BufferSize, Buffer, OutPno, OutPos, HostError,
		ErrText, DumpCodeFileDir, DumpMarkFileDir, MoveError);
    if ( e_ok != MoveError ) return;
	
	/* dump maximum number of files */
	const tsp00_Int4 MaxNumFiles = MAX_OBJ_FILE_NO_GG92;
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &MaxNumFiles, sizeof(MaxNumFiles));
	OutPos         += sizeof(MaxNumFiles);
	
	/* dump number of files in the object file directory */
	int NumFiles = bd920NumItems();
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &NumFiles, sizeof(NumFiles));
	OutPos         += sizeof(NumFiles);
	
    /* dump entries in the Object file directory */
    SAPDB_RangeMove( __FILE__, 2, DUMPMARKSIZE_BD900, BufferSize, DumpMarkFileInfo,
		1, Buffer, OutPos, DUMPMARKSIZE_BD900 , MoveError);
    if ( e_ok != MoveError ) return;

	OutPos += DUMPMARKSIZE_BD900;
	
	SAPDB_MemCopyNoCheck (Buffer + OutPos - 1, &DumpCodeFileInfo, sizeof(DumpCodeFileInfo));
	OutPos         += sizeof(DumpCodeFileInfo);

	tsp00_Int4	NumElemPos      = OutPos;
	tsp00_Int2  ElemsOnThisPage = 0;
	OutPos      += sizeof (ElemsOnThisPage);
	
	cbd900_ObjFileDirIter ObjFileIter (*this);
	
	for (ObjFileIter.bd920Begin(); (!ObjFileIter.bd920End()) && (HostError == vf_ok) && (e_ok == MoveError ); 
        ++ObjFileIter)
	{
		ObjFileIter()->bd900DumpFileInfo ( HostFile, BufferSize,
			Buffer, OutPno, OutPos,	HostError, ErrText, ElemsOnThisPage, 
			NumElemPos,	ObjFileIter.bd920Key(), /* = FileNo */
			PRIM_CONT_OBJ_FILE_NO_BD900, DumpCodeFileInfo, DumpMarkFileInfo, MoveError);
	}
	
	//flush number of entries an this page 
    if ((HostError != vf_ok) || (e_ok != MoveError ))
        SAPDB_MemCopyNoCheck (Buffer + NumElemPos - 1, &ElemsOnThisPage, sizeof(ElemsOnThisPage));
}

/*---------------------------------------------------------------------------*/
/* METHODS of cbd900_ObjFileDir                                              */
/*---------------------------------------------------------------------------*/

void 
cbd900_ContObjFileDir::bd900DumpContObjFileDir (tgg00_VfFileref      &HostFile,
												tsp00_Int4            BufferSize,
												tsp00_Page           &Buffer,
												tsp00_Int4           &OutPno,
												tsp00_Int4           &OutPos,
												tsp00_VfReturn       &HostError,
												tsp00_ErrText        &ErrText,
                                                tgg00_BasisError     &MoveError)
{
	ROUTINE_DBG_MEO00 ("bd900DumpContObjFileDir");	

    tsp00_Int2                 DumpCode   = 254;
    char                       DumpMark[] = "B93CODIR";
	cbd900_ContObjFileDirIter  ContObjFileIter (*this);
	
    // OutPos is handled as a Pascal (!) Position
    // only for C-Routines 1 must be subtracted
	
    HostError.becomes(vf_ok);
	
	bd900_NewDumpPage (HostFile, BufferSize, Buffer, OutPno, OutPos, HostError,
		ErrText, DumpCode, DumpMark, MoveError);
	if ((HostError != vf_ok) || ( e_ok != MoveError ))
        return;
	
	tsp00_Int4 NumElemPos       = OutPos;
	tsp00_Int2 ElemsOnThisPage  = 0;
	OutPos                     += sizeof (ElemsOnThisPage);
	
	for (ContObjFileIter.bd920Begin(); 
	(!ContObjFileIter.bd920End()) && (HostError == vf_ok);
	++ContObjFileIter)
	{	
		for (tsp00_Int4 iContFileNo=1; 
		(iContFileNo <= ContObjFileIter()->cfiNumContFiles_bd900) && (HostError == vf_ok) && (e_ok == MoveError );
		++iContFileNo)
		{
			if ((*ContObjFileIter())[iContFileNo].GetRootPage() != NIL_PAGE_NO_GG00)
			{
				(*ContObjFileIter())[iContFileNo].bd900DumpFileInfo (
					HostFile, BufferSize, Buffer, OutPno, OutPos,
					HostError, ErrText, ElemsOnThisPage, NumElemPos, 
					ContObjFileIter.bd920Key(), /* = FileNo*/
			        iContFileNo, DumpCode, DumpMark, MoveError);
			}
		}
	}
	//flush number of entries an this page 
    if ((HostError != vf_ok) || ( e_ok != MoveError ))
        SAPDB_MemCopyNoCheck (Buffer + NumElemPos - 1, &ElemsOnThisPage, sizeof(ElemsOnThisPage));
}

/*---------------------------------------------------------------------------*/

// end of vbd900.cpp
