IBR-DTNSuite
0.8
|
00001 /* 00002 * ExtensionBlock.cpp 00003 * 00004 * Created on: 26.05.2010 00005 * Author: morgenro 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::BLOB::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() const 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, size_t &length) 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, const size_t length) 00122 { 00123 // lock the BLOB 00124 ibrcommon::BLOB::iostream io = _blobref.iostream(); 00125 00126 // clear the blob 00127 io.clear(); 00128 00129 // check if the blob is ready 00130 if (!(*io).good()) throw dtn::SerializationFailedException("could not open BLOB for payload"); 00131 00132 try { 00133 ibrcommon::BLOB::copy(*io, stream, length); 00134 } catch (const ibrcommon::IOException &ex) { 00135 throw dtn::SerializationFailedException(ex.what()); 00136 } 00137 00138 // set block not processed bit 00139 set(dtn::data::Block::FORWARDED_WITHOUT_PROCESSED, true); 00140 00141 return stream; 00142 } 00143 } 00144 }