Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrdtn/data/ExtensionBlock.h"
00009 #include "ibrdtn/data/Exceptions.h"
00010 #include "ibrdtn/data/ExtensionBlock.h"
00011 #include <ibrcommon/thread/MutexLock.h>
00012
00013 namespace dtn
00014 {
00015 namespace data
00016 {
00017 ExtensionBlock::FactoryList *ExtensionBlock::factories = NULL;
00018
00019 ExtensionBlock::FactoryList::FactoryList()
00020 { }
00021
00022 ExtensionBlock::FactoryList::~FactoryList()
00023 { }
00024
00025 void ExtensionBlock::FactoryList::initialize()
00026 {
00027 static ibrcommon::Mutex mutex;
00028 ibrcommon::MutexLock l(mutex);
00029
00030 if (ExtensionBlock::factories == NULL)
00031 {
00032 ExtensionBlock::factories = new ExtensionBlock::FactoryList();
00033 }
00034 }
00035
00036 ExtensionBlock::Factory& ExtensionBlock::FactoryList::get(const char type) throw (ibrcommon::Exception)
00037 {
00038 std::map<char, ExtensionBlock::Factory*>::iterator iter = fmap.find(type);
00039
00040 if (iter != fmap.end())
00041 {
00042 return *(iter->second);
00043 }
00044
00045 throw ibrcommon::Exception("Factory not available");
00046 }
00047
00048 void ExtensionBlock::FactoryList::add(const char type, Factory *f) throw (ibrcommon::Exception)
00049 {
00050 try {
00051 get(type);
00052 throw ibrcommon::Exception("extension block type already taken");
00053 } catch (const ibrcommon::Exception&) {
00054 fmap[type] = f;
00055 }
00056 }
00057
00058 void ExtensionBlock::FactoryList::remove(const char type)
00059 {
00060 fmap.erase(type);
00061 }
00062
00063 ExtensionBlock::Factory::Factory(char type)
00064 : _type(type)
00065 {
00066 ExtensionBlock::FactoryList::initialize();
00067 ExtensionBlock::factories->add(type, this);
00068 }
00069
00070 ExtensionBlock::Factory::~Factory()
00071 {
00072 ExtensionBlock::factories->remove(_type);
00073 }
00074
00075 ExtensionBlock::Factory& ExtensionBlock::Factory::get(char type) throw (ibrcommon::Exception)
00076 {
00077 ExtensionBlock::FactoryList::initialize();
00078 return ExtensionBlock::factories->get(type);
00079 }
00080
00081 ExtensionBlock::ExtensionBlock()
00082 : Block(0), _blobref(ibrcommon::TmpFileBLOB::create())
00083 {
00084 }
00085
00086 ExtensionBlock::ExtensionBlock(ibrcommon::BLOB::Reference ref)
00087 : Block(0), _blobref(ref)
00088 {
00089 }
00090
00091 ExtensionBlock::~ExtensionBlock()
00092 {
00093 }
00094
00095 ibrcommon::BLOB::Reference ExtensionBlock::getBLOB()
00096 {
00097 return _blobref;
00098 }
00099
00100 size_t ExtensionBlock::getLength() const
00101 {
00102 ibrcommon::BLOB::Reference blobref = _blobref;
00103 ibrcommon::BLOB::iostream io = blobref.iostream();
00104 return io.size();
00105 }
00106
00107 std::ostream& ExtensionBlock::serialize(std::ostream &stream) const
00108 {
00109 ibrcommon::BLOB::Reference blobref = _blobref;
00110 ibrcommon::BLOB::iostream io = blobref.iostream();
00111
00112 try {
00113 ibrcommon::BLOB::copy(stream, *io, io.size());
00114 } catch (const ibrcommon::IOException &ex) {
00115 throw dtn::SerializationFailedException(ex.what());
00116 }
00117
00118 return stream;
00119 }
00120
00121 std::istream& ExtensionBlock::deserialize(std::istream &stream)
00122 {
00123
00124 ibrcommon::BLOB::iostream io = _blobref.iostream();
00125
00126
00127 io.clear();
00128
00129
00130 if (!(*io).good()) throw dtn::SerializationFailedException("could not open BLOB for payload");
00131
00132 try {
00133 ibrcommon::BLOB::copy(*io, stream, _blocksize);
00134 } catch (const ibrcommon::IOException &ex) {
00135 throw dtn::SerializationFailedException(ex.what());
00136 }
00137
00138
00139 set(dtn::data::Block::FORWARDED_WITHOUT_PROCESSED, true);
00140
00141 return stream;
00142 }
00143 }
00144 }