EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FairDbBinaryFile.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FairDbBinaryFile.cxx
1 
2 #include <iostream>
3 
4 #include "TClass.h"
5 #include "TObject.h"
6 #include "TSystem.h"
7 
8 
9 #include "FairDbBinaryFile.h"
10 #include "FairDbTableRow.h"
11 #include "ValRange.h"
12 #include "ValTimeStamp.h"
13 
14 enum Markers { StartMarker = 0xaabbccdd,
15  EndMarker = 0xddbbccaa
16  };
17 
18 void* GetVTptr(const void* obj)
19 {
20  void* ptr;
21  memcpy(&ptr,obj,4);
22  return ptr;
23 
24 }
25 void SetVTptr(void* obj, const void* vt)
26 {
27  memcpy(obj,&vt,4);
28 }
29 // Definition of static data members
30 // *********************************
31 
33 Bool_t FairDbBinaryFile::fgReadAccess = kTRUE;
34 Bool_t FairDbBinaryFile::fgWriteAccess = kTRUE;
35 
36 FairDbBinaryFile::FairDbBinaryFile(const char* fileName, Bool_t input )
37  :
38  fFile(0),
39  fReading(input),
40  fHasErrors(kFALSE),
41  fArrayBuffer(0),
42  fFileName(fileName)
43 {
44 
45  // Complete the file name.
46  // fFileName = fileName;
47  if ( fFileName != "" ) {
48  Bool_t access = input ? fgReadAccess : fgWriteAccess;
49  if ( fgWorkDir == "" || ! access ) { fFileName = ""; }
50  else { fFileName = fgWorkDir + fFileName; }
51  }
52 
53  // Open the file.
54  ios_base::openmode mode = ios_base::in|ios_base::binary;
55  if ( ! input ) { mode = ios_base::out|ios_base::binary; }
56 
57  if ( fFileName == "" ) { fHasErrors = kTRUE; }
58  else {
59  fFile = new fstream(fFileName.c_str(),mode);
60  if ( ! fFile->is_open() || ! fFile->good() ) {
61  cout << "Cannot open " << fFileName
62  << "; all I/O will fail." << endl;
63  fHasErrors = kTRUE;
64  }
65  }
66 
67 }
69 {
70  delete[] fArrayBuffer;
71  fArrayBuffer = 0;
72  this->Close();
73  delete fFile;
74  fFile = 0;
75 
76 }
77 //.....................................................................
78 
80 {
81 
82  if ( fFile ) { fFile->close(); }
83 }
84 
85 
86 #define READ_BUILTIN(t) \
87  \
88 FairDbBinaryFile& FairDbBinaryFile::operator >> (t& v) { \
89  UInt_t numBytes = sizeof(v); \
90  char* bytes = reinterpret_cast<char*>(&v); \
91  this->Read(bytes,numBytes); \
92  return *this; \
93 }
94 #define WRITE_BUILTIN(t) \
95  \
96 FairDbBinaryFile& FairDbBinaryFile::operator << (const t& v) { \
97  UInt_t numBytes = sizeof(v); \
98  const char* bytes = reinterpret_cast<const char*>(&v); \
99  this->Write(bytes,numBytes); \
100  return *this; \
101 }
102 
103 READ_BUILTIN(Bool_t)
104 WRITE_BUILTIN(Bool_t)
105 READ_BUILTIN(Int_t)
106 WRITE_BUILTIN(Int_t)
107 READ_BUILTIN(UInt_t)
108 WRITE_BUILTIN(UInt_t)
109 READ_BUILTIN(Double_t)
110 WRITE_BUILTIN(Double_t)
111 
112 
113 
114 #define READ_SIMPLE(t) \
115  \
116 FairDbBinaryFile& FairDbBinaryFile::operator >> (t& v) { \
117  void* vt = GetVTptr(&v); \
118  UInt_t numBytes = sizeof(v); \
119  char* bytes = reinterpret_cast<char*>(&v); \
120  this->Read(bytes,numBytes); \
121  SetVTptr(&v,vt); \
122  return *this; \
123 }
124 #define WRITE_SIMPLE(t) \
125  \
126 FairDbBinaryFile& FairDbBinaryFile::operator << (const t& v) { \
127  UInt_t numBytes = sizeof(v); \
128  const char* bytes = reinterpret_cast<const char*>(&v); \
129  this->Write(bytes,numBytes); \
130  return *this; \
131 }
132 
135 
136 
137 FairDbBinaryFile& FairDbBinaryFile::operator >> (string& str)
138 {
139 
140  if ( this->CanRead() ) {
141  getline(*fFile,str,'\0');
142  this->CheckFileStatus();
143  }
144  return *this;
145 }
146 
148 {
149 
150  UInt_t numBytes = str.size()+1;
151  this->Write(str.c_str(),numBytes);
152  return *this;
153 }
154 
156 {
157 
158  if ( this->CanRead() ) {
159  Int_t detectorMask;
160  Int_t simMask;
161  ValTimeStamp timeStart;
162  ValTimeStamp timeEnd;
163  string str;
164  (*this) >> detectorMask
165  >> simMask
166  >> timeStart
167  >> timeEnd
168  >> str;
169  TString dataSource(str.c_str());
170  ValRange tmp(detectorMask,simMask,timeStart,timeEnd,dataSource);
171  vr = tmp;
172  }
173  return *this;
174 }
175 
177 {
178 
179  if ( this->CanWrite() ) {
180  string str(vr.GetDataSource().Data());
181  (*this) << vr.GetDetectorMask()
182  << vr.GetSimMask()
183  << vr.GetTimeStart()
184  << vr.GetTimeEnd()
185  << str;
186  }
187  return *this;
188 }
189 
190 FairDbBinaryFile& FairDbBinaryFile::operator >> (vector<FairDbTableRow*>& arr)
191 {
192  if ( ! this->CanRead() ) { return *this; }
193 
194  if ( arr.size() ) {
195  cout << "Attempting to read into non-empty array" << endl;
196  return *this;
197  }
198 
199 // Check for start of array marker.
200 
201  UInt_t marker = 0;
202  (*this) >> marker;
203  if ( marker != StartMarker ) {
204  cout << "Cannot find start of array marker" << endl;
205  this->Close();
206  this->CheckFileStatus();
207  return *this;
208  }
209 
210 // Get array size and deal with non-empty arrays.
211 
212  Int_t arrSize = 0;
213  (*this) >> arrSize;
214 
215  if ( arrSize ) {
216  Int_t objSize = 0;
217  string objName;
218  (*this) >> objName >> objSize;
219 
220  // Ensure that sizes look sensible and use ROOT to instatiate
221  // an example object so that we can get the address of the
222  // virtual table.
223 
224  TClass objClass(objName.c_str());
225  Int_t objSizefromRoot = objClass.Size();
226  void* obj = objClass.New();
227  void* vt = GetVTptr(obj);
228  // This only works if the address of the sub-class object is the same
229  // as the underlying base class, which should be true in this simple case.
230  FairDbTableRow* tr = reinterpret_cast<FairDbTableRow*>(obj);
231  delete tr;
232 
233  cout
234  << "Restoring array of " << arrSize << " "
235  << objName << " objects"
236  << " VTaddr " << hex << vt << dec
237  << " object size " << objSize << "(from file) "
238  << objSizefromRoot << "(from ROOT)"
239  << endl;
240 
241  if ( arrSize < 0 || objSize != objSizefromRoot ) {
242  cout << "Illegal array size ("<< arrSize
243  << ") or object size(" << objSize
244  << "," << objSizefromRoot << ")" << endl;
245  this->Close();
246  this->CheckFileStatus();
247  return *this;
248  }
249 
250 // Allocate buffer and load in array.
251  delete[] fArrayBuffer;
252  Int_t buffSize = arrSize*objSize;
253  fArrayBuffer = new char[buffSize];
254  this->Read(fArrayBuffer,buffSize);
255 
256 // Fix up VT pointers and populate the vector.
257 
258  char* elem = fArrayBuffer;
259  arr.reserve(arrSize);
260  for (int row = 0; row < arrSize; ++row ) {
261  SetVTptr(elem,vt);
262  arr.push_back(reinterpret_cast<FairDbTableRow*>(elem));
263  elem += objSize;
264  }
265 
266  }
267 
268 // Check for end of array marker.
269 
270  (*this) >> marker;
271  if ( marker != EndMarker ) {
272  cout << "Cannot find end of array marker" << endl;
273  this->Close();
274  this->CheckFileStatus();
275  }
276 
277  return *this;
278 
279 }
280 
281 
282 FairDbBinaryFile& FairDbBinaryFile::operator << (vector<FairDbTableRow*>& arr)
283 {
284 
285  if ( ! this->CanWrite() ) { return *this; }
286 
287  UInt_t marker = StartMarker;
288  (*this) << marker;
289  Int_t arrSize = arr.size();
290  (*this) << arrSize;
291 
292  if ( arrSize ) {
293  FairDbTableRow* obj = arr[0];
294  Int_t objSize = obj->IsA()->Size();
295  string objName = obj->ClassName();
296  (*this) << objName << objSize;
297  for (int row = 0; row < arrSize; ++row ) {
298  obj = arr[row];
299  const char* p = reinterpret_cast<const char*>(arr[row]);
300  this->Write(p,objSize);
301  }
302 
303  }
304 
305  marker = EndMarker;
306  (*this) << marker;
307 
308  return *this;
309 
310 }
311 
312 
314 {
315 
316  if ( ! fReading ) {
317  cout << "Attempting to read from a write-only file" << endl;
318  return kFALSE;
319  }
320  return this->IsOK();
321 
322 }
323 
325 {
326 
327  if ( fReading ) {
328  cout << "Attempting to write to a read-only file" << endl;
329  return kFALSE;
330  }
331  return this->IsOK();
332 
333 }
334 
336 {
337 
338 // If file was good but has just gone bad, report and close it.
339 // Delete it if writing.
340 
341  if ( fFile
342  && ! fHasErrors
343  && ( ! fFile->is_open() || ! fFile->good() ) ) {
344  cout << "File not open or has gone bad,"
345  << " all further I/O will fail." << endl;
346  fHasErrors = kTRUE;
347  this->Close();
348 
349  //Delete file if writing.
350  if ( ! fReading ) {
351  cout << "Erasing " << fFileName << endl;
352  gSystem->Unlink(fFileName.c_str());
353  }
354 
355  }
356 
357 }
358 
359 
360 Bool_t FairDbBinaryFile::Read(char* bytes, UInt_t numBytes)
361 {
362  if ( ! this->CanRead() ) { return kFALSE; }
363 
364  fFile->read(bytes,numBytes);
365  this->CheckFileStatus();
366  return ! fHasErrors;
367 }
368 
369 
370 Bool_t FairDbBinaryFile::Write(const char* bytes, UInt_t numBytes)
371 {
372  if ( ! this->CanWrite() ) { return kFALSE; }
373 
374  fFile->write(bytes,numBytes);
375  this->CheckFileStatus();
376  return ! fHasErrors;
377 }
378