Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wroot/key is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_wroot_key
0005 #define tools_wroot_key
0006 
0007 #include "seek"
0008 #include "date"
0009 #include "ifile"
0010 #include "wbuf"
0011 #include "../sout"
0012 
0013 #include <ostream>
0014 
0015 namespace tools {
0016 namespace wroot {
0017 
0018 //doc :
0019 //////////////////////////////////////////////////////////////////////////
0020 //                                                                      //
0021 //  The Key class includes functions to book space on a file,           //
0022 //   to create I/O buffers, to fill these buffers                       //
0023 //   to compress/uncompress data buffers.                               //
0024 //                                                                      //
0025 //  Before saving (making persistent) an object on a file, a key must   //
0026 //  be created. The key structure contains all the information to       //
0027 //  uniquely identify a persistent object on a file.                    //
0028 //     fNbytes    = number of bytes for the compressed object+key       //
0029 //     version of the Key class                                         //
0030 //     fObjlen    = Length of uncompressed object                       //
0031 //     fDatime    = Date/Time when the object was written               //
0032 //     fKeylen    = number of bytes for the key structure               //
0033 //     fCycle     = cycle number of the object                          //
0034 //     fSeekKey   = Address of the object on file (points to fNbytes)   //
0035 //                  This is a redundant information used to cross-check //
0036 //                  the data base integrity.                            //
0037 //     fSeekPdir  = Pointer to the directory supporting this object     //
0038 //     fClassName = Object class name                                   //
0039 //     fName      = name of the object                                  //
0040 //     fTitle     = title of the object                                 //
0041 //                                                                      //
0042 //  The Key class is used by ROOT to:                                   //
0043 //    - to write an object in the Current Directory                     //
0044 //    - to write a new ntuple buffer                                    //
0045 //                                                                      //
0046 //////////////////////////////////////////////////////////////////////////
0047 class key {
0048   static uint32 class_version() {return 2;}
0049   static const std::string& s_class() {
0050     static const std::string s_v("tools::wroot::key");
0051     return s_v;
0052   }
0053 public:
0054   static unsigned int std_string_record_size(const std::string& x) {
0055     // Returns size string will occupy on I/O buffer.
0056     if (x.size() > 254)
0057       return uint32(x.size()+sizeof(unsigned char)+sizeof(int));
0058     else
0059       return uint32(x.size()+sizeof(unsigned char));
0060   }
0061 public:
0062   key(std::ostream& a_out,
0063       seek a_seek_directory,
0064       const std::string& a_object_name,
0065       const std::string& a_object_title,
0066       const std::string& a_object_class) //for basket cstor.
0067   :m_out(a_out)
0068   ,m_buf_size(0)
0069   ,m_buffer(0)
0070   // Record :
0071   ,m_nbytes(0)
0072   ,m_version(class_version())
0073   ,m_object_size(0)
0074   ,m_date(0)
0075   ,m_key_length(0)
0076   ,m_cycle(0)
0077   ,m_seek_key(0)
0078   ,m_seek_directory(0)
0079   ,m_object_class(a_object_class)
0080   ,m_object_name(a_object_name)
0081   ,m_object_title(a_object_title)
0082   {
0083     if(a_seek_directory>START_BIG_FILE()) m_version += big_file_version_tag();
0084 
0085     m_key_length = record_size(m_version);
0086 
0087     initialize_zero();
0088 
0089     m_seek_directory = a_seek_directory;
0090   }
0091 
0092   key(std::ostream& a_out,
0093       ifile& a_file,
0094       seek a_seek_directory,
0095       const std::string& a_object_name,
0096       const std::string& a_object_title,
0097       const std::string& a_object_class,
0098       uint32 a_object_size) //uncompressed data size.
0099   :m_out(a_out)
0100   ,m_buf_size(0)
0101   ,m_buffer(0)
0102   // Record :
0103   ,m_nbytes(0)
0104   ,m_version(class_version())
0105   ,m_object_size(a_object_size)
0106   ,m_date(0)
0107   ,m_key_length(0)
0108   ,m_cycle(0)
0109   ,m_seek_key(0)
0110   ,m_seek_directory(0)
0111   ,m_object_class(a_object_class)
0112   ,m_object_name(a_object_name)
0113   ,m_object_title(a_object_title)
0114   {
0115     if(a_object_size) {
0116       if(a_file.END()>START_BIG_FILE()) m_version += big_file_version_tag();
0117     }
0118     if(m_version>big_file_version_tag()) {
0119     } else {
0120       if(a_seek_directory>START_BIG_FILE()) m_version += big_file_version_tag();
0121     }
0122 
0123     m_key_length = record_size(m_version);
0124 
0125     initialize(a_file,a_object_size);
0126 
0127     m_seek_directory = a_seek_directory;
0128   }
0129   virtual ~key(){
0130     delete [] m_buffer;
0131   }
0132 protected:
0133   key(const key& a_from):m_out(a_from.m_out){
0134   }
0135   key& operator=(const key &){return *this;}
0136 public:
0137   uint16 cycle() const {return m_cycle;}
0138   void set_cycle(uint16 a_cycle) {m_cycle = a_cycle;}
0139 
0140   const std::string& object_name() const {return m_object_name;}
0141   const std::string& object_title() const {return m_object_title;}
0142   const std::string& object_class() const {return m_object_class;}
0143 
0144   bool write_self(ifile& a_file) {
0145     char* buffer = m_buffer;
0146     wbuf wb(m_out,a_file.byte_swap(),eob(),buffer);
0147     return to_buffer(wb,a_file.verbose());
0148   }
0149 
0150   bool write_file(ifile& a_file,uint32& a_nbytes) {
0151     if(!a_file.set_pos(m_seek_key)) {
0152       a_nbytes = 0;
0153       return false;
0154     }
0155     if(!a_file.write_buffer(m_buffer,m_nbytes)) {
0156       a_nbytes = 0;
0157       return false;
0158     }
0159 
0160     if(a_file.verbose()) {
0161       m_out << "tools::wroot::key::write_file :"
0162             << " writing " << m_nbytes << " bytes"
0163             << " at address " << m_seek_key
0164             << " for ID=" << sout(m_object_name)
0165             << " Title=" << sout(m_object_title) << "."
0166             << std::endl;
0167     }
0168 
0169     delete [] m_buffer; //???
0170     m_buffer = 0;
0171     m_buf_size = 0;
0172 
0173     a_nbytes = m_nbytes;
0174     return true;
0175   }
0176 
0177   void set_number_of_bytes(uint32 a_n) {m_nbytes = a_n;}
0178   uint32 number_of_bytes() const {return m_nbytes;}
0179 
0180   uint32 object_size() const {return m_object_size;}
0181 
0182   seek seek_key() const {return m_seek_key;}
0183   short key_length() const {return m_key_length;}
0184 
0185   char* data_buffer() {return m_buffer + m_key_length;}
0186   const char* eob() const {return m_buffer + m_buf_size;}
0187 
0188   bool to_buffer(wbuf& a_wb,bool a_verbose) const {
0189     if(!a_wb.write(m_nbytes)) return false;
0190     short version = m_version;
0191     if(!a_wb.write(version)) return false;
0192     if(!a_wb.write(m_object_size)) return false;
0193     unsigned int _date = 0; //FIXME
0194     if(!a_wb.write(_date)) return false;
0195     if(!a_wb.write(m_key_length)) return false;
0196     if(!a_wb.write(m_cycle)) return false;
0197     if(version>(short)big_file_version_tag()) {
0198       if(!a_wb.write(m_seek_key)) return false;
0199       if(!a_wb.write(m_seek_directory)) return false;
0200     } else {
0201       if(m_seek_key>START_BIG_FILE()) {
0202         m_out << "tools::wroot::key::to_buffer :"
0203               << " attempt to write big seek "
0204               << m_seek_key << " on 32 bits."
0205               << std::endl;
0206         return false;
0207       }
0208       if(!a_wb.write((seek32)m_seek_key)) return false;
0209       if(m_seek_directory>START_BIG_FILE()) {
0210         m_out << "tools::wroot::key::to_buffer :"
0211               << " (2) attempt to write big seek "
0212               << m_seek_directory << " on 32 bits."
0213               << std::endl;
0214         return false;
0215       }
0216       if(!a_wb.write((seek32)m_seek_directory)) return false;
0217     }
0218     if(!a_wb.write(m_object_class)) return false;
0219     if(!a_wb.write(m_object_name)) return false;
0220     if(!a_wb.write(m_object_title)) return false;
0221     if(a_verbose) {
0222       m_out << "tools::wroot::key::to_buffer :"
0223             << " nbytes : " << m_nbytes
0224             << ", object class : " << sout(m_object_class)
0225             << ", object name : " << sout(m_object_name)
0226             << ", object title : " << sout(m_object_title)
0227             << ", object size : " << m_object_size
0228             << "."
0229             << std::endl;
0230     }
0231     return true;
0232   }
0233 
0234 protected:
0235   uint32 record_size(uint32 a_version) const {
0236     // Return the size in bytes of the key header structure.
0237     uint32 nbytes = sizeof(m_nbytes);
0238     nbytes += sizeof(short);
0239     nbytes += sizeof(m_object_size);
0240     nbytes += sizeof(date);
0241     nbytes += sizeof(m_key_length);
0242     nbytes += sizeof(m_cycle);
0243     if(a_version>big_file_version_tag()) {
0244       nbytes += sizeof(seek);
0245       nbytes += sizeof(seek);
0246     } else {
0247       nbytes += sizeof(seek32);
0248       nbytes += sizeof(seek32);
0249     }
0250     nbytes += std_string_record_size(m_object_class);
0251     nbytes += std_string_record_size(m_object_name);
0252     nbytes += std_string_record_size(m_object_title);
0253     return nbytes;
0254   }
0255 
0256   bool initialize_zero() {
0257     uint32 nsize = m_key_length;
0258     m_date = get_date();
0259     m_seek_key = 0;
0260     delete [] m_buffer;
0261     m_buffer = new char[nsize];
0262     m_buf_size = nsize;
0263     m_nbytes = nsize;
0264     return true;
0265   }
0266   bool initialize(ifile& a_file,uint32 a_nbytes) {
0267     uint32 nsize = m_key_length+a_nbytes;
0268 
0269     m_date = get_date();
0270 
0271     if(a_nbytes) {//GB
0272       m_seek_key = a_file.END();
0273       a_file.set_END(m_seek_key+nsize);
0274 
0275       //NOTE : the free segment logic found in CERN-ROOT/TKey
0276       //       is not yet needed right now for us, since
0277       //       we always write at end of file. The update
0278       //       of the eof free_seg is done in set_END.
0279     } else { //basket
0280       m_seek_key = 0;
0281     }
0282 
0283     delete [] m_buffer;
0284     m_buffer = new char[nsize];
0285     m_buf_size = nsize;
0286     m_nbytes = nsize;
0287 
0288     return true;
0289   }
0290 protected:
0291   std::ostream& m_out;
0292   uint32 m_buf_size;
0293   char* m_buffer;
0294   // Record (stored in file) :
0295   uint32 m_nbytes;            //Number of bytes for the object on file
0296   uint32 m_version;           //Key version identifier
0297   uint32 m_object_size;       //Length of uncompressed object in bytes
0298   date m_date;                //Date/Time of insertion in file
0299   uint16 m_key_length;        //Number of bytes for the key itself
0300   uint16 m_cycle;             //Cycle number
0301   seek m_seek_key;            //Location of object on file
0302   seek m_seek_directory;      //Location of parent directory on file
0303   std::string m_object_class; //Object Class name.
0304   std::string m_object_name;  //name of the object.
0305   std::string m_object_title; //title of the object.
0306 };
0307 
0308 }}
0309 
0310 #endif
0311