inlib
1.2.0
|
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 // //