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