TDbiBinaryFile.cxx
Go to the documentation of this file.00001
00002
00003 #include <iostream>
00004
00005 #include "TClass.h"
00006 #include "TObject.h"
00007 #include "Api.h"
00008 #include "TSystem.h"
00009
00010 #include "TDbiBinaryFile.hxx"
00011 #include "TDbiTableRow.hxx"
00012 #include <TSK_DBI_Log.hxx>
00013 #include <MsgFormat.h>
00014 using std::endl;
00015 #include "TVldRange.hxx"
00016 #include "TVldTimeStamp.hxx"
00017
00018 enum Markers { StartMarker = 0xaabbccdd,
00019 EndMarker = 0xddbbccaa};
00020
00021
00022
00023
00024 void* GetVTptr(const void* obj) {
00025
00026
00027
00028 void* ptr;
00029 memcpy(&ptr,obj,4);
00030 return ptr;
00031
00032 }
00033 void SetVTptr(void* obj, const void* vt) {
00034
00035
00036
00037 memcpy(obj,&vt,4);
00038
00039 }
00040
00041
00042
00043 string TDbiBinaryFile::fgWorkDir;
00044 Bool_t TDbiBinaryFile::fgReadAccess = kTRUE;
00045 Bool_t TDbiBinaryFile::fgWriteAccess = kTRUE;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 TDbiBinaryFile::TDbiBinaryFile(const char* fileName, Bool_t input ) :
00056 fFile(0),
00057 fReading(input),
00058 fHasErrors(kFALSE),
00059 fArrayBuffer(0)
00060 {
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 fFileName = fileName;
00077 if ( fFileName != "" ) {
00078 Bool_t access = input ? fgReadAccess : fgWriteAccess;
00079 if ( fgWorkDir == "" || ! access ) fFileName = "";
00080 else fFileName = fgWorkDir + fFileName;
00081 }
00082
00083
00084 ios_base::openmode mode = ios_base::in|ios_base::binary;
00085 if ( ! input ) mode = ios_base::out|ios_base::binary;
00086
00087 if ( fFileName == "" ) fHasErrors = kTRUE;
00088 else {
00089 fFile = new fstream(fFileName.c_str(),mode);
00090 if ( ! fFile->is_open() || ! fFile->good() ) {
00091 SK_DBI_Debug( "Cannot open " << fFileName
00092 << "; all I/O will fail." << " ");
00093 fHasErrors = kTRUE;
00094 }
00095 }
00096
00097 }
00098
00099
00100 TDbiBinaryFile::~TDbiBinaryFile()
00101 {
00102
00103
00104
00105
00106 delete[] fArrayBuffer;
00107 fArrayBuffer = 0;
00108 this->Close();
00109 delete fFile;
00110 fFile = 0;
00111
00112 }
00113
00114
00115 void TDbiBinaryFile::Close()
00116 {
00117
00118
00119
00120
00121 if ( fFile ) fFile->close();
00122 }
00123
00124
00125
00126
00127 #define READ_BUILTIN(t) \
00128 \
00129 TDbiBinaryFile& TDbiBinaryFile::operator >> (t& v) { \
00130 UInt_t numBytes = sizeof(v); \
00131 char* bytes = reinterpret_cast<char*>(&v); \
00132 this->Read(bytes,numBytes); \
00133 return *this; \
00134 }
00135 #define WRITE_BUILTIN(t) \
00136 \
00137 TDbiBinaryFile& TDbiBinaryFile::operator << (const t& v) { \
00138 UInt_t numBytes = sizeof(v); \
00139 const char* bytes = reinterpret_cast<const char*>(&v); \
00140 this->Write(bytes,numBytes); \
00141 return *this; \
00142 }
00143
00144 READ_BUILTIN(Bool_t)
00145 WRITE_BUILTIN(Bool_t)
00146 READ_BUILTIN(Int_t)
00147 WRITE_BUILTIN(Int_t)
00148 READ_BUILTIN(UInt_t)
00149 WRITE_BUILTIN(UInt_t)
00150 READ_BUILTIN(Double_t)
00151 WRITE_BUILTIN(Double_t)
00152
00153
00154
00155
00156
00157 #define READ_SIMPLE(t) \
00158 \
00159 TDbiBinaryFile& TDbiBinaryFile::operator >> (t& v) { \
00160 void* vt = GetVTptr(&v); \
00161 UInt_t numBytes = sizeof(v); \
00162 char* bytes = reinterpret_cast<char*>(&v); \
00163 this->Read(bytes,numBytes); \
00164 SetVTptr(&v,vt); \
00165 return *this; \
00166 }
00167 #define WRITE_SIMPLE(t) \
00168 \
00169 TDbiBinaryFile& TDbiBinaryFile::operator << (const t& v) { \
00170 UInt_t numBytes = sizeof(v); \
00171 const char* bytes = reinterpret_cast<const char*>(&v); \
00172 this->Write(bytes,numBytes); \
00173 return *this; \
00174 }
00175
00176 READ_SIMPLE(TVldTimeStamp)
00177 WRITE_BUILTIN(TVldTimeStamp)
00178
00179
00180
00181
00182
00183
00184
00185 TDbiBinaryFile& TDbiBinaryFile::operator >> (string& str) {
00186
00187 if ( this->CanRead() ) {
00188 getline(*fFile,str,'\0');
00189 this->CheckFileStatus();
00190 }
00191 return *this;
00192 }
00193
00194
00195 TDbiBinaryFile& TDbiBinaryFile::operator << (const string& str) {
00196
00197 UInt_t numBytes = str.size()+1;
00198 this->Write(str.c_str(),numBytes);
00199 return *this;
00200 }
00201
00202
00203
00204 TDbiBinaryFile& TDbiBinaryFile::operator >> (TVldRange& vr) {
00205
00206 if ( this->CanRead() ) {
00207 Int_t detectorMask;
00208 Int_t simMask;
00209 TVldTimeStamp timeStart;
00210 TVldTimeStamp timeEnd;
00211 string str;
00212 (*this) >> detectorMask
00213 >> simMask
00214 >> timeStart
00215 >> timeEnd
00216 >> str;
00217 TString dataSource(str.c_str());
00218 TVldRange tmp(detectorMask,simMask,timeStart,timeEnd,dataSource);
00219 vr = tmp;
00220 }
00221 return *this;
00222 }
00223
00224
00225 TDbiBinaryFile& TDbiBinaryFile::operator << (const TVldRange& vr) {
00226
00227 if ( this->CanWrite() ) {
00228 string str(vr.GetDataSource().Data());
00229 (*this) << vr.GetDetectorMask()
00230 << vr.GetSimMask()
00231 << vr.GetTimeStart()
00232 << vr.GetTimeEnd()
00233 << str;
00234 }
00235 return *this;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 TDbiBinaryFile& TDbiBinaryFile::operator >> (vector<TDbiTableRow*>& arr) {
00258
00259
00260 if ( ! this->CanRead() ) return *this;
00261
00262 if ( arr.size() ) {
00263 SK_DBI_Severe( "Attempting to read into non-empty array" << " ");
00264 return *this;
00265 }
00266
00267
00268
00269 UInt_t marker = 0;
00270 (*this) >> marker;
00271 if ( marker != StartMarker ) {
00272 SK_DBI_Severe( "Cannot find start of array marker" << " ");
00273 this->Close();
00274 this->CheckFileStatus();
00275 return *this;
00276 }
00277
00278
00279
00280 Int_t arrSize = 0;
00281 (*this) >> arrSize;
00282
00283 if ( arrSize ) {
00284 Int_t objSize = 0;
00285 string objName;
00286 (*this) >> objName >> objSize;
00287
00288
00289
00290
00291
00292 TClass objClass(objName.c_str());
00293 Int_t objSizefromRoot = objClass.Size();
00294 void* obj = objClass.New();
00295 void* vt = GetVTptr(obj);
00296
00297
00298 TDbiTableRow* tr = reinterpret_cast<TDbiTableRow*>(obj);
00299 delete tr;
00300
00301 SK_DBI_Verbose( "Restoring array of " << arrSize << " "
00302 << objName << " objects"
00303 << " VTaddr " << std::ios::hex << vt << std::ios::dec
00304 << " object size " << objSize << "(from file) "
00305 << objSizefromRoot << "(from ROOT)"
00306 << " ");
00307
00308 if ( arrSize < 0 || objSize != objSizefromRoot ) {
00309 SK_DBI_Severe( "Illegal array size ("<< arrSize
00310 << ") or object size(" << objSize
00311 << "," << objSizefromRoot << ")" << " ");
00312 this->Close();
00313 this->CheckFileStatus();
00314 return *this;
00315 }
00316
00317
00318 delete[] fArrayBuffer;
00319 Int_t buffSize = arrSize*objSize;
00320 fArrayBuffer = new char[buffSize];
00321 this->Read(fArrayBuffer,buffSize);
00322
00323
00324
00325 char* elem = fArrayBuffer;
00326 arr.reserve(arrSize);
00327 for (int row = 0; row < arrSize; ++row ) {
00328 SetVTptr(elem,vt);
00329 arr.push_back(reinterpret_cast<TDbiTableRow*>(elem));
00330 elem += objSize;
00331 }
00332
00333 }
00334
00335
00336
00337 (*this) >> marker;
00338 if ( marker != EndMarker ) {
00339 SK_DBI_Severe( "Cannot find end of array marker" << " ");
00340 this->Close();
00341 this->CheckFileStatus();
00342 }
00343
00344 return *this;
00345
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 TDbiBinaryFile& TDbiBinaryFile::operator << (vector<TDbiTableRow*>& arr) {
00369
00370
00371 if ( ! this->CanWrite() ) return *this;
00372
00373 UInt_t marker = StartMarker;
00374 (*this) << marker;
00375 Int_t arrSize = arr.size();
00376 (*this) << arrSize;
00377
00378 if ( arrSize ) {
00379 TDbiTableRow* obj = arr[0];
00380 Int_t objSize = obj->IsA()->Size();
00381 string objName = obj->ClassName();
00382 (*this) << objName << objSize;
00383 for (int row = 0; row < arrSize; ++row ) {
00384 obj = arr[row];
00385 const char* p = reinterpret_cast<const char*>(arr[row]);
00386 this->Write(p,objSize);
00387 }
00388
00389 }
00390
00391 marker = EndMarker;
00392 (*this) << marker;
00393
00394 return *this;
00395
00396 }
00397
00398
00399
00400
00401
00402
00403 Bool_t TDbiBinaryFile::CanRead() {
00404
00405 if ( ! fReading ) {
00406 SK_DBI_Severe( "Attempting to read from a write-only file" << " ");
00407 return kFALSE;
00408 }
00409 return this->IsOK();
00410
00411 }
00412
00413
00414 Bool_t TDbiBinaryFile::CanWrite() {
00415
00416 if ( fReading ) {
00417 SK_DBI_Severe( "Attempting to write to a read-only file" << " ");
00418 return kFALSE;
00419 }
00420 return this->IsOK();
00421
00422 }
00423
00424
00425
00426 void TDbiBinaryFile::CheckFileStatus() {
00427
00428
00429
00430
00431 if ( fFile
00432 && ! fHasErrors
00433 && ( ! fFile->is_open() || ! fFile->good() ) ) {
00434 SK_DBI_Severe( "File not open or has gone bad,"
00435 << " all further I/O will fail." << " ");
00436 fHasErrors = kTRUE;
00437 this->Close();
00438
00439
00440 if ( ! fReading ) {
00441 SK_DBI_Severe( "Erasing " << fFileName << " ");
00442 gSystem->Unlink(fFileName.c_str());
00443 }
00444
00445 }
00446
00447 }
00448
00449
00450
00451 Bool_t TDbiBinaryFile::Read(char* bytes, UInt_t numBytes) {
00452
00453
00454
00455
00456
00457 if ( ! this->CanRead() ) return kFALSE;
00458
00459 fFile->read(bytes,numBytes);
00460 this->CheckFileStatus();
00461 return ! fHasErrors;
00462 }
00463
00464
00465
00466 Bool_t TDbiBinaryFile::Write(const char* bytes, UInt_t numBytes) {
00467
00468
00469
00470
00471
00472 if ( ! this->CanWrite() ) return kFALSE;
00473
00474 fFile->write(bytes,numBytes);
00475 this->CheckFileStatus();
00476 return ! fHasErrors;
00477 }
00478
00479