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_key_length = basket_key_length;
0061 }
0062 if(!m_object_size) {
0063 m_object_size = m_nbytes-m_key_length;
0064 }
0065
0066 if(!flag) return true; //fHeaderOnly
0067
0068 //G.Barrand : add the below test.
0069 if( (flag!=1) &&(flag!=2) &&
0070 (flag!=11)&&(flag!=12) &&
0071 (flag!=41)&&(flag!=42) &&
0072 (flag!=51)&&(flag!=52) ) {
0073 m_out << "tools::rroot::basket::stream :"
0074 << " bad flag " << (int)flag
0075 << std::endl;
0076 return false;
0077 }
0078
0079 if((flag%10)!=2) {
0080 //due to the upper "G.Barrand if", flag is here in {1,11,41,51}
0081
0082 if(!m_nev_buf_size) {
0083 m_out << "tools::rroot::basket::stream :"
0084 << " m_nev_buf_size is zero." << std::endl;
0085 return false;
0086 }
0087 if(m_nev>m_nev_buf_size) {
0088 m_out << "tools::rroot::basket::stream :"
0089 << " m_nev>m_nev_buf_size !"
0090 << " m_nev " << m_nev
0091 << " m_nev_buf_size " << m_nev_buf_size
0092 << std::endl;
0093 return false;
0094 }
0095 m_entry_offset = new int[m_nev_buf_size];
0096 if(m_nev) {
0097 uint32 n;
0098 if(!a_buffer.read_array<int>(m_nev_buf_size,m_entry_offset,n)) {
0099 _clear();
0100 return false;
0101 }
0102 if((n!=m_nev)&&(n!=(m_nev+1))) {
0103 m_out << "tools::rroot::basket::stream :"
0104 << " m_entry_offset read len mismatch."
0105 << " n " << n
0106 << " m_nev " << m_nev
0107 << std::endl;
0108 _clear();
0109 return false;
0110 }
0111 }
0112 if(flag>40) {
0113 m_displacement = new int[m_nev_buf_size];
0114 uint32 n;
0115 if(!a_buffer.read_array<int>(m_nev_buf_size,m_displacement,n)) {
0116 _clear();
0117 return false;
0118 }
0119 if((n!=m_nev)&&(n!=(m_nev+1))) {
0120 m_out << "tools::rroot::basket::stream :"
0121 << " m_displacement read len mismatch."
0122 << " n " << n
0123 << " m_nev " << m_nev
0124 << std::endl;
0125 _clear();
0126 return false;
0127 }
0128 }
0129 } else {
0130 //m_nev_buf_size is the size in bytes of one entry.
0131 }
0132 if((flag==1)||(flag>10)) {
0133 delete [] m_buffer;
0134 m_buffer = 0;
0135 m_buf_size = 0;
0136 if(fBufferSize) {
0137 char* _buf = new char[fBufferSize];
0138 if(!_buf) {
0139 m_out << "tools::rroot::basket::stream :"
0140 << " can't alloc " << fBufferSize << std::endl;
0141 _clear();
0142 return false;
0143 }
0144 if(v>1) {
0145 if(!a_buffer.read_fast_array(_buf,m_last)) {
0146 _clear();
0147 delete [] _buf;
0148 return false;
0149 }
0150 } else {
0151 uint32 n;
0152 if(!a_buffer.read_array<char>(fBufferSize,_buf,n)) {
0153 _clear();
0154 delete [] _buf;
0155 return false;
0156 }
0157 }
0158 m_buffer = _buf;
0159 m_buf_size = fBufferSize;
0160 }
0161 }
0162
0163 return true;
0164 }
0165 public:
0166 basket(std::ostream& a_out)
0167 :parent(a_out)
0168 ,m_nev_buf_size(0)
0169 ,m_nev(0)
0170 ,m_last(0)
0171 ,m_entry_offset(0)
0172 ,m_displacement(0)
0173 {
0174 }
0175 basket(std::ostream& a_out,seek a_pos,uint32 a_nbytes)
0176 :parent(a_out,a_pos,a_nbytes)
0177 ,m_nev_buf_size(0)
0178 ,m_nev(0)
0179 ,m_last(0)
0180 ,m_entry_offset(0)
0181 ,m_displacement(0)
0182 {
0183 }
0184 virtual ~basket(){
0185 _clear();
0186 }
0187 public:
0188 basket(const basket& a_from)
0189 :iro(a_from)
0190 ,parent(a_from)
0191 ,m_nev_buf_size(a_from.m_nev_buf_size)
0192 ,m_nev(a_from.m_nev)
0193 ,m_last(a_from.m_last)
0194 ,m_entry_offset(0)
0195 ,m_displacement(0)
0196 {
0197 if(a_from.m_nev && a_from.m_entry_offset) {
0198 m_entry_offset = new int[a_from.m_nev];
0199 if(!m_entry_offset) {
0200 m_out << "tools::rroot::basket::basket(cpcstor) :"
0201 << " can't alloc " << a_from.m_nev << "."
0202 << std::endl;
0203 } else {
0204 uint32 len = a_from.m_nev*sizeof(int);
0205 ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
0206 }
0207 }
0208 if(a_from.m_nev && a_from.m_displacement) {
0209 m_displacement = new int[a_from.m_nev];
0210 if(!m_displacement) {
0211 m_out << "tools::rroot::basket::basket(cpcstor) :"
0212 << " can't alloc " << a_from.m_nev << "."
0213 << std::endl;
0214 } else {
0215 uint32 len = a_from.m_nev*sizeof(int);
0216 ::memcpy(m_displacement,a_from.m_displacement,len);
0217 }
0218 }
0219 }
0220 basket& operator=(const basket& a_from){
0221 parent::operator=(a_from);
0222
0223 if(&a_from==this) return *this;
0224
0225 m_nev_buf_size = a_from.m_nev_buf_size;
0226 m_nev = a_from.m_nev;
0227 m_last = a_from.m_last;
0228
0229 delete [] m_entry_offset;
0230 m_entry_offset = 0;
0231 delete [] m_displacement;
0232 m_displacement = 0;
0233
0234 if(a_from.m_nev && a_from.m_entry_offset) {
0235 m_entry_offset = new int[a_from.m_nev];
0236 if(!m_entry_offset) {
0237 m_out << "tools::rroot::basket::operator=() :"
0238 << " can't alloc " << a_from.m_nev << "."
0239 << std::endl;
0240 } else {
0241 uint32 len = a_from.m_nev*sizeof(int);
0242 ::memcpy(m_entry_offset,a_from.m_entry_offset,len);
0243 }
0244 }
0245 if(a_from.m_nev && a_from.m_displacement) {
0246 m_displacement = new int[a_from.m_nev];
0247 if(!m_displacement) {
0248 m_out << "tools::rroot::basket::operator=() :"
0249 << " can't alloc " << a_from.m_nev << "."
0250 << std::endl;
0251 } else {
0252 uint32 len = a_from.m_nev*sizeof(int);
0253 ::memcpy(m_displacement,a_from.m_displacement,len);
0254 }
0255 }
0256
0257 return *this;
0258 }
0259 public:
0260 int* entry_offset() {return m_entry_offset;}
0261 int* displacement() {return m_displacement;}
0262 uint32 nev_buf_size() const {return m_nev_buf_size;}
0263 uint32 nev() const {return m_nev;}
0264 uint32 last() const {return m_last;}
0265
0266 bool read_offset_tables(bool a_byte_swap) {
0267 if(!m_buffer) return false;
0268 if(!m_last) return false;
0269
0270 delete [] m_entry_offset;
0271 m_entry_offset = 0;
0272
0273 buffer _buffer(m_out,a_byte_swap,m_buf_size,m_buffer,0,false);
0274 _buffer.set_offset(m_last);
0275
0276 {uint32 n;
0277 if(!_buffer.read_array<int>(0,m_entry_offset,n)) {
0278 m_out << "tools::rroot::basket::read_offset_tables :"
0279 << " read_array failed."
0280 << std::endl;
0281 return false;
0282 }
0283 if((n!=m_nev)&&(n!=(m_nev+1))) {
0284 m_out << "tools::rroot::basket::read_offset_tables :"
0285 << " m_entry_offset read len mismatch."
0286 << " n " << n
0287 << " m_nev " << m_nev
0288 << std::endl;
0289 return false;
0290 }}
0291
0292 delete [] m_displacement;
0293 m_displacement = 0;
0294 if(_buffer.length()!=_buffer.size()) {
0295 // There is more data in the buffer! It is the diplacement
0296 // array.
0297 uint32 n;
0298 if(!_buffer.read_array<int>(0,m_displacement,n)) {
0299 m_out << "tools::rroot::basket::read_offset_tables :"
0300 << " readArray(2) failed."
0301 << std::endl;
0302 return false;
0303 }
0304 if((n!=m_nev)&&(n!=(m_nev+1))) {
0305 m_out << "tools::rroot::basket::read_offset_tables :"
0306 << " m_displacement read len mismatch."
0307 << " n " << n
0308 << " m_nev " << m_nev
0309 << std::endl;
0310 return false;
0311 }
0312 }
0313
0314 return true;
0315 }
0316
0317 protected:
0318 void _clear(){
0319 delete [] m_entry_offset;
0320 delete [] m_displacement;
0321 m_entry_offset = 0;
0322 m_displacement = 0;
0323 }
0324 protected: //Named
0325 uint32 m_nev_buf_size; //Length in Int_t of m_entry_offset
0326 uint32 m_nev; //Number of entries in basket
0327 uint32 m_last; //Pointer to last used byte in basket
0328 int* m_entry_offset; //[m_nev] Offset of entries in fBuffer(TKey)
0329 int* m_displacement; //![m_nev] Displacement of entries in fBuffer(TKey)
0330 };
0331
0332 }}
0333
0334 #endif