Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/rroot/basket

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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