Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_rroot_key 4 #ifndef tools_rroot_key 5 #define tools_rroot_key 5 #define tools_rroot_key 6 6 7 #include "rbuf" 7 #include "rbuf" 8 #include "seek" 8 #include "seek" 9 #include "date" 9 #include "date" 10 #include "ifile" 10 #include "ifile" 11 #include "../sout" 11 #include "../sout" 12 12 13 #ifdef TOOLS_MEM 13 #ifdef TOOLS_MEM 14 #include "../mem" 14 #include "../mem" 15 #endif 15 #endif 16 16 17 #include <map> 17 #include <map> 18 #include <ostream> 18 #include <ostream> 19 #include <cstring> //memcpy 19 #include <cstring> //memcpy 20 20 21 //#include <zlib.h> 21 //#include <zlib.h> 22 22 23 #ifdef TOOLS_USE_CSZ 23 #ifdef TOOLS_USE_CSZ 24 // CSZ code where used as default compressor i 24 // CSZ code where used as default compressor in old CERN-ROOT, then it may be needed 25 // to read old file (as the pawdemo.root one). 25 // to read old file (as the pawdemo.root one). 26 //FIXME : arrange to have csz coming from the 26 //FIXME : arrange to have csz coming from the "outside" (as zip). 27 extern "C" { 27 extern "C" { 28 void csz__Init_Inflate(long,unsigned char*,l 28 void csz__Init_Inflate(long,unsigned char*,long,unsigned char*); 29 int csz__Inflate(); 29 int csz__Inflate(); 30 unsigned char* csz__obufptr(); 30 unsigned char* csz__obufptr(); 31 } 31 } 32 #endif 32 #endif 33 33 34 namespace tools { 34 namespace tools { 35 namespace rroot { 35 namespace rroot { 36 36 37 class key { 37 class key { 38 static uint32 class_version() {return 2;} 38 static uint32 class_version() {return 2;} 39 public: 39 public: 40 static uint32 std_string_record_size(const s 40 static uint32 std_string_record_size(const std::string& x) { 41 // Returns size string will occupy on I/O 41 // Returns size string will occupy on I/O buffer. 42 if (x.size() > 254) 42 if (x.size() > 254) 43 return uint32(x.size()+sizeof(unsigned c 43 return uint32(x.size()+sizeof(unsigned char)+sizeof(int)); 44 else 44 else 45 return uint32(x.size()+sizeof(unsigned c 45 return uint32(x.size()+sizeof(unsigned char)); 46 } 46 } 47 47 48 public: 48 public: 49 key(std::ostream& a_out) 49 key(std::ostream& a_out) 50 :m_out(a_out) 50 :m_out(a_out) 51 ,m_buf_size(0) 51 ,m_buf_size(0) 52 ,m_buffer(0) 52 ,m_buffer(0) 53 // Record : 53 // Record : 54 ,m_nbytes(0) 54 ,m_nbytes(0) 55 ,m_version(class_version()) 55 ,m_version(class_version()) 56 ,m_object_size(0) 56 ,m_object_size(0) 57 ,m_date(0) 57 ,m_date(0) 58 ,m_key_length(0) 58 ,m_key_length(0) 59 ,m_cycle(0) 59 ,m_cycle(0) 60 ,m_seek_key(0) 60 ,m_seek_key(0) 61 ,m_seek_parent_dir(0) 61 ,m_seek_parent_dir(0) 62 //,m_object_class 62 //,m_object_class 63 //,m_object_name 63 //,m_object_name 64 //,m_object_title 64 //,m_object_title 65 { 65 { 66 #ifdef TOOLS_MEM 66 #ifdef TOOLS_MEM 67 mem::increment(s_class().c_str()); 67 mem::increment(s_class().c_str()); 68 #endif 68 #endif 69 m_key_length = record_size(m_version); 69 m_key_length = record_size(m_version); 70 //fDate.setDate(0); 70 //fDate.setDate(0); 71 } 71 } 72 72 73 key(std::ostream& a_out,seek a_pos,uint32 a_ 73 key(std::ostream& a_out,seek a_pos,uint32 a_nbytes) 74 :m_out(a_out) 74 :m_out(a_out) 75 ,m_buf_size(0) 75 ,m_buf_size(0) 76 ,m_buffer(0) 76 ,m_buffer(0) 77 // Record : 77 // Record : 78 ,m_nbytes(a_nbytes) //key len + compressed o 78 ,m_nbytes(a_nbytes) //key len + compressed object size 79 ,m_version(class_version()) 79 ,m_version(class_version()) 80 ,m_object_size(0) 80 ,m_object_size(0) 81 ,m_date(0) 81 ,m_date(0) 82 ,m_key_length(0) 82 ,m_key_length(0) 83 ,m_cycle(0) 83 ,m_cycle(0) 84 ,m_seek_key(a_pos) 84 ,m_seek_key(a_pos) 85 ,m_seek_parent_dir(0) 85 ,m_seek_parent_dir(0) 86 //,m_object_class 86 //,m_object_class 87 //,m_object_name 87 //,m_object_name 88 //,m_object_title 88 //,m_object_title 89 { 89 { 90 #ifdef TOOLS_MEM 90 #ifdef TOOLS_MEM 91 mem::increment(s_class().c_str()); 91 mem::increment(s_class().c_str()); 92 #endif 92 #endif 93 if(a_pos>START_BIG_FILE) m_version += big_ 93 if(a_pos>START_BIG_FILE) m_version += big_file_version_tag(); 94 m_buffer = new char[a_nbytes]; 94 m_buffer = new char[a_nbytes]; 95 if(!m_buffer) { 95 if(!m_buffer) { 96 m_out << "tools::rroot::key::key(cpcstor 96 m_out << "tools::rroot::key::key(cpcstor) :" 97 << " can't alloc " << a_nby 97 << " can't alloc " << a_nbytes << "." 98 << std::endl; 98 << std::endl; 99 } else { 99 } else { 100 m_buf_size = a_nbytes; 100 m_buf_size = a_nbytes; 101 } 101 } 102 } 102 } 103 virtual ~key(){ 103 virtual ~key(){ 104 delete [] m_buffer; 104 delete [] m_buffer; 105 #ifdef TOOLS_MEM 105 #ifdef TOOLS_MEM 106 mem::decrement(s_class().c_str()); 106 mem::decrement(s_class().c_str()); 107 #endif 107 #endif 108 } 108 } 109 protected: 109 protected: 110 key(const key& a_from) 110 key(const key& a_from) 111 :m_out(a_from.m_out) 111 :m_out(a_from.m_out) 112 ,m_buf_size(0) 112 ,m_buf_size(0) 113 ,m_buffer(0) 113 ,m_buffer(0) 114 ,m_nbytes(a_from.m_nbytes) 114 ,m_nbytes(a_from.m_nbytes) 115 ,m_version(a_from.m_version) 115 ,m_version(a_from.m_version) 116 ,m_object_size(a_from.m_object_size) 116 ,m_object_size(a_from.m_object_size) 117 ,m_date(a_from.m_date) 117 ,m_date(a_from.m_date) 118 ,m_key_length(a_from.m_key_length) 118 ,m_key_length(a_from.m_key_length) 119 ,m_cycle(a_from.m_cycle) 119 ,m_cycle(a_from.m_cycle) 120 ,m_seek_key(a_from.m_seek_key) 120 ,m_seek_key(a_from.m_seek_key) 121 ,m_seek_parent_dir(a_from.m_seek_parent_dir) 121 ,m_seek_parent_dir(a_from.m_seek_parent_dir) 122 ,m_object_class(a_from.m_object_class) 122 ,m_object_class(a_from.m_object_class) 123 ,m_object_name(a_from.m_object_name) 123 ,m_object_name(a_from.m_object_name) 124 ,m_object_title(a_from.m_object_title) 124 ,m_object_title(a_from.m_object_title) 125 { 125 { 126 #ifdef TOOLS_MEM 126 #ifdef TOOLS_MEM 127 mem::increment(s_class().c_str()); 127 mem::increment(s_class().c_str()); 128 #endif 128 #endif 129 if(a_from.m_buf_size && a_from.m_buffer) { 129 if(a_from.m_buf_size && a_from.m_buffer) { 130 m_buffer = new char[a_from.m_buf_size]; 130 m_buffer = new char[a_from.m_buf_size]; 131 if(!m_buffer) { 131 if(!m_buffer) { 132 m_out << "tools::rroot::key::key(cpcst 132 m_out << "tools::rroot::key::key(cpcstor) :" 133 << " can't alloc " << a_f 133 << " can't alloc " << a_from.m_buf_size << "." 134 << std::endl; 134 << std::endl; 135 } else { 135 } else { 136 m_buf_size = a_from.m_buf_size; 136 m_buf_size = a_from.m_buf_size; 137 ::memcpy(m_buffer,a_from.m_buffer,a_fr 137 ::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size); 138 } 138 } 139 } 139 } 140 } 140 } 141 public: 141 public: 142 key& operator=(const key& a_from){ 142 key& operator=(const key& a_from){ 143 if(&a_from==this) return *this; 143 if(&a_from==this) return *this; 144 m_nbytes = a_from.m_nbytes; 144 m_nbytes = a_from.m_nbytes; 145 m_version = a_from.m_version; 145 m_version = a_from.m_version; 146 m_object_size = a_from.m_object_size; 146 m_object_size = a_from.m_object_size; 147 m_date = a_from.m_date; 147 m_date = a_from.m_date; 148 m_key_length = a_from.m_key_length; 148 m_key_length = a_from.m_key_length; 149 m_cycle = a_from.m_cycle; 149 m_cycle = a_from.m_cycle; 150 m_seek_key = a_from.m_seek_key; 150 m_seek_key = a_from.m_seek_key; 151 m_seek_parent_dir = a_from.m_seek_parent_d 151 m_seek_parent_dir = a_from.m_seek_parent_dir; 152 m_object_class = a_from.m_object_class; 152 m_object_class = a_from.m_object_class; 153 m_object_name = a_from.m_object_name; 153 m_object_name = a_from.m_object_name; 154 m_object_title = a_from.m_object_title; 154 m_object_title = a_from.m_object_title; 155 155 156 delete [] m_buffer; 156 delete [] m_buffer; 157 m_buffer = 0; 157 m_buffer = 0; 158 m_buf_size = 0; 158 m_buf_size = 0; 159 159 160 if(a_from.m_buf_size && a_from.m_buffer) { 160 if(a_from.m_buf_size && a_from.m_buffer) { 161 m_buffer = new char[a_from.m_buf_size]; 161 m_buffer = new char[a_from.m_buf_size]; 162 if(!m_buffer) { 162 if(!m_buffer) { 163 m_out << "tools::rroot::key::operator= 163 m_out << "tools::rroot::key::operator=() :" 164 << " can't alloc " << a_f 164 << " can't alloc " << a_from.m_buf_size << "." 165 << std::endl; 165 << std::endl; 166 } else { 166 } else { 167 m_buf_size = a_from.m_buf_size; 167 m_buf_size = a_from.m_buf_size; 168 ::memcpy(m_buffer,a_from.m_buffer,a_fr 168 ::memcpy(m_buffer,a_from.m_buffer,a_from.m_buf_size); 169 } 169 } 170 } 170 } 171 171 172 return *this; 172 return *this; 173 } 173 } 174 174 175 public: 175 public: 176 std::ostream& out() const {return m_out;} 176 std::ostream& out() const {return m_out;} 177 177 178 uint32 nbytes() const {return m_nbytes;} 178 uint32 nbytes() const {return m_nbytes;} 179 seek seek_key() const {return m_seek_key;} 179 seek seek_key() const {return m_seek_key;} 180 uint32 object_size() const {return m_object_ 180 uint32 object_size() const {return m_object_size;} 181 181 182 const std::string& object_name() const {retu 182 const std::string& object_name() const {return m_object_name;} 183 const std::string& object_title() const {ret 183 const std::string& object_title() const {return m_object_title;} 184 const std::string& object_class() const {ret 184 const std::string& object_class() const {return m_object_class;} 185 185 186 bool read_file(ifile& a_file){ 186 bool read_file(ifile& a_file){ 187 // Read the key structure from the file. 187 // Read the key structure from the file. 188 if(!a_file.set_pos(m_seek_key)) return fal 188 if(!a_file.set_pos(m_seek_key)) return false; 189 if(!a_file.read_buffer(m_buffer,m_nbytes)) 189 if(!a_file.read_buffer(m_buffer,m_nbytes)) return false; 190 if(a_file.verbose()) { 190 if(a_file.verbose()) { 191 m_out << "tools::rroot::key::read_file : 191 m_out << "tools::rroot::key::read_file :" 192 << " reading " << m_nbytes 192 << " reading " << m_nbytes << " bytes" 193 << " at position " << m_see 193 << " at position " << m_seek_key 194 << "." 194 << "." 195 << std::endl; 195 << std::endl; 196 } 196 } 197 return true; 197 return true; 198 } 198 } 199 199 200 char* buf() const {return m_buffer;} 200 char* buf() const {return m_buffer;} 201 char* data_buffer() const {return m_buffer + 201 char* data_buffer() const {return m_buffer + m_key_length;} 202 const char* eob() const {return m_buffer + m 202 const char* eob() const {return m_buffer + m_buf_size;} 203 uint32 buf_size() const {return m_buf_size;} 203 uint32 buf_size() const {return m_buf_size;} 204 uint32 key_length() const {return m_key_leng 204 uint32 key_length() const {return m_key_length;} 205 205 206 bool from_buffer(bool a_byte_swap,const char 206 bool from_buffer(bool a_byte_swap,const char* aEOB,char*& a_pos,bool a_verbose) { 207 rbuf rb(m_out,a_byte_swap,aEOB,a_pos); 207 rbuf rb(m_out,a_byte_swap,aEOB,a_pos); 208 int _nbytes; 208 int _nbytes; 209 if(!rb.read(_nbytes)) return false; 209 if(!rb.read(_nbytes)) return false; 210 /* 210 /* 211 if(m_nbytes) { 211 if(m_nbytes) { 212 if(_nbytes!=int(m_nbytes)) { 212 if(_nbytes!=int(m_nbytes)) { 213 out << "tools::rroot::key::from_buffer 213 out << "tools::rroot::key::from_buffer :" 214 << " nbytes not consistent." 214 << " nbytes not consistent." 215 << " read " << _nbytes 215 << " read " << _nbytes 216 << ", expected " << m_nbytes 216 << ", expected " << m_nbytes 217 << ". Continue with " << _nbytes 217 << ". Continue with " << _nbytes 218 << std::endl; 218 << std::endl; 219 m_nbytes = _nbytes; 219 m_nbytes = _nbytes; 220 } 220 } 221 } else { 221 } else { 222 */ 222 */ 223 m_nbytes = _nbytes; 223 m_nbytes = _nbytes; 224 //} 224 //} 225 short version; 225 short version; 226 if(!rb.read(version)) return false; 226 if(!rb.read(version)) return false; 227 m_version = version; 227 m_version = version; 228 {int v; 228 {int v; 229 if(!rb.read(v)) return false; 229 if(!rb.read(v)) return false; 230 m_object_size = v;} 230 m_object_size = v;} 231 unsigned int _date; 231 unsigned int _date; 232 if(!rb.read(_date)) return false; 232 if(!rb.read(_date)) return false; 233 //fDate.setDate(_date); 233 //fDate.setDate(_date); 234 {short v; 234 {short v; 235 if(!rb.read(v)) return false; 235 if(!rb.read(v)) return false; 236 m_key_length = v;} 236 m_key_length = v;} 237 {short v; 237 {short v; 238 if(!rb.read(v)) return false; 238 if(!rb.read(v)) return false; 239 m_cycle = v;} 239 m_cycle = v;} 240 if(version>(short)big_file_version_tag()) 240 if(version>(short)big_file_version_tag()) { 241 if(!rb.read(m_seek_key)) return false; 241 if(!rb.read(m_seek_key)) return false; 242 if(!rb.read(m_seek_parent_dir)) return f 242 if(!rb.read(m_seek_parent_dir)) return false; 243 } else { 243 } else { 244 {seek32 i; 244 {seek32 i; 245 if(!rb.read(i)) return false; 245 if(!rb.read(i)) return false; 246 m_seek_key = i;} 246 m_seek_key = i;} 247 {seek32 i; 247 {seek32 i; 248 if(!rb.read(i)) return false; 248 if(!rb.read(i)) return false; 249 m_seek_parent_dir = i;} 249 m_seek_parent_dir = i;} 250 } 250 } 251 if(!rb.read(m_object_class)) return false; 251 if(!rb.read(m_object_class)) return false; 252 if(!rb.read(m_object_name)) return false; 252 if(!rb.read(m_object_name)) return false; 253 if(!rb.read(m_object_title)) return false; 253 if(!rb.read(m_object_title)) return false; 254 if(a_verbose) { 254 if(a_verbose) { 255 m_out << "tools::rroot::key::from_buffer 255 m_out << "tools::rroot::key::from_buffer :" 256 << " nbytes : " << m_nbytes 256 << " nbytes : " << m_nbytes 257 << ", object class : " << s 257 << ", object class : " << sout(m_object_class) 258 << ", object name : " << so 258 << ", object name : " << sout(m_object_name) 259 << ", object title : " << s 259 << ", object title : " << sout(m_object_title) 260 << ", object size : " << m_ 260 << ", object size : " << m_object_size 261 << "." 261 << "." 262 << std::endl; 262 << std::endl; 263 } 263 } 264 return true; 264 return true; 265 } 265 } 266 266 267 char* get_object_buffer(ifile& a_file,uint32 267 char* get_object_buffer(ifile& a_file,uint32& a_size) { 268 if(!m_key_length) { 268 if(!m_key_length) { 269 m_out << "tools::rroot::key::get_object_ 269 m_out << "tools::rroot::key::get_object_buffer :" 270 << " WARNING : m_key_length 270 << " WARNING : m_key_length is zero." 271 << std::endl; 271 << std::endl; 272 //delete [] m_buffer; 272 //delete [] m_buffer; 273 //m_buffer = 0; 273 //m_buffer = 0; 274 //m_buf_size = 0; 274 //m_buf_size = 0; 275 //a_size = 0; 275 //a_size = 0; 276 //return 0; 276 //return 0; 277 } 277 } 278 if(!m_nbytes) { 278 if(!m_nbytes) { 279 m_out << "tools::rroot::key::get_object_ 279 m_out << "tools::rroot::key::get_object_buffer :" 280 << " m_nbytes is zero." 280 << " m_nbytes is zero." 281 << std::endl; 281 << std::endl; 282 delete [] m_buffer; 282 delete [] m_buffer; 283 m_buffer = 0; 283 m_buffer = 0; 284 m_buf_size = 0; 284 m_buf_size = 0; 285 a_size = 0; 285 a_size = 0; 286 return 0; 286 return 0; 287 } 287 } 288 if(!m_object_size) { 288 if(!m_object_size) { 289 m_out << "tools::rroot::key::get_object_ 289 m_out << "tools::rroot::key::get_object_buffer :" 290 << " WARNING : m_object_siz 290 << " WARNING : m_object_size is zero." 291 << std::endl; 291 << std::endl; 292 } 292 } 293 293 294 if(a_file.verbose()) { 294 if(a_file.verbose()) { 295 m_out << "tools::rroot::key::get_object_ 295 m_out << "tools::rroot::key::get_object_buffer :" 296 << " m_nbytes : " << m_nbyt 296 << " m_nbytes : " << m_nbytes 297 << " m_key_length : " << m_ 297 << " m_key_length : " << m_key_length 298 << " m_object_size : " << m 298 << " m_object_size : " << m_object_size << "." 299 << " m_seek_key : " << m_se 299 << " m_seek_key : " << m_seek_key << "." 300 << std::endl; 300 << std::endl; 301 } 301 } 302 302 303 if(m_object_size <= (m_nbytes-m_key_length 303 if(m_object_size <= (m_nbytes-m_key_length)) { 304 delete [] m_buffer; 304 delete [] m_buffer; 305 m_buf_size = m_key_length+m_object_size; 305 m_buf_size = m_key_length+m_object_size; 306 if(m_buf_size<m_nbytes) { 306 if(m_buf_size<m_nbytes) { 307 m_out << "tools::rroot::key::get_objec 307 m_out << "tools::rroot::key::get_object_buffer :" 308 << " WARNING : m_buf_size 308 << " WARNING : m_buf_size<m_nbytes." 309 << " m_buf_size " << m_bu 309 << " m_buf_size " << m_buf_size 310 << " m_nbytes " << m_nbyt 310 << " m_nbytes " << m_nbytes 311 << ". Raise m_buf_size to 311 << ". Raise m_buf_size to " << m_nbytes << "." 312 << std::endl; 312 << std::endl; 313 m_buf_size = m_nbytes; //for read_file 313 m_buf_size = m_nbytes; //for read_file() 314 } 314 } 315 m_buffer = new char[m_buf_size]; 315 m_buffer = new char[m_buf_size]; 316 if(!m_buffer) { 316 if(!m_buffer) { 317 m_out << "tools::rroot::key::get_objec 317 m_out << "tools::rroot::key::get_object_buffer :" 318 << " can't alloc " << m_b 318 << " can't alloc " << m_buf_size 319 << std::endl; 319 << std::endl; 320 m_buffer = 0; 320 m_buffer = 0; 321 m_buf_size = 0; 321 m_buf_size = 0; 322 a_size = 0; 322 a_size = 0; 323 return 0; 323 return 0; 324 } 324 } 325 325 326 if(!read_file(a_file)) { 326 if(!read_file(a_file)) { 327 delete [] m_buffer; 327 delete [] m_buffer; 328 m_buffer = 0; 328 m_buffer = 0; 329 m_buf_size = 0; 329 m_buf_size = 0; 330 a_size = 0; 330 a_size = 0; 331 return 0; 331 return 0; 332 } 332 } 333 333 334 } else { 334 } else { 335 // have to decompress. Need a second buf 335 // have to decompress. Need a second buffer. 336 336 337 uint32 decsiz = m_key_length+m_object_si 337 uint32 decsiz = m_key_length+m_object_size; 338 char* decbuf = new char[decsiz]; 338 char* decbuf = new char[decsiz]; 339 if(!decbuf) { 339 if(!decbuf) { 340 m_out << "tools::rroot::key::get_objec 340 m_out << "tools::rroot::key::get_object_buffer :" 341 << " can't alloc " << dec 341 << " can't alloc " << decsiz 342 << std::endl; 342 << std::endl; 343 a_size = 0; 343 a_size = 0; 344 return 0; 344 return 0; 345 } 345 } 346 346 347 delete [] m_buffer; 347 delete [] m_buffer; 348 m_buffer = new char[m_nbytes]; 348 m_buffer = new char[m_nbytes]; 349 m_buf_size = m_nbytes; 349 m_buf_size = m_nbytes; 350 if(!read_file(a_file)) { 350 if(!read_file(a_file)) { 351 delete [] decbuf; 351 delete [] decbuf; 352 decbuf = 0; 352 decbuf = 0; 353 delete [] m_buffer; 353 delete [] m_buffer; 354 m_buffer = 0; 354 m_buffer = 0; 355 m_buf_size = 0; 355 m_buf_size = 0; 356 a_size = 0; 356 a_size = 0; 357 return 0; 357 return 0; 358 } 358 } 359 359 360 ::memcpy(decbuf,m_buffer,m_key_length); 360 ::memcpy(decbuf,m_buffer,m_key_length); 361 361 362 // decompress : 362 // decompress : 363 unsigned char* objbuf = (unsigned char*) 363 unsigned char* objbuf = (unsigned char*)(decbuf+m_key_length); 364 unsigned char* bufcur = (unsigned char*) 364 unsigned char* bufcur = (unsigned char*)(m_buffer+m_key_length); 365 int nout = 0; 365 int nout = 0; 366 uint32 noutot = 0; 366 uint32 noutot = 0; 367 while(true) { 367 while(true) { 368 int nin = 9 + ((int)bufcur[3] | ((int) 368 int nin = 9 + ((int)bufcur[3] | ((int)bufcur[4] << 8) | ((int)bufcur[5] << 16)); 369 int nbuf = (int)bufcur[6] | ((int)bufc 369 int nbuf = (int)bufcur[6] | ((int)bufcur[7] << 8) | ((int)bufcur[8] << 16); 370 if(!unzip(m_out,a_file,nin,bufcur,nbuf 370 if(!unzip(m_out,a_file,nin,bufcur,nbuf,objbuf,nout)) break; 371 if(!nout) break; 371 if(!nout) break; 372 noutot += nout; 372 noutot += nout; 373 if(noutot >= m_object_size) break; 373 if(noutot >= m_object_size) break; 374 bufcur += nin; 374 bufcur += nin; 375 objbuf += nout; 375 objbuf += nout; 376 } 376 } 377 377 378 delete [] m_buffer; 378 delete [] m_buffer; 379 m_buffer = 0; 379 m_buffer = 0; 380 m_buf_size = 0; 380 m_buf_size = 0; 381 381 382 if(!noutot) { 382 if(!noutot) { 383 m_out << "tools::rroot::key::get_objec 383 m_out << "tools::rroot::key::get_object_buffer :" 384 << " nothing from decompr 384 << " nothing from decompression." 385 << std::endl; 385 << std::endl; 386 delete [] decbuf; 386 delete [] decbuf; 387 decbuf = 0; 387 decbuf = 0; 388 a_size = 0; 388 a_size = 0; 389 return 0; 389 return 0; 390 } 390 } 391 if(noutot!=m_object_size) { 391 if(noutot!=m_object_size) { 392 m_out << "tools::rroot::key::get_objec 392 m_out << "tools::rroot::key::get_object_buffer :" 393 << " decompression mismat 393 << " decompression mismatch." 394 << " noutot " << noutot 394 << " noutot " << noutot 395 << " m_object_size " << m 395 << " m_object_size " << m_object_size 396 << std::endl; 396 << std::endl; 397 delete [] decbuf; 397 delete [] decbuf; 398 decbuf = 0; 398 decbuf = 0; 399 a_size = 0; 399 a_size = 0; 400 return 0; 400 return 0; 401 } 401 } 402 402 403 m_buffer = decbuf; 403 m_buffer = decbuf; 404 m_buf_size = decsiz; 404 m_buf_size = decsiz; 405 405 406 } 406 } 407 a_size = m_object_size; 407 a_size = m_object_size; 408 return m_buffer+m_key_length; 408 return m_buffer+m_key_length; 409 } 409 } 410 //NOTE : print is a Python keyword. 410 //NOTE : print is a Python keyword. 411 void dump(std::ostream& a_out) const { 411 void dump(std::ostream& a_out) const { 412 a_out << "class : " << sout(m_object_class 412 a_out << "class : " << sout(m_object_class) 413 << ", name : " << sout(m_object_name 413 << ", name : " << sout(m_object_name) 414 << ", title : " << sout(m_object_tit 414 << ", title : " << sout(m_object_title) 415 << ", size : " << m_object_size 415 << ", size : " << m_object_size 416 << "." 416 << "." 417 << std::endl; 417 << std::endl; 418 } 418 } 419 419 420 protected: 420 protected: 421 static const uint32 START_BIG_FILE = 2000000 421 static const uint32 START_BIG_FILE = 2000000000; 422 protected: 422 protected: 423 uint32 record_size(uint32 a_version) const { 423 uint32 record_size(uint32 a_version) const { 424 // Return the size in bytes of the key hea 424 // Return the size in bytes of the key header structure. 425 uint32 _nbytes = sizeof(m_nbytes); 425 uint32 _nbytes = sizeof(m_nbytes); 426 _nbytes += sizeof(short); //2 426 _nbytes += sizeof(short); //2 427 _nbytes += sizeof(m_object_size); 427 _nbytes += sizeof(m_object_size); 428 _nbytes += sizeof(date); 428 _nbytes += sizeof(date); 429 _nbytes += sizeof(m_key_length); 429 _nbytes += sizeof(m_key_length); 430 _nbytes += sizeof(m_cycle); //2+4*4= 430 _nbytes += sizeof(m_cycle); //2+4*4=18 431 if(a_version>big_file_version_tag()) { 431 if(a_version>big_file_version_tag()) { 432 _nbytes += sizeof(seek); 432 _nbytes += sizeof(seek); 433 _nbytes += sizeof(seek); //18+2*8 433 _nbytes += sizeof(seek); //18+2*8=34 434 } else { 434 } else { 435 _nbytes += sizeof(seek32); 435 _nbytes += sizeof(seek32); 436 _nbytes += sizeof(seek32); //18+2*4 436 _nbytes += sizeof(seek32); //18+2*4=26 437 } 437 } 438 _nbytes += std_string_record_size(m_object 438 _nbytes += std_string_record_size(m_object_class); 439 _nbytes += std_string_record_size(m_object 439 _nbytes += std_string_record_size(m_object_name); 440 _nbytes += std_string_record_size(m_object 440 _nbytes += std_string_record_size(m_object_title); 441 //::printf("debug : record_size %d\n",_nby 441 //::printf("debug : record_size %d\n",_nbytes); 442 return _nbytes; 442 return _nbytes; 443 } 443 } 444 444 445 bool unzip(std::ostream& a_out,ifile& a_file 445 bool unzip(std::ostream& a_out,ifile& a_file, 446 int a_srcsize,unsigned char* a_sr 446 int a_srcsize,unsigned char* a_src,int a_tgtsize,unsigned char* a_tgt,int& a_irep) { 447 447 448 // Author: E.Chernyaev (IHEP/Protvino) 448 // Author: E.Chernyaev (IHEP/Protvino) 449 // Input: scrsize - size of input buffer 449 // Input: scrsize - size of input buffer 450 // src - input buffer 450 // src - input buffer 451 // tgtsize - size of target buffer 451 // tgtsize - size of target buffer 452 // 452 // 453 // Output: tgt - target buffer (decompress 453 // Output: tgt - target buffer (decompressed) 454 // irep - size of decompressed data 454 // irep - size of decompressed data 455 // 0 - if error 455 // 0 - if error 456 456 457 a_irep = 0; 457 a_irep = 0; 458 458 459 // C H E C K H E A D E R 459 // C H E C K H E A D E R 460 const int HDRSIZE = 9; 460 const int HDRSIZE = 9; 461 461 462 if (a_srcsize < HDRSIZE) { 462 if (a_srcsize < HDRSIZE) { 463 a_out << "tools::rroot::key::unzip : too 463 a_out << "tools::rroot::key::unzip : too small source" << std::endl; 464 return false; 464 return false; 465 } 465 } 466 466 467 unsigned char DEFLATE = 8; 467 unsigned char DEFLATE = 8; 468 468 469 if ((a_src[0] != 'C' && a_src[0] != 'Z') | 469 if ((a_src[0] != 'C' && a_src[0] != 'Z') || 470 (a_src[1] != 'S' && a_src[1] != 'L') | 470 (a_src[1] != 'S' && a_src[1] != 'L') || 471 a_src[2] != DEFLATE) { 471 a_src[2] != DEFLATE) { 472 a_out << "tools::rroot::key::unzip : err 472 a_out << "tools::rroot::key::unzip : error in header" << std::endl; 473 return false; 473 return false; 474 } 474 } 475 475 476 long _ibufcnt = (long)a_src[3] | ((long)a_ 476 long _ibufcnt = (long)a_src[3] | ((long)a_src[4] << 8) | ((long)a_src[5] << 16); 477 long isize = (long)a_src[6] | ((long)a_src 477 long isize = (long)a_src[6] | ((long)a_src[7] << 8) | ((long)a_src[8] << 16); 478 478 479 if(a_tgtsize<isize) { 479 if(a_tgtsize<isize) { 480 a_out << "tools::rroot::key::unzip : too 480 a_out << "tools::rroot::key::unzip : too small target." << std::endl; 481 return false; 481 return false; 482 } 482 } 483 483 484 if(_ibufcnt + HDRSIZE != a_srcsize) { 484 if(_ibufcnt + HDRSIZE != a_srcsize) { 485 a_out << "tools::rroot::key::unzip :" 485 a_out << "tools::rroot::key::unzip :" 486 << " discrepancy in source length. 486 << " discrepancy in source length." << std::endl; 487 return false; 487 return false; 488 } 488 } 489 489 490 // D E C O M P R E S S D A T A 490 // D E C O M P R E S S D A T A 491 491 492 if (a_src[0] == 'Z' && a_src[1] == 'L') { 492 if (a_src[0] == 'Z' && a_src[1] == 'L') { //compressed with zlib. 493 decompress_func func; 493 decompress_func func; 494 if(!a_file.unziper('Z',func)) { 494 if(!a_file.unziper('Z',func)) { 495 a_out << "tools::rroot::key::unzip : " 495 a_out << "tools::rroot::key::unzip : " 496 << " zlib unziper not found." << 496 << " zlib unziper not found." << std::endl; 497 return false; 497 return false; 498 } 498 } 499 499 500 unsigned int irep; 500 unsigned int irep; 501 char* src = (char*)(a_src + HDRSIZE); 501 char* src = (char*)(a_src + HDRSIZE); 502 if(!func(a_out, 502 if(!func(a_out, 503 (unsigned int)a_srcsize,src, 503 (unsigned int)a_srcsize,src, 504 (unsigned int)a_tgtsize,(char*) 504 (unsigned int)a_tgtsize,(char*)a_tgt,irep)) { 505 a_out << "tools::rroot::key::unzip : " 505 a_out << "tools::rroot::key::unzip : " 506 << " unzip function failed." << 506 << " unzip function failed." << std::endl; 507 a_irep = 0; 507 a_irep = 0; 508 return false; 508 return false; 509 } 509 } 510 a_irep = irep; 510 a_irep = irep; 511 511 512 #ifdef TOOLS_USE_CSZ 512 #ifdef TOOLS_USE_CSZ 513 } else if (a_src[0] == 'C' && a_src[1] == 513 } else if (a_src[0] == 'C' && a_src[1] == 'S') { 514 //compressed with Chernyaev & Smirnov 514 //compressed with Chernyaev & Smirnov 515 515 516 csz__Init_Inflate(_ibufcnt,a_src + HDRSI 516 csz__Init_Inflate(_ibufcnt,a_src + HDRSIZE,a_tgtsize,a_tgt); 517 517 518 if (csz__Inflate()) { 518 if (csz__Inflate()) { 519 a_out << "tools::rroot::key::unzip :" 519 a_out << "tools::rroot::key::unzip :" 520 << " error during decompression. 520 << " error during decompression." << std::endl; 521 return false; 521 return false; 522 } 522 } 523 523 524 unsigned char* obufptr = csz__obufptr(); 524 unsigned char* obufptr = csz__obufptr(); 525 525 526 // if (obufptr - a_tgt != isize) { 526 // if (obufptr - a_tgt != isize) { 527 // There are some rare cases when a few 527 // There are some rare cases when a few more bytes are required 528 if (obufptr - a_tgt > a_tgtsize) { 528 if (obufptr - a_tgt > a_tgtsize) { 529 a_out << "tools::rroot::key::_unzip :" 529 a_out << "tools::rroot::key::_unzip :" 530 << " discrepancy " << (int)(obuf 530 << " discrepancy " << (int)(obufptr - a_tgt) 531 << " with initial size: " << (in 531 << " with initial size: " << (int)isize 532 << ", tgtsize= " << a_tgtsize 532 << ", tgtsize= " << a_tgtsize 533 << std::endl; 533 << std::endl; 534 a_irep = int(obufptr - a_tgt); 534 a_irep = int(obufptr - a_tgt); 535 //return false; 535 //return false; 536 } 536 } 537 a_irep = isize; 537 a_irep = isize; 538 538 539 //a_out << "tools::rroot::key::unzip : C 539 //a_out << "tools::rroot::key::unzip : CS : ok " 540 // << a_irep << std::endl; 540 // << a_irep << std::endl; 541 #endif 541 #endif 542 } else { 542 } else { 543 a_out << "tools::rroot::key::_unzip : un 543 a_out << "tools::rroot::key::_unzip : unknown a_src[0,1]." 544 << " [0] = " << a_src[0] << ", [1] 544 << " [0] = " << a_src[0] << ", [1] = " << a_src[1] 545 << std::endl; 545 << std::endl; 546 a_irep = 0; 546 a_irep = 0; 547 return false; 547 return false; 548 } 548 } 549 return true; 549 return true; 550 } 550 } 551 551 552 static const std::string& s_class() { 552 static const std::string& s_class() { 553 static const std::string s_v("tools::rroot 553 static const std::string s_v("tools::rroot::key"); 554 return s_v; 554 return s_v; 555 } 555 } 556 protected: 556 protected: 557 std::ostream& m_out; 557 std::ostream& m_out; 558 uint32 m_buf_size; 558 uint32 m_buf_size; 559 char* m_buffer; 559 char* m_buffer; 560 // Record (stored in file) : 560 // Record (stored in file) : 561 uint32 m_nbytes; //Number of b 561 uint32 m_nbytes; //Number of bytes for the object on file 562 uint32 m_version; //Key version 562 uint32 m_version; //Key version identifier 563 uint32 m_object_size; //Length of u 563 uint32 m_object_size; //Length of uncompressed object in bytes 564 date m_date; //Date/Time of i 564 date m_date; //Date/Time of insertion in file 565 uint16 m_key_length; //Number of byt 565 uint16 m_key_length; //Number of bytes for the key itself 566 uint16 m_cycle; //Cycle number 566 uint16 m_cycle; //Cycle number 567 seek m_seek_key; //Location of ob 567 seek m_seek_key; //Location of object on file 568 seek m_seek_parent_dir; //Location of pa 568 seek m_seek_parent_dir; //Location of parent directory on file 569 std::string m_object_class; //Object Class n 569 std::string m_object_class; //Object Class name. 570 std::string m_object_name; //name of the ob 570 std::string m_object_name; //name of the object. 571 std::string m_object_title; //title of the o 571 std::string m_object_title; //title of the object. 572 }; 572 }; 573 573 574 }} 574 }} 575 575 576 #endif 576 #endif 577 577 578 //doc : 578 //doc : 579 ////////////////////////////////////////////// 579 ////////////////////////////////////////////////////////////////////////// 580 // 580 // // 581 // The Key class includes functions to book s 581 // The Key class includes functions to book space on a file, // 582 // to create I/O buffers, to fill these buff 582 // to create I/O buffers, to fill these buffers // 583 // to compress/uncompress data buffers. 583 // to compress/uncompress data buffers. // 584 // 584 // // 585 // Before saving (making persistent) an objec 585 // Before saving (making persistent) an object on a file, a key must // 586 // be created. The key structure contains all 586 // be created. The key structure contains all the information to // 587 // uniquely identify a persistent object on a 587 // uniquely identify a persistent object on a file. // 588 // fNbytes = number of bytes for the co 588 // fNbytes = number of bytes for the compressed object+key // 589 // version of the Key class 589 // version of the Key class // 590 // fObjlen = Length of uncompressed obj 590 // fObjlen = Length of uncompressed object // 591 // fDatime = Date/Time when the object 591 // fDatime = Date/Time when the object was written // 592 // fKeylen = number of bytes for the ke 592 // fKeylen = number of bytes for the key structure // 593 // fCycle = cycle number of the object 593 // fCycle = cycle number of the object // 594 // fSeekKey = Address of the object on f 594 // fSeekKey = Address of the object on file (points to fNbytes) // 595 // This is a redundant inform 595 // This is a redundant information used to cross-check // 596 // the data base integrity. 596 // the data base integrity. // 597 // fSeekPdir = Pointer to the directory s 597 // fSeekPdir = Pointer to the directory supporting this object // 598 // fClassName = Object class name 598 // fClassName = Object class name // 599 // fName = name of the object 599 // fName = name of the object // 600 // fTitle = title of the object 600 // fTitle = title of the object // 601 // 601 // // 602 // The Key class is used by ROOT to: 602 // The Key class is used by ROOT to: // 603 // - to write an object in the Current Dire 603 // - to write an object in the Current Directory // 604 // - to write a new ntuple buffer 604 // - to write a new ntuple buffer // 605 // 605 // // 606 ////////////////////////////////////////////// 606 //////////////////////////////////////////////////////////////////////////