1,376c1,203
< // Block.cpp: implementation of the Block class.
< //
< ////////////////////////////////////
< 
< #include <iostream>
< //#include <fstream>
< #include <string>
< #include <cstring> // strcpy
< #include <stdexcept> // range_error
< 
< #include "Block.h"
< #include "Serializer.h"
< #include "init.h"
< 
< using namespace std;
< using namespace tsb; // timber supply branch namespace
< 
< ////////////////////////////////////
< // Construction/Destruction
< ////////////////////////////////////
< 
< // counter for number of C++ block objects
< int Block::m_blockCount = 0;
< 
< vector<string> Block::m_indexLabels = vector<string>();
< 
< map<string, int> Block::m_labelIndex = map<string, int>();
< 
< vector<BLOCK*> Block::m_structMemoryAddresses = vector<BLOCK*>();
< 
< Block::Block(BLOCK* pBlockStruct)
<     : m_pStruct(pBlockStruct), m_index(++m_blockCount)
<     // !!! NOTE: blocks objects are indexed from 1 !!!
< {
<     if (0 != m_pStruct)
<     {
<         //IndexAndAddress indexAndAddress(m_index, m_pStruct);
<         m_labelIndex[m_pStruct->label] = m_index; // create & insert key-value pair
<         m_indexLabels.push_back(m_pStruct->label); // insert string in vector
<         // list of neighbouring blocks will be populated after all
<         // Block objects have been created by FssimApp::serializeBlockList
<     }
< }
< 
< Block::~Block()
< {
<     // do nothing yet, but may need to clean up m_pStruct Neighbours list
< }
< 
< // write contents to binary file
< void Block::serialize( Serializer& binaryArchive ) //throw (FileException)
< {
<     if (binaryArchive.isWriting())
<     {
<         // write block index
<         //ofs.write( &m_index, sizeof( m_index ) );
<         //binaryArchive.getFileStream() << m_index;
<         binaryArchive.write( &m_index, sizeof(m_index) ); // data, size
< 
<         // write block label length & text
<         size_t labelLength = 0;
<         labelLength = strlen( m_pStruct->label ) + 1; // write with terminating null
<         binaryArchive.write( &labelLength, sizeof(labelLength) ); // data, size
<         binaryArchive.write( &(m_pStruct->label), labelLength ); // data, size
< 
<         // write block adjacency delay
<         binaryArchive.write( &(m_pStruct->AdjacencyDelay), sizeof(m_pStruct->AdjacencyDelay) ); // data, size
<     }
<     else // reading archive
<     {
<         // read block index
<         binaryArchive.read( &m_index, sizeof(m_index) ); // data, size
< 
<         // read block label length & text
<         size_t labelLength = 0; // already includes terminating null
<         binaryArchive.read( &labelLength, sizeof(labelLength) ); // data, size
<         char* label = new char[labelLength];
<         binaryArchive.read( label, labelLength ); // data, size
<         //strcpy(m_pStruct->label, label);
< 
<         // re-create & insert the C-struct into the hashed FssimApp::m_blockList
<         this->recreateStruct(label);
< 
<         //IndexAndAddress indexAndAddress(m_index, m_pStruct);
<         m_indexLabels.push_back(m_pStruct->label); // insert string in vector
<         m_labelIndex[m_pStruct->label] = m_index; // create & insert key-value pair
<         delete[] label;
<         label = 0;
< 
<         // read block adjacency delay
<         //ofs.read( &m_pStruct->AdjacencyDelay, sizeof( m_pStruct->AdjacencyDelay ) );
<         //binaryArchive.getFileStream() >> m_pStruct->AdjacencyDelay;
<         binaryArchive.read( &(m_pStruct->AdjacencyDelay), sizeof(m_pStruct->AdjacencyDelay) ); // data, size
<     }
<     this->serializeNeighbourList(binaryArchive);
< }
< 
< void Block::serializeNeighbourList(Serializer& binaryArchive)
< {
<     if (binaryArchive.isWriting())
<     {
<         int numberOfNeighbours = m_neighbourIndices.size();
< 
<         // write number of block's Neighbours
<         binaryArchive.write( &numberOfNeighbours, sizeof(numberOfNeighbours) ); // data, size
< 
<         if (0 != numberOfNeighbours)
<         {
<             // write Neighbours' block indices
<             int index = 0;
<             list<int>::iterator iter = m_neighbourIndices.begin( );
<             while(iter != m_neighbourIndices.end( ))
<             {
<             	index = (*iter);
<                 binaryArchive.write( &index, sizeof(index) ); // data, size
<                 ++iter;
<             }
<         }
<     }
<     else // reading archive
<     {
<         // clear list of neighbours' indices, in case not already empty
<         m_neighbourIndices.clear();
<         // read number of block's Neighbours
<         int numberOfNeighbours = 0;
<         binaryArchive.read( &numberOfNeighbours, sizeof(numberOfNeighbours) ); // data, size
< 
< #ifdef _TSB_SERIALIZER_DEBUG
<         if (0 != numberOfNeighbours) // does the BLOCK have neighbours?
<         {
<             cout << "Block " << m_index << " has "
<              << numberOfNeighbours << " neighbours" << endl;
<         }
< #endif
< 
<         // read block Neighbours' indices
<         int currentNeighbourIndex = 0;
<         for( int i = 0; i < numberOfNeighbours; ++i )
<         {
< #ifdef _TSB_SERIALIZER_DEBUG
<             if (m_index == 1434) // last line of class.dat to debug with benchmark dataset
<             {
<                 cout << "end of file..." << endl;
<             }
< #endif
<             // neighbour labels are not serialized. Neighbour lists are recreated
<             // by: Block::recreateNeighbourList after all blocks are re-loaded
<             binaryArchive.read( &currentNeighbourIndex, sizeof(currentNeighbourIndex) ); // data, size
<             m_neighbourIndices.push_back(currentNeighbourIndex);
<         }
<     }
< }
< 
< void Block::recreateStruct(char* label)
< {
<     /*if (0 != m_pStruct) // clean up memory if overwriting existing struct
<     {
<         init_delete_block(m_pStruct);
<     }*/
<     BLOCK* pBlock = 0;
<     pBlock = init_make_block(label);
<     if (0 == pBlock)
<     {
<         string message = "ERROR: init_make_block() failed in Block::serialize.\n";
<         throw (message);
<     }
<     else
<     {
<         m_pStruct = pBlock;
<         m_structMemoryAddresses.push_back(m_pStruct);
<     }
< }
< 
< /* inlined for speed
< int Block::lookupBlockID(const string& label)
< {
<     // lookup neighbour's index in map by label
<     AConstIndexIterator item = m_labelIndex.find(label);
<     if ( item != m_labelIndex.end() )
<     {
<         return ( (item->second) );
<     }
<     else
<     {
<         throw ("Neighbour not found in labelIndex map");
<     }
<     return -1;
< }
< */
< 
< /* inlined for speed
< string Block::lookupBlockLabel(const int id)
< {
<     // lookup neighbour's index in map by label
<     if( 0 < id || id < m_indexLabels.size() ) // warning signed/unsigned compare
<     {
<         return m_indexLabels[id - 1];
<     }
<     else
<     {
<         throw range_error("Block id is out of the bounds of the vector.");
<     }
<     return 0;
< }
< */
< 
< /*BLOCK* Block::lookupLabelAddress(const string& label)
< {
<     // lookup neighbour's index in map by label
<     AConstIndexIterator item = m_labelIndex.find(label);
<     if ( item != m_labelIndex.end() )
<     {
<         return ( (item->second) );
<     }
<     else
<     {
<         throw ("Neighbour not found in labelIndex map");
<     }
< }*/
< 
< void Block::createNeighbourIndexList() // called before binary write
< {
< #ifdef _TSB_SERIALIZER_DEBUG
<     cout << "Block " << m_index << " has "
<          << m_pStruct->Neighbours->size << " neighbours" << endl;
< #endif
<     m_pStruct->Neighbours = (LIST_PTR *)List::reset(m_pStruct->Neighbours);
<     BLOCK* pNeighbour = 0;
<     do
<     {
<         pNeighbour = static_cast<BLOCK*>(List::next(m_pStruct->Neighbours));
<         if (0 != pNeighbour)
<         {
<             m_neighbourIndices.push_back(lookupBlockID(pNeighbour->label));
<         }
< 
<     } while (0 != pNeighbour);
< }
< 
< void Block::recreateNeighbourStructureList(vector<Block>& blockList) // called after binary read
< {
<     if (0 != m_pStruct) // does the BLOCK exist?
<     {
<         // populate list of neighbouring block indices
<         list<int>::iterator iter = m_neighbourIndices.begin();
<         while(iter != m_neighbourIndices.end())
<         {
<             // insert into list of neighbours
<             BLOCK* pNeighbour = blockList[(*iter)-1].m_pStruct; // get address of indexed Block's struct
<             m_pStruct->Neighbours =
<                     static_cast<LIST_PTR*>(List::insert(m_pStruct->Neighbours, pNeighbour, 0));
<             ++iter;
<         }
<         if (0 != m_pStruct->Neighbours) // does the BLOCK have neighbours?
<         {
< #ifdef _TSB_SERIALIZER_DEBUG
<             cout << "Block " << m_index << " has "
<              << m_pStruct->Neighbours->size << " neighbours" << endl;
< #endif
<         }
<     }
< }
< 
< void Block::serializeBlockList(Serializer& binaryArchive)
< {
<     FssimApp* pApp = FssimApp::getApp();
<     //list<Block> blockList;
<     if (binaryArchive.isWriting())
<     {
<         list<Block> blockList;
< 
<         BLOCK* pBlock;
<         HASHREC* pHashrec;
<         pApp->m_blockList = static_cast<LIST_PTR*>(List::reset(pApp->m_blockList));
<         pHashrec = static_cast<HASHREC*>(List::next(pApp->m_blockList));
<         while (pHashrec != 0)
<         {
<             pHashrec->candidates = static_cast<LIST_PTR*>(List::reset(pHashrec->candidates));
<             pBlock = static_cast<BLOCK*>(List::next(pHashrec->candidates));
<             while (pBlock != 0)
<             {
<                 Block newBlockObject( pBlock );
<                 pBlock = static_cast<BLOCK*>(List::next(pHashrec->candidates));
<                 blockList.push_back(newBlockObject); // shallow copy into list
<             }
<             pHashrec = static_cast<HASHREC*>(List::next(pApp->m_blockList));
<         }
< 
<         // TO-DO: in version 6, replace with output of true size of hashed list
<         // write the number of blocks in m_blockList
<         int blockListLength = blockList.size();
<         binaryArchive.write( &blockListLength, sizeof(blockListLength) ); // key, data
< #ifdef _TSB_SERIALIZER_DEBUG
<         cout << endl << "Writing " << blockListLength
<              << " blocks to binary file..." << endl;
< #endif
<         // populate lists of neighbours using Block object vectors of neighbour indices
<         // and then serialize all Block objects, including their lists of neighbour indices
<         list<Block>::iterator iter = blockList.begin();
<         while (iter != blockList.end())
<         {
<             if(0 != iter->hasNeighbours())
<             {
<                 iter->createNeighbourIndexList();
<             }
<             iter->serialize(binaryArchive);
<             ++iter;
<         }
<         // destruct C++ block objects (do not delete associated structs)
<         blockList.clear();
<     }
<     else // we are reading from binary file
<     {
<         vector<Block> blockList;
<         // read size of m_blockList
<         int blockListLength = 0;
<         binaryArchive.read( &blockListLength, sizeof(blockListLength) ); // data, size
< #ifdef _TSB_SERIALIZER_DEBUG
<             cout << endl << "Reading " << blockListLength
<                  << " blocks from binary file..." << endl;
< #endif
<         // populate m_blockList
<         for( int i = 0; i < blockListLength; ++i )
<         {
<             Block newBlockObject; // create default Block object
<             try
<             {
<                 newBlockObject.serialize(binaryArchive);
<                 blockList.push_back(newBlockObject); // shallow copy into list
<                 // new block is added to m_blockList by init_make_block
<                 //pApp->m_blockList =
<                 //       static_cast<LIST_PTR*>( List::insert(pApp->m_blockList,
<                 //                                            newBlockObject.getStruct(), 0) );
<             }
<             catch(FileException& e)
<             {
< #ifdef _TSB_SERIALIZER_DEBUG
<                 cout << "File exception: " << e.what() << endl;
< #endif
<                 if (e.isEndOfFile())
<                 {
<                     //endOfFile = true;
<                     break;
<                 }
<                 else
<                 {
<                     throw e;
<                 }
<             }
<             catch(exception& e)
<             {
<                 cout << "Binary read exception: " << e.what() << endl;
<                 throw e;
<             }
<         }
< #ifdef _TSB_SERIALIZER_DEBUG
<         if (0 != pApp->m_blockList) // does the Block list have blocks?
<         {
<             cout << "m_blockList " << " has "
<              << blockListLength << " Blocks" << endl;
<         }
< #endif
<         // populate lists of neighbours using Block object vectors of neighbour indices
<         //vector<Block>::iterator iter = blockList.begin();
<         //while (iter != blockList.end())
<         for(int j = 0 ; j < blockList.size() ; ++j) // warning signed/unsigned compare
<         {
<             blockList[j].recreateNeighbourStructureList(blockList);
<             //iter++;
<         }
<         // destruct C++ block objects (do not delete associated structs)
<         blockList.clear();
<     }
< }
< 
< 
---
> // Block.cpp: implementation of the Block class.
> 
> #include <iostream>
> #include <string>
> #include <cstring> // strcpy
> #include <stdexcept> // range_error
> 
> #include "Block.h"
> 
> #include "ArchiveException.h"
> #include "FileException.h"
> #include "IOException.h"
> 
> #include "init.h"
> 
> using namespace std;
> using namespace tsb; // timber supply branch namespace
> 
> 
> // write contents to binary file
> void Block::serialize( Serializer& binaryArchive ) //throw (FileException)
> {
>     if (binaryArchive.isWriting())
>     {
>         // write block index
>         binaryArchive.write( &m_pStruct->id, sizeof(m_pStruct->id) ); // data, size
> 
>         // write block label length & text
>         size_t labelLength = 0;
>         labelLength = strlen( m_pStruct->label ) + 1; // write with terminating null
>         binaryArchive.write( &labelLength, sizeof(labelLength) ); // data, size
>         binaryArchive.write( &(m_pStruct->label), labelLength ); // data, size
> 
>         // write block adjacency delay
>         binaryArchive.write( &(m_pStruct->AdjacencyDelay), sizeof(m_pStruct->AdjacencyDelay) ); // data, size
>     }
>     else // reading archive
>     {
>         // read block index
>         int id = 0;
>         binaryArchive.read( &id, sizeof(id) ); // data, size
> 
>         // read block label length & text
>         size_t labelLength = 0; // already includes terminating null
>         binaryArchive.read( &labelLength, sizeof(labelLength) ); // data, size
>         char* label = new char[labelLength];
>         binaryArchive.read( label, labelLength ); // data, size
> 
>         // re-create & insert the C-struct into the hashed FssimApp::m_blockList
>         this->recreateStruct(label, id);
>         delete[] label;
>         label = 0;
> 
>         // read block adjacency delay
>         binaryArchive.read( &(m_pStruct->AdjacencyDelay), sizeof(m_pStruct->AdjacencyDelay) ); // data, size
>     }
>     this->serializeNeighbourList(binaryArchive);
> }
> 
> void Block::serializeNeighbourList(Serializer& binaryArchive)
> {
>     if (binaryArchive.isWriting())
>     {
>         int numberOfNeighbours = m_pStruct->m_neighbourIndices.size();
> 
> #ifdef _TSB_SERIALIZER_DEBUG
>         if (0 != numberOfNeighbours) // does the BlockStruct have neighbours?
>         {
>             cout << "Block " << m_pStruct->id << " has "
>              << numberOfNeighbours << " neighbours" << endl;
>         }
> #endif
> 
>         // write number of block's Neighbours
>         binaryArchive.write( &numberOfNeighbours, sizeof(numberOfNeighbours) ); // data, size
> 
>         if (0 != numberOfNeighbours)
>         {
>             // write Neighbours' block indices
>             int index = 0;
>             list<int>::iterator iter = m_pStruct->m_neighbourIndices.begin( );
>             while(iter != m_pStruct->m_neighbourIndices.end( ))
>             {
>             	index = (*iter);
>                 binaryArchive.write( &index, sizeof(index) ); // data, size
>                 ++iter;
>             }
>         }
>     }
>     else // reading archive
>     {
>         // clear list of neighbours' indices, in case not already empty
>         m_pStruct->m_neighbourIndices.clear();
>         // read number of block's Neighbours
>         int numberOfNeighbours = 0;
>         binaryArchive.read( &numberOfNeighbours, sizeof(numberOfNeighbours) ); // data, size
> 
> #ifdef _TSB_SERIALIZER_DEBUG
>         if (0 != numberOfNeighbours) // does the BlockStruct have neighbours?
>         {
>             cout << "Block " << m_pStruct->id << " has "
>              << numberOfNeighbours << " neighbours" << endl;
>         }
> #endif
> 
>         // read block Neighbours' indices
>         int currentNeighbourIndex = 0;
>         for( int i = 0; i < numberOfNeighbours; ++i )
>         {
>             // neighbour labels are not serialized. Neighbour lists are recreated
>             // by: Block::recreateNeighbourList after all blocks are re-loaded
>             binaryArchive.read( &currentNeighbourIndex, sizeof(currentNeighbourIndex) ); // data, size
>             m_pStruct->m_neighbourIndices.push_back(currentNeighbourIndex);
>         }
>     }
> }
> 
> void Block::recreateStruct(const char* label, const int id)
> {
>     BlockStruct* pBlock = 0;
>     pBlock = init_make_block(label, id);
>     if (0 == pBlock)
>     {
>         string message = "ERROR: init_make_block() failed in Block::serialize.\n";
>         throw ArchiveException(message);
>     }
>     else
>     {
>         m_pStruct = pBlock;
>     }
> }
> 
> 
> void Block::serializeBlockList(Serializer& binaryArchive)
> {
>     FssimApp* pApp = FssimApp::getApp();
>     if (binaryArchive.isWriting())
>     {
>         vector<BlockStruct*>& blockList = BlockStruct::m_blockIndex;
> 
>         int blockListLength = blockList.size();
>         binaryArchive.write( &blockListLength, sizeof(blockListLength) ); // key, data
> 
>         typedef vector<BlockStruct*>::iterator BI;
>         for (BI blockIter = blockList.begin(); blockIter != blockList.end(); ++blockIter)
>         {
>             BlockStruct* pBlock = *blockIter;
>             if (0 != pBlock)
>             {
>                 Block newBlockObject(pBlock);
>                 newBlockObject.serialize(binaryArchive);
>             }
>         }
> #ifdef _TSB_SERIALIZER_DEBUG
>         cout << endl << "Writing " << blockListLength << " blocks to binary file..." << endl;
> #endif
> 
>     }
>     else // we are reading from binary file
>     {
>         // read size of m_blockList
>         int blockListLength = 0;
>         binaryArchive.read( &blockListLength, sizeof(blockListLength) ); // data, size
> 
> #ifdef _TSB_SERIALIZER_DEBUG
>         cout << endl << "Reading " << blockListLength << " blocks from binary file..." << endl;
> #endif
> 
>         // populate m_blockList
>         for( int i = 0; i < blockListLength; ++i )
>         {
>             Block newBlockObject; // create default Block object
>             try
>             {
>                 newBlockObject.serialize(binaryArchive);
>                 // new block struct is added to m_blockList by init_make_block on Block::recreateStruct
>             }
>             catch(FileException& e)
>             {
> #ifdef _TSB_DEBUG
>                 cerr << "File exception: " << e.what() << endl;
> #endif
>                 if (e.isEndOfFile())
>                 {
>                     break;
>                 }
>                 else
>                 {
>                     throw e;
>                 }
>             }
>             catch(IOException& e)
>             {
>                 cout << "Input/output exception: " << e.what() << endl;
>                 throw e;
>             }
>         }
> 
> #ifdef _TSB_SERIALIZER_DEBUG
>         cout << "m_blockList has " << blockListLength << " Blocks" << endl;
> #endif
>     }
> }
