|
IBR-DTNSuite 0.6
|
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 void Bundle::BlockList::push_front(Block *block) 00042 { 00043 if (_blocks.empty()) 00044 { 00045 // set the last block flag 00046 block->set(dtn::data::Block::LAST_BLOCK, true); 00047 } 00048 00049 _blocks.push_front(refcnt_ptr<Block>(block)); 00050 } 00051 00052 void Bundle::BlockList::push_back(Block *block) 00053 { 00054 // set the last block flag 00055 block->set(dtn::data::Block::LAST_BLOCK, true); 00056 00057 if (!_blocks.empty()) 00058 { 00059 // remove the last block flag of the previous block 00060 dtn::data::Block *lastblock = (_blocks.back().getPointer()); 00061 lastblock->set(dtn::data::Block::LAST_BLOCK, false); 00062 } 00063 00064 _blocks.push_back(refcnt_ptr<Block>(block)); 00065 } 00066 00067 void Bundle::BlockList::insert(Block *block, const Block *before) 00068 { 00069 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00070 { 00071 const dtn::data::Block *lb = (*iter).getPointer(); 00072 00073 if (lb == before) 00074 { 00075 _blocks.insert(iter, refcnt_ptr<Block>(block) ); 00076 return; 00077 } 00078 } 00079 } 00080 00081 void Bundle::BlockList::remove(const Block *block) 00082 { 00083 // delete all blocks 00084 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00085 { 00086 const dtn::data::Block &lb = (*(*iter)); 00087 if ( &lb == block ) 00088 { 00089 _blocks.erase(iter++); 00090 00091 // set the last block bit 00092 if (!_blocks.empty()) 00093 (*_blocks.back()).set(dtn::data::Block::LAST_BLOCK, true); 00094 00095 return; 00096 } 00097 } 00098 } 00099 00100 void Bundle::BlockList::clear() 00101 { 00102 // clear the list of objects 00103 _blocks.clear(); 00104 } 00105 00106 const std::list<const Block*> Bundle::BlockList::getList() const 00107 { 00108 std::list<const dtn::data::Block*> ret; 00109 00110 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00111 { 00112 ret.push_back( (*iter).getPointer() ); 00113 } 00114 00115 return ret; 00116 } 00117 00118 const std::set<dtn::data::EID> Bundle::BlockList::getEIDs() const 00119 { 00120 std::set<dtn::data::EID> ret; 00121 00122 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00123 { 00124 std::list<EID> elist = (*iter)->getEIDList(); 00125 00126 for (std::list<dtn::data::EID>::const_iterator iter = elist.begin(); iter != elist.end(); iter++) 00127 { 00128 ret.insert(*iter); 00129 } 00130 } 00131 00132 return ret; 00133 } 00134 00135 bool Bundle::operator!=(const Bundle& other) const 00136 { 00137 return PrimaryBlock(*this) != other; 00138 } 00139 00140 bool Bundle::operator==(const Bundle& other) const 00141 { 00142 return PrimaryBlock(*this) == other; 00143 } 00144 00145 bool Bundle::operator<(const Bundle& other) const 00146 { 00147 return PrimaryBlock(*this) < other; 00148 } 00149 00150 bool Bundle::operator>(const Bundle& other) const 00151 { 00152 return PrimaryBlock(*this) > other; 00153 } 00154 00155 const std::list<const dtn::data::Block*> Bundle::getBlocks() const 00156 { 00157 return _blocks.getList(); 00158 } 00159 00160 void Bundle::remove(const dtn::data::Block &block) 00161 { 00162 _blocks.remove(&block); 00163 } 00164 00165 void Bundle::clearBlocks() 00166 { 00167 _blocks.clear(); 00168 } 00169 00170 dtn::data::PayloadBlock& Bundle::insert(const dtn::data::Block &before, ibrcommon::BLOB::Reference &ref) 00171 { 00172 dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref); 00173 dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock); 00174 00175 #ifdef __DEVELOPMENT_ASSERTIONS__ 00176 assert(block != NULL); 00177 #endif 00178 00179 _blocks.insert(block, &before); 00180 return (*tmpblock); 00181 } 00182 00183 dtn::data::PayloadBlock& Bundle::push_front(ibrcommon::BLOB::Reference &ref) 00184 { 00185 dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref); 00186 dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock); 00187 00188 #ifdef __DEVELOPMENT_ASSERTIONS__ 00189 assert(block != NULL); 00190 #endif 00191 00192 _blocks.push_front(block); 00193 return (*tmpblock); 00194 } 00195 00196 dtn::data::PayloadBlock& Bundle::push_back(ibrcommon::BLOB::Reference &ref) 00197 { 00198 dtn::data::PayloadBlock *tmpblock = new dtn::data::PayloadBlock(ref); 00199 dtn::data::Block *block = dynamic_cast<dtn::data::Block*>(tmpblock); 00200 00201 #ifdef __DEVELOPMENT_ASSERTIONS__ 00202 assert(block != NULL); 00203 #endif 00204 00205 _blocks.push_back(block); 00206 return (*tmpblock); 00207 } 00208 00209 dtn::data::Block& Bundle::push_back(dtn::data::ExtensionBlock::Factory &factory) 00210 { 00211 dtn::data::Block *block = factory.create(); 00212 00213 #ifdef __DEVELOPMENT_ASSERTIONS__ 00214 assert(block != NULL); 00215 #endif 00216 00217 _blocks.push_back(block); 00218 return (*block); 00219 } 00220 00221 Block& Bundle::insert(dtn::data::ExtensionBlock::Factory& factory, const dtn::data::Block& before) 00222 { 00223 dtn::data::Block *block = factory.create(); 00224 00225 #ifdef __DEVELOPMENT_ASSERTIONS__ 00226 assert(block != NULL); 00227 #endif 00228 00229 _blocks.insert(block, &before); 00230 return (*block); 00231 } 00232 00233 string Bundle::toString() const 00234 { 00235 return PrimaryBlock::toString(); 00236 } 00237 00238 template<> 00239 CustodySignalBlock& Bundle::BlockList::get<CustodySignalBlock>() 00240 { 00241 try { 00242 // copy all blocks to the list 00243 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00244 { 00245 if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE) 00246 { 00247 Block *b = (*iter).getPointer(); 00248 return dynamic_cast<CustodySignalBlock&>(*b); 00249 } 00250 } 00251 } catch (const std::bad_cast&) { 00252 00253 } 00254 00255 throw NoSuchBlockFoundException(); 00256 } 00257 00258 template<> 00259 const CustodySignalBlock& Bundle::BlockList::get<const CustodySignalBlock>() const 00260 { 00261 try { 00262 // copy all blocks to the list 00263 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00264 { 00265 if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE) 00266 { 00267 const Block *b = (*iter).getPointer(); 00268 return dynamic_cast<const CustodySignalBlock&>(*b); 00269 } 00270 } 00271 } catch (const std::bad_cast&) { 00272 00273 } 00274 00275 throw NoSuchBlockFoundException(); 00276 } 00277 00278 template<> 00279 StatusReportBlock& Bundle::BlockList::get<StatusReportBlock> () 00280 { 00281 try { 00282 // copy all blocks to the list 00283 for (std::list<refcnt_ptr<Block> >::iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00284 { 00285 if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE) 00286 { 00287 Block *b = (*iter).getPointer(); 00288 return dynamic_cast<StatusReportBlock&>(*b); 00289 } 00290 } 00291 } catch (const std::bad_cast&) { 00292 00293 } 00294 00295 throw NoSuchBlockFoundException(); 00296 } 00297 00298 template<> 00299 const StatusReportBlock& Bundle::BlockList::get<const StatusReportBlock>() const 00300 { 00301 try { 00302 // copy all blocks to the list 00303 for (std::list<refcnt_ptr<Block> >::const_iterator iter = _blocks.begin(); iter != _blocks.end(); iter++) 00304 { 00305 if ((*iter)->getType() == PayloadBlock::BLOCK_TYPE) 00306 { 00307 const Block *b = (*iter).getPointer(); 00308 return dynamic_cast<const StatusReportBlock&>(*b); 00309 } 00310 } 00311 } catch (const std::bad_cast&) { 00312 00313 } 00314 00315 throw NoSuchBlockFoundException(); 00316 } 00317 } 00318 } 00319