Go to the documentation of this file.00001
00002
00003
00004
00005
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
00061 _blob->enter();
00062 _blob->_locked = true;
00063
00064
00065 _blob->open();
00066 }
00067
00068 void BLOB::Reference::leave() throw (ibrcommon::MutexException)
00069 {
00070 _blob->_locked = false;
00071
00072
00073 _blob->close();
00074
00075
00076 _blob->leave();
00077 }
00078
00079 void BLOB::Reference::trylock() throw (ibrcommon::MutexException)
00080 {
00081
00082 _blob->trylock();
00083 _blob->_locked = true;
00084
00085
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
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
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
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
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
00226 _filestream.close();
00227
00228
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
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
00259 _tmpfile.remove();
00260 }
00261
00262 void TmpFileBLOB::open()
00263 {
00264 BLOB::_filelimit.wait();
00265
00266
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
00279 _filestream.close();
00280
00281 BLOB::_filelimit.post();
00282 }
00283 }