IBR-DTNSuite  0.8
ibrdtn/ibrdtn/data/ExtensionBlock.cpp
Go to the documentation of this file.
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 }