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