inlib
1.2.0
|
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