Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wroot/key

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_wroot_key
  5 #define tools_wroot_key
  6 
  7 #include "seek"
  8 #include "date"
  9 #include "ifile"
 10 #include "wbuf"
 11 #include "../sout"
 12 
 13 #ifdef TOOLS_MEM
 14 #include "../mem"
 15 #endif
 16 
 17 #include <ostream>
 18 
 19 namespace tools {
 20 namespace wroot {
 21 
 22 class key {
 23   static uint32 class_version() {return 2;}
 24   static const std::string& s_class() {
 25     static const std::string s_v("tools::wroot::key");
 26     return s_v;
 27   }
 28 public:
 29   static unsigned int std_string_record_size(const std::string& x) {
 30     // Returns size string will occupy on I/O buffer.
 31     if (x.size() > 254)
 32       return uint32(x.size()+sizeof(unsigned char)+sizeof(int));
 33     else
 34       return uint32(x.size()+sizeof(unsigned char));
 35   }
 36 public:
 37   key(std::ostream& a_out,
 38       seek a_seek_directory,
 39       const std::string& a_object_name,
 40       const std::string& a_object_title,
 41       const std::string& a_object_class) //for basket cstor.
 42   :m_out(a_out)
 43   ,m_buf_size(0)
 44   ,m_buffer(0)
 45   // Record :
 46   ,m_nbytes(0)
 47   ,m_version(class_version())
 48   ,m_object_size(0)
 49   ,m_date(0)
 50   ,m_key_length(0)
 51   ,m_cycle(0)
 52   ,m_seek_key(0)
 53   ,m_seek_directory(0)
 54   ,m_object_class(a_object_class)
 55   ,m_object_name(a_object_name)
 56   ,m_object_title(a_object_title)
 57   {
 58 #ifdef TOOLS_MEM
 59     mem::increment(s_class().c_str());
 60 #endif
 61 
 62     if(a_seek_directory>START_BIG_FILE()) m_version += big_file_version_tag();
 63 
 64     m_key_length = record_size(m_version);
 65 
 66     initialize_zero();
 67 
 68     m_seek_directory = a_seek_directory;
 69   }
 70 
 71   key(std::ostream& a_out,
 72       ifile& a_file,
 73       seek a_seek_directory,
 74       const std::string& a_object_name,
 75       const std::string& a_object_title,
 76       const std::string& a_object_class,
 77       uint32 a_object_size) //uncompressed data size.
 78   :m_out(a_out)
 79   ,m_buf_size(0)
 80   ,m_buffer(0)
 81   // Record :
 82   ,m_nbytes(0)
 83   ,m_version(class_version())
 84   ,m_object_size(a_object_size)
 85   ,m_date(0)
 86   ,m_key_length(0)
 87   ,m_cycle(0)
 88   ,m_seek_key(0)
 89   ,m_seek_directory(0)
 90   ,m_object_class(a_object_class)
 91   ,m_object_name(a_object_name)
 92   ,m_object_title(a_object_title)
 93   {
 94 #ifdef TOOLS_MEM
 95     mem::increment(s_class().c_str());
 96 #endif
 97 
 98     if(a_object_size) {
 99       if(a_file.END()>START_BIG_FILE()) m_version += big_file_version_tag();
100     }
101     if(m_version>big_file_version_tag()) {
102     } else {
103       if(a_seek_directory>START_BIG_FILE()) m_version += big_file_version_tag();
104     }
105 
106     m_key_length = record_size(m_version);
107 
108     initialize(a_file,a_object_size);
109 
110     m_seek_directory = a_seek_directory;
111   }
112   virtual ~key(){
113     delete [] m_buffer;
114 #ifdef TOOLS_MEM
115     mem::decrement(s_class().c_str());
116 #endif
117   }
118 protected:
119   key(const key& a_from):m_out(a_from.m_out){
120 #ifdef TOOLS_MEM
121     mem::increment(s_class().c_str());
122 #endif
123   }
124   key& operator=(const key &){return *this;}
125 public:
126   uint16 cycle() const {return m_cycle;}
127   void set_cycle(uint16 a_cycle) {m_cycle = a_cycle;}
128 
129   const std::string& object_name() const {return m_object_name;}
130   const std::string& object_title() const {return m_object_title;}
131   const std::string& object_class() const {return m_object_class;}
132 
133   bool write_self(ifile& a_file) {
134     char* buffer = m_buffer;
135     wbuf wb(m_out,a_file.byte_swap(),eob(),buffer);
136     return to_buffer(wb,a_file.verbose());
137   }
138 
139   bool write_file(ifile& a_file,uint32& a_nbytes) {
140     if(!a_file.set_pos(m_seek_key)) {
141       a_nbytes = 0;
142       return false;
143     }
144     if(!a_file.write_buffer(m_buffer,m_nbytes)) {
145       a_nbytes = 0;
146       return false;
147     }
148 
149     if(a_file.verbose()) {
150       m_out << "tools::wroot::key::write_file :"
151             << " writing " << m_nbytes << " bytes"
152             << " at address " << m_seek_key
153             << " for ID=" << sout(m_object_name)
154             << " Title=" << sout(m_object_title) << "."
155             << std::endl;
156     }
157 
158     delete [] m_buffer; //???
159     m_buffer = 0;
160     m_buf_size = 0;
161 
162     a_nbytes = m_nbytes;
163     return true;
164   }
165 
166   void set_number_of_bytes(uint32 a_n) {m_nbytes = a_n;}
167   uint32 number_of_bytes() const {return m_nbytes;}
168 
169   uint32 object_size() const {return m_object_size;}
170 
171   seek seek_key() const {return m_seek_key;}
172   short key_length() const {return m_key_length;}
173 
174   char* data_buffer() {return m_buffer + m_key_length;}
175   const char* eob() const {return m_buffer + m_buf_size;}
176 
177   bool to_buffer(wbuf& a_wb,bool a_verbose) const {
178     if(!a_wb.write(m_nbytes)) return false;
179     short version = m_version;
180     if(!a_wb.write(version)) return false;
181     if(!a_wb.write(m_object_size)) return false;
182     unsigned int _date = 0; //FIXME
183     if(!a_wb.write(_date)) return false;
184     if(!a_wb.write(m_key_length)) return false;
185     if(!a_wb.write(m_cycle)) return false;
186     if(version>(short)big_file_version_tag()) {
187       if(!a_wb.write(m_seek_key)) return false;
188       if(!a_wb.write(m_seek_directory)) return false;
189     } else {
190       if(m_seek_key>START_BIG_FILE()) {
191         m_out << "tools::wroot::key::to_buffer :"
192               << " attempt to write big seek "
193               << m_seek_key << " on 32 bits."
194               << std::endl;
195         return false;
196       }
197       if(!a_wb.write((seek32)m_seek_key)) return false;
198       if(m_seek_directory>START_BIG_FILE()) {
199         m_out << "tools::wroot::key::to_buffer :"
200               << " (2) attempt to write big seek "
201               << m_seek_directory << " on 32 bits."
202               << std::endl;
203         return false;
204       }
205       if(!a_wb.write((seek32)m_seek_directory)) return false;
206     }
207     if(!a_wb.write(m_object_class)) return false;
208     if(!a_wb.write(m_object_name)) return false;
209     if(!a_wb.write(m_object_title)) return false;
210     if(a_verbose) {
211       m_out << "tools::wroot::key::to_buffer :"
212             << " nbytes : " << m_nbytes
213             << ", object class : " << sout(m_object_class)
214             << ", object name : " << sout(m_object_name)
215             << ", object title : " << sout(m_object_title)
216             << ", object size : " << m_object_size
217             << "."
218             << std::endl;
219     }
220     return true;
221   }
222 
223 protected:
224   uint32 record_size(uint32 a_version) const {
225     // Return the size in bytes of the key header structure.
226     uint32 nbytes = sizeof(m_nbytes);
227     nbytes += sizeof(short);
228     nbytes += sizeof(m_object_size);
229     nbytes += sizeof(date);
230     nbytes += sizeof(m_key_length);
231     nbytes += sizeof(m_cycle);
232     if(a_version>big_file_version_tag()) {
233       nbytes += sizeof(seek);
234       nbytes += sizeof(seek);
235     } else {
236       nbytes += sizeof(seek32);
237       nbytes += sizeof(seek32);
238     }
239     nbytes += std_string_record_size(m_object_class);
240     nbytes += std_string_record_size(m_object_name);
241     nbytes += std_string_record_size(m_object_title);
242     return nbytes;
243   }
244 
245   bool initialize_zero() {
246     uint32 nsize = m_key_length;
247     m_date = get_date();
248     m_seek_key = 0;
249     delete [] m_buffer;
250     m_buffer = new char[nsize];
251     m_buf_size = nsize;
252     m_nbytes = nsize;
253     return true;
254   }
255   bool initialize(ifile& a_file,uint32 a_nbytes) {
256     uint32 nsize = m_key_length+a_nbytes;
257 
258     m_date = get_date();
259 
260     if(a_nbytes) {//GB
261       m_seek_key = a_file.END();
262       a_file.set_END(m_seek_key+nsize);
263 
264       //NOTE : the free segment logic found in CERN-ROOT/TKey
265       //       is not yet needed right now for us, since
266       //       we always write at end of file. The update
267       //       of the eof free_seg is done in set_END.
268     } else { //basket
269       m_seek_key = 0;
270     }
271 
272     delete [] m_buffer;
273     m_buffer = new char[nsize];
274     m_buf_size = nsize;
275     m_nbytes = nsize;
276 
277     return true;
278   }
279 protected:
280   std::ostream& m_out;
281   uint32 m_buf_size;
282   char* m_buffer;
283   // Record (stored in file) :
284   uint32 m_nbytes;            //Number of bytes for the object on file
285   uint32 m_version;           //Key version identifier
286   uint32 m_object_size;       //Length of uncompressed object in bytes
287   date m_date;                //Date/Time of insertion in file
288   uint16 m_key_length;        //Number of bytes for the key itself
289   uint16 m_cycle;             //Cycle number
290   seek m_seek_key;            //Location of object on file
291   seek m_seek_directory;      //Location of parent directory on file
292   std::string m_object_class; //Object Class name.
293   std::string m_object_name;  //name of the object.
294   std::string m_object_title; //title of the object.
295 };
296 
297 }}
298 
299 #endif
300 
301 //doc :
302 //////////////////////////////////////////////////////////////////////////
303 //                                                                      //
304 //  The Key class includes functions to book space on a file,           //
305 //   to create I/O buffers, to fill these buffers                       //
306 //   to compress/uncompress data buffers.                               //
307 //                                                                      //
308 //  Before saving (making persistent) an object on a file, a key must   //
309 //  be created. The key structure contains all the information to       //
310 //  uniquely identify a persistent object on a file.                    //
311 //     fNbytes    = number of bytes for the compressed object+key       //
312 //     version of the Key class                                         //
313 //     fObjlen    = Length of uncompressed object                       //
314 //     fDatime    = Date/Time when the object was written               //
315 //     fKeylen    = number of bytes for the key structure               //
316 //     fCycle     = cycle number of the object                          //
317 //     fSeekKey   = Address of the object on file (points to fNbytes)   //
318 //                  This is a redundant information used to cross-check //
319 //                  the data base integrity.                            //
320 //     fSeekPdir  = Pointer to the directory supporting this object     //
321 //     fClassName = Object class name                                   //
322 //     fName      = name of the object                                  //
323 //     fTitle     = title of the object                                 //
324 //                                                                      //
325 //  The Key class is used by ROOT to:                                   //
326 //    - to write an object in the Current Directory                     //
327 //    - to write a new ntuple buffer                                    //
328 //                                                                      //
329 //////////////////////////////////////////////////////////////////////////