00001 #include "ibrdtn/data/Serializer.h"
00002 #include "ibrdtn/data/Bundle.h"
00003 #include "ibrdtn/data/Block.h"
00004 #include "ibrdtn/data/StatusReportBlock.h"
00005 #include "ibrdtn/data/CustodySignalBlock.h"
00006 #include "ibrdtn/data/ExtensionBlock.h"
00007 #include "ibrdtn/data/ExtensionBlockFactory.h"
00008 #include "ibrcommon/refcnt_ptr.h"
00009 #include <list>
00010 #include <cassert>
00011
00012 namespace dtn
00013 {
00014 namespace data
00015 {
00016 DefaultSerializer::DefaultSerializer(std::ostream& stream)
00017 : _stream(stream)
00018 {
00019 }
00020
00021 DefaultSerializer::DefaultSerializer(std::ostream& stream, const Dictionary &d)
00022 : _stream(stream), _dictionary(d)
00023 {
00024 }
00025
00026 void DefaultSerializer::rebuildDictionary(const dtn::data::Bundle &obj)
00027 {
00028
00029 _dictionary.clear();
00030
00031
00032 _dictionary.add(obj._destination);
00033 _dictionary.add(obj._source);
00034 _dictionary.add(obj._reportto);
00035 _dictionary.add(obj._custodian);
00036
00037
00038 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00039
00040 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00041 {
00042 const Block &b = (*(*iter));
00043 _dictionary.add( b.getEIDList() );
00044 }
00045 }
00046
00047 Serializer& DefaultSerializer::operator <<(const dtn::data::Bundle& obj)
00048 {
00049
00050 rebuildDictionary(obj);
00051
00052
00053 (*this) << (PrimaryBlock&)obj;
00054
00055
00056 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00057
00058 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00059 {
00060 const Block &b = (*(*iter));
00061 (*this) << b;
00062 }
00063
00064 return (*this);
00065 }
00066
00067 Serializer& DefaultSerializer::operator <<(const dtn::data::PrimaryBlock& obj)
00068 {
00069 _stream << dtn::data::BUNDLE_VERSION;
00070 _stream << dtn::data::SDNV(obj._procflags);
00071
00072
00073 size_t len = 0;
00074 dtn::data::SDNV primaryheader[14];
00075 pair<size_t, size_t> ref;
00076
00077
00078 ref = _dictionary.getRef(obj._destination);
00079 primaryheader[0] = SDNV(ref.first);
00080 primaryheader[1] = SDNV(ref.second);
00081
00082
00083 ref = _dictionary.getRef(obj._source);
00084 primaryheader[2] = SDNV(ref.first);
00085 primaryheader[3] = SDNV(ref.second);
00086
00087
00088 ref = _dictionary.getRef(obj._reportto);
00089 primaryheader[4] = SDNV(ref.first);
00090 primaryheader[5] = SDNV(ref.second);
00091
00092
00093 ref = _dictionary.getRef(obj._custodian);
00094 primaryheader[6] = SDNV(ref.first);
00095 primaryheader[7] = SDNV(ref.second);
00096
00097
00098 primaryheader[8] = SDNV(obj._timestamp);
00099
00100
00101 primaryheader[9] = SDNV(obj._sequencenumber);
00102
00103
00104 primaryheader[10] = SDNV(obj._lifetime);
00105
00106
00107 primaryheader[11] = SDNV(_dictionary.getSize());
00108
00109 for (int i = 0; i < 12; i++)
00110 {
00111 len += primaryheader[i].getLength();
00112 }
00113
00114 len += _dictionary.getSize();
00115
00116 if (obj._procflags & dtn::data::Bundle::FRAGMENT)
00117 {
00118 primaryheader[12] = SDNV(obj._fragmentoffset);
00119 primaryheader[13] = SDNV(obj._appdatalength);
00120
00121 len += primaryheader[12].getLength();
00122 len += primaryheader[13].getLength();
00123 }
00124
00125
00126 _stream << SDNV(len);
00127
00128
00129
00130
00131
00132 for (int i = 0; i < 11; i++)
00133 {
00134 _stream << primaryheader[i];
00135 }
00136
00137
00138 _stream << _dictionary;
00139
00140 if (obj._procflags & dtn::data::Bundle::FRAGMENT)
00141 {
00142 _stream << primaryheader[12];
00143 _stream << primaryheader[13];
00144 }
00145
00146 return (*this);
00147 }
00148
00149 Serializer& DefaultSerializer::operator <<(const dtn::data::Block& obj)
00150 {
00151 _stream << obj._blocktype;
00152 _stream << dtn::data::SDNV(obj._procflags);
00153
00154
00155 assert(!(obj._procflags & Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00156
00157 if (obj._procflags & Block::BLOCK_CONTAINS_EIDS)
00158 {
00159 _stream << SDNV(obj._eids.size());
00160 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00161 {
00162 pair<size_t, size_t> offsets = _dictionary.getRef(*it);
00163 _stream << SDNV(offsets.first);
00164 _stream << SDNV(offsets.second);
00165 }
00166 }
00167
00168
00169 _stream << SDNV(obj.getLength());
00170
00171
00172 obj.serialize(_stream);
00173
00174 return (*this);
00175 }
00176
00177 size_t DefaultSerializer::getLength(const dtn::data::Bundle &obj) const
00178 {
00179 size_t len = 0;
00180 len += getLength( (PrimaryBlock&)obj );
00181
00182
00183 std::list<refcnt_ptr<Block> > list = obj._blocks._blocks;
00184
00185 for (std::list<refcnt_ptr<Block> >::const_iterator iter = list.begin(); iter != list.end(); iter++)
00186 {
00187 const Block &b = (*(*iter));
00188 len += getLength( b );
00189 }
00190
00191 return len;
00192 }
00193
00194 size_t DefaultSerializer::getLength(const dtn::data::PrimaryBlock& obj) const
00195 {
00196 size_t len = 0;
00197
00198 len += sizeof(dtn::data::BUNDLE_VERSION);
00199 len += dtn::data::SDNV(obj._procflags).getLength();
00200
00201
00202 dtn::data::SDNV primaryheader[14];
00203 pair<size_t, size_t> ref;
00204
00205
00206 ref = _dictionary.getRef(obj._destination);
00207 primaryheader[0] = SDNV(ref.first);
00208 primaryheader[1] = SDNV(ref.second);
00209
00210
00211 ref = _dictionary.getRef(obj._source);
00212 primaryheader[2] = SDNV(ref.first);
00213 primaryheader[3] = SDNV(ref.second);
00214
00215
00216 ref = _dictionary.getRef(obj._reportto);
00217 primaryheader[4] = SDNV(ref.first);
00218 primaryheader[5] = SDNV(ref.second);
00219
00220
00221 ref = _dictionary.getRef(obj._custodian);
00222 primaryheader[6] = SDNV(ref.first);
00223 primaryheader[7] = SDNV(ref.second);
00224
00225
00226 primaryheader[8] = SDNV(obj._timestamp);
00227
00228
00229 primaryheader[9] = SDNV(obj._sequencenumber);
00230
00231
00232 primaryheader[10] = SDNV(obj._lifetime);
00233
00234
00235 primaryheader[11] = SDNV(_dictionary.getSize());
00236
00237 for (int i = 0; i < 12; i++)
00238 {
00239 len += primaryheader[i].getLength();
00240 }
00241
00242 len += _dictionary.getSize();
00243
00244 if (obj._procflags & dtn::data::Bundle::FRAGMENT)
00245 {
00246 primaryheader[12] = SDNV(obj._fragmentoffset);
00247 primaryheader[13] = SDNV(obj._appdatalength);
00248
00249 len += primaryheader[12].getLength();
00250 len += primaryheader[13].getLength();
00251 }
00252
00253 return len;
00254 }
00255
00256 size_t DefaultSerializer::getLength(const dtn::data::Block &obj) const
00257 {
00258 size_t len = 0;
00259
00260 len += sizeof(obj._blocktype);
00261 len += dtn::data::SDNV(obj._procflags).getLength();
00262
00263
00264 assert(!(obj._procflags & Block::BLOCK_CONTAINS_EIDS) || (obj._eids.size() > 0));
00265
00266 if (obj._procflags & Block::BLOCK_CONTAINS_EIDS)
00267 {
00268 len += dtn::data::SDNV(obj._eids.size()).getLength();
00269 for (std::list<dtn::data::EID>::const_iterator it = obj._eids.begin(); it != obj._eids.end(); it++)
00270 {
00271 pair<size_t, size_t> offsets = _dictionary.getRef(*it);
00272 len += SDNV(offsets.first).getLength();
00273 len += SDNV(offsets.second).getLength();
00274 }
00275 }
00276
00277
00278 len += obj.getLength();
00279
00280 return len;
00281 }
00282
00283 DefaultDeserializer::DefaultDeserializer(std::istream& stream)
00284 : _stream(stream), _validator(_default_validator)
00285 {
00286 }
00287
00288 DefaultDeserializer::DefaultDeserializer(std::istream &stream, Validator &v)
00289 : _stream(stream), _validator(v)
00290 {
00291 }
00292
00293 DefaultDeserializer::DefaultDeserializer(std::istream &stream, const Dictionary &d)
00294 : _stream(stream), _dictionary(d), _validator(_default_validator)
00295 {
00296 }
00297
00298 Deserializer& DefaultDeserializer::operator >>(dtn::data::Bundle& obj)
00299 {
00300 (*this) >> (PrimaryBlock&)obj;
00301
00302
00303 bool lastblock = false;
00304
00305
00306 while (!_stream.eof() && !lastblock)
00307 {
00308 char block_type;
00309
00310
00311 block_type = _stream.peek();
00312
00313 switch (block_type)
00314 {
00315 case 0:
00316 {
00317 throw dtn::InvalidDataException("block type is zero");
00318 break;
00319 }
00320
00321 case dtn::data::PayloadBlock::BLOCK_TYPE:
00322 {
00323 if (obj._procflags & dtn::data::Bundle::APPDATA_IS_ADMRECORD)
00324 {
00325
00326 dtn::data::ExtensionBlock &block = obj.push_back<dtn::data::ExtensionBlock>();
00327
00328
00329 (*this) >> block;
00330
00331
00332 ibrcommon::BLOB::Reference ref = block.getBLOB();
00333 char admfield; (*ref) >> admfield;
00334
00335
00336 stringstream ss;
00337 DefaultSerializer serializer(ss, _dictionary);
00338 DefaultDeserializer deserializer(ss, _dictionary);
00339
00340 serializer << block;
00341
00342
00343 obj.remove(block);
00344
00345 switch (admfield >> 4)
00346 {
00347 case 1:
00348 {
00349 dtn::data::StatusReportBlock &block = obj.push_back<dtn::data::StatusReportBlock>();
00350 deserializer >> block;
00351 lastblock = block.get(Block::LAST_BLOCK);
00352 break;
00353 }
00354
00355 case 2:
00356 {
00357 dtn::data::CustodySignalBlock &block = obj.push_back<dtn::data::CustodySignalBlock>();
00358 deserializer >> block;
00359 lastblock = block.get(Block::LAST_BLOCK);
00360 break;
00361 }
00362
00363 default:
00364 {
00365
00366 break;
00367 }
00368 }
00369
00370 }
00371 else
00372 {
00373 dtn::data::PayloadBlock &block = obj.push_back<dtn::data::PayloadBlock>();
00374 (*this) >> block;
00375
00376 lastblock = block.get(Block::LAST_BLOCK);
00377 }
00378 break;
00379 }
00380
00381 default:
00382 {
00383
00384 std::map<char, ExtensionBlockFactory*> &factories = dtn::data::Bundle::getExtensionBlockFactories();
00385 std::map<char, ExtensionBlockFactory*>::iterator iter = factories.find(block_type);
00386
00387 if (iter != factories.end())
00388 {
00389 ExtensionBlockFactory &f = (*iter->second);
00390 dtn::data::Block &block = obj.push_back(f);
00391 (*this) >> block;
00392 lastblock = block.get(Block::LAST_BLOCK);
00393 }
00394 else
00395 {
00396 dtn::data::ExtensionBlock &block = obj.push_back<dtn::data::ExtensionBlock>();
00397 (*this) >> block;
00398 lastblock = block.get(Block::LAST_BLOCK);
00399 }
00400 break;
00401 }
00402 }
00403 }
00404
00405
00406 _validator.validate(obj);
00407
00408 return (*this);
00409 }
00410
00411 Deserializer& DefaultDeserializer::operator >>(dtn::data::PrimaryBlock& obj)
00412 {
00413 char version = 0;
00414 SDNV tmpsdnv;
00415 SDNV blocklength;
00416
00417
00418 _stream >> version;
00419 if (version != dtn::data::BUNDLE_VERSION) throw dtn::InvalidProtocolException("Bundle version differ from ours.");
00420
00421
00422 _stream >> tmpsdnv;
00423 obj._procflags = tmpsdnv.getValue();
00424
00425
00426 _stream >> blocklength;
00427
00428
00429 pair<SDNV, SDNV> ref[4];
00430 for (int i = 0; i < 4; i++)
00431 {
00432 _stream >> ref[i].first;
00433 _stream >> ref[i].second;
00434 }
00435
00436
00437 _stream >> tmpsdnv;
00438 obj._timestamp = tmpsdnv.getValue();
00439
00440
00441 _stream >> tmpsdnv;
00442 obj._sequencenumber = tmpsdnv.getValue();
00443
00444
00445 _stream >> tmpsdnv;
00446 obj._lifetime = tmpsdnv.getValue();
00447
00448
00449 _stream >> _dictionary;
00450
00451
00452 obj._destination = _dictionary.get(ref[0].first.getValue(), ref[0].second.getValue());
00453 obj._source = _dictionary.get(ref[1].first.getValue(), ref[1].second.getValue());
00454 obj._reportto = _dictionary.get(ref[2].first.getValue(), ref[2].second.getValue());
00455 obj._custodian = _dictionary.get(ref[3].first.getValue(), ref[3].second.getValue());
00456
00457
00458 if (obj._procflags & dtn::data::Bundle::FRAGMENT)
00459 {
00460 _stream >> tmpsdnv;
00461 obj._fragmentoffset = tmpsdnv.getValue();
00462
00463 _stream >> tmpsdnv;
00464 obj._appdatalength = tmpsdnv.getValue();
00465 }
00466
00467
00468 _validator.validate(obj);
00469
00470 return (*this);
00471 }
00472
00473 Deserializer& DefaultDeserializer::operator >>(dtn::data::Block& obj)
00474 {
00475 dtn::data::SDNV procflags_sdnv;
00476 _stream >> obj._blocktype;
00477 _stream >> procflags_sdnv;
00478 obj._procflags = procflags_sdnv.getValue();
00479
00480
00481 if ( obj._procflags & dtn::data::Block::BLOCK_CONTAINS_EIDS)
00482 {
00483 SDNV eidcount;
00484 _stream >> eidcount;
00485
00486 for (unsigned int i = 0; i < eidcount.getValue(); i++)
00487 {
00488 SDNV scheme, ssp;
00489 _stream >> scheme;
00490 _stream >> ssp;
00491
00492 EID eid = _dictionary.get(scheme.getValue(), ssp.getValue());
00493
00494 obj.addEID(eid);
00495 }
00496 }
00497
00498
00499 SDNV block_size;
00500 _stream >> block_size;
00501 obj._blocksize = block_size.getValue();
00502
00503
00504 _validator.validate(obj, block_size.getValue());
00505
00506
00507 obj.deserialize(_stream);
00508
00509 return (*this);
00510 }
00511
00512 AcceptValidator::AcceptValidator()
00513 {
00514 }
00515
00516 AcceptValidator::~AcceptValidator()
00517 {
00518 }
00519
00520 void AcceptValidator::validate(const dtn::data::PrimaryBlock&) const throw (RejectedException)
00521 {
00522 }
00523
00524 void AcceptValidator::validate(const dtn::data::Block&, const size_t) const throw (RejectedException)
00525 {
00526
00527 }
00528
00529 void AcceptValidator::validate(const dtn::data::Bundle&) const throw (RejectedException)
00530 {
00531
00532 }
00533 }
00534 }