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_basket 4 #ifndef tools_rroot_basket 5 #define tools_rroot_basket 5 #define tools_rroot_basket 6 6 7 #include "iro" 7 #include "iro" 8 #include "key" 8 #include "key" 9 9 10 #include "../scast" 10 #include "../scast" 11 #include "buffer" 11 #include "buffer" 12 #include "cids" 12 #include "cids" 13 13 14 namespace tools { 14 namespace tools { 15 namespace rroot { 15 namespace rroot { 16 16 17 class basket : public virtual iro, public key 17 class basket : public virtual iro, public key { 18 typedef key parent; 18 typedef key parent; 19 static uint32 kDisplacementMask() {return 0x 19 static uint32 kDisplacementMask() {return 0xFF000000;} 20 public: 20 public: 21 static const std::string& s_class() { 21 static const std::string& s_class() { 22 static const std::string s_v("tools::rroot 22 static const std::string s_v("tools::rroot::basket"); 23 return s_v; 23 return s_v; 24 } 24 } 25 public: //iro 25 public: //iro 26 virtual void* cast(const std::string& a_clas 26 virtual void* cast(const std::string& a_class) const { 27 if(void* p = cmp_cast<basket>(this,a_class 27 if(void* p = cmp_cast<basket>(this,a_class)) return p; 28 return 0; 28 return 0; 29 } 29 } 30 virtual const std::string& s_cls() const {re 30 virtual const std::string& s_cls() const {return s_class();} 31 public: 31 public: 32 static cid id_class() {return basket_cid();} 32 static cid id_class() {return basket_cid();} 33 virtual void* cast(cid a_class) const { 33 virtual void* cast(cid a_class) const { 34 if(void* p = cmp_cast<basket>(this,a_class 34 if(void* p = cmp_cast<basket>(this,a_class)) {return p;} 35 else return 0; 35 else return 0; 36 } 36 } 37 public: 37 public: 38 virtual iro* copy() const {return new basket 38 virtual iro* copy() const {return new basket(*this);} 39 virtual bool stream(buffer& a_buffer) { 39 virtual bool stream(buffer& a_buffer) { 40 _clear(); 40 _clear(); 41 41 42 uint32 startpos = a_buffer.length(); 42 uint32 startpos = a_buffer.length(); 43 43 44 if(!parent::from_buffer(a_buffer.byte_swap 44 if(!parent::from_buffer(a_buffer.byte_swap(),a_buffer.eob(),a_buffer.pos(),a_buffer.verbose())) return false; 45 45 46 uint32 fBufferSize; 46 uint32 fBufferSize; 47 47 48 short v; 48 short v; 49 if(!a_buffer.read_version(v)) return false 49 if(!a_buffer.read_version(v)) return false; 50 if(!a_buffer.read(fBufferSize)) return fal 50 if(!a_buffer.read(fBufferSize)) return false; 51 if(!a_buffer.read(m_nev_buf_size)) return 51 if(!a_buffer.read(m_nev_buf_size)) return false; 52 if(!a_buffer.read(m_nev)) return false; 52 if(!a_buffer.read(m_nev)) return false; 53 if(!a_buffer.read(m_last)) return false; 53 if(!a_buffer.read(m_last)) return false; 54 char flag; 54 char flag; 55 if(!a_buffer.read(flag)) return false; 55 if(!a_buffer.read(flag)) return false; 56 if(m_last>fBufferSize) fBufferSize = m_las 56 if(m_last>fBufferSize) fBufferSize = m_last; 57 57 58 uint16 basket_key_length = a_buffer.length 58 uint16 basket_key_length = a_buffer.length()-startpos; 59 if(basket_key_length!=m_key_length) { 59 if(basket_key_length!=m_key_length) { 60 //m_out << "tools::rroot::basket::stream 60 //m_out << "tools::rroot::basket::stream :" 61 // << " key length not consi 61 // << " key length not consistent." 62 // << " read " << m_key_leng 62 // << " read " << m_key_length 63 // << ", expected " << baske 63 // << ", expected " << basket_key_length 64 // << ". Continue with " << 64 // << ". Continue with " << basket_key_length 65 // << std::endl; 65 // << std::endl; 66 m_key_length = basket_key_length; 66 m_key_length = basket_key_length; 67 } 67 } 68 if(!m_object_size) { 68 if(!m_object_size) { 69 //m_out << "tools::rroot::basket::stream 69 //m_out << "tools::rroot::basket::stream :" 70 // << " m_object_size is fou 70 // << " m_object_size is found to be zero." 71 // << " Continue with (m_nby 71 // << " Continue with (m_nbytes-m_key_length) " 72 // << (m_nbytes-m_key_length 72 // << (m_nbytes-m_key_length) 73 // << std::endl; 73 // << std::endl; 74 m_object_size = m_nbytes-m_key_length; 74 m_object_size = m_nbytes-m_key_length; 75 } 75 } 76 76 77 if(!flag) return true; //fHeaderOnly 77 if(!flag) return true; //fHeaderOnly 78 78 79 //G.Barrand : add the below test. 79 //G.Barrand : add the below test. 80 if( (flag!=1) &&(flag!=2) && 80 if( (flag!=1) &&(flag!=2) && 81 (flag!=11)&&(flag!=12) && 81 (flag!=11)&&(flag!=12) && 82 (flag!=41)&&(flag!=42) && 82 (flag!=41)&&(flag!=42) && 83 (flag!=51)&&(flag!=52) ) { 83 (flag!=51)&&(flag!=52) ) { 84 m_out << "tools::rroot::basket::stream : 84 m_out << "tools::rroot::basket::stream :" 85 << " bad flag " << (int)fla 85 << " bad flag " << (int)flag 86 << std::endl; 86 << std::endl; 87 return false; 87 return false; 88 } 88 } 89 89 90 if((flag%10)!=2) { 90 if((flag%10)!=2) { 91 //due to the upper "G.Barrand if", flag 91 //due to the upper "G.Barrand if", flag is here in {1,11,41,51} 92 92 93 if(!m_nev_buf_size) { 93 if(!m_nev_buf_size) { 94 m_out << "tools::rroot::basket::stream 94 m_out << "tools::rroot::basket::stream :" 95 << " m_nev_buf_size is ze 95 << " m_nev_buf_size is zero." << std::endl; 96 return false; 96 return false; 97 } 97 } 98 if(m_nev>m_nev_buf_size) { 98 if(m_nev>m_nev_buf_size) { 99 m_out << "tools::rroot::basket::stream 99 m_out << "tools::rroot::basket::stream :" 100 << " m_nev>m_nev_buf_size 100 << " m_nev>m_nev_buf_size !" 101 << " m_nev " << m_nev 101 << " m_nev " << m_nev 102 << " m_nev_buf_size " << 102 << " m_nev_buf_size " << m_nev_buf_size 103 << std::endl; 103 << std::endl; 104 return false; 104 return false; 105 } 105 } 106 m_entry_offset = new int[m_nev_buf_size] 106 m_entry_offset = new int[m_nev_buf_size]; 107 if(m_nev) { 107 if(m_nev) { 108 uint32 n; 108 uint32 n; 109 if(!a_buffer.read_array<int>(m_nev_buf 109 if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) { 110 _clear(); 110 _clear(); 111 return false; 111 return false; 112 } 112 } 113 if((n!=m_nev)&&(n!=(m_nev+1))) { 113 if((n!=m_nev)&&(n!=(m_nev+1))) { 114 m_out << "tools::rroot::basket::stre 114 m_out << "tools::rroot::basket::stream :" 115 << " m_entry_offset rea 115 << " m_entry_offset read len mismatch." 116 << " n " << n 116 << " n " << n 117 << " m_nev " << m_nev 117 << " m_nev " << m_nev 118 << std::endl; 118 << std::endl; 119 _clear(); 119 _clear(); 120 return false; 120 return false; 121 } 121 } 122 } 122 } 123 /* Due to the upper "G.Barrand if", flag can't 123 /* Due to the upper "G.Barrand if", flag can't be in ]20,40[, then to quiet Coverity we comment the below test. 124 if((20<flag)&&(flag<40)) { 124 if((20<flag)&&(flag<40)) { 125 for(uint32 i=0;i<m_nev;i++){ 125 for(uint32 i=0;i<m_nev;i++){ 126 m_entry_offset[i] &= ~kDisplacementM 126 m_entry_offset[i] &= ~kDisplacementMask(); 127 } 127 } 128 } 128 } 129 */ 129 */ 130 if(flag>40) { 130 if(flag>40) { 131 m_displacement = new int[m_nev_buf_siz 131 m_displacement = new int[m_nev_buf_size]; 132 uint32 n; 132 uint32 n; 133 if(!a_buffer.read_array<int>(m_nev_buf 133 if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) { 134 _clear(); 134 _clear(); 135 return false; 135 return false; 136 } 136 } 137 if((n!=m_nev)&&(n!=(m_nev+1))) { 137 if((n!=m_nev)&&(n!=(m_nev+1))) { 138 m_out << "tools::rroot::basket::stre 138 m_out << "tools::rroot::basket::stream :" 139 << " m_displacement rea 139 << " m_displacement read len mismatch." 140 << " n " << n 140 << " n " << n 141 << " m_nev " << m_nev 141 << " m_nev " << m_nev 142 << std::endl; 142 << std::endl; 143 _clear(); 143 _clear(); 144 return false; 144 return false; 145 } 145 } 146 } 146 } 147 } else { 147 } else { 148 //m_nev_buf_size is the size in bytes of 148 //m_nev_buf_size is the size in bytes of one entry. 149 } 149 } 150 if((flag==1)||(flag>10)) { 150 if((flag==1)||(flag>10)) { 151 delete [] m_buffer; 151 delete [] m_buffer; 152 m_buffer = 0; 152 m_buffer = 0; 153 m_buf_size = 0; 153 m_buf_size = 0; 154 if(fBufferSize) { 154 if(fBufferSize) { 155 char* _buf = new char[fBufferSize]; 155 char* _buf = new char[fBufferSize]; 156 if(!_buf) { 156 if(!_buf) { 157 m_out << "tools::rroot::basket::stre 157 m_out << "tools::rroot::basket::stream :" 158 << " can't alloc " << f 158 << " can't alloc " << fBufferSize << std::endl; 159 _clear(); 159 _clear(); 160 return false; 160 return false; 161 } 161 } 162 if(v>1) { 162 if(v>1) { 163 if(!a_buffer.read_fast_array(_buf,m_ 163 if(!a_buffer.read_fast_array(_buf,m_last)) { 164 _clear(); 164 _clear(); 165 delete [] _buf; 165 delete [] _buf; 166 return false; 166 return false; 167 } 167 } 168 } else { 168 } else { 169 uint32 n; 169 uint32 n; 170 if(!a_buffer.read_array<char>(fBuffe 170 if(!a_buffer.read_array<char>(fBufferSize,_buf,n)) { 171 _clear(); 171 _clear(); 172 delete [] _buf; 172 delete [] _buf; 173 return false; 173 return false; 174 } 174 } 175 } 175 } 176 m_buffer = _buf; 176 m_buffer = _buf; 177 m_buf_size = fBufferSize; 177 m_buf_size = fBufferSize; 178 //fBufferRef->inline_setBufferOffset(m 178 //fBufferRef->inline_setBufferOffset(m_last); 179 //fBranch.tree().incrementTotalBuffers 179 //fBranch.tree().incrementTotalBuffers(fBufferSize); 180 } 180 } 181 } 181 } 182 182 183 return true; 183 return true; 184 } 184 } 185 public: 185 public: 186 basket(std::ostream& a_out) 186 basket(std::ostream& a_out) 187 :parent(a_out) 187 :parent(a_out) 188 ,m_nev_buf_size(0) 188 ,m_nev_buf_size(0) 189 ,m_nev(0) 189 ,m_nev(0) 190 ,m_last(0) 190 ,m_last(0) 191 ,m_entry_offset(0) 191 ,m_entry_offset(0) 192 ,m_displacement(0) 192 ,m_displacement(0) 193 { 193 { 194 #ifdef TOOLS_MEM 194 #ifdef TOOLS_MEM 195 mem::increment(s_class().c_str()); 195 mem::increment(s_class().c_str()); 196 #endif 196 #endif 197 } 197 } 198 basket(std::ostream& a_out,seek a_pos,uint32 198 basket(std::ostream& a_out,seek a_pos,uint32 a_nbytes) 199 :parent(a_out,a_pos,a_nbytes) 199 :parent(a_out,a_pos,a_nbytes) 200 ,m_nev_buf_size(0) 200 ,m_nev_buf_size(0) 201 ,m_nev(0) 201 ,m_nev(0) 202 ,m_last(0) 202 ,m_last(0) 203 ,m_entry_offset(0) 203 ,m_entry_offset(0) 204 ,m_displacement(0) 204 ,m_displacement(0) 205 { 205 { 206 #ifdef TOOLS_MEM 206 #ifdef TOOLS_MEM 207 mem::increment(s_class().c_str()); 207 mem::increment(s_class().c_str()); 208 #endif 208 #endif 209 } 209 } 210 virtual ~basket(){ 210 virtual ~basket(){ 211 _clear(); 211 _clear(); 212 #ifdef TOOLS_MEM 212 #ifdef TOOLS_MEM 213 mem::decrement(s_class().c_str()); 213 mem::decrement(s_class().c_str()); 214 #endif 214 #endif 215 } 215 } 216 public: 216 public: 217 basket(const basket& a_from) 217 basket(const basket& a_from) 218 :iro(a_from) 218 :iro(a_from) 219 ,parent(a_from) 219 ,parent(a_from) 220 ,m_nev_buf_size(a_from.m_nev_buf_size) 220 ,m_nev_buf_size(a_from.m_nev_buf_size) 221 ,m_nev(a_from.m_nev) 221 ,m_nev(a_from.m_nev) 222 ,m_last(a_from.m_last) 222 ,m_last(a_from.m_last) 223 ,m_entry_offset(0) 223 ,m_entry_offset(0) 224 ,m_displacement(0) 224 ,m_displacement(0) 225 { 225 { 226 #ifdef TOOLS_MEM 226 #ifdef TOOLS_MEM 227 mem::increment(s_class().c_str()); 227 mem::increment(s_class().c_str()); 228 #endif 228 #endif 229 if(a_from.m_nev && a_from.m_entry_offset) 229 if(a_from.m_nev && a_from.m_entry_offset) { 230 m_entry_offset = new int[a_from.m_nev]; 230 m_entry_offset = new int[a_from.m_nev]; 231 if(!m_entry_offset) { 231 if(!m_entry_offset) { 232 m_out << "tools::rroot::basket::basket 232 m_out << "tools::rroot::basket::basket(cpcstor) :" 233 << " can't alloc " << a_f 233 << " can't alloc " << a_from.m_nev << "." 234 << std::endl; 234 << std::endl; 235 } else { 235 } else { 236 uint32 len = a_from.m_nev*sizeof(int); 236 uint32 len = a_from.m_nev*sizeof(int); 237 ::memcpy(m_entry_offset,a_from.m_entry 237 ::memcpy(m_entry_offset,a_from.m_entry_offset,len); 238 } 238 } 239 } 239 } 240 if(a_from.m_nev && a_from.m_displacement) 240 if(a_from.m_nev && a_from.m_displacement) { 241 m_displacement = new int[a_from.m_nev]; 241 m_displacement = new int[a_from.m_nev]; 242 if(!m_displacement) { 242 if(!m_displacement) { 243 m_out << "tools::rroot::basket::basket 243 m_out << "tools::rroot::basket::basket(cpcstor) :" 244 << " can't alloc " << a_f 244 << " can't alloc " << a_from.m_nev << "." 245 << std::endl; 245 << std::endl; 246 } else { 246 } else { 247 uint32 len = a_from.m_nev*sizeof(int); 247 uint32 len = a_from.m_nev*sizeof(int); 248 ::memcpy(m_displacement,a_from.m_displ 248 ::memcpy(m_displacement,a_from.m_displacement,len); 249 } 249 } 250 } 250 } 251 } 251 } 252 basket& operator=(const basket& a_from){ 252 basket& operator=(const basket& a_from){ 253 parent::operator=(a_from); 253 parent::operator=(a_from); 254 254 255 if(&a_from==this) return *this; 255 if(&a_from==this) return *this; 256 256 257 m_nev_buf_size = a_from.m_nev_buf_size; 257 m_nev_buf_size = a_from.m_nev_buf_size; 258 m_nev = a_from.m_nev; 258 m_nev = a_from.m_nev; 259 m_last = a_from.m_last; 259 m_last = a_from.m_last; 260 260 261 delete [] m_entry_offset; 261 delete [] m_entry_offset; 262 m_entry_offset = 0; 262 m_entry_offset = 0; 263 delete [] m_displacement; 263 delete [] m_displacement; 264 m_displacement = 0; 264 m_displacement = 0; 265 265 266 if(a_from.m_nev && a_from.m_entry_offset) 266 if(a_from.m_nev && a_from.m_entry_offset) { 267 m_entry_offset = new int[a_from.m_nev]; 267 m_entry_offset = new int[a_from.m_nev]; 268 if(!m_entry_offset) { 268 if(!m_entry_offset) { 269 m_out << "tools::rroot::basket::operat 269 m_out << "tools::rroot::basket::operator=() :" 270 << " can't alloc " << a_f 270 << " can't alloc " << a_from.m_nev << "." 271 << std::endl; 271 << std::endl; 272 } else { 272 } else { 273 uint32 len = a_from.m_nev*sizeof(int); 273 uint32 len = a_from.m_nev*sizeof(int); 274 ::memcpy(m_entry_offset,a_from.m_entry 274 ::memcpy(m_entry_offset,a_from.m_entry_offset,len); 275 } 275 } 276 } 276 } 277 if(a_from.m_nev && a_from.m_displacement) 277 if(a_from.m_nev && a_from.m_displacement) { 278 m_displacement = new int[a_from.m_nev]; 278 m_displacement = new int[a_from.m_nev]; 279 if(!m_displacement) { 279 if(!m_displacement) { 280 m_out << "tools::rroot::basket::operat 280 m_out << "tools::rroot::basket::operator=() :" 281 << " can't alloc " << a_f 281 << " can't alloc " << a_from.m_nev << "." 282 << std::endl; 282 << std::endl; 283 } else { 283 } else { 284 uint32 len = a_from.m_nev*sizeof(int); 284 uint32 len = a_from.m_nev*sizeof(int); 285 ::memcpy(m_displacement,a_from.m_displ 285 ::memcpy(m_displacement,a_from.m_displacement,len); 286 } 286 } 287 } 287 } 288 288 289 return *this; 289 return *this; 290 } 290 } 291 public: 291 public: 292 int* entry_offset() {return m_entry_offset;} 292 int* entry_offset() {return m_entry_offset;} 293 int* displacement() {return m_displacement;} 293 int* displacement() {return m_displacement;} 294 uint32 nev_buf_size() const {return m_nev_bu 294 uint32 nev_buf_size() const {return m_nev_buf_size;} 295 uint32 nev() const {return m_nev;} 295 uint32 nev() const {return m_nev;} 296 uint32 last() const {return m_last;} 296 uint32 last() const {return m_last;} 297 297 298 bool read_offset_tables(bool a_byte_swap) { 298 bool read_offset_tables(bool a_byte_swap) { 299 if(!m_buffer) return false; 299 if(!m_buffer) return false; 300 if(!m_last) return false; 300 if(!m_last) return false; 301 301 302 delete [] m_entry_offset; 302 delete [] m_entry_offset; 303 m_entry_offset = 0; 303 m_entry_offset = 0; 304 304 305 buffer _buffer(m_out,a_byte_swap,m_buf_siz 305 buffer _buffer(m_out,a_byte_swap,m_buf_size,m_buffer,0,false); 306 _buffer.set_offset(m_last); 306 _buffer.set_offset(m_last); 307 307 308 {uint32 n; 308 {uint32 n; 309 if(!_buffer.read_array<int>(0,m_entry_offs 309 if(!_buffer.read_array<int>(0,m_entry_offset,n)) { 310 m_out << "tools::rroot::basket::read_off 310 m_out << "tools::rroot::basket::read_offset_tables :" 311 << " read_array failed." 311 << " read_array failed." 312 << std::endl; 312 << std::endl; 313 return false; 313 return false; 314 } 314 } 315 if((n!=m_nev)&&(n!=(m_nev+1))) { 315 if((n!=m_nev)&&(n!=(m_nev+1))) { 316 m_out << "tools::rroot::basket::read_off 316 m_out << "tools::rroot::basket::read_offset_tables :" 317 << " m_entry_offset read le 317 << " m_entry_offset read len mismatch." 318 << " n " << n 318 << " n " << n 319 << " m_nev " << m_nev 319 << " m_nev " << m_nev 320 << std::endl; 320 << std::endl; 321 return false; 321 return false; 322 }} 322 }} 323 323 324 delete [] m_displacement; 324 delete [] m_displacement; 325 m_displacement = 0; 325 m_displacement = 0; 326 if(_buffer.length()!=_buffer.size()) { 326 if(_buffer.length()!=_buffer.size()) { 327 // There is more data in the buffer! It 327 // There is more data in the buffer! It is the diplacement 328 // array. 328 // array. 329 uint32 n; 329 uint32 n; 330 if(!_buffer.read_array<int>(0,m_displace 330 if(!_buffer.read_array<int>(0,m_displacement,n)) { 331 m_out << "tools::rroot::basket::read_o 331 m_out << "tools::rroot::basket::read_offset_tables :" 332 << " readArray(2) failed. 332 << " readArray(2) failed." 333 << std::endl; 333 << std::endl; 334 return false; 334 return false; 335 } 335 } 336 if((n!=m_nev)&&(n!=(m_nev+1))) { 336 if((n!=m_nev)&&(n!=(m_nev+1))) { 337 m_out << "tools::rroot::basket::read_o 337 m_out << "tools::rroot::basket::read_offset_tables :" 338 << " m_displacement read 338 << " m_displacement read len mismatch." 339 << " n " << n 339 << " n " << n 340 << " m_nev " << m_nev 340 << " m_nev " << m_nev 341 << std::endl; 341 << std::endl; 342 return false; 342 return false; 343 } 343 } 344 } 344 } 345 345 346 return true; 346 return true; 347 } 347 } 348 348 349 protected: 349 protected: 350 void _clear(){ 350 void _clear(){ 351 delete [] m_entry_offset; 351 delete [] m_entry_offset; 352 delete [] m_displacement; 352 delete [] m_displacement; 353 m_entry_offset = 0; 353 m_entry_offset = 0; 354 m_displacement = 0; 354 m_displacement = 0; 355 } 355 } 356 protected: //Named 356 protected: //Named 357 uint32 m_nev_buf_size; //Length in Int_t of 357 uint32 m_nev_buf_size; //Length in Int_t of m_entry_offset 358 uint32 m_nev; //Number of entries 358 uint32 m_nev; //Number of entries in basket 359 uint32 m_last; //Pointer to last us 359 uint32 m_last; //Pointer to last used byte in basket 360 int* m_entry_offset; //[m_nev] Offset of 360 int* m_entry_offset; //[m_nev] Offset of entries in fBuffer(TKey) 361 int* m_displacement; //![m_nev] Displacem 361 int* m_displacement; //![m_nev] Displacement of entries in fBuffer(TKey) 362 }; 362 }; 363 363 364 }} 364 }} 365 365 366 #endif 366 #endif