Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_rroot_buffer 4 #ifndef tools_rroot_buffer 5 #define tools_rroot_buffer 5 #define tools_rroot_buffer 6 6 7 #include "rbuf" 7 #include "rbuf" 8 #include "ifac" 8 #include "ifac" 9 #include "iro" 9 #include "iro" 10 #include "../sout" 10 #include "../sout" 11 #include "../mapmanip" 11 #include "../mapmanip" 12 #ifdef TOOLS_MEM 12 #ifdef TOOLS_MEM 13 #include "../mem" 13 #include "../mem" 14 #endif 14 #endif 15 15 16 #include <string> 16 #include <string> 17 #include <vector> 17 #include <vector> 18 #include <ostream> 18 #include <ostream> 19 #include <utility> << 20 19 21 // in TOOLS_STL, we don't have (yet) a perform 20 // in TOOLS_STL, we don't have (yet) a performant map. 22 21 23 #ifdef tools_stl_vector 22 #ifdef tools_stl_vector 24 #define TOOLS_RROOT_OBJ_MAP_HASH_TABLE 23 #define TOOLS_RROOT_OBJ_MAP_HASH_TABLE 25 //#define TOOLS_RROOT_OBJ_MAP_OMAP 24 //#define TOOLS_RROOT_OBJ_MAP_OMAP 26 #else 25 #else 27 #define TOOLS_RROOT_OBJ_MAP_STD_MAP 26 #define TOOLS_RROOT_OBJ_MAP_STD_MAP 28 #endif 27 #endif 29 28 30 #ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP 29 #ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP 31 #include <map> 30 #include <map> 32 #endif 31 #endif 33 #ifdef TOOLS_RROOT_OBJ_MAP_OMAP 32 #ifdef TOOLS_RROOT_OBJ_MAP_OMAP 34 #include "../omap" 33 #include "../omap" 35 #endif 34 #endif 36 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 35 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 37 #include "../hash_table" 36 #include "../hash_table" 38 #include "../hash" 37 #include "../hash" 39 #endif 38 #endif 40 39 41 namespace tools { 40 namespace tools { 42 namespace rroot { 41 namespace rroot { 43 42 44 class buffer : public rbuf { 43 class buffer : public rbuf { 45 typedef rbuf parent; 44 typedef rbuf parent; 46 45 47 static const std::string& s_class() { 46 static const std::string& s_class() { 48 static const std::string s_v("tools::rroot 47 static const std::string s_v("tools::rroot::buffer"); 49 return s_v; 48 return s_v; 50 } 49 } 51 50 52 #ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP 51 #ifdef TOOLS_RROOT_OBJ_MAP_STD_MAP 53 typedef std::map<uint32,iro*> obj_map; 52 typedef std::map<uint32,iro*> obj_map; 54 #endif 53 #endif 55 #ifdef TOOLS_RROOT_OBJ_MAP_OMAP 54 #ifdef TOOLS_RROOT_OBJ_MAP_OMAP 56 typedef omap<uint32,iro*> obj_map; 55 typedef omap<uint32,iro*> obj_map; 57 #endif 56 #endif 58 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 57 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 59 class obj_map : public hash_table<uint32,iro 58 class obj_map : public hash_table<uint32,iro*> { 60 typedef hash_table<uint32,iro*> parent; 59 typedef hash_table<uint32,iro*> parent; 61 protected: 60 protected: 62 virtual unsigned int hash(const uint32& a_ 61 virtual unsigned int hash(const uint32& a_key) { 63 return hash(&a_key,sizeof(uint32)); 62 return hash(&a_key,sizeof(uint32)); 64 } 63 } 65 virtual bool cmp(const uint32& a_key1,cons 64 virtual bool cmp(const uint32& a_key1,const uint32& a_key2) { 66 return a_key1==a_key2?true:false; 65 return a_key1==a_key2?true:false; 67 } 66 } 68 public: 67 public: 69 obj_map():parent(){} 68 obj_map():parent(){} 70 virtual ~obj_map(){} 69 virtual ~obj_map(){} 71 private: 70 private: 72 obj_map(const obj_map& a_from):parent(a_fr 71 obj_map(const obj_map& a_from):parent(a_from){} 73 obj_map& operator=(const obj_map& a_from){ 72 obj_map& operator=(const obj_map& a_from){ 74 parent::operator=(a_from); 73 parent::operator=(a_from); 75 return *this; 74 return *this; 76 } 75 } 77 }; 76 }; 78 #endif 77 #endif 79 78 80 public: 79 public: 81 buffer(std::ostream& a_out,bool a_byte_swap, 80 buffer(std::ostream& a_out,bool a_byte_swap,uint32 a_size,char* a_buffer,uint32 a_klen,bool a_verbose) 82 :parent(a_out,a_byte_swap,a_buffer+a_size,m_ 81 :parent(a_out,a_byte_swap,a_buffer+a_size,m_pos) 83 ,m_byte_swap(a_byte_swap) 82 ,m_byte_swap(a_byte_swap) 84 ,m_verbose(a_verbose) 83 ,m_verbose(a_verbose) 85 //,m_verbose(true) 84 //,m_verbose(true) 86 ,m_size(a_size) //expect a not zero size 85 ,m_size(a_size) //expect a not zero size. 87 ,m_buffer(a_buffer) //don't get ownership. 86 ,m_buffer(a_buffer) //don't get ownership. 88 ,m_pos(a_buffer) 87 ,m_pos(a_buffer) 89 ,m_klen(a_klen) //to compute refs (used in r 88 ,m_klen(a_klen) //to compute refs (used in read_class, read_object) 90 //,m_map_objs(false) 89 //,m_map_objs(false) 91 ,m_map_objs(true) 90 ,m_map_objs(true) 92 { 91 { 93 #ifdef TOOLS_MEM 92 #ifdef TOOLS_MEM 94 mem::increment(s_class().c_str()); 93 mem::increment(s_class().c_str()); 95 #endif 94 #endif 96 } 95 } 97 virtual ~buffer(){ 96 virtual ~buffer(){ 98 m_objs.clear(); 97 m_objs.clear(); 99 #ifdef TOOLS_MEM 98 #ifdef TOOLS_MEM 100 mem::decrement(s_class().c_str()); 99 mem::decrement(s_class().c_str()); 101 #endif 100 #endif 102 } 101 } 103 protected: 102 protected: 104 buffer(const buffer& a_from) 103 buffer(const buffer& a_from) 105 :parent(a_from.m_out,a_from.m_byte_swap,0,m_ 104 :parent(a_from.m_out,a_from.m_byte_swap,0,m_pos) 106 ,m_byte_swap(a_from.m_byte_swap) 105 ,m_byte_swap(a_from.m_byte_swap) 107 ,m_map_objs(a_from.m_map_objs) 106 ,m_map_objs(a_from.m_map_objs) 108 { 107 { 109 #ifdef TOOLS_MEM 108 #ifdef TOOLS_MEM 110 mem::increment(s_class().c_str()); 109 mem::increment(s_class().c_str()); 111 #endif 110 #endif 112 } 111 } 113 buffer& operator=(const buffer&){return *thi 112 buffer& operator=(const buffer&){return *this;} 114 public: 113 public: 115 bool byte_swap() const {return m_byte_swap;} 114 bool byte_swap() const {return m_byte_swap;} 116 bool verbose() const {return m_verbose;} 115 bool verbose() const {return m_verbose;} 117 116 118 void set_offset(unsigned int a_off) {m_pos = 117 void set_offset(unsigned int a_off) {m_pos = m_buffer+a_off;} 119 118 120 //char* buffer() const {return m_buffer;} 119 //char* buffer() const {return m_buffer;} 121 uint32 length() const {return uint32(m_pos-m 120 uint32 length() const {return uint32(m_pos-m_buffer);} 122 uint32 size() const {return m_size;} 121 uint32 size() const {return m_size;} 123 122 124 void set_map_objs(bool a_value) {m_map_objs 123 void set_map_objs(bool a_value) {m_map_objs = a_value;} 125 bool map_objs() const {return m_map_objs;} 124 bool map_objs() const {return m_map_objs;} 126 protected: 125 protected: 127 // on first_int : 126 // on first_int : 128 static uint32 kNullTag() {return 0;} 127 static uint32 kNullTag() {return 0;} 129 static uint32 kByteCountMask() {return 0x400 128 static uint32 kByteCountMask() {return 0x40000000;} 130 // on tag : 129 // on tag : 131 static uint32 kNewClassTag() {return 0xFFFFF 130 static uint32 kNewClassTag() {return 0xFFFFFFFF;} 132 static uint32 kClassMask() {return 0x8000000 131 static uint32 kClassMask() {return 0x80000000; } 133 static uint32 kMapOffset() {return 2;} 132 static uint32 kMapOffset() {return 2;} 134 static short kByteCountVMask() {return 0x400 133 static short kByteCountVMask() {return 0x4000;} 135 134 136 bool read_class_tag(std::string& a_class) { 135 bool read_class_tag(std::string& a_class) { 137 a_class.clear(); 136 a_class.clear(); 138 137 139 uint32 tag; 138 uint32 tag; 140 if(!parent::read(tag)) return false; 139 if(!parent::read(tag)) return false; 141 140 142 if(tag==kNewClassTag()) { 141 if(tag==kNewClassTag()) { 143 char _s[80]; 142 char _s[80]; 144 if(!read_string(_s, 80)) { 143 if(!read_string(_s, 80)) { 145 m_out << "tools::rroot::read_class_tag 144 m_out << "tools::rroot::read_class_tag :" 146 << " read string." << std::endl; 145 << " read string." << std::endl; 147 return false; 146 return false; 148 } 147 } 149 //m_out << "tools::rroot::read_class_tag 148 //m_out << "tools::rroot::read_class_tag :" 150 // << " tag kNewClassTag" 149 // << " tag kNewClassTag" 151 // << " class " << _s 150 // << " class " << _s 152 // << std::endl; 151 // << std::endl; 153 a_class = _s; 152 a_class = _s; 154 return true; 153 return true; 155 154 156 } else if(tag & kClassMask()) { 155 } else if(tag & kClassMask()) { 157 //m_out << "tools::rroot::read_class_tag 156 //m_out << "tools::rroot::read_class_tag :" 158 // << " tag & kClassMask" 157 // << " tag & kClassMask" 159 // << " ref " << (uint32)(tag & ~kC 158 // << " ref " << (uint32)(tag & ~kClassMask) 160 // << " recurse..." 159 // << " recurse..." 161 // << std::endl; 160 // << std::endl; 162 161 163 unsigned int cl_offset = (tag & ~kClassM 162 unsigned int cl_offset = (tag & ~kClassMask()); 164 cl_offset -= kMapOffset(); 163 cl_offset -= kMapOffset(); 165 cl_offset -= m_klen; 164 cl_offset -= m_klen; 166 char* old_pos = m_pos; 165 char* old_pos = m_pos; 167 m_pos = m_buffer + cl_offset; 166 m_pos = m_buffer + cl_offset; 168 //std::string scls; 167 //std::string scls; 169 //uint32 ref; 168 //uint32 ref; 170 if(!read_class_tag(a_class)) return fals 169 if(!read_class_tag(a_class)) return false; 171 m_pos = old_pos; 170 m_pos = old_pos; 172 171 173 return true; 172 return true; 174 173 175 } else { 174 } else { 176 175 177 std::ios::fmtflags old_flags = m_out.fla 176 std::ios::fmtflags old_flags = m_out.flags(); 178 m_out << "tools::rroot::read_class_tag : 177 m_out << "tools::rroot::read_class_tag :" 179 << " tag unknown case ! " 178 << " tag unknown case ! " 180 << tag << " hex " << std::hex << t 179 << tag << " hex " << std::hex << tag 181 << std::endl; 180 << std::endl; 182 m_out.flags(old_flags); 181 m_out.flags(old_flags); 183 182 184 return false; 183 return false; 185 } 184 } 186 } 185 } 187 186 188 bool read_class(std::string& a_class,uint32& 187 bool read_class(std::string& a_class,uint32& a_bcnt,bool& a_is_ref){ 189 //m_verbose = true; 188 //m_verbose = true; 190 a_class.clear(); 189 a_class.clear(); 191 a_bcnt = 0; 190 a_bcnt = 0; 192 a_is_ref = false; 191 a_is_ref = false; 193 192 194 //uint32 fVersion = 0; //Buffer form 193 //uint32 fVersion = 0; //Buffer format version 195 194 196 // read byte count and/or tag (older files 195 // read byte count and/or tag (older files don't have byte count) 197 uint32 first_int = 0; 196 uint32 first_int = 0; 198 if(!parent::read(first_int)) return false; 197 if(!parent::read(first_int)) return false; 199 198 200 if(m_verbose) { 199 if(m_verbose) { 201 std::ios::fmtflags old_flags = m_out.fla 200 std::ios::fmtflags old_flags = m_out.flags(); 202 m_out << "tools::rroot::read_class :" 201 m_out << "tools::rroot::read_class :" 203 << " first_int " << std::hex << fi 202 << " first_int " << std::hex << first_int 204 << std::endl; 203 << std::endl; 205 m_out.flags(old_flags); 204 m_out.flags(old_flags); 206 } 205 } 207 206 208 if(first_int==kNullTag()) { //GB 207 if(first_int==kNullTag()) { //GB 209 if(m_verbose) { 208 if(m_verbose) { 210 m_out << "tools::rroot::read_class :" 209 m_out << "tools::rroot::read_class :" 211 << " first_int is kNullTag." 210 << " first_int is kNullTag." 212 << std::endl; 211 << std::endl; 213 } 212 } 214 a_bcnt = 0; 213 a_bcnt = 0; 215 return true; 214 return true; 216 215 217 //} else if(first_int==kNewClassTag()) { // 216 //} else if(first_int==kNewClassTag()) { // class desc follows. 218 } else if(first_int & kByteCountMask()) { 217 } else if(first_int & kByteCountMask()) { 219 // at write : 218 // at write : 220 // skip int to store bcnt. 219 // skip int to store bcnt. 221 // + write class 220 // + write class 222 // if(!write((clIdx | Rio_kClassMask 221 // if(!write((clIdx | Rio_kClassMask))) return false; 223 // or 222 // or 224 // if(!write(Rio_kNewClassTag)) retu 223 // if(!write(Rio_kNewClassTag)) return false; 225 // + write object 224 // + write object 226 // + set byte cnt (cnt|kByteCountMask()) 225 // + set byte cnt (cnt|kByteCountMask()) at skipped int. 227 226 228 if(m_verbose) { 227 if(m_verbose) { 229 m_out << "tools::rroot::read_class :" 228 m_out << "tools::rroot::read_class :" 230 << " first_int & kByteCountMask. 229 << " first_int & kByteCountMask." 231 << std::endl; 230 << std::endl; 232 } 231 } 233 232 234 uint32 bef_tag = uint32(m_pos-m_buffer); 233 uint32 bef_tag = uint32(m_pos-m_buffer); 235 //fVersion = 1; 234 //fVersion = 1; 236 235 237 std::string scls; 236 std::string scls; 238 if(!read_class_tag(scls)) return false; 237 if(!read_class_tag(scls)) return false; 239 if(scls.empty()) { 238 if(scls.empty()) { 240 m_out << "tools::rroot::buffer::read_c 239 m_out << "tools::rroot::buffer::read_class :" 241 << " read_class_tag did not find 240 << " read_class_tag did not find a class name." 242 << std::endl; 241 << std::endl; 243 return false; 242 return false; 244 } 243 } 245 244 246 a_class = std::move(scls); << 245 a_class = scls; 247 a_bcnt = (first_int & ~kByteCountMask()) 246 a_bcnt = (first_int & ~kByteCountMask()); 248 247 249 if(m_verbose) { 248 if(m_verbose) { 250 m_out << "tools::rroot::read_class :" 249 m_out << "tools::rroot::read_class :" 251 << " kNewClassTag : read class n 250 << " kNewClassTag : read class name " << sout(a_class) 252 << " a_bcnt " << a_bcnt 251 << " a_bcnt " << a_bcnt 253 << " bef_tag " << bef_tag 252 << " bef_tag " << bef_tag 254 << "." << std::endl; 253 << "." << std::endl; 255 } 254 } 256 255 257 return true; 256 return true; 258 257 259 } else { 258 } else { 260 if(m_verbose) { 259 if(m_verbose) { 261 std::ios::fmtflags old_flags = m_out.f 260 std::ios::fmtflags old_flags = m_out.flags(); 262 m_out << "tools::rroot::read_class :" 261 m_out << "tools::rroot::read_class :" 263 << " first_int " << std::hex << 262 << " first_int " << std::hex << first_int 264 << ". first_int is position tow 263 << ". first_int is position toward object." 265 << std::endl; 264 << std::endl; 266 m_out.flags(old_flags); 265 m_out.flags(old_flags); 267 } 266 } 268 a_bcnt = first_int; //pos toward object. 267 a_bcnt = first_int; //pos toward object. 269 a_is_ref = true; 268 a_is_ref = true; 270 a_class.clear(); 269 a_class.clear(); 271 return true; 270 return true; 272 } 271 } 273 272 274 return false; 273 return false; 275 } 274 } 276 public: 275 public: 277 void remove_in_map(iro* a_obj) { 276 void remove_in_map(iro* a_obj) { 278 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 277 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 279 m_out << "tools::rroot::remove_in_map : du 278 m_out << "tools::rroot::remove_in_map : dummy." << std::endl; 280 #else 279 #else 281 find_and_remove_value(m_objs,a_obj); 280 find_and_remove_value(m_objs,a_obj); 282 #endif 281 #endif 283 } 282 } 284 bool read_object(ifac& a_fac,const ifac::arg 283 bool read_object(ifac& a_fac,const ifac::args& a_args,iro*& a_obj,bool& a_created){ 285 a_obj = 0; 284 a_obj = 0; 286 a_created = false; 285 a_created = false; 287 286 288 //m_out << "debug : tools::rroot::buffer:: 287 //m_out << "debug : tools::rroot::buffer::read_object : begin :" << std::endl; 289 288 290 // before reading object save start positi 289 // before reading object save start position 291 uint32 startpos = (uint32)(m_pos-m_buffer) 290 uint32 startpos = (uint32)(m_pos-m_buffer); 292 291 293 uint32 bcnt; 292 uint32 bcnt; 294 std::string sclass; 293 std::string sclass; 295 bool is_ref; 294 bool is_ref; 296 if(!read_class(sclass,bcnt,is_ref)) { 295 if(!read_class(sclass,bcnt,is_ref)) { 297 m_out << "tools::rroot::buffer::read_obj 296 m_out << "tools::rroot::buffer::read_object :" 298 << " can't read class." << std::en 297 << " can't read class." << std::endl; 299 return false; 298 return false; 300 } 299 } 301 //::printf("debug : %d\n",length()-startpo 300 //::printf("debug : %d\n",length()-startpos); 302 301 303 if(m_verbose) { 302 if(m_verbose) { 304 m_out << "tools::rroot::buffer::read_obj 303 m_out << "tools::rroot::buffer::read_object :" 305 << " class " << sout(sclass) << ", 304 << " class " << sout(sclass) << ", is_ref " << is_ref 306 << ", bcnt " << bcnt 305 << ", bcnt " << bcnt 307 << std::endl; 306 << std::endl; 308 } 307 } 309 308 310 if(is_ref) { //bcnt is the position toward 309 if(is_ref) { //bcnt is the position toward an object or an object ref. 311 //m_out << "debug : tools::rroot::buffer 310 //m_out << "debug : tools::rroot::buffer::read_object : is_ref : bcnt " << bcnt << std::endl; 312 311 313 unsigned int obj_offset = bcnt; 312 unsigned int obj_offset = bcnt; 314 obj_offset -= kMapOffset(); 313 obj_offset -= kMapOffset(); 315 obj_offset -= m_klen; 314 obj_offset -= m_klen; 316 315 317 if(!m_map_objs) { 316 if(!m_map_objs) { 318 m_out << "tools::rroot::buffer::read_o 317 m_out << "tools::rroot::buffer::read_object : warning :" 319 << " class " << sout(sclass) << 318 << " class " << sout(sclass) << ", is_ref but map objs is not enabled on this buffer." 320 << std::endl; 319 << std::endl; 321 } 320 } 322 321 323 if(m_map_objs) { 322 if(m_map_objs) { 324 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 323 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 325 if(m_objs.find(obj_offset,a_obj)) { 324 if(m_objs.find(obj_offset,a_obj)) { 326 //m_out << "debug : tools::rroot::bu 325 //m_out << "debug : tools::rroot::buffer::read_object : found object in map." << bcnt << std::endl; 327 return true; 326 return true; 328 } 327 } 329 #else 328 #else 330 obj_map::const_iterator it = m_objs.fi 329 obj_map::const_iterator it = m_objs.find(obj_offset); 331 if(it!=m_objs.end()) { 330 if(it!=m_objs.end()) { 332 a_obj = (*it).second; 331 a_obj = (*it).second; 333 //::printf("debug : find : %d %lu\n" 332 //::printf("debug : find : %d %lu\n",obj_offset,a_obj); 334 //stay at current m_pos ? 333 //stay at current m_pos ? 335 return true; 334 return true; 336 } 335 } 337 #endif 336 #endif 338 } 337 } 339 338 340 {char* old_pos = m_pos; 339 {char* old_pos = m_pos; 341 340 342 m_pos = m_buffer + obj_offset; 341 m_pos = m_buffer + obj_offset; 343 342 344 uint32 first_int; 343 uint32 first_int; 345 if(!parent::read(first_int)) { 344 if(!parent::read(first_int)) { 346 m_out << "tools::rroot::buffer::read_o 345 m_out << "tools::rroot::buffer::read_object : parent::read(first_int) failed." << std::endl; 347 return false; 346 return false; 348 } 347 } 349 if(first_int & kByteCountMask()) { 348 if(first_int & kByteCountMask()) { 350 std::string scls; 349 std::string scls; 351 if(!read_class_tag(scls)) { 350 if(!read_class_tag(scls)) { 352 m_out << "tools::rroot::buffer::read 351 m_out << "tools::rroot::buffer::read_object : read_class_tag() failed." << std::endl; 353 return false; 352 return false; 354 } 353 } 355 if(scls.empty()) { 354 if(scls.empty()) { 356 m_out << "tools::rroot::buffer::read 355 m_out << "tools::rroot::buffer::read_object :" 357 << " read_class_tag did not fi 356 << " read_class_tag did not find a class name." 358 << std::endl; 357 << std::endl; 359 return false; 358 return false; 360 } 359 } 361 360 362 //m_out << "tools::rroot::buffer::read 361 //m_out << "tools::rroot::buffer::read_object :" 363 // << " is_ref : class " << sout( 362 // << " is_ref : class " << sout(scls) 364 // << std::endl; 363 // << std::endl; 365 364 366 iro* obj = a_fac.create(scls,a_args); 365 iro* obj = a_fac.create(scls,a_args); 367 if(!obj) { 366 if(!obj) { 368 m_out << "tools::rroot::buffer::read 367 m_out << "tools::rroot::buffer::read_object : is_ref : creation of object" 369 << " of class " << sout(sclass 368 << " of class " << sout(sclass) << " failed." << std::endl; 370 return false; 369 return false; 371 } 370 } 372 371 373 if(m_map_objs) { 372 if(m_map_objs) { 374 //must be done before stream() 373 //must be done before stream() 375 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 374 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 376 if(!m_objs.insert(obj_offset,obj)) { 375 if(!m_objs.insert(obj_offset,obj)) { 377 m_out << "tools::rroot::buffer::re 376 m_out << "tools::rroot::buffer::read_object :" 378 << " map insert failed." 377 << " map insert failed." 379 << std::endl; 378 << std::endl; 380 } 379 } 381 #else 380 #else 382 m_objs[obj_offset] = obj; 381 m_objs[obj_offset] = obj; 383 #endif 382 #endif 384 } 383 } 385 384 386 if(!obj->stream(*this)) { 385 if(!obj->stream(*this)) { 387 m_out << "tools::rroot::buffer::read 386 m_out << "tools::rroot::buffer::read_object :" 388 << " is_ref : streamed failed 387 << " is_ref : streamed failed for class " << sout(scls) 389 << std::endl; 388 << std::endl; 390 //restore a good buffer position : 389 //restore a good buffer position : 391 //m_pos = m_buffer+startpos+sizeof(u 390 //m_pos = m_buffer+startpos+sizeof(unsigned int); 392 delete obj; 391 delete obj; 393 return false; 392 return false; 394 } 393 } 395 394 396 //m_out << "tools::rroot::buffer::read 395 //m_out << "tools::rroot::buffer::read_object :" 397 // << " is_ref : streamed ok for 396 // << " is_ref : streamed ok for class " << sout(scls) 398 // << std::endl; 397 // << std::endl; 399 398 400 a_obj = obj; 399 a_obj = obj; 401 a_created = true; 400 a_created = true; 402 401 403 } else { 402 } else { 404 m_out << "tools::rroot::buffer::read_o 403 m_out << "tools::rroot::buffer::read_object :" 405 << " is_ref : zzz" 404 << " is_ref : zzz" 406 << std::endl; 405 << std::endl; 407 } 406 } 408 407 409 m_pos = old_pos;} 408 m_pos = old_pos;} 410 409 411 // in principle at this point m_pos shou 410 // in principle at this point m_pos should be 412 // m_buffer+startpos+sizeof(unsigned i 411 // m_buffer+startpos+sizeof(unsigned int) 413 // but enforce it anyway : 412 // but enforce it anyway : 414 m_pos = m_buffer+startpos+sizeof(unsigne 413 m_pos = m_buffer+startpos+sizeof(unsigned int); 415 //check_byte_count(startpos,0,sclass) wo 414 //check_byte_count(startpos,0,sclass) would always be ok. 416 415 417 //a_obj = ??? 416 //a_obj = ??? 418 417 419 } else { 418 } else { 420 if(sclass.empty()) { 419 if(sclass.empty()) { 421 //m_out << "debug : tools::rroot::buff 420 //m_out << "debug : tools::rroot::buffer::read_object : found empty class name." << std::endl; 422 421 423 m_pos = m_buffer+startpos+bcnt+sizeof( 422 m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int); 424 423 425 } else { 424 } else { 426 //m_out << "debug : tools::rroot::buff 425 //m_out << "debug : tools::rroot::buffer::read_object : not a ref, create object." << std::endl; 427 426 428 // Being not a ref, it must NOT be in 427 // Being not a ref, it must NOT be in the map. 429 // We gain a lot by not doing the belo 428 // We gain a lot by not doing the below find. 430 /* 429 /* 431 if(m_map_objs) { 430 if(m_map_objs) { 432 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 431 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 433 if(m_objs.find(startpos,a_obj)) retu 432 if(m_objs.find(startpos,a_obj)) return true; 434 #else 433 #else 435 obj_map::const_iterator it = m_objs. 434 obj_map::const_iterator it = m_objs.find(startpos); 436 if(it!=m_objs.end()) { 435 if(it!=m_objs.end()) { 437 a_obj = (*it).second; 436 a_obj = (*it).second; 438 ::printf("debug : find xxx : %d %l 437 ::printf("debug : find xxx : %d %lu\n",startpos,a_obj); 439 //stay at current m_pos ? 438 //stay at current m_pos ? 440 return true; 439 return true; 441 } 440 } 442 #endif 441 #endif 443 } 442 } 444 */ 443 */ 445 444 446 iro* obj = a_fac.create(sclass,a_args) 445 iro* obj = a_fac.create(sclass,a_args); 447 if(!obj) { 446 if(!obj) { 448 m_out << "tools::rroot::buffer::read 447 m_out << "tools::rroot::buffer::read_object : creation of object" 449 << " of class " << sout(sclass 448 << " of class " << sout(sclass) << " failed." << std::endl; 450 return false; 449 return false; 451 } 450 } 452 //m_out << "debug : tools::rroot::buff 451 //m_out << "debug : tools::rroot::buffer::read_object : object created." << std::endl; 453 452 454 if(m_map_objs) { 453 if(m_map_objs) { 455 //must be done before stream() 454 //must be done before stream() 456 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 455 #ifdef TOOLS_RROOT_OBJ_MAP_HASH_TABLE 457 if(!m_objs.insert(startpos,obj)) { 456 if(!m_objs.insert(startpos,obj)) { 458 m_out << "tools::rroot::buffer::re 457 m_out << "tools::rroot::buffer::read_object :" 459 << " map insert failed." 458 << " map insert failed." 460 << std::endl; 459 << std::endl; 461 } 460 } 462 #else 461 #else 463 m_objs[startpos] = obj; 462 m_objs[startpos] = obj; 464 #endif 463 #endif 465 } 464 } 466 465 467 //::printf("debug : map : %d %lu\n",st 466 //::printf("debug : map : %d %lu\n",startpos,obj); 468 467 469 //NOTE : if class ref, "up there"-star 468 //NOTE : if class ref, "up there"-startpos = 8. 470 if(!obj->stream(*this)) { 469 if(!obj->stream(*this)) { 471 m_out << "tools::rroot::buffer::read 470 m_out << "tools::rroot::buffer::read_object : object.stream() failed" 472 << " for object of class " << 471 << " for object of class " << sout(sclass) << "." << std::endl; 473 //restore a good buffer position : 472 //restore a good buffer position : 474 //m_pos = m_buffer+startpos+bcnt+siz 473 //m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int); 475 delete obj; 474 delete obj; 476 return false; 475 return false; 477 } 476 } 478 477 479 //NOTE : if obj stream ok, the below l 478 //NOTE : if obj stream ok, the below line is not needed. 480 //m_pos = m_buffer+startpos+bcnt+sizeo 479 //m_pos = m_buffer+startpos+bcnt+sizeof(unsigned int); 481 480 482 if(!check_byte_count(startpos,bcnt,scl 481 if(!check_byte_count(startpos,bcnt,sclass)) { 483 m_out << "tools::rroot::buffer::read 482 m_out << "tools::rroot::buffer::read_object :" 484 << " check_byte_count failed " 483 << " check_byte_count failed " 485 << "for object of class " 484 << "for object of class " 486 << sout(sclass) << "." << std: 485 << sout(sclass) << "." << std::endl; 487 delete obj; 486 delete obj; 488 return false; 487 return false; 489 } 488 } 490 489 491 a_obj = obj; 490 a_obj = obj; 492 a_created = true; 491 a_created = true; 493 } 492 } 494 493 495 } 494 } 496 495 497 if(m_verbose) { 496 if(m_verbose) { 498 m_out << "tools::rroot::buffer::read_obj 497 m_out << "tools::rroot::buffer::read_object : end." << std::endl; 499 } 498 } 500 499 501 return true; 500 return true; 502 } 501 } 503 public: 502 public: 504 bool read_version(short& a_version){ 503 bool read_version(short& a_version){ 505 // Read class version from I/O buffer. 504 // Read class version from I/O buffer. 506 // Is read a short or three shorts. 505 // Is read a short or three shorts. 507 a_version = 0; 506 a_version = 0; 508 short version = 0; 507 short version = 0; 509 // not interested in byte count 508 // not interested in byte count 510 if(!parent::read(version)) return false; 509 if(!parent::read(version)) return false; 511 510 512 // if this is a byte count, then skip next 511 // if this is a byte count, then skip next short and read version 513 if(version & kByteCountVMask()) { 512 if(version & kByteCountVMask()) { 514 if(!parent::read(version)) return false; 513 if(!parent::read(version)) return false; 515 if(!parent::read(version)) return false; 514 if(!parent::read(version)) return false; 516 } 515 } 517 516 518 a_version = version; 517 a_version = version; 519 return true; 518 return true; 520 } 519 } 521 520 522 bool read_version(short& a_version,uint32& a 521 bool read_version(short& a_version,uint32& a_start_pos,uint32& a_byte_count){ 523 // Read class version from I/O buffer. 522 // Read class version from I/O buffer. 524 // Is read one or three shorts. 523 // Is read one or three shorts. 525 a_version = 0; 524 a_version = 0; 526 a_start_pos = 0; 525 a_start_pos = 0; 527 a_byte_count = 0; 526 a_byte_count = 0; 528 527 529 short version = 0; 528 short version = 0; 530 529 531 // before reading object save start positi 530 // before reading object save start position 532 uint32 startpos = (uint32)(m_pos-m_buffer) 531 uint32 startpos = (uint32)(m_pos-m_buffer); 533 532 534 // read byte count (older files don't have 533 // read byte count (older files don't have byte count) 535 // byte count is packed in two individual 534 // byte count is packed in two individual shorts, this to be 536 // backward compatible with old files that 535 // backward compatible with old files that have at this location 537 // only a single short (i.e. the version) 536 // only a single short (i.e. the version) 538 union { 537 union { 539 unsigned int cnt; 538 unsigned int cnt; 540 short vers[2]; 539 short vers[2]; 541 } v; 540 } v; 542 541 543 if(m_byte_swap) { 542 if(m_byte_swap) { 544 if(!parent::read(v.vers[1])) return fals 543 if(!parent::read(v.vers[1])) return false; 545 if(!parent::read(v.vers[0])) return fals 544 if(!parent::read(v.vers[0])) return false; 546 } else { 545 } else { 547 if(!parent::read(v.vers[0])) return fals 546 if(!parent::read(v.vers[0])) return false; 548 if(!parent::read(v.vers[1])) return fals 547 if(!parent::read(v.vers[1])) return false; 549 } 548 } 550 549 551 // no bytecount, backup and read version 550 // no bytecount, backup and read version 552 uint32 bcnt = 0; 551 uint32 bcnt = 0; 553 if(v.cnt & kByteCountMask()) { 552 if(v.cnt & kByteCountMask()) { 554 bcnt = (v.cnt & ~kByteCountMask()); 553 bcnt = (v.cnt & ~kByteCountMask()); 555 } else { 554 } else { 556 m_pos -= sizeof(unsigned int); 555 m_pos -= sizeof(unsigned int); 557 } 556 } 558 if(!parent::read(version)) return false; 557 if(!parent::read(version)) return false; 559 //printf("Reading version=%d at pos=%d, by 558 //printf("Reading version=%d at pos=%d, bytecount=%d\n", 560 //version,*startpos,*bcnt); 559 //version,*startpos,*bcnt); 561 560 562 a_version = version; 561 a_version = version; 563 a_start_pos = startpos; 562 a_start_pos = startpos; 564 a_byte_count = bcnt; 563 a_byte_count = bcnt; 565 564 566 return true; 565 return true; 567 } 566 } 568 567 569 bool check_byte_count(uint32 a_start_pos,uin 568 bool check_byte_count(uint32 a_start_pos,uint32 a_byte_count,const std::string& a_store_cls){ 570 if(!a_byte_count) return true; 569 if(!a_byte_count) return true; 571 570 572 size_t len = a_start_pos + a_byte_count + 571 size_t len = a_start_pos + a_byte_count + sizeof(unsigned int); 573 572 574 size_t diff = size_t(m_pos-m_buffer); 573 size_t diff = size_t(m_pos-m_buffer); 575 574 576 if(diff==len) return true; 575 if(diff==len) return true; 577 576 578 if(diff<len) { 577 if(diff<len) { 579 m_out << "tools::rroot::buffer::check_by 578 m_out << "tools::rroot::buffer::check_byte_count :" 580 << " object of class " << sout(a_s 579 << " object of class " << sout(a_store_cls) 581 << " read too few bytes (" 580 << " read too few bytes (" 582 << long_out(long(len-diff)) << " m 581 << long_out(long(len-diff)) << " missing)." 583 << std::endl; 582 << std::endl; 584 } 583 } 585 if(diff>len) { 584 if(diff>len) { 586 m_out << "tools::rroot::buffer::check_by 585 m_out << "tools::rroot::buffer::check_byte_count :" 587 << " object of class " << sout(a_s 586 << " object of class " << sout(a_store_cls) 588 << " read too many bytes (" 587 << " read too many bytes (" 589 << long_out(long(diff-len)) << " i 588 << long_out(long(diff-len)) << " in excess)." << std::endl; 590 } 589 } 591 590 592 m_out << "tools::rroot::buffer::check_byte 591 m_out << "tools::rroot::buffer::check_byte_count :" 593 << " " << sout(a_store_cls) 592 << " " << sout(a_store_cls) 594 << " streamer not in sync with data 593 << " streamer not in sync with data on file, fix streamer." 595 << std::endl; 594 << std::endl; 596 595 597 m_pos = m_buffer+len; 596 m_pos = m_buffer+len; 598 597 599 return false; 598 return false; 600 } 599 } 601 protected: 600 protected: 602 bool read_string(char* a_string,uint32 a_max 601 bool read_string(char* a_string,uint32 a_max) { 603 // Read string from I/O buffer. String is 602 // Read string from I/O buffer. String is read till 0 character is 604 // found or till max-1 characters are read 603 // found or till max-1 characters are read (i.e. string s has max 605 // bytes allocated). 604 // bytes allocated). 606 int nr = 0; 605 int nr = 0; 607 while (nr < int(a_max-1)) { 606 while (nr < int(a_max-1)) { 608 char ch; 607 char ch; 609 if(!parent::read(ch)) return false; 608 if(!parent::read(ch)) return false; 610 // stop when 0 read 609 // stop when 0 read 611 if(ch == 0) break; 610 if(ch == 0) break; 612 a_string[nr++] = ch; 611 a_string[nr++] = ch; 613 } 612 } 614 a_string[nr] = 0; 613 a_string[nr] = 0; 615 return true; 614 return true; 616 } 615 } 617 protected: 616 protected: 618 // buffer objects cannot be copied or assign 617 // buffer objects cannot be copied or assigned 619 //void checkCount(unsigned int); 618 //void checkCount(unsigned int); 620 //unsigned int checkObject(unsigned int,cons 619 //unsigned int checkObject(unsigned int,const IClass*,bool = false); 621 protected: 620 protected: 622 bool m_byte_swap; 621 bool m_byte_swap; 623 bool m_verbose; 622 bool m_verbose; 624 uint32 m_size; 623 uint32 m_size; 625 char* m_buffer; 624 char* m_buffer; 626 char* m_pos; 625 char* m_pos; 627 uint32 m_klen; //GB 626 uint32 m_klen; //GB 628 bool m_map_objs; 627 bool m_map_objs; 629 obj_map m_objs; 628 obj_map m_objs; 630 }; 629 }; 631 630 632 inline bool dummy_TXxx_pointer_stream(buffer& 631 inline bool dummy_TXxx_pointer_stream(buffer& a_buffer,ifac& a_fac) { 633 ifac::args args; 632 ifac::args args; 634 iro* obj; 633 iro* obj; 635 bool created; 634 bool created; 636 bool status = a_buffer.read_object(a_fac,arg 635 bool status = a_buffer.read_object(a_fac,args,obj,created); 637 if(obj) { 636 if(obj) { 638 if(created) { 637 if(created) { 639 if(a_buffer.map_objs()) a_buffer.remove_ 638 if(a_buffer.map_objs()) a_buffer.remove_in_map(obj); 640 delete obj; 639 delete obj; 641 } 640 } 642 } 641 } 643 return status; 642 return status; 644 } 643 } 645 644 646 template <class T> 645 template <class T> 647 inline bool pointer_stream(buffer& a_buffer, 646 inline bool pointer_stream(buffer& a_buffer, 648 ifac& a_fac,ifac::a 647 ifac& a_fac,ifac::args& a_args, 649 const std::string& 648 const std::string& a_T_class, 650 T*& a_obj,bool& a_c 649 T*& a_obj,bool& a_created){ 651 iro* obj; 650 iro* obj; 652 if(!a_buffer.read_object(a_fac,a_args,obj,a_ 651 if(!a_buffer.read_object(a_fac,a_args,obj,a_created)) { 653 a_buffer.out() << "tools::rroot::pointer_s 652 a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl; 654 a_obj = 0; 653 a_obj = 0; 655 a_created = false; 654 a_created = false; 656 return false; 655 return false; 657 } 656 } 658 if(!obj) { 657 if(!obj) { 659 a_obj = 0; 658 a_obj = 0; 660 a_created = false; 659 a_created = false; 661 } else { 660 } else { 662 a_obj = (T*)obj->cast(a_T_class); 661 a_obj = (T*)obj->cast(a_T_class); 663 if(!a_obj) { 662 if(!a_obj) { 664 a_buffer.out() << "tools::rroot::pointer 663 a_buffer.out() << "tools::rroot::pointer_stream : " 665 << " tools::cast to " << 664 << " tools::cast to " << a_T_class << " failed." 666 << ". Object is a " << ob 665 << ". Object is a " << obj->s_cls() << "." 667 << std::endl; 666 << std::endl; 668 if(a_created) delete obj; 667 if(a_created) delete obj; 669 a_created = false; 668 a_created = false; 670 return false; 669 return false; 671 } 670 } 672 } 671 } 673 return true; 672 return true; 674 } 673 } 675 674 676 template <class T> 675 template <class T> 677 inline bool pointer_stream(buffer& a_buffer, 676 inline bool pointer_stream(buffer& a_buffer, 678 ifac& a_fac,ifac::a 677 ifac& a_fac,ifac::args& a_args, 679 cid a_T_class, 678 cid a_T_class, 680 T*& a_obj,bool& a_c 679 T*& a_obj,bool& a_created){ 681 iro* obj; 680 iro* obj; 682 if(!a_buffer.read_object(a_fac,a_args,obj,a_ 681 if(!a_buffer.read_object(a_fac,a_args,obj,a_created)) { 683 a_buffer.out() << "tools::rroot::pointer_s 682 a_buffer.out() << "tools::rroot::pointer_stream : read_object failed." << std::endl; 684 a_obj = 0; 683 a_obj = 0; 685 a_created = false; 684 a_created = false; 686 return false; 685 return false; 687 } 686 } 688 if(!obj) { 687 if(!obj) { 689 a_obj = 0; 688 a_obj = 0; 690 a_created = false; 689 a_created = false; 691 } else { 690 } else { 692 a_obj = (T*)obj->cast(a_T_class); 691 a_obj = (T*)obj->cast(a_T_class); 693 if(!a_obj) { 692 if(!a_obj) { 694 a_buffer.out() << "tools::rroot::pointer 693 a_buffer.out() << "tools::rroot::pointer_stream : " 695 << " tools::cast to " << 694 << " tools::cast to " << a_T_class << " failed." 696 << ". Object is a " << ob 695 << ". Object is a " << obj->s_cls() << "." 697 << std::endl; 696 << std::endl; 698 if(a_created) delete obj; 697 if(a_created) delete obj; 699 a_created = false; 698 a_created = false; 700 return false; 699 return false; 701 } 700 } 702 } 701 } 703 return true; 702 return true; 704 } 703 } 705 704 706 template <class T> 705 template <class T> 707 inline bool pointer_stream(buffer& a_buffer,if 706 inline bool pointer_stream(buffer& a_buffer,ifac& a_fac,ifac::args& a_args,T*& a_obj,bool& a_created){ 708 //return pointer_stream(a_buffer,a_fac,a_arg 707 //return pointer_stream(a_buffer,a_fac,a_args,T::s_class(),a_obj,a_created); 709 return pointer_stream(a_buffer,a_fac,a_args, 708 return pointer_stream(a_buffer,a_fac,a_args,T::id_class(),a_obj,a_created); 710 } 709 } 711 710 712 template <class T> 711 template <class T> 713 inline bool fixed_array_stream(buffer& a_buffe 712 inline bool fixed_array_stream(buffer& a_buffer,int a_n,T*& a_v){ 714 delete [] a_v; 713 delete [] a_v; 715 a_v = 0; 714 a_v = 0; 716 char is_array; 715 char is_array; 717 if(!a_buffer.read(is_array)) return false; 716 if(!a_buffer.read(is_array)) return false; 718 if(!is_array) return true; 717 if(!is_array) return true; 719 if(!a_n) return true; 718 if(!a_n) return true; 720 a_v = new T[a_n]; 719 a_v = new T[a_n]; 721 if(!a_buffer.read_fast_array<T>(a_v,a_n)) { 720 if(!a_buffer.read_fast_array<T>(a_v,a_n)) { 722 delete [] a_v; 721 delete [] a_v; 723 a_v = 0; 722 a_v = 0; 724 return false; 723 return false; 725 } 724 } 726 return true; 725 return true; 727 } 726 } 728 727 729 }} 728 }} 730 729 731 #endif 730 #endif