inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/wroot/key
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_wroot_key
00005 #define inlib_wroot_key
00006 
00007 #include "seek"
00008 #include "date"
00009 #include "ifile"
00010 #include "wbuf"
00011 
00012 #ifdef INLIB_MEM
00013 #include "../mem"
00014 #endif
00015 
00016 #include <ostream>
00017 
00018 namespace inlib {
00019 namespace wroot {
00020 
00021 class key {
00022   static uint32 class_version() {return 2;}
00023   static uint32 START_BIG_FILE() {return 2000000000;}
00024   static const std::string& s_class() {
00025     static const std::string s_v("inlib::wroot::key");
00026     return s_v;
00027   }
00028 public:
00029   static unsigned int std_string_record_size(const std::string& x) {
00030     // Returns size string will occupy on I/O buffer.
00031     if (x.size() > 254)
00032       return x.size()+sizeof(unsigned char)+sizeof(int);
00033     else
00034       return x.size()+sizeof(unsigned char);
00035   }
00036 public:
00037   key(ifile& a_file,
00038       seek a_seek_parent_dir,
00039       const std::string& a_object_name,
00040       const std::string& a_object_title,
00041       const std::string& a_object_class,
00042       uint32 a_object_size) //uncompressed data size.
00043   :m_file(a_file)
00044   ,m_buf_size(0)
00045   ,m_buffer(0)
00046   // Record :
00047   ,m_nbytes(0)
00048   ,m_version(class_version())
00049   ,m_object_size(a_object_size)
00050   ,m_date(0)
00051   ,m_key_length(0)
00052   ,m_cycle(0)
00053   ,m_seek_key(0)
00054   ,m_seek_parent_dir(0)
00055   ,m_object_class(a_object_class)
00056   ,m_object_name(a_object_name)
00057   ,m_object_title(a_object_title)
00058   {
00059 #ifdef INLIB_MEM
00060     mem::increment(s_class().c_str());
00061 #endif
00062 
00063     if(a_object_size) {
00064       if(m_file.END()>START_BIG_FILE()) m_version += 1000;
00065     }
00066     if(m_version>1000) {
00067     } else {
00068       if(a_seek_parent_dir>START_BIG_FILE()) m_version += 1000;
00069     }
00070 
00071     m_key_length = record_size(m_version);
00072 
00073     initialize(a_object_size);
00074 
00075     m_seek_parent_dir = a_seek_parent_dir;
00076   }
00077   virtual ~key(){
00078     delete [] m_buffer;
00079 #ifdef INLIB_MEM
00080     mem::decrement(s_class().c_str());
00081 #endif
00082   }
00083 protected:
00084   key(const key& a_from):m_file(a_from.m_file){
00085 #ifdef INLIB_MEM
00086     mem::increment(s_class().c_str());
00087 #endif
00088   }
00089   key& operator=(const key &){return *this;}
00090 public:
00091   uint16 cycle() const {return m_cycle;}
00092   void set_cycle(uint16 a_cycle) {m_cycle = a_cycle;}
00093 
00094   const std::string& object_name() const {return m_object_name;}
00095   std::string object_name() {return m_object_name;}
00096 
00097   const std::string& object_class() const {return m_object_class;}
00098   std::string object_class() {return m_object_class;}
00099 
00100   bool write_self() {
00101     char* buffer = m_buffer;
00102     wbuf wb(m_file.out(),m_file.byte_swap(),eob(),buffer);
00103     return to_buffer(wb);
00104   }
00105 
00106   bool write_file(uint32& a_nbytes){
00107     if(!m_file.set_pos(m_seek_key)) {
00108       a_nbytes = 0;
00109       return false;
00110     }
00111     if(!m_file.write_buffer(m_buffer,m_nbytes)) {
00112       a_nbytes = 0;
00113       return false;
00114     }
00115 
00116     if(m_file.verbose()) {
00117       m_file.out() << "inlib::wroot::key::write_file :"
00118                    << " writing " << m_nbytes << " bytes"
00119                    << " at address " << m_seek_key
00120                    << " for ID=" << sout(m_object_name)
00121                    << " Title=" << sout(m_object_title) << "."
00122                    << std::endl;
00123     }
00124 
00125     delete [] m_buffer; //???
00126     m_buffer = 0;
00127     m_buf_size = 0;
00128 
00129     a_nbytes = m_nbytes;
00130     return true;
00131   }
00132 
00133   void set_number_of_bytes(uint32 a_n) {m_nbytes = a_n;}
00134   uint32 number_of_bytes() const {return m_nbytes;}
00135 
00136   uint32 object_size() const {return m_object_size;}
00137 
00138   seek seek_key() const {return m_seek_key;}
00139   short key_length() const {return m_key_length;}
00140 
00141   char* data_buffer() {return m_buffer + m_key_length;}
00142   const char* eob() const {return m_buffer + m_buf_size;}
00143 
00144   bool to_buffer(wbuf& a_wb) const {
00145     if(!a_wb.write(m_nbytes)) return false;
00146     short version = m_version;
00147     if(!a_wb.write(version)) return false;
00148     if(!a_wb.write(m_object_size)) return false;
00149     unsigned int date = 0; //FIXME
00150     if(!a_wb.write(date)) return false;
00151     if(!a_wb.write(m_key_length)) return false;
00152     if(!a_wb.write(m_cycle)) return false;
00153     if(version>1000) {
00154       if(!a_wb.write(m_seek_key)) return false;
00155       if(!a_wb.write(m_seek_parent_dir)) return false;
00156     } else {
00157       if(m_seek_key>START_BIG_FILE()) {
00158         m_file.out() << "inlib::wroot::key::to_buffer :"
00159                      << " attempt to write big seek "
00160                      << m_seek_key << " on 32 bits."
00161                      << std::endl;
00162         return false;
00163       }
00164       if(!a_wb.write((seek32)m_seek_key)) return false;
00165       if(m_seek_parent_dir>START_BIG_FILE()) {
00166         m_file.out() << "inlib::wroot::key::to_buffer :"
00167                      << " (2) attempt to write big seek "
00168                      << m_seek_parent_dir << " on 32 bits."
00169                      << std::endl;
00170         return false;
00171       }
00172       if(!a_wb.write((seek32)m_seek_parent_dir)) return false;
00173     }
00174     if(!a_wb.write(m_object_class)) return false;
00175     if(!a_wb.write(m_object_name)) return false;
00176     if(!a_wb.write(m_object_title)) return false;
00177     if(m_file.verbose()) {
00178       m_file.out() << "inlib::wroot::key::to_buffer :"
00179                    << " nbytes : " << m_nbytes
00180                    << ", object class : " << sout(m_object_class)
00181                    << ", object name : " << sout(m_object_name)
00182                    << ", object title : " << sout(m_object_title)
00183                    << ", object size : " << m_object_size
00184                    << "." 
00185                    << std::endl;
00186     }
00187     return true;
00188   }
00189 
00190 protected:
00191   static std::string sout(const std::string& a_string) {
00192     return std::string("\"")+a_string+"\"";
00193   }
00194 protected:
00195   uint32 record_size(uint32 a_version) const {
00196     // Return the size in bytes of the key header structure.
00197     uint32 nbytes = sizeof(m_nbytes);
00198     nbytes += sizeof(short);
00199     nbytes += sizeof(m_object_size);
00200     nbytes += sizeof(date);
00201     nbytes += sizeof(m_key_length);
00202     nbytes += sizeof(m_cycle);
00203     if(a_version>1000) {
00204       nbytes += sizeof(seek);
00205       nbytes += sizeof(seek);
00206     } else {
00207       nbytes += sizeof(seek32);
00208       nbytes += sizeof(seek32);
00209     }
00210     nbytes += std_string_record_size(m_object_class);
00211     nbytes += std_string_record_size(m_object_name);
00212     nbytes += std_string_record_size(m_object_title);
00213     return nbytes;
00214   }
00215 
00216   bool initialize(uint32 a_nbytes) {
00217     uint32 nsize = m_key_length+a_nbytes;
00218 
00219     m_date = get_date();
00220 
00221     if(a_nbytes) {//GB
00222       m_seek_key = m_file.END();
00223       m_file.set_END(m_seek_key+nsize);
00224     } else { //basket
00225       m_seek_key = 0;
00226     }
00227 
00228     delete [] m_buffer;
00229     m_buffer = new char[nsize];
00230     m_buf_size = nsize;
00231     m_nbytes = nsize;
00232 
00233     return true;
00234   }
00235 protected:
00236   ifile& m_file;
00237   uint32 m_buf_size;
00238   char* m_buffer;
00239   // Record (stored in file) :
00240   uint32 m_nbytes;               //Number of bytes for the object on file
00241   uint32 m_version;              //Key version identifier
00242   uint32 m_object_size;       //Length of uncompressed object in bytes
00243   date m_date;                //Date/Time of insertion in file
00244   uint16 m_key_length;        //Number of bytes for the key itself
00245   uint16 m_cycle;              //Cycle number
00246   seek m_seek_key;            //Location of object on file
00247   seek m_seek_parent_dir;     //Location of parent directory on file
00248   std::string m_object_class; //Object Class name.
00249   std::string m_object_name;  //name of the object.
00250   std::string m_object_title; //title of the object.
00251 };
00252 
00253 }}
00254 
00255 #endif
00256 
00257 //doc :
00259 //                                                                      //
00260 //  The Key class includes functions to book space on a file,           //
00261 //   to create I/O buffers, to fill these buffers                       //
00262 //   to compress/uncompress data buffers.                               //
00263 //                                                                      //
00264 //  Before saving (making persistent) an object on a file, a key must   //
00265 //  be created. The key structure contains all the information to       //
00266 //  uniquely identify a persistent object on a file.                    //
00267 //     fNbytes    = number of bytes for the compressed object+key       //
00268 //     version of the Key class                                         //
00269 //     fObjlen    = Length of uncompressed object                       //
00270 //     fDatime    = Date/Time when the object was written               //
00271 //     fKeylen    = number of bytes for the key structure               //
00272 //     fCycle     = cycle number of the object                          //
00273 //     fSeekKey   = Address of the object on file (points to fNbytes)   //
00274 //                  This is a redundant information used to cross-check //
00275 //                  the data base integrity.                            //
00276 //     fSeekPdir  = Pointer to the directory supporting this object     //
00277 //     fClassName = Object class name                                   //
00278 //     fName      = name of the object                                  //
00279 //     fTitle     = title of the object                                 //
00280 //                                                                      //
00281 //  The Key class is used by ROOT to:                                   //
00282 //    - to write an object in the Current Directory                     //
00283 //    - to write a new ntuple buffer                                    //
00284 //                                                                      //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines