Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_rroot_leaf 5 #define tools_rroot_leaf 6 7 #include "base_leaf" 8 #include "../stype" 9 #include "../cids" 10 11 namespace tools { 12 namespace rroot { 13 14 inline const std::string& leaf_store_class(char) { 15 static const std::string s_v("TLeafB"); 16 return s_v; 17 } 18 inline const std::string& leaf_store_class(short) { 19 static const std::string s_v("TLeafS"); 20 return s_v; 21 } 22 inline const std::string& leaf_store_class(int) { 23 static const std::string s_v("TLeafI"); 24 return s_v; 25 } 26 inline const std::string& leaf_store_class(float) { 27 static const std::string s_v("TLeafF"); 28 return s_v; 29 } 30 inline const std::string& leaf_store_class(double) { 31 static const std::string s_v("TLeafD"); 32 return s_v; 33 } 34 inline const std::string& leaf_store_class(bool) { 35 static const std::string s_v("TLeafO"); 36 return s_v; 37 } 38 39 inline const std::string& leaf_float_cls() { 40 static const std::string s_v("tools::rroot::leaf<float>"); 41 return s_v; 42 } 43 inline const std::string& leaf_double_cls() { 44 static const std::string s_v("tools::rroot::leaf<double>"); 45 return s_v; 46 } 47 inline const std::string& leaf_int_cls() { 48 static const std::string s_v("tools::rroot::leaf<int>"); 49 return s_v; 50 } 51 inline const std::string& leaf_bool_cls() { 52 static const std::string s_v("tools::rroot::leaf<bool>"); 53 return s_v; 54 } 55 56 template <class T> 57 class leaf : public base_leaf { 58 public: 59 typedef T value_t; 60 public: 61 static const std::string& s_class() { 62 static const std::string s_v("tools::rroot::leaf<"+stype(T())+">"); 63 return s_v; 64 } 65 public: //iro 66 virtual void* cast(const std::string& a_class) const { 67 if(void* p = cmp_cast< leaf<T> >(this,a_class)) {return p;} 68 return base_leaf::cast(a_class); 69 } 70 virtual const std::string& s_cls() const {return s_class();} 71 public: 72 static cid id_class() {return base_leaf_cid()+_cid(T());} 73 virtual void* cast(cid a_class) const { 74 if(void* p = cmp_cast<leaf>(this,a_class)) {return p;} 75 return base_leaf::cast(a_class); 76 } 77 public: 78 virtual iro* copy() const {return new leaf<T>(*this);} 79 virtual bool stream(buffer& a_buffer) { 80 short v; 81 unsigned int _s,_c; 82 if(!a_buffer.read_version(v,_s,_c)) return false; 83 if(!base_leaf::stream(a_buffer)) return false; 84 if(!a_buffer.read(m_min)) return false; 85 if(!a_buffer.read(m_max)) return false; 86 if(!a_buffer.check_byte_count(_s,_c,leaf_store_class(T()))) return false; 87 return true; 88 } 89 public: //base_leaf 90 virtual bool read_buffer(buffer& a_buffer) { 91 if(m_leaf_count) { 92 leaf<int>* leaf_i = safe_cast<base_leaf, leaf<int> >(*m_leaf_count); 93 if(!leaf_i) { 94 m_out << "tools::rroot::leaf::read_buffer : leaf_count not a leaf<int>." << std::endl; 95 return false; 96 } 97 int len; 98 if(!leaf_i->value(0,len)) { 99 m_out << "tools::rroot::leaf::read_buffer : leaf<int>.value() failed." 100 << " m_leaf_count " << m_leaf_count 101 << " leaf_i " << leaf_i 102 << " Name " << sout(leaf_i->name()) 103 << " Size " << leaf_i->num_elem() << std::endl; 104 return false; 105 } 106 107 if (len > leaf_i->get_max()) { //protection. 108 m_out << "tools::rroot::leaf::read_buffer : warning : " << sout(name()) 109 << ", len = " << len << " > max = " 110 << leaf_i->get_max() << std::endl; 111 len = leaf_i->get_max(); 112 } 113 114 uint32 ndata = len * m_length; 115 116 //if(!ndata) { 117 // delete [] m_value; 118 // m_value = new T[1]; 119 // m_size = 0; 120 // return true; 121 //} 122 123 if(ndata>m_size) { 124 delete [] m_value; 125 m_value = new T[ndata]; 126 } 127 128 m_size = ndata; 129 if(!a_buffer.read_fast_array(m_value,ndata)) { 130 m_out << "tools::rroot::leaf::read_buffer : \"" << name() << "\" :" 131 << " read_fast_array failed." 132 << std::endl; 133 return false; 134 } 135 return true; 136 137 } else { 138 if(m_length) { 139 if(m_length>m_size) { 140 delete [] m_value; 141 m_value = new T[m_length]; 142 } 143 m_size = m_length; 144 if(!a_buffer.read_fast_array<T>(m_value,m_length)) { 145 m_out << "tools::rroot::leaf::read_buffer :" 146 << " read_fast_array failed. m_length " << m_length 147 << std::endl; 148 return false; 149 } 150 return true; 151 } else { 152 m_out << "tools::rroot::leaf::read_buffer :" 153 << " read_fast_array failed. m_length is zero." 154 << std::endl; 155 return false; 156 } 157 } 158 return true; 159 } 160 virtual bool print_value(std::ostream& a_out,uint32 a_index) const { 161 if(!m_value) return false; 162 if(a_index>=m_size) return false; 163 a_out << m_value[a_index]; 164 return true; 165 } 166 //virtual uint32 num_elem() const {return m_length;} 167 virtual uint32 num_elem() const {return m_size;} 168 public: 169 leaf(std::ostream& a_out,ifac& a_fac) 170 :base_leaf(a_out,a_fac) 171 ,m_min(T()),m_max(T()) 172 ,m_value(0),m_size(0) 173 {} 174 virtual ~leaf(){ 175 delete [] m_value; 176 } 177 protected: 178 leaf(const leaf& a_from) 179 :iro(a_from) 180 ,base_leaf(a_from) 181 ,m_min(T()),m_max(T()) 182 ,m_value(0),m_size(0) 183 {} 184 leaf& operator=(const leaf&){return *this;} 185 public: 186 bool value(uint32 a_index,T& a_value) const { 187 if(!m_value) {a_value = T();return false;} 188 if(a_index>=m_size) {a_value = T();return false;} 189 a_value = m_value[a_index]; 190 return true; 191 } 192 bool value(std::vector<T>& a_v) const { 193 if(!m_value) {a_v.clear();return false;} 194 a_v.resize(m_size); 195 for(uint32 index=0;index<m_size;index++) a_v[index] = m_value[index]; 196 return true; 197 } 198 T get_max() const {return m_max;} 199 //uint32 size() const {return m_size;} 200 protected: 201 T m_min; //Minimum value if leaf range is specified 202 T m_max; //Maximum value if leaf range is specified 203 T* m_value; //!Pointer to data buffer 204 uint32 m_size; //size of m_value array. 205 }; 206 207 class leaf_string : public base_leaf { 208 static const std::string& s_store_class() { 209 static const std::string s_v("TLeafC"); 210 return s_v; 211 } 212 public: 213 static const std::string& s_class() { 214 static const std::string s_v("tools::rroot::leaf_string"); 215 return s_v; 216 } 217 public: //iro 218 virtual void* cast(const std::string& a_class) const { 219 if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;} 220 return base_leaf::cast(a_class); 221 } 222 virtual const std::string& s_cls() const {return s_class();} 223 public: 224 static cid id_class() {return leaf_string_cid();} 225 virtual void* cast(cid a_class) const { 226 if(void* p = cmp_cast<leaf_string>(this,a_class)) {return p;} 227 return base_leaf::cast(a_class); 228 } 229 public: 230 virtual iro* copy() const {return new leaf_string(*this);} 231 virtual bool stream(buffer& a_buffer) { 232 short v; 233 unsigned int _s,_c; 234 if(!a_buffer.read_version(v,_s,_c)) return false; 235 if(!base_leaf::stream(a_buffer)) return false; 236 if(!a_buffer.read(m_min)) return false; 237 if(!a_buffer.read(m_max)) return false; 238 if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; 239 return true; 240 } 241 public: //base_leaf 242 virtual bool read_buffer(buffer& a_buffer) { 243 delete [] m_value; 244 m_value = 0; 245 246 unsigned char lenchar; 247 if(!a_buffer.read(lenchar)) { 248 m_out << "tools::rroot::leaf_string::read_buffer :" 249 << " read(uchar) failed." 250 << std::endl; 251 return false; 252 } 253 uint32 len = 0; 254 if(lenchar < 255) { 255 len = lenchar; 256 } else { 257 if(!a_buffer.read(len)) { 258 m_out << "tools::rroot::leaf_string::read_buffer :" 259 << " read(int) failed." 260 << std::endl; 261 return false; 262 } 263 } 264 if(len) { 265 //if(!m_length) { 266 // m_out << "tools::rroot::leaf_string::read_buffer : m_length is zero." << std::endl; 267 // return false; 268 //} 269 //if(len >= m_length) len = m_length-1; 270 271 m_value = new char[len+1]; 272 273 if(!a_buffer.read_fast_array(m_value,len)) { 274 m_out << "tools::rroot::leaf_string::read_buffer :" 275 << " read_fast_array failed." 276 << std::endl; 277 delete [] m_value; 278 m_value = 0; 279 return false; 280 } 281 m_value[len] = 0; 282 } else { 283 m_value = new char[1]; 284 m_value[0] = 0; 285 } 286 287 return true; 288 } 289 virtual bool print_value(std::ostream& a_out,uint32) const { 290 if(m_value) a_out << m_value; 291 return true; 292 } 293 virtual uint32 num_elem() const {return 1;} 294 public: 295 leaf_string(std::ostream& a_out,ifac& a_fac) 296 :base_leaf(a_out,a_fac) 297 ,m_min(0),m_max(0),m_value(0){} 298 virtual ~leaf_string(){ 299 delete [] m_value; 300 } 301 protected: 302 leaf_string(const leaf_string& a_from) 303 :iro(a_from),base_leaf(a_from) 304 ,m_min(0),m_max(0),m_value(0){} 305 leaf_string& operator=(const leaf_string&){return *this;} 306 public: 307 const char* value() const {return m_value;} 308 protected: 309 int m_min; 310 int m_max; 311 char* m_value; 312 }; 313 314 class leaf_element : public base_leaf { 315 static const std::string& s_store_class() { 316 static const std::string s_v("TLeafElement"); 317 return s_v; 318 } 319 public: 320 static const std::string& s_class() { 321 static const std::string s_v("tools::rroot::leaf_element"); 322 return s_v; 323 } 324 public: //iro 325 virtual void* cast(const std::string& a_class) const { 326 if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;} 327 return base_leaf::cast(a_class); 328 } 329 virtual const std::string& s_cls() const {return s_class();} 330 public: 331 static cid id_class() {return leaf_element_cid();} 332 virtual void* cast(cid a_class) const { 333 if(void* p = cmp_cast<leaf_element>(this,a_class)) {return p;} 334 return base_leaf::cast(a_class); 335 } 336 public: 337 virtual iro* copy() const {return new leaf_element(*this);} 338 virtual bool stream(buffer& a_buffer) { 339 short v; 340 unsigned int _s,_c; 341 if(!a_buffer.read_version(v,_s,_c)) return false; 342 if(!base_leaf::stream(a_buffer)) return false; 343 if(!a_buffer.read(fID)) return false; 344 if(!a_buffer.read(fType)) return false; 345 if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; 346 return true; 347 } 348 public: //base_leaf 349 virtual bool read_buffer(buffer&) { 350 m_out << "tools::rroot::leaf_element::read_buffer : dummy." << std::endl; 351 return false; 352 } 353 virtual bool print_value(std::ostream&,uint32) const {return true;} 354 virtual uint32 num_elem() const {return 0;} 355 public: 356 leaf_element(std::ostream& a_out,ifac& a_fac) 357 :base_leaf(a_out,a_fac),fID(0),fType(0){} 358 virtual ~leaf_element(){} 359 protected: 360 leaf_element(const leaf_element& a_from) 361 :iro(a_from),base_leaf(a_from),fID(0),fType(0){} 362 leaf_element& operator=(const leaf_element&){return *this;} 363 public: 364 //int id() const {return fID;} 365 int leaf_type() const {return fType;} 366 protected: 367 int fID; //element serial number in fInfo 368 int fType; //leaf type 369 }; 370 371 }} 372 373 #include "iobject" 374 375 namespace tools { 376 namespace rroot { 377 378 class leaf_object : public base_leaf { 379 static const std::string& s_store_class() { 380 static const std::string s_v("TLeafObject"); 381 return s_v; 382 } 383 public: 384 static const std::string& s_class() { 385 static const std::string s_v("tools::rroot::leaf_object"); 386 return s_v; 387 } 388 public: //iro 389 virtual void* cast(const std::string& a_class) const { 390 if(void* p = cmp_cast<leaf_object>(this,a_class)) {return p;} 391 return base_leaf::cast(a_class); 392 } 393 virtual const std::string& s_cls() const {return s_class();} 394 public: 395 static cid id_class() {return leaf_object_cid();} 396 virtual void* cast(cid a_class) const { 397 if(void* p = cmp_cast<leaf_object>(this,a_class)) {return p;} 398 return base_leaf::cast(a_class); 399 } 400 public: 401 virtual iro* copy() const {return new leaf_object(*this);} 402 virtual bool stream(buffer& a_buffer) { 403 short v; 404 unsigned int _s,_c; 405 if(!a_buffer.read_version(v,_s,_c)) return false; 406 if(!base_leaf::stream(a_buffer)) return false; 407 if(!a_buffer.read(fVirtual)) return false; 408 if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; 409 return true; 410 } 411 public: //base_leaf 412 virtual bool read_buffer(buffer& a_buffer) { 413 if(!m_obj) { 414 m_out << "tools::rroot::leaf_object::read_buffer : m_obj is null." << std::endl; 415 return false; 416 } 417 std::string fClassName; 418 if (fVirtual) { 419 unsigned char n; 420 if(!a_buffer.read(n)) { 421 m_out << "tools::rroot::leaf_object::read_buffer :" 422 << " read(unsigned char) failed." 423 << std::endl; 424 return false; 425 } 426 char classname[128]; 427 if(!a_buffer.read_fast_array(classname,n+1)) { 428 m_out << "tools::rroot::leaf_object::read_buffer :" 429 << " readFastArray failed." 430 << std::endl; 431 return false; 432 } 433 fClassName = classname; 434 } 435 if(m_obj->store_class_name()!=fClassName) { 436 m_out << "tools::rroot::leaf_object::read_buffer : WARNING : class mismatch :" 437 << " fClassName " << sout(fClassName) 438 << ". m_obj.store_class_name() " << sout(m_obj->store_class_name()) 439 << std::endl; 440 //return false; 441 } 442 if(!m_obj->stream(a_buffer)) { 443 m_out << "tools::rroot::leaf_object::read_buffer :" 444 << " object stream failed." 445 << " Object store class was " << m_obj->store_class_name() << "." 446 << std::endl; 447 return false; 448 } 449 // in case we had written a null pointer a Zombie object was created 450 // we must delete it 451 //FIXME 452 //if (object->TestBit(kInvalidObject)) { 453 // if (object->GetUniqueID() == 123456789) { 454 // delete object; 455 // object = 0; 456 // } 457 //} 458 return true; 459 } 460 virtual bool print_value(std::ostream&,uint32) const { 461 m_out << m_obj << std::endl; 462 return true; 463 } 464 virtual uint32 num_elem() const {return 0;} 465 public: 466 leaf_object(std::ostream& a_out,ifac& a_fac) 467 :base_leaf(a_out,a_fac),m_obj(0),fVirtual(true){} 468 virtual ~leaf_object(){} 469 protected: 470 leaf_object(const leaf_object& a_from) 471 :iro(a_from),base_leaf(a_from),m_obj(0),fVirtual(true){} 472 leaf_object& operator=(const leaf_object&){return *this;} 473 public: 474 void set_object(iobject* a_obj) {m_obj = a_obj;} //do not get ownership. 475 protected: 476 iobject* m_obj; 477 protected: 478 bool fVirtual; // Support for Virtuality 479 }; 480 481 // for SWIG : 482 inline leaf<int>* cast_leaf_int(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<int> >(a_leaf);} 483 inline leaf<float>* cast_leaf_float(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<float> >(a_leaf);} 484 inline leaf<double>* cast_leaf_double(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<double> >(a_leaf);} 485 486 }} 487 488 #endif