• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ibrcommon/ibrcommon/data/BLOB.cpp

Go to the documentation of this file.
00001 /*
00002  * BLOB.cpp
00003  *
00004  *  Created on: 15.12.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/data/BLOB.h"
00009 #include "ibrcommon/thread/MutexLock.h"
00010 #include "ibrcommon/Exceptions.h"
00011 #include "ibrcommon/Logger.h"
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <cassert>
00016 
00017 namespace ibrcommon
00018 {
00019         ibrcommon::Semaphore BLOB::_filelimit(128);
00020 
00021         File BLOB::tmppath;
00022 
00023         BLOB::BLOB()
00024          : _locked(false), _refcount(0)
00025         { }
00026 
00027         BLOB::~BLOB()
00028         {
00029         }
00030 
00031         BLOB::Reference::Reference(const Reference &ref)
00032          : ibrcommon::Mutex(MUTEX_ERRORCHECK), _blob(ref._blob)
00033         {
00034                 _blob->increment();
00035         }
00036 
00037         BLOB::Reference::~Reference()
00038         {
00039                 _blob->decrement();
00040                 if (_blob->isUnbound())
00041                 {
00042                         delete _blob;
00043                 }
00044         }
00045 
00046         std::iostream& BLOB::Reference::operator* ()
00047         {
00048                 assert(_blob->_locked);
00049                 return _blob->__get_stream();
00050         }
00051 
00052         BLOB::Reference::Reference(BLOB *blob)
00053          : _blob(blob)
00054         {
00055                 _blob->increment();
00056         }
00057 
00058         void BLOB::Reference::enter() throw (ibrcommon::MutexException)
00059         {
00060                 // lock the stream
00061                 _blob->enter();
00062                 _blob->_locked = true;
00063 
00064                 // open the stream
00065                 _blob->open();
00066         }
00067 
00068         void BLOB::Reference::leave() throw (ibrcommon::MutexException)
00069         {
00070                 _blob->_locked = false;
00071 
00072                 // close the stream
00073                 _blob->close();
00074 
00075                 // unlock the stream
00076                 _blob->leave();
00077         }
00078 
00079         void BLOB::Reference::trylock() throw (ibrcommon::MutexException)
00080         {
00081                 // lock the stream
00082                 _blob->trylock();
00083                 _blob->_locked = true;
00084 
00085                 // open the stream
00086                 _blob->open();
00087         }
00088 
00089         size_t BLOB::Reference::getSize() const
00090         {
00091                 return _blob->getSize();
00092         }
00093 
00094         void BLOB::Reference::clear()
00095         {
00096                 assert(_blob->_locked);
00097                 _blob->clear();
00098         }
00099 
00100         void BLOB::increment()
00101         {
00102                 MutexLock l(_reflock);
00103                 _refcount++;
00104         }
00105 
00106         void BLOB::decrement()
00107         {
00108                 MutexLock l(_reflock);
00109                 _refcount--;
00110         }
00111 
00112         bool BLOB::isUnbound()
00113         {
00114                 MutexLock l(_reflock);
00115                 if (_refcount == 0) return true;
00116                 return false;
00117         }
00118 
00119         size_t BLOB::getSize()
00120         {
00121                 assert(_locked);
00122 
00123                 std::iostream &stream = this->__get_stream();
00124 
00125                 // store current position
00126                 size_t pos = stream.tellg();
00127 
00128                 stream.seekg(0, std::ios_base::end);
00129                 size_t size = stream.tellg();
00130                 stream.seekg(pos);
00131 
00132                 return size;
00133         }
00134 
00135         BLOB::Reference StringBLOB::create()
00136         {
00137                 BLOB::Reference ref(new StringBLOB());
00138                 return ref;
00139         }
00140 
00141         void StringBLOB::clear()
00142         {
00143                 _stringstream.str("");
00144         }
00145 
00146         StringBLOB::StringBLOB()
00147          : BLOB(), _stringstream()
00148         {
00149 
00150         }
00151 
00152         StringBLOB::~StringBLOB()
00153         {
00154         }
00155 
00156         void StringBLOB::open()
00157         {
00158                 // set pointer to the beginning of the stream and remove any error flags
00159                 _stringstream.clear();
00160                 _stringstream.seekp(0);
00161                 _stringstream.seekg(0);
00162         }
00163 
00164         void StringBLOB::close()
00165         {
00166         }
00167 
00168         BLOB::Reference FileBLOB::create(const File &f)
00169         {
00170                 BLOB::Reference ref(new FileBLOB(f));
00171                 return ref;
00172         }
00173 
00174         void FileBLOB::clear()
00175         {
00176                 throw ibrcommon::IOException("clear is not possible on a read only file");
00177         }
00178 
00179         FileBLOB::FileBLOB(const File &f)
00180          : BLOB(), _filestream(), _file(f)
00181         {
00182                 if (!f.exists())
00183                 {
00184                         throw ibrcommon::FileNotExistsException(f);
00185                 }
00186         }
00187 
00188         FileBLOB::~FileBLOB()
00189         {
00190         }
00191 
00192         void FileBLOB::open()
00193         {
00194                 BLOB::_filelimit.wait();
00195 
00196                 // open the file
00197                 _filestream.open(_file, ios::in|ios::binary);
00198 
00199                 if (!_filestream.is_open())
00200                 {
00201                         throw ibrcommon::CanNotOpenFileException(_file);
00202                 }
00203         }
00204 
00205         void FileBLOB::close()
00206         {
00207                 // close the file
00208                 _filestream.close();
00209 
00210                 BLOB::_filelimit.post();
00211         }
00212 
00213         BLOB::Reference TmpFileBLOB::create()
00214         {
00215                 try {
00216                         BLOB::Reference ref(new TmpFileBLOB());
00217                         return ref;
00218                 } catch (ibrcommon::IOException ex) {
00219                         return StringBLOB::create();
00220                 }
00221         }
00222 
00223         void TmpFileBLOB::clear()
00224         {
00225                 // close the file
00226                 _filestream.close();
00227 
00228                 // open temporary file
00229                 _filestream.open(_tmpfile, ios::in | ios::out | ios::trunc | ios::binary );
00230 
00231                 if (!_filestream.is_open())
00232                 {
00233                         IBRCOMMON_LOGGER(error) << "can not open temporary file " << _tmpfile.getPath() << IBRCOMMON_LOGGER_ENDL;
00234                         throw ibrcommon::CanNotOpenFileException(_tmpfile);
00235                 }
00236         }
00237 
00238         TmpFileBLOB::TmpFileBLOB()
00239          : BLOB(), _filestream()
00240         {
00241                 // check if path is a directory
00242                 if (!BLOB::tmppath.isDirectory())
00243                 {
00244                         throw ibrcommon::IOException("BLOB::tmppath not initialized or path is not a directory.");
00245                 }
00246 
00247                 createtmpfile();
00248         }
00249 
00250         void TmpFileBLOB::createtmpfile()
00251         {
00252                 _tmpfile = ibrcommon::TemporaryFile(BLOB::tmppath, "blob");
00253                 _tmpfile.update();
00254         }
00255 
00256         TmpFileBLOB::~TmpFileBLOB()
00257         {
00258                 // delete the file if the last reference is destroyed
00259                 _tmpfile.remove();
00260         }
00261 
00262         void TmpFileBLOB::open()
00263         {
00264                 BLOB::_filelimit.wait();
00265 
00266                 // open temporary file
00267                 _filestream.open(_tmpfile, ios::in | ios::out | ios::binary );
00268 
00269                 if (!_filestream.is_open())
00270                 {
00271                         IBRCOMMON_LOGGER(error) << "can not open temporary file " << _tmpfile.getPath() << IBRCOMMON_LOGGER_ENDL;
00272                         throw ibrcommon::CanNotOpenFileException(_tmpfile);
00273                 }
00274         }
00275 
00276         void TmpFileBLOB::close()
00277         {
00278                 // close the file
00279                 _filestream.close();
00280 
00281                 BLOB::_filelimit.post();
00282         }
00283 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1