inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/rroot/basket
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_rroot_basket
00005 #define inlib_rroot_basket
00006 
00007 #include "iro"
00008 #include "key"
00009 
00010 #include "../scast"
00011 #include "buffer"
00012 
00013 namespace inlib {
00014 namespace rroot {
00015 
00016 class basket : public virtual iro, public key {
00017   static uint32 kDisplacementMask() {return 0xFF000000;}
00018 public:
00019   static const std::string& s_class() {
00020     static const std::string s_v("inlib::rroot::basket");
00021     return s_v;
00022   }
00023 public: //iro
00024   virtual void* cast(const std::string& a_class) const {
00025     if(void* p = inlib::cmp_cast<basket>(this,a_class)) {return p;}
00026     else return 0;
00027   }
00028   virtual bool stream(buffer& a_buffer) {
00029     _clear();
00030 
00031     uint32 startpos = a_buffer.length();
00032 
00033     if(!key::from_buffer(a_buffer.eob(),a_buffer.pos())) return false;
00034 
00035     uint32 fBufferSize;
00036 
00037     short v;
00038     if(!a_buffer.read_version(v)) return false;
00039     if(!a_buffer.read(fBufferSize)) return false;
00040     if(!a_buffer.read(m_nev_buf_size)) return false;
00041     if(!a_buffer.read(m_nev)) return false;
00042     if(!a_buffer.read(m_last)) return false;
00043     char flag;
00044     if(!a_buffer.read(flag)) return false;
00045     if(m_last>fBufferSize) fBufferSize = m_last;
00046 
00047     uint16 basket_key_length = a_buffer.length()-startpos;
00048     if(basket_key_length!=m_key_length) {
00049       //m_file.out() << "inlib::rroot::basket::stream :"
00050       //             << " key length not consistent."
00051       //             << " read " << m_key_length
00052       //             << ", expected " << basket_key_length
00053       //             << ". Continue with " << basket_key_length
00054       //             << std::endl;
00055       m_key_length = basket_key_length;
00056     }
00057     if(!m_object_size) {
00058       //m_file.out() << "inlib::rroot::basket::stream :"
00059       //             << " m_object_size is found to be zero."
00060       //             << " Continue with (m_nbytes-m_key_length) "
00061       //             << (m_nbytes-m_key_length)
00062       //             << std::endl;
00063       m_object_size = m_nbytes-m_key_length;
00064     }
00065 
00066     if(!flag) return true; //fHeaderOnly
00067 
00068     //G.Barrand : add the below test.
00069     if( (flag!=1) &&(flag!=2)  &&
00070         (flag!=11)&&(flag!=12) &&
00071         (flag!=41)&&(flag!=42) &&
00072         (flag!=51)&&(flag!=52) ) {
00073       m_file.out() << "inlib::rroot::basket::stream :"
00074                    << " bad flag " << (int)flag
00075                    << std::endl; 
00076       return false;
00077     }
00078 
00079     if((flag%10)!=2) {
00080       if(!m_nev_buf_size) {
00081         m_file.out() << "inlib::rroot::basket::stream :" 
00082                      << " m_nev_buf_size is zero." << std::endl; 
00083         return false;
00084       }
00085       if(m_nev>m_nev_buf_size) {
00086         m_file.out() << "inlib::rroot::basket::stream :" 
00087                      << " m_nev>m_nev_buf_size !"
00088                      << " m_nev " << m_nev
00089                      << " m_nev_buf_size " << m_nev_buf_size
00090                      << std::endl; 
00091         return false;
00092       }
00093       m_entry_offset = new int[m_nev_buf_size];
00094       if(m_nev) {
00095         uint32 n;
00096         if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) {
00097           _clear();
00098           return false;
00099         }
00100         if((n!=m_nev)&&(n!=(m_nev+1))) {
00101           m_file.out() << "inlib::rroot::basket::stream :" 
00102                        << " m_entry_offset read len mismatch."
00103                        << " n " << n
00104                        << " m_nev " << m_nev
00105                        << std::endl;
00106           _clear();
00107           return false;
00108         }
00109       }
00110       if((20<flag)&&(flag<40)) {
00111         for(uint32 i=0;i<m_nev;i++){        
00112           m_entry_offset[i] &= ~kDisplacementMask();
00113         }
00114       }
00115       if(flag>40) {
00116         m_displacement = new int[m_nev_buf_size];
00117         uint32 n;
00118         if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) {
00119           _clear();
00120           return false;
00121         }
00122         if((n!=m_nev)&&(n!=(m_nev+1))) {
00123           m_file.out() << "inlib::rroot::basket::stream :" 
00124                        << " m_displacement read len mismatch."
00125                        << " n " << n
00126                        << " m_nev " << m_nev
00127                        << std::endl;
00128           _clear();
00129           return false;
00130         }
00131       }
00132     } else {
00133       //m_nev_buf_size is the size in bytes of one entry.
00134     }
00135     if((flag==1)||(flag>10)) {
00136       delete [] m_buffer;  
00137       m_buffer = 0;
00138       m_buf_size = 0;
00139       if(fBufferSize) {
00140         char* buf = new char[fBufferSize];
00141         if(!buf) {
00142           m_file.out() << "inlib::rroot::basket::stream :" 
00143                        << " can't alloc " << fBufferSize << std::endl; 
00144           _clear();
00145           return false;
00146         }
00147         if(v>1) {
00148           if(!a_buffer.read_fast_array(buf,m_last)) {
00149             _clear();
00150             delete [] buf;  
00151             return false;
00152           }
00153         } else {
00154           uint32 n;
00155           if(!a_buffer.read_array<char>(fBufferSize,buf,n)) {
00156             _clear();
00157             delete [] buf;  
00158             return false;
00159           }
00160         }
00161         m_buffer = buf;
00162         m_buf_size = fBufferSize;
00163         //fBufferRef->inline_setBufferOffset(m_last);
00164         //fBranch.tree().incrementTotalBuffers(fBufferSize);
00165       }
00166     }
00167 
00168     return true;
00169   }
00170 public:
00171   basket(ifile& a_file)
00172   :key(a_file)
00173   ,m_nev_buf_size(0)
00174   ,m_nev(0)
00175   ,m_last(0)
00176   ,m_entry_offset(0)
00177   ,m_displacement(0)
00178   {
00179 #ifdef INLIB_MEM
00180     mem::increment(s_class().c_str());
00181 #endif
00182   }
00183   basket(ifile& a_file,seek a_pos,uint32 a_nbytes)
00184   :key(a_file,a_pos,a_nbytes)
00185   ,m_entry_offset(0)
00186   ,m_displacement(0)
00187   {
00188 #ifdef INLIB_MEM
00189     mem::increment(s_class().c_str());
00190 #endif
00191   }
00192   virtual ~basket(){
00193     _clear();
00194 #ifdef INLIB_MEM
00195     mem::decrement(s_class().c_str());
00196 #endif
00197   }
00198 public:
00199   basket(const basket& a_from)
00200   : iro(a_from)
00201   ,key(a_from)
00202   ,m_nev_buf_size(a_from.m_nev_buf_size)
00203   ,m_nev(a_from.m_nev)
00204   ,m_last(a_from.m_last)
00205   ,m_entry_offset(0)
00206   ,m_displacement(0)
00207   {
00208 #ifdef INLIB_MEM
00209     mem::increment(s_class().c_str());
00210 #endif
00211     if(a_from.m_nev && a_from.m_entry_offset) {
00212       m_entry_offset = new int[a_from.m_nev];
00213       if(!m_entry_offset) {
00214         m_file.out() << "inlib::rroot::basket::basket(cpcstor) :"
00215                      << " can't alloc " << a_from.m_nev << "." 
00216                      << std::endl;
00217       } else {
00218         uint32 len = a_from.m_nev*sizeof(int);
00219         ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
00220       }
00221     }
00222     if(a_from.m_nev && a_from.m_displacement) {
00223       m_displacement = new int[a_from.m_nev];
00224       if(!m_displacement) {
00225         m_file.out() << "inlib::rroot::basket::basket(cpcstor) :"
00226                      << " can't alloc " << a_from.m_nev << "." 
00227                      << std::endl;
00228       } else {
00229         uint32 len = a_from.m_nev*sizeof(int);
00230         ::memcpy(m_displacement,a_from.m_displacement,len);
00231       }
00232     }    
00233   }
00234   basket& operator=(const basket& a_from){
00235     key::operator=(a_from);
00236     m_nev_buf_size = a_from.m_nev_buf_size;
00237     m_nev = a_from.m_nev;
00238     m_last = a_from.m_last;
00239 
00240     delete [] m_entry_offset;
00241     m_entry_offset = 0;
00242     delete [] m_displacement;
00243     m_displacement = 0;
00244 
00245     if(a_from.m_nev && a_from.m_entry_offset) {
00246       m_entry_offset = new int[a_from.m_nev];
00247       if(!m_entry_offset) {
00248         m_file.out() << "inlib::rroot::basket::operator=() :"
00249                      << " can't alloc " << a_from.m_nev << "." 
00250                      << std::endl;
00251       } else {
00252         uint32 len = a_from.m_nev*sizeof(int);
00253         ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
00254       }
00255     }
00256     if(a_from.m_nev && a_from.m_displacement) {
00257       m_displacement = new int[a_from.m_nev];
00258       if(!m_displacement) {
00259         m_file.out() << "inlib::rroot::basket::operator=() :"
00260                      << " can't alloc " << a_from.m_nev << "." 
00261                      << std::endl;
00262       } else {
00263         uint32 len = a_from.m_nev*sizeof(int);
00264         ::memcpy(m_displacement,a_from.m_displacement,len);
00265       }
00266     }    
00267 
00268     return *this;
00269   }
00270 public:
00271   int* entry_offset() {return m_entry_offset;}
00272   int* displacement() {return m_displacement;}
00273   uint32 nev_buf_size() const {return m_nev_buf_size;}
00274   uint32 nev() const {return m_nev;}
00275 
00276   bool read_offset_tables() {
00277     if(!m_buffer) return false;    
00278     if(!m_last) return false;    
00279 
00280     delete [] m_entry_offset;
00281     m_entry_offset = 0;
00282 
00283     rroot::buffer buffer(m_file.out(),m_file.byte_swap(),
00284                          m_buf_size,m_buffer,0,false); 
00285     buffer.set_offset(m_last);
00286 
00287    {uint32 n;
00288     if(!buffer.read_array<int>(0,m_entry_offset,n)) {
00289       m_file.out() << "inlib::rroot::basket::read_offset_tables :"
00290                    << " read_array failed."
00291                    << std::endl;
00292       return false;
00293     }
00294     if((n!=m_nev)&&(n!=(m_nev+1))) {
00295       m_file.out() << "inlib::rroot::basket::read_offset_tables :"
00296                    << " m_entry_offset read len mismatch."
00297                    << " n " << n
00298                    << " m_nev " << m_nev
00299                    << std::endl;
00300       return false;
00301     }}
00302 
00303     delete [] m_displacement;
00304     m_displacement = 0;
00305     if(buffer.length()!=buffer.size()) {
00306       // There is more data in the buffer!  It is the diplacement
00307       // array.
00308       uint32 n;
00309       if(!buffer.read_array<int>(0,m_displacement,n)) {
00310         m_file.out() << "inlib::rroot::basket::read_offset_tables :"
00311                      << " readArray(2) failed."
00312                      << std::endl;
00313         return false;
00314       }
00315       if((n!=m_nev)&&(n!=(m_nev+1))) {
00316         m_file.out() << "inlib::rroot::basket::read_offset_tables :"
00317                      << " m_displacement read len mismatch."
00318                      << " n " << n
00319                      << " m_nev " << m_nev
00320                      << std::endl;
00321         return false;
00322       }
00323     }
00324 
00325     return true;
00326   }
00327 
00328 protected:
00329   void _clear(){
00330     delete [] m_entry_offset;
00331     delete [] m_displacement;
00332     m_entry_offset = 0;
00333     m_displacement = 0;
00334   }
00335 protected: //Named
00336   uint32 m_nev_buf_size;  //Length in Int_t of m_entry_offset
00337   uint32 m_nev;           //Number of entries in basket
00338   uint32 m_last;          //Pointer to last used byte in basket
00339   int* m_entry_offset;    //[m_nev] Offset of entries in fBuffer(TKey)
00340   int* m_displacement;    
00341 };
00342 
00343 }}
00344 
00345 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines