///////////////////////////////////////////////////////////////////////////////
// FindRoomForData
///////////////////////////////////////////////////////////////////////////////
int cBlockRecordFile::FindRoomForData(int32 dataSize) //throw (eArchive)
{
    ASSERT((dataSize > 0) && (dataSize <= cBlockRecordArray::MAX_DATA_SIZE));
    ASSERT(mbOpen);
#ifdef _BLOCKFILE_DEBUG
    AssertValid();
#endif
    cDebug d("cBlockRecordFile::FindRoomForData");

    // first, try the last added to block...
    //
    d.TraceDetail("Looking for room for %d bytes; first trying mLastAddedTo (%d)\n", dataSize, mLastAddedTo);
    if (mLastAddedTo >= 0)
    {
        util_InitBlockArray(mvBlocks[mLastAddedTo]);
        if (mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize)
        {
            d.TraceDetail("---Found room in block %d\n", mLastAddedTo);
            return mLastAddedTo;
        }
    }
    //
    // ok, I guess we will have to iterate through all the blocks...
    //
    BlockArray::iterator it;
    int                  cnt = 0;
    for (it = mvBlocks.begin(); it != mvBlocks.end(); ++it, ++cnt)
    {
        util_InitBlockArray(*it);
        if (it->GetAvailableSpace() >= dataSize)
        {
            d.TraceDetail("---Found room in block %d\n", cnt);
            return cnt;
        }
    }
    //
    // if we got here, then we need to add a new block
    //
    d.TraceDetail("---We need to add new block(%d)\n", cnt);
    mBlockFile.CreateBlock();
    ASSERT((mBlockFile.GetNumBlocks() == (mvBlocks.size() + 1)) && (mvBlocks.size() == cnt));
    mvBlocks.push_back(cBlockRecordArray(&mBlockFile, cnt));
    mvBlocks.back().InitNewBlock();

    ASSERT(mvBlocks.back().GetAvailableSpace() >= dataSize);

    return cnt;
}
///////////////////////////////////////////////////////////////////////////////
// OpenImpl
///////////////////////////////////////////////////////////////////////////////
void cBlockRecordFile::OpenImpl( bool bTruncate ) //throw (eArchive)
{
    ASSERT( ! mbOpen );
    //
    // create the vector of block record arrays...avoid initializing them all
    //  right now so that we don't page the whole file into memory
    //
    mvBlocks.clear();
    for( int i=0; i < mBlockFile.GetNumBlocks(); i++ )
    {
        mvBlocks.push_back( cBlockRecordArray( &mBlockFile, i ) );
        //
        // if we are creating a new file, initialize the block for first usage...
        //
        if( bTruncate )
        {
            mvBlocks.back().InitNewBlock();
        }
    }
    //
    // use the integrity of the first block as a q&d check for file integrity...
    //
    ASSERT( mvBlocks.size() > 0 );
    if(! mvBlocks.begin()->Initialized() )
    {
        mvBlocks.begin()->InitForExistingBlock();
    }
    if( ! mvBlocks.begin()->IsClassValid() )
    {
        TSTRING str = _T("Bad file format for the Block Record File");
        throw eArchiveFormat( str );
    }
    // set the last item added to to zero (TODO -- is this the right thing to do or
    // should I store it in the archive?
    //
    mLastAddedTo = 0;

    mbOpen = true;
}