IBR-DTNSuite  0.8
ibrdtn/ibrdtn/data/Bundle.cpp
Go to the documentation of this file.
00001 /*
00002  * Bundle.cpp
00003  *
00004  *  Created on: 29.05.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrdtn/data/Bundle.h"
00009 #include "ibrdtn/data/StatusReportBlock.h"
00010 #include "ibrdtn/data/CustodySignalBlock.h"
00011 #include "ibrdtn/data/Serializer.h"
00012 #include "ibrdtn/data/AgeBlock.h"
00013 
00014 namespace dtn
00015 {
00016         namespace data
00017         {
00018                 Bundle::Bundle()
00019                 {
00020                         // if the timestamp is not set, add a ageblock
00021                         if (_timestamp == 0)
00022                         {
00023                                 // add a new ageblock
00024                                 push_front<dtn::data::AgeBlock>();
00025                         }
00026                 }
00027 
00028                 Bundle::~Bundle()
00029                 {
00030                         clearBlocks();
00031                 }
00032 
00033                 Bundle::BlockList::BlockList()
00034                 {
00035                 }
00036 
00037                 Bundle::BlockList::~BlockList()
00038                 {
00039                 }
00040 
00041                 Bundle::BlockList& Bundle::BlockList::operator=(const Bundle::BlockList &ref)
00042                 {
00043                         _blocks.clear();
00044                         for (std::list<refcnt_ptr<Block> >::const_iterator iter = ref._blocks.begin(); iter != ref._blocks.end(); iter++)
00045                         {
00046                                 const refcnt_ptr<Block> &obj = (*iter);
00047                                 _blocks.push_back(obj);
00048                         }
00049                         return *this;
00050                 }
00051 
00052                 void Bundle::BlockList::push_front(Block *block)
00053                 {
00054                         if (_blocks.empty())
00055                         {
00056                                 // set the last block flag
00057                                 block->set(dtn::data::Block::LAST_BLOCK, true);
00058                         }
00059 
00060                         _blocks.push_front(refcnt_ptr<Block>(block));
00061                 }
00062 
00063                 void Bundle::BlockList::push_back(Block *block)
00064                 {
00065                         // set the last block flag
00066                         block->set(dtn::data::Block::LAST_BLOCK, true);
00067 
00068                         if (!_blocks.empty())
00069                         {
00070                                 // remove the last block flag of the previous block
00071                                 dtn::data::Block *lastblock = (_blocks.back().getPointer());
00072                                 lastblock->set(dtn::data::Block::LAST_BLOCK, false);
00073                         }
00074 
00075                         _blocks.push_back(refcnt_ptr<Block>(block));
00076                 }
00077 
00078                 void Bundle::BlockList::insert(Block *block, const Block *before)
00079                 {
00080                         for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00081                         {
00082                                 const dtn::data::Block *lb = (*iter).getPointer();
00083 
00084                                 if (lb == before)
00085                                 {
00086                                         _blocks.insert(iter, refcnt_ptr<Block>(block) );
00087                                         return;
00088                                 }
00089                         }
00090                 }
00091 
00092                 void Bundle::BlockList::remove(const Block *block)
00093                 {
00094                         // delete all blocks
00095                         for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00096                         {
00097                                 const dtn::data::Block &lb = (*(*iter));
00098                                 if ( &lb == block )
00099                                 {
00100                                         _blocks.erase(iter++);
00101 
00102                                         // set the last block bit
00103                                         if (!_blocks.empty())
00104                                                 (*_blocks.back()).set(dtn::data::Block::LAST_BLOCK, true);
00105 
00106                                         return;
00107                                 }
00108                         }
00109                 }
00110 
00111                 void Bundle::BlockList::clear()
00112                 {
00113                         // clear the list of objects
00114                         _blocks.clear();
00115                 }
00116 
00117                 const std::list<const Block*> Bundle::BlockList::getList() const
00118                 {
00119                         std::list<const dtn::data::Block*> ret;
00120 
00121                         for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00122                         {
00123                                 ret.push_back( (*iter).getPointer() );
00124                         }
00125 
00126                         return ret;
00127                 }
00128 
00129                 const std::set<dtn::data::EID> Bundle::BlockList::getEIDs() const
00130                 {
00131                         std::set<dtn::data::EID> ret;
00132 
00133                         for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00134                         {
00135                                 std::list<EID> elist = (*iter)->getEIDList();
00136 
00137                                 for (std::list<dtn::data::EID>::const_iterator iter = elist.begin(); iter != elist.end(); iter++)
00138                                 {
00139                                         ret.insert(*iter);
00140                                 }
00141                         }
00142 
00143                         return ret;
00144                 }
00145 
00146                 bool Bundle::operator!=(const Bundle& other) const
00147                 {
00148                         return PrimaryBlock(*this) != other;
00149                 }
00150 
00151                 bool Bundle::operator==(const Bundle& other) const
00152                 {
00153                         return PrimaryBlock(*this) == other;
00154                 }
00155 
00156                 bool Bundle::operator<(const Bundle& other) const
00157                 {
00158                         return PrimaryBlock(*this) < other;
00159                 }
00160 
00161                 bool Bundle::operator>(const Bundle& other) const
00162                 {
00163                         return PrimaryBlock(*this) > other;
00164                 }
00165 
00166                 const std::list<const dtn::data::Block*> Bundle::getBlocks() const
00167                 {
00168                         return _blocks.getList();
00169                 }
00170 
00171                 dtn::data::Block& Bundle::getBlock(int index)
00172                 {
00173                         return _blocks.get(index);
00174                 }
00175                 
00176                 const dtn::data::Block& Bundle::getBlock(int index) const
00177                 {
00178                         return _blocks.get(index);
00179                 }
00180 
00181                 void Bundle::remove(const dtn::data::Block &block)
00182                 {
00183                         _blocks.remove(&block);
00184                 }
00185 
00186                 void Bundle::clearBlocks()
00187                 {
00188                         _blocks.clear();
00189                 }
00190 
00191                 dtn::data::PayloadBlock& Bundle::insert(const dtn::data::Block &before, ibrcommon::BLOB::Reference &ref)
00192                 {
00193                         dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref);
00194                         dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock);
00195 
00196 #ifdef __DEVELOPMENT_ASSERTIONS__
00197                         assert(block != NULL);
00198 #endif
00199 
00200                         _blocks.insert(block, &before);
00201                         return (*tmpblock);
00202                 }
00203 
00204                 dtn::data::PayloadBlock& Bundle::push_front(ibrcommon::BLOB::Reference &ref)
00205                 {
00206                         dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref);
00207                         dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock);
00208 
00209 #ifdef __DEVELOPMENT_ASSERTIONS__
00210                         assert(block != NULL);
00211 #endif
00212 
00213                         _blocks.push_front(block);
00214                         return (*tmpblock);
00215                 }
00216 
00217                 dtn::data::PayloadBlock& Bundle::push_back(ibrcommon::BLOB::Reference &ref)
00218                 {
00219                         dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref);
00220                         dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock);
00221 
00222 #ifdef __DEVELOPMENT_ASSERTIONS__
00223                         assert(block != NULL);
00224 #endif
00225 
00226                         _blocks.push_back(block);
00227                         return (*tmpblock);
00228                 }
00229 
00230                 dtn::data::Block& Bundle::push_front(dtn::data::ExtensionBlock::Factory &factory)
00231                 {
00232                         dtn::data::Block *block = factory.create();
00233 
00234 #ifdef __DEVELOPMENT_ASSERTIONS__
00235                         assert(block != NULL);
00236 #endif
00237 
00238                         _blocks.push_front(block);
00239                         return (*block);
00240                 }
00241 
00242                 dtn::data::Block& Bundle::push_back(dtn::data::ExtensionBlock::Factory &factory)
00243                 {
00244                         dtn::data::Block *block = factory.create();
00245 
00246 #ifdef __DEVELOPMENT_ASSERTIONS__
00247                         assert(block != NULL);
00248 #endif
00249 
00250                         _blocks.push_back(block);
00251                         return (*block);
00252                 }
00253                 
00254                 Block& Bundle::insert(dtn::data::ExtensionBlock::Factory& factory, const dtn::data::Block& before)
00255                 {
00256                         dtn::data::Block *block = factory.create();
00257                         
00258 #ifdef __DEVELOPMENT_ASSERTIONS__
00259                         assert(block != NULL);
00260 #endif
00261 
00262                         _blocks.insert(block, &before);
00263                         return (*block);
00264                 }
00265 
00266                 string Bundle::toString() const
00267                 {
00268                         return PrimaryBlock::toString();
00269                 }
00270 
00271                 size_t Bundle::blockCount() const
00272                 {
00273                         return _blocks.size();
00274                 }
00275 
00276                 size_t Bundle::BlockList::size() const
00277                 {
00278                         return _blocks.size();
00279                 }
00280 
00281                 template<>
00282                 CustodySignalBlock& Bundle::BlockList::get<CustodySignalBlock>()
00283                 {
00284                         try {
00285                                 // copy all blocks to the list
00286                                 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00287                                 {
00288                                         if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE)
00289                                         {
00290                                                 Block *b = (*iter).getPointer();
00291                                                 return dynamic_cast<CustodySignalBlock&>(*b);
00292                                         }
00293                                 }
00294                         } catch (const std::bad_cast&) {
00295 
00296                         }
00297 
00298                         throw NoSuchBlockFoundException();
00299                 }
00300 
00301                 const Block& Bundle::BlockList::get(int index) const
00302                 {
00303                         if(index < 0 || index >= _blocks.size()){
00304                                 throw NoSuchBlockFoundException();
00305                         }
00306 
00307                         std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin();
00308                         std::advance(iter, index);
00309                         return *((*iter).getPointer());
00310                 }
00311 
00312                 Block& Bundle::BlockList::get(int index)
00313                 {
00314                         if(index < 0 || index >= _blocks.size()){
00315                                 throw NoSuchBlockFoundException();
00316                         }
00317 
00318                         std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin();
00319                         std::advance(iter, index);
00320                         return *((*iter).getPointer());
00321                 }
00322 
00323                 template<>
00324                 const CustodySignalBlock& Bundle::BlockList::get<const CustodySignalBlock>() const
00325                 {
00326                         try {
00327                                 // copy all blocks to the list
00328                                 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00329                                 {
00330                                         if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE)
00331                                         {
00332                                                 const Block *b = (*iter).getPointer();
00333                                                 return dynamic_cast<const CustodySignalBlock&>(*b);
00334                                         }
00335                                 }
00336                         } catch (const std::bad_cast&) {
00337 
00338                         }
00339 
00340                         throw NoSuchBlockFoundException();
00341                 }
00342 
00343                 template<>
00344                 StatusReportBlock& Bundle::BlockList::get<StatusReportBlock> ()
00345                 {
00346                         try {
00347                                 // copy all blocks to the list
00348                                 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00349                                 {
00350                                         if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE)
00351                                         {
00352                                                 Block *b = (*iter).getPointer();
00353                                                 return dynamic_cast<StatusReportBlock&>(*b);
00354                                         }
00355                                 }
00356                         } catch (const std::bad_cast&) {
00357 
00358                         }
00359 
00360                         throw NoSuchBlockFoundException();
00361                 }
00362 
00363                 template<>
00364                 const StatusReportBlock& Bundle::BlockList::get<const StatusReportBlock>() const
00365                 {
00366                         try {
00367                                 // copy all blocks to the list
00368                                 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++)
00369                                 {
00370                                         if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE)
00371                                         {
00372                                                 const Block *b = (*iter).getPointer();
00373                                                 return dynamic_cast<const StatusReportBlock&>(*b);
00374                                         }
00375                                 }
00376                         } catch (const std::bad_cast&) {
00377 
00378                         }
00379 
00380                         throw NoSuchBlockFoundException();
00381                 }
00382         }
00383 }
00384