Go to the documentation of this file.00001 #include "ibrdtn/data/Serializer.h"
00002 #include "ibrdtn/data/Bundle.h"
00003 #include "ibrdtn/data/Block.h"
00004 #include "ibrdtn/data/BundleString.h"
00005 #include "ibrdtn/data/StatusReportBlock.h"
00006 #include "ibrdtn/data/CustodySignalBlock.h"
00007 #include "ibrdtn/data/ExtensionBlock.h"
00008 #include <ibrcommon/refcnt_ptr.h>
00009 #include <ibrcommon/Logger.h>
00010 #include <list>
00011
00012 #ifdef __DEVELOPMENT_ASSERTIONS__
00013 #include <cassert>
00014 #endif
00015
00016 namespace dtn
00017 {
00018 namespace data
00019 {
00020 DefaultSerializer::DefaultSerializer(std::ostream& stream)
00021 : _stream(stream), _compressable(false)
00022 {
00023 }
00024
00025 DefaultSerializer::DefaultSerializer(std::ostream& stream, const Dictionary &d)
00026 : _stream(stream), _dictionary(d), _compressable(false)
00027 {
00028 }
00029
00030 void DefaultSerializer::rebuildDictionary(const dtn::data::Bundle &obj)
00031 {
00032
00033 _dictionary.clear();
00034
00035
00036 _dictionary.add(obj._destination);
00037 _dictionary.add(obj._source);
00038 _dictionary.add(obj._reportto);
00039 _dictionary.add(obj._custodian);
00040
00041
00042 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00043
00044 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00045 {
00046 const Block &b = (*(*iter));
00047 _dictionary.add( b.getEIDList() );
00048 }
00049 }
00050
00051 Serializer& DefaultSerializer::operator <<(const dtn::data::Bundle& obj)
00052 {
00053
00054 rebuildDictionary(obj);
00055
00056
00057 _compressable = isCompressable(obj);
00058
00059
00060 (*this) << (PrimaryBlock&)obj;
00061
00062
00063 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00064
00065 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00066 {
00067 const Block &b = (*(*iter));
00068 (*this) << b;
00069 }
00070
00071 return (*this);
00072 }
00073
00074 bool DefaultSerializer::isCompressable(const dtn::data::Bundle &obj) const
00075 {
00076
00077 bool compressable = ( obj._source.isCompressable() &&
00078 obj._destination.isCompressable() &&
00079 obj._reportto.isCompressable() &&
00080 obj._custodian.isCompressable() );
00081
00082 if (compressable)
00083 {
00084
00085 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00086
00087 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00088 {
00089 const Block &b = (*(*iter));
00090 const std::list<dtn::data::EID> eids = b.getEIDList();
00091
00092 for (std::list<dtn::data::EID>::const_iterator eit = eids.begin(); eit != eids.end(); eit++)
00093 {
00094 const dtn::data::EID &eid = (*eit);
00095 if (!eid.isCompressable())
00096 {
00097 return false;
00098 }
00099 }
00100 }
00101 }
00102
00103 return compressable;
00104 }
00105
00106 Serializer& DefaultSerializer::operator <<(const dtn::data::PrimaryBlock& obj)
00107 {
00108 _stream << dtn::data::BUNDLE_VERSION;
00109 _stream << dtn::data::SDNV(obj._procflags);
00110
00111
00112 size_t len = 0;
00113 dtn::data::SDNV primaryheader[14];
00114
00115 primaryheader[8] = SDNV(obj._timestamp);
00116 primaryheader[9] = SDNV(obj._sequencenumber);
00117 primaryheader[10] = SDNV(obj._lifetime);
00118
00119 pair<size_t, size_t> ref;
00120
00121 if (_compressable)
00122 {
00123
00124 ref = obj._destination.getCompressed();
00125 primaryheader[0] = SDNV(ref.first);
00126 primaryheader[1] = SDNV(ref.second);
00127
00128
00129 ref = obj._source.getCompressed();
00130 primaryheader[2] = SDNV(ref.first);
00131 primaryheader[3] = SDNV(ref.second);
00132
00133
00134 ref = obj._reportto.getCompressed();
00135 primaryheader[4] = SDNV(ref.first);
00136 primaryheader[5] = SDNV(ref.second);
00137
00138
00139 ref = obj._custodian.getCompressed();
00140 primaryheader[6] = SDNV(ref.first);
00141 primaryheader[7] = SDNV(ref.second);
00142
00143
00144 primaryheader[11] = SDNV(0);
00145 }
00146 else
00147 {
00148
00149 ref = _dictionary.getRef(obj._destination);
00150 primaryheader[0] = SDNV(ref.first);
00151 primaryheader[1] = SDNV(ref.second);
00152
00153
00154 ref = _dictionary.getRef(obj._source);
00155 primaryheader[2] = SDNV(ref.first);
00156 primaryheader[3] = SDNV(ref.second);
00157
00158
00159 ref = _dictionary.getRef(obj._reportto);
00160 primaryheader[4] = SDNV(ref.first);
00161 primaryheader[5] = SDNV(ref.second);
00162
00163
00164 ref = _dictionary.getRef(obj._custodian);
00165 primaryheader[6] = SDNV(ref.first);
00166 primaryheader[7] = SDNV(ref.second);
00167
00168
00169 primaryheader[11] = SDNV(_dictionary.getSize());
00170 len += _dictionary.getSize();
00171 }
00172
00173 for (int i = 0; i < 12; i++)
00174 {
00175 len += primaryheader[i].getLength();
00176 }
00177
00178 if (obj.get(dtn::data::Bundle::FRAGMENT))
00179 {
00180 primaryheader[12] = SDNV(obj._fragmentoffset);
00181 primaryheader[13] = SDNV(obj._appdatalength);
00182
00183 len += primaryheader[12].getLength();
00184 len += primaryheader[13].getLength();
00185 }
00186
00187
00188 _stream << SDNV(len);
00189
00190
00191
00192
00193
00194 for (int i = 0; i < 11; i++)
00195 {
00196 _stream << primaryheader[i];
00197 }
00198
00199 if (_compressable)
00200 {
00201
00202 _stream << primaryheader[11];
00203 }
00204 else
00205 {
00206
00207 _stream << _dictionary;
00208 }
00209
00210 if (obj.get(dtn::data::Bundle::FRAGMENT))
00211 {
00212 _stream << primaryheader[12];
00213 _stream << primaryheader[13];
00214 }
00215
00216 return (*this);
00217 }
00218
00219 Serializer& DefaultSerializer::operator <<(const dtn::data::Block& obj)
00220 {
00221 _stream << obj._blocktype;
00222 _stream << dtn::data::SDNV(obj._procflags);
00223
00224 #ifdef __DEVELOPMENT_ASSERTIONS__
00225
00226 assert(!obj.get(Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00227 #endif
00228
00229 if (obj.get(Block::BLOCK_CONTAINS_EIDS))
00230 {
00231 _stream << SDNV(obj._eids.size());
00232 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00233 {
00234 pair<size_t, size_t> offsets;
00235
00236 if (_compressable)
00237 {
00238 offsets = (*it).getCompressed();
00239 }
00240 else
00241 {
00242 offsets = _dictionary.getRef(*it);
00243 }
00244
00245 _stream << SDNV(offsets.first);
00246 _stream << SDNV(offsets.second);
00247 }
00248 }
00249
00250
00251 _stream << SDNV(obj.getLength());
00252
00253
00254 obj.serialize(_stream);
00255
00256 return (*this);
00257 }
00258
00259 size_t DefaultSerializer::getLength(const dtn::data::Bundle &obj)
00260 {
00261
00262 rebuildDictionary(obj);
00263
00264 size_t len = 0;
00265 len += getLength( (PrimaryBlock&)obj );
00266
00267
00268 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00269
00270 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00271 {
00272 const Block &b = (*(*iter));
00273 len += getLength( b );
00274 }
00275
00276 return len;
00277 }
00278
00279 size_t DefaultSerializer::getLength(const dtn::data::PrimaryBlock& obj) const
00280 {
00281 size_t len = 0;
00282
00283 len += sizeof(dtn::data::BUNDLE_VERSION);
00284 len += dtn::data::SDNV(obj._procflags).getLength();
00285
00286
00287 dtn::data::SDNV primaryheader[14];
00288 pair<size_t, size_t> ref;
00289
00290 if (_compressable)
00291 {
00292
00293 ref = obj._destination.getCompressed();
00294 primaryheader[0] = SDNV(ref.first);
00295 primaryheader[1] = SDNV(ref.second);
00296
00297
00298 ref = obj._source.getCompressed();
00299 primaryheader[2] = SDNV(ref.first);
00300 primaryheader[3] = SDNV(ref.second);
00301
00302
00303 ref = obj._reportto.getCompressed();
00304 primaryheader[4] = SDNV(ref.first);
00305 primaryheader[5] = SDNV(ref.second);
00306
00307
00308 ref = obj._custodian.getCompressed();
00309 primaryheader[6] = SDNV(ref.first);
00310 primaryheader[7] = SDNV(ref.second);
00311
00312
00313 primaryheader[11] = SDNV(0);
00314 }
00315 else
00316 {
00317
00318 ref = _dictionary.getRef(obj._destination);
00319 primaryheader[0] = SDNV(ref.first);
00320 primaryheader[1] = SDNV(ref.second);
00321
00322
00323 ref = _dictionary.getRef(obj._source);
00324 primaryheader[2] = SDNV(ref.first);
00325 primaryheader[3] = SDNV(ref.second);
00326
00327
00328 ref = _dictionary.getRef(obj._reportto);
00329 primaryheader[4] = SDNV(ref.first);
00330 primaryheader[5] = SDNV(ref.second);
00331
00332
00333 ref = _dictionary.getRef(obj._custodian);
00334 primaryheader[6] = SDNV(ref.first);
00335 primaryheader[7] = SDNV(ref.second);
00336
00337
00338 primaryheader[11] = SDNV(_dictionary.getSize());
00339 }
00340
00341
00342 primaryheader[8] = SDNV(obj._timestamp);
00343
00344
00345 primaryheader[9] = SDNV(obj._sequencenumber);
00346
00347
00348 primaryheader[10] = SDNV(obj._lifetime);
00349
00350 for (int i = 0; i < 11; i++)
00351 {
00352 len += primaryheader[i].getLength();
00353 }
00354
00355 if (_compressable)
00356 {
00357
00358 len += primaryheader[11].getLength();
00359 }
00360 else
00361 {
00362
00363 len += primaryheader[11].getLength();
00364 len += _dictionary.getSize();
00365 }
00366
00367 if (obj.get(dtn::data::Bundle::FRAGMENT))
00368 {
00369 primaryheader[12] = SDNV(obj._fragmentoffset);
00370 primaryheader[13] = SDNV(obj._appdatalength);
00371
00372 len += primaryheader[12].getLength();
00373 len += primaryheader[13].getLength();
00374 }
00375
00376 len += SDNV(len).getLength();
00377
00378 return len;
00379 }
00380
00381 size_t DefaultSerializer::getLength(const dtn::data::Block &obj) const
00382 {
00383 size_t len = 0;
00384
00385 len += sizeof(obj._blocktype);
00386 len += dtn::data::SDNV(obj._procflags).getLength();
00387
00388 #ifdef __DEVELOPMENT_ASSERTIONS__
00389
00390 assert(!obj.get(Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00391 #endif
00392
00393 if (obj.get(Block::BLOCK_CONTAINS_EIDS))
00394 {
00395 len += dtn::data::SDNV(obj._eids.size()).getLength();
00396 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00397 {
00398 pair<size_t, size_t> offsets = _dictionary.getRef(*it);
00399 len += SDNV(offsets.first).getLength();
00400 len += SDNV(offsets.second).getLength();
00401 }
00402 }
00403
00404
00405 len += obj.getLength();
00406
00407 return len;
00408 }
00409
00410 DefaultDeserializer::DefaultDeserializer(std::istream& stream)
00411 : _stream(stream), _validator(_default_validator), _compressed(false)
00412 {
00413 }
00414
00415 DefaultDeserializer::DefaultDeserializer(std::istream &stream, Validator &v)
00416 : _stream(stream), _validator(v), _compressed(false)
00417 {
00418 }
00419
00420 DefaultDeserializer::DefaultDeserializer(std::istream &stream, const Dictionary &d)
00421 : _stream(stream), _validator(_default_validator), _dictionary(d), _compressed(false)
00422 {
00423 }
00424
00425 Deserializer& DefaultDeserializer::operator >>(dtn::data::Bundle& obj)
00426 {
00427
00428 obj.clearBlocks();
00429
00430
00431 (*this) >> (PrimaryBlock&)obj;
00432
00433
00434 bool lastblock = false;
00435
00436
00437 while (!_stream.eof() && !lastblock)
00438 {
00439 char block_type;
00440
00441
00442 block_type = _stream.peek();
00443
00444 switch (block_type)
00445 {
00446 case 0:
00447 {
00448 throw dtn::InvalidDataException("block type is zero");
00449 break;
00450 }
00451
00452 case dtn::data::PayloadBlock::BLOCK_TYPE:
00453 {
00454 if (obj.get(dtn::data::Bundle::APPDATA_IS_ADMRECORD))
00455 {
00456
00457 dtn::data::ExtensionBlock &block = obj.push_back<dtn::data::ExtensionBlock>();
00458
00459
00460 (*this) >> block;
00461
00462
00463 char admfield;
00464 ibrcommon::BLOB::Reference ref = block.getBLOB();
00465 ref.iostream()->get(admfield);
00466
00467
00468 stringstream ss;
00469 DefaultSerializer serializer(ss, _dictionary);
00470 DefaultDeserializer deserializer(ss, _dictionary);
00471
00472 serializer << block;
00473
00474
00475 obj.remove(block);
00476
00477 switch (admfield >> 4)
00478 {
00479 case 1:
00480 {
00481 dtn::data::StatusReportBlock &block = obj.push_back<dtn::data::StatusReportBlock>();
00482 deserializer >> block;
00483 lastblock = block.get(Block::LAST_BLOCK);
00484 break;
00485 }
00486
00487 case 2:
00488 {
00489 dtn::data::CustodySignalBlock &block = obj.push_back<dtn::data::CustodySignalBlock>();
00490 deserializer >> block;
00491 lastblock = block.get(Block::LAST_BLOCK);
00492 break;
00493 }
00494
00495 default:
00496 {
00497
00498 break;
00499 }
00500 }
00501
00502 }
00503 else
00504 {
00505 dtn::data::PayloadBlock &block = obj.push_back<dtn::data::PayloadBlock>();
00506 (*this) >> block;
00507
00508 lastblock = block.get(Block::LAST_BLOCK);
00509 }
00510 break;
00511 }
00512
00513 default:
00514 {
00515
00516 try {
00517 ExtensionBlock::Factory &f = dtn::data::ExtensionBlock::Factory::get(block_type);
00518
00519 dtn::data::Block &block = obj.push_back(f);
00520 (*this) >> block;
00521 lastblock = block.get(Block::LAST_BLOCK);
00522
00523 if (block.get(dtn::data::Block::DISCARD_IF_NOT_PROCESSED))
00524 {
00525 IBRCOMMON_LOGGER_DEBUG(5) << "unprocessable block in bundle " << obj.toString() << " has been removed" << IBRCOMMON_LOGGER_ENDL;
00526
00527
00528 obj.remove(block);
00529 }
00530 }
00531 catch (const ibrcommon::Exception &ex)
00532 {
00533 dtn::data::ExtensionBlock &block = obj.push_back<dtn::data::ExtensionBlock>();
00534 (*this) >> block;
00535 lastblock = block.get(Block::LAST_BLOCK);
00536
00537 if (block.get(dtn::data::Block::DISCARD_IF_NOT_PROCESSED))
00538 {
00539 IBRCOMMON_LOGGER_DEBUG(5) << "unprocessable block in bundle " << obj.toString() << " has been removed" << IBRCOMMON_LOGGER_ENDL;
00540
00541
00542 obj.remove(block);
00543 }
00544 }
00545 break;
00546 }
00547 }
00548 }
00549
00550
00551 _validator.validate(obj);
00552
00553 return (*this);
00554 }
00555
00556 Deserializer& DefaultDeserializer::operator >>(dtn::data::PrimaryBlock& obj)
00557 {
00558 char version = 0;
00559 SDNV tmpsdnv;
00560 SDNV blocklength;
00561
00562
00563 _stream.get(version);
00564 if (version != dtn::data::BUNDLE_VERSION) throw dtn::InvalidProtocolException("Bundle version differ from ours.");
00565
00566
00567 _stream >> tmpsdnv;
00568 obj._procflags = tmpsdnv.getValue();
00569
00570
00571 _stream >> blocklength;
00572
00573
00574 pair<SDNV, SDNV> ref[4];
00575 for (int i = 0; i < 4; i++)
00576 {
00577 _stream >> ref[i].first;
00578 _stream >> ref[i].second;
00579 }
00580
00581
00582 _stream >> tmpsdnv;
00583 obj._timestamp = tmpsdnv.getValue();
00584
00585
00586 _stream >> tmpsdnv;
00587 obj._sequencenumber = tmpsdnv.getValue();
00588
00589
00590 _stream >> tmpsdnv;
00591 obj._lifetime = tmpsdnv.getValue();
00592
00593 try {
00594
00595 _stream >> _dictionary;
00596
00597
00598 obj._destination = _dictionary.get(ref[0].first.getValue(), ref[0].second.getValue());
00599 obj._source = _dictionary.get(ref[1].first.getValue(), ref[1].second.getValue());
00600 obj._reportto = _dictionary.get(ref[2].first.getValue(), ref[2].second.getValue());
00601 obj._custodian = _dictionary.get(ref[3].first.getValue(), ref[3].second.getValue());
00602 _compressed = false;
00603 } catch (const dtn::InvalidDataException&) {
00604
00605 obj._destination = dtn::data::EID(ref[0].first.getValue(), ref[0].second.getValue());
00606 obj._source = dtn::data::EID(ref[1].first.getValue(), ref[1].second.getValue());
00607 obj._reportto = dtn::data::EID(ref[2].first.getValue(), ref[2].second.getValue());
00608 obj._custodian = dtn::data::EID(ref[3].first.getValue(), ref[3].second.getValue());
00609 _compressed = true;
00610 }
00611
00612
00613 if (obj.get(dtn::data::Bundle::FRAGMENT))
00614 {
00615 _stream >> tmpsdnv;
00616 obj._fragmentoffset = tmpsdnv.getValue();
00617
00618 _stream >> tmpsdnv;
00619 obj._appdatalength = tmpsdnv.getValue();
00620 }
00621
00622
00623 _validator.validate(obj);
00624
00625 return (*this);
00626 }
00627
00628 Deserializer& DefaultDeserializer::operator >>(dtn::data::Block& obj)
00629 {
00630 dtn::data::SDNV procflags_sdnv;
00631 _stream.get(obj._blocktype);
00632 _stream >> procflags_sdnv;
00633
00634
00635 obj._procflags = procflags_sdnv.getValue() & (~(dtn::data::Block::LAST_BLOCK) | obj._procflags);
00636
00637
00638 if ( obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS))
00639 {
00640 SDNV eidcount;
00641 _stream >> eidcount;
00642
00643 for (unsigned int i = 0; i < eidcount.getValue(); i++)
00644 {
00645 SDNV scheme, ssp;
00646 _stream >> scheme;
00647 _stream >> ssp;
00648
00649 if (_compressed)
00650 {
00651 obj.addEID( dtn::data::EID(scheme.getValue(), ssp.getValue()) );
00652 }
00653 else
00654 {
00655 obj.addEID( _dictionary.get(scheme.getValue(), ssp.getValue()) );
00656 }
00657 }
00658 }
00659
00660
00661 SDNV block_size;
00662 _stream >> block_size;
00663 obj._blocksize = block_size.getValue();
00664
00665
00666 _validator.validate(obj, block_size.getValue());
00667
00668
00669 obj.deserialize(_stream);
00670
00671 return (*this);
00672 }
00673
00674 AcceptValidator::AcceptValidator()
00675 {
00676 }
00677
00678 AcceptValidator::~AcceptValidator()
00679 {
00680 }
00681
00682 void AcceptValidator::validate(const dtn::data::PrimaryBlock&) const throw (RejectedException)
00683 {
00684 }
00685
00686 void AcceptValidator::validate(const dtn::data::Block&, const size_t) const throw (RejectedException)
00687 {
00688
00689 }
00690
00691 void AcceptValidator::validate(const dtn::data::Bundle&) const throw (RejectedException)
00692 {
00693
00694 }
00695
00696 SeparateSerializer::SeparateSerializer(std::ostream& stream)
00697 : DefaultSerializer(stream)
00698 {
00699 }
00700
00701 SeparateSerializer::~SeparateSerializer()
00702 {
00703 }
00704
00705 Serializer& SeparateSerializer::operator <<(const dtn::data::Block& obj)
00706 {
00707 _stream << obj._blocktype;
00708 _stream << dtn::data::SDNV(obj._procflags);
00709
00710 #ifdef __DEVELOPMENT_ASSERTIONS__
00711
00712 assert(!obj.get(Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00713 #endif
00714
00715 if (obj.get(Block::BLOCK_CONTAINS_EIDS))
00716 {
00717 _stream << SDNV(obj._eids.size());
00718 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00719 {
00720 dtn::data::BundleString str((*it).getString());
00721 _stream << str;
00722 }
00723 }
00724
00725
00726 _stream << SDNV(obj.getLength());
00727
00728
00729 obj.serialize(_stream);
00730
00731 return (*this);
00732 }
00733
00734 size_t SeparateSerializer::getLength(const dtn::data::Block &obj) const
00735 {
00736 size_t len = 0;
00737
00738 len += sizeof(obj._blocktype);
00739 len += dtn::data::SDNV(obj._procflags).getLength();
00740
00741 #ifdef __DEVELOPMENT_ASSERTIONS__
00742
00743 assert(!obj.get(Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00744 #endif
00745
00746 if (obj.get(Block::BLOCK_CONTAINS_EIDS))
00747 {
00748 len += dtn::data::SDNV(obj._eids.size()).getLength();
00749 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00750 {
00751 dtn::data::BundleString str((*it).getString());
00752 len += str.getLength();
00753 }
00754 }
00755
00756
00757 len += obj.getLength();
00758
00759 return len;
00760 }
00761
00762 SeparateDeserializer::SeparateDeserializer(std::istream& stream, Bundle &b)
00763 : DefaultDeserializer(stream), _bundle(b)
00764 {
00765 }
00766
00767 SeparateDeserializer::~SeparateDeserializer()
00768 {
00769 }
00770
00771 void SeparateDeserializer::readBlock()
00772 {
00773 char block_type;
00774
00775
00776 block_type = _stream.peek();
00777
00778 switch (block_type)
00779 {
00780 case 0:
00781 {
00782 throw dtn::InvalidDataException("block type is zero");
00783 break;
00784 }
00785
00786 case dtn::data::PayloadBlock::BLOCK_TYPE:
00787 {
00788 if (_bundle.get(dtn::data::Bundle::APPDATA_IS_ADMRECORD))
00789 {
00790
00791 dtn::data::ExtensionBlock &block = _bundle.push_back<dtn::data::ExtensionBlock>();
00792
00793
00794 int blockbegin = _stream.tellg();
00795
00796
00797 (*this) >> block;
00798
00799
00800 char admfield;
00801 ibrcommon::BLOB::Reference ref = block.getBLOB();
00802 ref.iostream()->get(admfield);
00803
00804
00805 _bundle.remove(block);
00806
00807
00808
00809 _stream.seekg(blockbegin);
00810
00811 switch (admfield >> 4)
00812 {
00813 case 1:
00814 {
00815 dtn::data::StatusReportBlock &block = _bundle.push_back<dtn::data::StatusReportBlock>();
00816 (*this) >> block;
00817 break;
00818 }
00819
00820 case 2:
00821 {
00822 dtn::data::CustodySignalBlock &block = _bundle.push_back<dtn::data::CustodySignalBlock>();
00823 (*this) >> block;
00824 break;
00825 }
00826
00827 default:
00828 {
00829
00830 break;
00831 }
00832 }
00833
00834 }
00835 else
00836 {
00837 dtn::data::PayloadBlock &block = _bundle.push_back<dtn::data::PayloadBlock>();
00838 (*this) >> block;
00839 }
00840 break;
00841 }
00842
00843 default:
00844 {
00845
00846 try {
00847 ExtensionBlock::Factory &f = dtn::data::ExtensionBlock::Factory::get(block_type);
00848 dtn::data::Block &block = _bundle.push_back(f);
00849 (*this) >> block;
00850 } catch (const ibrcommon::Exception &ex) {
00851 dtn::data::ExtensionBlock &block = _bundle.push_back<dtn::data::ExtensionBlock>();
00852 (*this) >> block;
00853 }
00854 break;
00855 }
00856 }
00857 }
00858
00859 Deserializer& SeparateDeserializer::operator >>(dtn::data::Block& obj)
00860 {
00861 dtn::data::SDNV procflags_sdnv;
00862 _stream.get(obj._blocktype);
00863 _stream >> procflags_sdnv;
00864 obj._procflags = procflags_sdnv.getValue();
00865
00866
00867 if ( obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS))
00868 {
00869 SDNV eidcount;
00870 _stream >> eidcount;
00871
00872 for (unsigned int i = 0; i < eidcount.getValue(); i++)
00873 {
00874 dtn::data::BundleString str;
00875 _stream >> str;
00876 obj.addEID(dtn::data::EID(str));
00877 }
00878 }
00879
00880
00881 SDNV block_size;
00882 _stream >> block_size;
00883 obj._blocksize = block_size.getValue();
00884
00885
00886 _validator.validate(obj, block_size.getValue());
00887
00888
00889 obj.deserialize(_stream);
00890
00891 return (*this);
00892 }
00893 }
00894 }