Warning, /include/Geant4/tools/rroot/basket 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_rroot_basket
0005 #define tools_rroot_basket
0006
0007 #include "iro"
0008 #include "key"
0009
0010 #include "../scast"
0011 #include "buffer"
0012 #include "cids"
0013
0014 namespace tools {
0015 namespace rroot {
0016
0017 class basket : public virtual iro, public key {
0018 typedef key parent;
0019 static uint32 kDisplacementMask() {return 0xFF000000;}
0020 public:
0021 static const std::string& s_class() {
0022 static const std::string s_v("tools::rroot::basket");
0023 return s_v;
0024 }
0025 public: //iro
0026 virtual void* cast(const std::string& a_class) const {
0027 if(void* p = cmp_cast<basket>(this,a_class)) return p;
0028 return 0;
0029 }
0030 virtual const std::string& s_cls() const {return s_class();}
0031 public:
0032 static cid id_class() {return basket_cid();}
0033 virtual void* cast(cid a_class) const {
0034 if(void* p = cmp_cast<basket>(this,a_class)) {return p;}
0035 else return 0;
0036 }
0037 public:
0038 virtual iro* copy() const {return new basket(*this);}
0039 virtual bool stream(buffer& a_buffer) {
0040 _clear();
0041
0042 uint32 startpos = a_buffer.length();
0043
0044 if(!parent::from_buffer(a_buffer.byte_swap(),a_buffer.eob(),a_buffer.pos(),a_buffer.verbose())) return false;
0045
0046 uint32 fBufferSize;
0047
0048 short v;
0049 if(!a_buffer.read_version(v)) return false;
0050 if(!a_buffer.read(fBufferSize)) return false;
0051 if(!a_buffer.read(m_nev_buf_size)) return false;
0052 if(!a_buffer.read(m_nev)) return false;
0053 if(!a_buffer.read(m_last)) return false;
0054 char flag;
0055 if(!a_buffer.read(flag)) return false;
0056 if(m_last>fBufferSize) fBufferSize = m_last;
0057
0058 uint16 basket_key_length = a_buffer.length()-startpos;
0059 if(basket_key_length!=m_key_length) {
0060 //m_out << "tools::rroot::basket::stream :"
0061 // << " key length not consistent."
0062 // << " read " << m_key_length
0063 // << ", expected " << basket_key_length
0064 // << ". Continue with " << basket_key_length
0065 // << std::endl;
0066 m_key_length = basket_key_length;
0067 }
0068 if(!m_object_size) {
0069 //m_out << "tools::rroot::basket::stream :"
0070 // << " m_object_size is found to be zero."
0071 // << " Continue with (m_nbytes-m_key_length) "
0072 // << (m_nbytes-m_key_length)
0073 // << std::endl;
0074 m_object_size = m_nbytes-m_key_length;
0075 }
0076
0077 if(!flag) return true; //fHeaderOnly
0078
0079 //G.Barrand : add the below test.
0080 if( (flag!=1) &&(flag!=2) &&
0081 (flag!=11)&&(flag!=12) &&
0082 (flag!=41)&&(flag!=42) &&
0083 (flag!=51)&&(flag!=52) ) {
0084 m_out << "tools::rroot::basket::stream :"
0085 << " bad flag " << (int)flag
0086 << std::endl;
0087 return false;
0088 }
0089
0090 if((flag%10)!=2) {
0091 //due to the upper "G.Barrand if", flag is here in {1,11,41,51}
0092
0093 if(!m_nev_buf_size) {
0094 m_out << "tools::rroot::basket::stream :"
0095 << " m_nev_buf_size is zero." << std::endl;
0096 return false;
0097 }
0098 if(m_nev>m_nev_buf_size) {
0099 m_out << "tools::rroot::basket::stream :"
0100 << " m_nev>m_nev_buf_size !"
0101 << " m_nev " << m_nev
0102 << " m_nev_buf_size " << m_nev_buf_size
0103 << std::endl;
0104 return false;
0105 }
0106 m_entry_offset = new int[m_nev_buf_size];
0107 if(m_nev) {
0108 uint32 n;
0109 if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) {
0110 _clear();
0111 return false;
0112 }
0113 if((n!=m_nev)&&(n!=(m_nev+1))) {
0114 m_out << "tools::rroot::basket::stream :"
0115 << " m_entry_offset read len mismatch."
0116 << " n " << n
0117 << " m_nev " << m_nev
0118 << std::endl;
0119 _clear();
0120 return false;
0121 }
0122 }
0123 /* Due to the upper "G.Barrand if", flag can't be in ]20,40[, then to quiet Coverity we comment the below test.
0124 if((20<flag)&&(flag<40)) {
0125 for(uint32 i=0;i<m_nev;i++){
0126 m_entry_offset[i] &= ~kDisplacementMask();
0127 }
0128 }
0129 */
0130 if(flag>40) {
0131 m_displacement = new int[m_nev_buf_size];
0132 uint32 n;
0133 if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) {
0134 _clear();
0135 return false;
0136 }
0137 if((n!=m_nev)&&(n!=(m_nev+1))) {
0138 m_out << "tools::rroot::basket::stream :"
0139 << " m_displacement read len mismatch."
0140 << " n " << n
0141 << " m_nev " << m_nev
0142 << std::endl;
0143 _clear();
0144 return false;
0145 }
0146 }
0147 } else {
0148 //m_nev_buf_size is the size in bytes of one entry.
0149 }
0150 if((flag==1)||(flag>10)) {
0151 delete [] m_buffer;
0152 m_buffer = 0;
0153 m_buf_size = 0;
0154 if(fBufferSize) {
0155 char* _buf = new char[fBufferSize];
0156 if(!_buf) {
0157 m_out << "tools::rroot::basket::stream :"
0158 << " can't alloc " << fBufferSize << std::endl;
0159 _clear();
0160 return false;
0161 }
0162 if(v>1) {
0163 if(!a_buffer.read_fast_array(_buf,m_last)) {
0164 _clear();
0165 delete [] _buf;
0166 return false;
0167 }
0168 } else {
0169 uint32 n;
0170 if(!a_buffer.read_array<char>(fBufferSize,_buf,n)) {
0171 _clear();
0172 delete [] _buf;
0173 return false;
0174 }
0175 }
0176 m_buffer = _buf;
0177 m_buf_size = fBufferSize;
0178 //fBufferRef->inline_setBufferOffset(m_last);
0179 //fBranch.tree().incrementTotalBuffers(fBufferSize);
0180 }
0181 }
0182
0183 return true;
0184 }
0185 public:
0186 basket(std::ostream& a_out)
0187 :parent(a_out)
0188 ,m_nev_buf_size(0)
0189 ,m_nev(0)
0190 ,m_last(0)
0191 ,m_entry_offset(0)
0192 ,m_displacement(0)
0193 {
0194 #ifdef TOOLS_MEM
0195 mem::increment(s_class().c_str());
0196 #endif
0197 }
0198 basket(std::ostream& a_out,seek a_pos,uint32 a_nbytes)
0199 :parent(a_out,a_pos,a_nbytes)
0200 ,m_nev_buf_size(0)
0201 ,m_nev(0)
0202 ,m_last(0)
0203 ,m_entry_offset(0)
0204 ,m_displacement(0)
0205 {
0206 #ifdef TOOLS_MEM
0207 mem::increment(s_class().c_str());
0208 #endif
0209 }
0210 virtual ~basket(){
0211 _clear();
0212 #ifdef TOOLS_MEM
0213 mem::decrement(s_class().c_str());
0214 #endif
0215 }
0216 public:
0217 basket(const basket& a_from)
0218 :iro(a_from)
0219 ,parent(a_from)
0220 ,m_nev_buf_size(a_from.m_nev_buf_size)
0221 ,m_nev(a_from.m_nev)
0222 ,m_last(a_from.m_last)
0223 ,m_entry_offset(0)
0224 ,m_displacement(0)
0225 {
0226 #ifdef TOOLS_MEM
0227 mem::increment(s_class().c_str());
0228 #endif
0229 if(a_from.m_nev && a_from.m_entry_offset) {
0230 m_entry_offset = new int[a_from.m_nev];
0231 if(!m_entry_offset) {
0232 m_out << "tools::rroot::basket::basket(cpcstor) :"
0233 << " can't alloc " << a_from.m_nev << "."
0234 << std::endl;
0235 } else {
0236 uint32 len = a_from.m_nev*sizeof(int);
0237 ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
0238 }
0239 }
0240 if(a_from.m_nev && a_from.m_displacement) {
0241 m_displacement = new int[a_from.m_nev];
0242 if(!m_displacement) {
0243 m_out << "tools::rroot::basket::basket(cpcstor) :"
0244 << " can't alloc " << a_from.m_nev << "."
0245 << std::endl;
0246 } else {
0247 uint32 len = a_from.m_nev*sizeof(int);
0248 ::memcpy(m_displacement,a_from.m_displacement,len);
0249 }
0250 }
0251 }
0252 basket& operator=(const basket& a_from){
0253 parent::operator=(a_from);
0254
0255 if(&a_from==this) return *this;
0256
0257 m_nev_buf_size = a_from.m_nev_buf_size;
0258 m_nev = a_from.m_nev;
0259 m_last = a_from.m_last;
0260
0261 delete [] m_entry_offset;
0262 m_entry_offset = 0;
0263 delete [] m_displacement;
0264 m_displacement = 0;
0265
0266 if(a_from.m_nev && a_from.m_entry_offset) {
0267 m_entry_offset = new int[a_from.m_nev];
0268 if(!m_entry_offset) {
0269 m_out << "tools::rroot::basket::operator=() :"
0270 << " can't alloc " << a_from.m_nev << "."
0271 << std::endl;
0272 } else {
0273 uint32 len = a_from.m_nev*sizeof(int);
0274 ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
0275 }
0276 }
0277 if(a_from.m_nev && a_from.m_displacement) {
0278 m_displacement = new int[a_from.m_nev];
0279 if(!m_displacement) {
0280 m_out << "tools::rroot::basket::operator=() :"
0281 << " can't alloc " << a_from.m_nev << "."
0282 << std::endl;
0283 } else {
0284 uint32 len = a_from.m_nev*sizeof(int);
0285 ::memcpy(m_displacement,a_from.m_displacement,len);
0286 }
0287 }
0288
0289 return *this;
0290 }
0291 public:
0292 int* entry_offset() {return m_entry_offset;}
0293 int* displacement() {return m_displacement;}
0294 uint32 nev_buf_size() const {return m_nev_buf_size;}
0295 uint32 nev() const {return m_nev;}
0296 uint32 last() const {return m_last;}
0297
0298 bool read_offset_tables(bool a_byte_swap) {
0299 if(!m_buffer) return false;
0300 if(!m_last) return false;
0301
0302 delete [] m_entry_offset;
0303 m_entry_offset = 0;
0304
0305 buffer _buffer(m_out,a_byte_swap,m_buf_size,m_buffer,0,false);
0306 _buffer.set_offset(m_last);
0307
0308 {uint32 n;
0309 if(!_buffer.read_array<int>(0,m_entry_offset,n)) {
0310 m_out << "tools::rroot::basket::read_offset_tables :"
0311 << " read_array failed."
0312 << std::endl;
0313 return false;
0314 }
0315 if((n!=m_nev)&&(n!=(m_nev+1))) {
0316 m_out << "tools::rroot::basket::read_offset_tables :"
0317 << " m_entry_offset read len mismatch."
0318 << " n " << n
0319 << " m_nev " << m_nev
0320 << std::endl;
0321 return false;
0322 }}
0323
0324 delete [] m_displacement;
0325 m_displacement = 0;
0326 if(_buffer.length()!=_buffer.size()) {
0327 // There is more data in the buffer! It is the diplacement
0328 // array.
0329 uint32 n;
0330 if(!_buffer.read_array<int>(0,m_displacement,n)) {
0331 m_out << "tools::rroot::basket::read_offset_tables :"
0332 << " readArray(2) failed."
0333 << std::endl;
0334 return false;
0335 }
0336 if((n!=m_nev)&&(n!=(m_nev+1))) {
0337 m_out << "tools::rroot::basket::read_offset_tables :"
0338 << " m_displacement read len mismatch."
0339 << " n " << n
0340 << " m_nev " << m_nev
0341 << std::endl;
0342 return false;
0343 }
0344 }
0345
0346 return true;
0347 }
0348
0349 protected:
0350 void _clear(){
0351 delete [] m_entry_offset;
0352 delete [] m_displacement;
0353 m_entry_offset = 0;
0354 m_displacement = 0;
0355 }
0356 protected: //Named
0357 uint32 m_nev_buf_size; //Length in Int_t of m_entry_offset
0358 uint32 m_nev; //Number of entries in basket
0359 uint32 m_last; //Pointer to last used byte in basket
0360 int* m_entry_offset; //[m_nev] Offset of entries in fBuffer(TKey)
0361 int* m_displacement; //![m_nev] Displacement of entries in fBuffer(TKey)
0362 };
0363
0364 }}
0365
0366 #endif