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_obj_array 5 #define tools_rroot_obj_array 6 7 #include "object" 8 #include "../vmanip" 9 #include "../scast" 10 11 #include "cids" 12 13 namespace tools { 14 namespace rroot { 15 16 template <class T> 17 class obj_array : public virtual iro,public std::vector<T*> { 18 typedef typename std::vector<T*> parent; 19 private: 20 static const std::string& s_store_class() { 21 static const std::string s_v("TObjArray"); 22 return s_v; 23 } 24 public: 25 static const std::string& s_class() { 26 static const std::string s_v("tools::rroot::obj_array<"+T::s_class()+">"); 27 return s_v; 28 } 29 public: //iro 30 virtual void* cast(const std::string& a_class) const { 31 if(void* p = cmp_cast< obj_array<T> >(this,a_class)) return p; 32 return 0; 33 } 34 virtual const std::string& s_cls() const {return s_class();} 35 public: 36 static cid id_class() {return obj_array_cid()+T::id_class();} 37 virtual void* cast(cid a_class) const { 38 if(void* p = cmp_cast<obj_array>(this,a_class)) {return p;} 39 return 0; 40 } 41 virtual iro* copy() const {return new obj_array<T>(*this);} 42 virtual bool stream(buffer& a_buffer) { 43 ifac::args args; 44 bool accept_null = false; 45 return stream(a_buffer,args,accept_null); 46 } 47 public: 48 obj_array(ifac& a_fac) 49 :m_fac(a_fac) 50 { 51 #ifdef TOOLS_MEM 52 mem::increment(s_class().c_str()); 53 #endif 54 } 55 virtual ~obj_array(){ 56 _clear(); 57 #ifdef TOOLS_MEM 58 mem::decrement(s_class().c_str()); 59 #endif 60 } 61 public: 62 obj_array(const obj_array& a_from) 63 :iro(a_from) 64 ,parent() 65 ,m_fac(a_from.m_fac) 66 { 67 #ifdef TOOLS_MEM 68 mem::increment(s_class().c_str()); 69 #endif 70 typedef typename parent::const_iterator it_t; 71 for(it_t it=a_from.begin();it!=a_from.end();++it) { 72 if(!(*it)) { 73 parent::push_back(0); 74 m_owns.push_back(false); 75 } else { 76 iro* _obj = (*it)->copy(); 77 T* obj = safe_cast<iro,T>(*_obj); 78 if(!obj) { 79 m_fac.out() << "tools::rroot::obj_array::obj_array :" 80 << " tools::cast failed." 81 << std::endl; 82 delete _obj; 83 parent::push_back(0); 84 m_owns.push_back(false); 85 } else { 86 parent::push_back(obj); 87 m_owns.push_back(true); 88 } 89 } 90 } 91 } 92 obj_array& operator=(const obj_array& a_from){ 93 if(&a_from==this) return *this; 94 95 _clear(); 96 97 typedef typename parent::const_iterator it_t; 98 for(it_t it=a_from.begin();it!=a_from.end();++it) { 99 if(!(*it)) { 100 parent::push_back(0); 101 m_owns.push_back(false); 102 } else { 103 iro* _obj = (*it)->copy(); 104 T* obj = safe_cast<iro,T>(*_obj); 105 if(!obj) { 106 m_fac.out() << "tools::rroot::obj_array::operator= :" 107 << " tools::cast failed." 108 << std::endl; 109 delete _obj; 110 parent::push_back(0); 111 m_owns.push_back(false); 112 } else { 113 parent::push_back(obj); 114 m_owns.push_back(true); 115 } 116 } 117 } 118 119 return *this; 120 } 121 public: 122 void cleanup() {_clear();} 123 public: 124 bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) { 125 _clear(); 126 127 //::printf("debug : obj_array::stream : %lu : begin\n",(unsigned long)this); 128 129 short v; 130 unsigned int sp, bc; 131 if(!a_buffer.read_version(v,sp,bc)) return false; 132 133 //::printf("debug : obj_array::stream : version %d, byte count %d\n",v,bc); 134 135 {uint32 id,bits; 136 if(!Object_stream(a_buffer,id,bits)) return false;} 137 std::string name; 138 if(!a_buffer.read(name)) return false; 139 int nobjects; 140 if(!a_buffer.read(nobjects)) return false; 141 int lowerBound; 142 if(!a_buffer.read(lowerBound)) return false; 143 144 //::printf("debug : obj_array : name \"%s\", nobject %d, lowerBound %d\n",name.c_str(),nobjects,lowerBound); 145 146 for (int i=0;i<nobjects;i++) { 147 //::printf("debug : obj_array::stream : %lu : n=%d i=%d ...\n",(unsigned long)this,nobjects,i); 148 149 iro* obj; 150 bool created; 151 if(!a_buffer.read_object(m_fac,a_args,obj,created)){ 152 a_buffer.out() << "tools::rroot::obj_array::stream : can't read object" 153 << " in obj_array : name " << sout(name) 154 << ", nobjects " << nobjects << ", iobject " << i << std::endl; 155 return false; 156 } 157 //::printf("debug : obj_array::stream : %lu : n=%d i=%d : ok, obj %lu\n",(unsigned long)this, 158 // nobjects,i,(unsigned long)obj); 159 if(obj) { 160 T* to = safe_cast<iro,T>(*obj); 161 if(!to) { 162 a_buffer.out() << "tools::rroot::obj_array::stream :" 163 << " tools::cast failed." 164 << " " << obj->s_cls() << " is not a " << T::s_class() << "." 165 << std::endl; 166 if(created) { 167 if(a_buffer.map_objs()) a_buffer.remove_in_map(obj); 168 delete obj; 169 } 170 } else { 171 if(created) { 172 parent::push_back(to); 173 m_owns.push_back(true); 174 } else { //someone else manage this object. 175 parent::push_back(to); 176 m_owns.push_back(false); 177 } 178 } 179 } else { 180 //a_accept_null for branch::stream m_baskets. 181 if(a_accept_null) { 182 parent::push_back(0); 183 m_owns.push_back(false); 184 } 185 } 186 } 187 188 return a_buffer.check_byte_count(sp,bc,s_store_class()); 189 } 190 protected: 191 void _clear() { 192 typedef typename parent::iterator it_t; 193 typedef std::vector<bool>::iterator itb_t; 194 while(!parent::empty()) { 195 it_t it = parent::begin(); 196 itb_t itb = m_owns.begin(); 197 T* entry = (*it); 198 bool own = (*itb); 199 parent::erase(it); 200 m_owns.erase(itb); 201 if(own) delete entry; 202 } 203 } 204 protected: 205 ifac& m_fac; 206 std::vector<bool> m_owns; 207 }; 208 209 }} 210 211 #endif