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