// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_rroot_named #define tools_rroot_named #include "buffer" #include "../vdata" #include "../vmanip" #include "../forit" #include "../scast" //for ObjArray #include "cids" namespace tools { namespace rroot { inline bool Object_stream(buffer& a_buffer,uint32& a_id,uint32& a_bits) { short v; if(!a_buffer.read_version(v)) return false; if(!a_buffer.read(a_id)) return false; if(!a_buffer.read(a_bits)) return false; return true; } inline bool Named_stream(buffer& a_buffer, std::string& a_name, std::string& a_title) { short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; {uint32 id,bits; if(!Object_stream(a_buffer,id,bits)) return false;} if(!a_buffer.read(a_name)) return false; if(!a_buffer.read(a_title)) return false; if(!a_buffer.check_byte_count(s,c,"TNamed")) return false; return true; } inline bool AttLine_stream(buffer& a_buffer, short& a_color, short& a_style, short& a_width){ short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; if(!a_buffer.read(a_color)) return false; if(!a_buffer.read(a_style)) return false; if(!a_buffer.read(a_width)) return false; if(!a_buffer.check_byte_count(s,c,"TAttLine")) return false; return true; } inline bool AttFill_stream(buffer& a_buffer, short& a_color, short& a_style){ short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; if(!a_buffer.read(a_color)) return false; if(!a_buffer.read(a_style)) return false; if(!a_buffer.check_byte_count(s,c,"TAttFill")) return false; return true; } inline bool AttMarker_stream(buffer& a_buffer) { short fMarkerColor; short fMarkerStyle; float fMarkerWidth; short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; if(!a_buffer.read(fMarkerColor)) return false; if(!a_buffer.read(fMarkerStyle)) return false; if(!a_buffer.read(fMarkerWidth)) return false; if(!a_buffer.check_byte_count(s,c,"TAttMarker")) return false; return true; } inline bool GeoAtt_stream(buffer& a_buffer) { unsigned int fGeoAtt; // option flags short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; if(!a_buffer.read(fGeoAtt)) return false; if(!a_buffer.check_byte_count(s,c,"TGeoAtt")) return false; return true; } inline bool Att3D_stream(buffer& a_buffer) { short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; if(!a_buffer.check_byte_count(s,c,"TAtt3D")) return false; return true; } template inline bool Array_stream(buffer& a_buffer,std::vector& a_v) { a_v.clear(); int sz; if(!a_buffer.read(sz)) return false; //check sz is not crazy : if(!a_buffer.check_eob(sz)) return false; a_v.resize(sz); if(!a_buffer.read_fast_array(vec_data(a_v),sz)) return false; return true; } template inline bool dummy_array_stream(buffer& a_buffer,int a_n){ char is_array; if(!a_buffer.read(is_array)) return false; if(!is_array) return true; if(!a_n) return true; T* v = new T[a_n]; bool status = a_buffer.read_fast_array(v,a_n); delete [] v; return status; } template inline bool fixed_array_stream(buffer& a_buffer,int a_n,T*& a_v){ delete [] a_v; a_v = 0; char is_array; if(!a_buffer.read(is_array)) return false; if(!is_array) return true; if(!a_n) return true; a_v = new T[a_n]; if(!a_buffer.read_fast_array(a_v,a_n)) { delete [] a_v; a_v = 0; return false; } return true; } class iros : public virtual iro,public std::vector { static const std::string& s_store_class() { static const std::string s_v("TObjArray"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::iros"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) return p; return 0; } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return List_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} else return 0; } public: virtual iro* copy() const {return new iros(*this);} virtual bool stream(buffer& a_buffer) { ifac::args args; bool accept_null = false; return stream(a_buffer,args,accept_null); } public: iros(ifac& a_fac,bool a_owner) :m_fac(a_fac) ,m_owner(a_owner) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif } virtual ~iros(){ _clear(); #ifdef TOOLS_MEM mem::decrement(s_class().c_str()); #endif } public: iros(const iros& a_from) :iro(a_from) ,std::vector() ,m_fac(a_from.m_fac) ,m_owner(a_from.m_owner) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif if(a_from.m_owner) { tools_vforcit(iro*,a_from,it) push_back((*it)->copy()); } else { tools_vforcit(iro*,a_from,it) push_back((*it)); } } iros& operator=(const iros& a_from){ if(&a_from==this) return *this; _clear(); m_owner = a_from.m_owner; if(a_from.m_owner) { tools_vforcit(iro*,a_from,it) push_back((*it)->copy()); } else { tools_vforcit(iro*,a_from,it) push_back((*it)); } return *this; } public: void cleanup() {_clear();} void dump(std::ostream& a_out) { a_out << " iros : size " << size() << std::endl; tools_vforcit(iro*,*this,it) { a_out << " class " << (*it)->s_cls() << std::endl; } } public: bool stream(buffer& a_buffer, const ifac::args& a_args,bool a_accept_null = false) { _clear(); short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; //::printf("debug : iros::stream : version %d, byte count %d\n",v,c); {uint32 id,bits; if(!Object_stream(a_buffer,id,bits)) return false;} std::string name; if(!a_buffer.read(name)) return false; int nobjects; if(!a_buffer.read(nobjects)) return false; int lowerBound; if(!a_buffer.read(lowerBound)) return false; //::printf("debug : iros : name \"%s\", nobject %d, lowerBound %d\n", // name.c_str(),nobjects,lowerBound); for (int i=0;i(*this); } else { std::vector::clear(); } } protected: ifac& m_fac; bool m_owner; }; template class ObjArray : public virtual iro,public std::vector { static const std::string& s_store_class() { static const std::string s_v("TObjArray"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::ObjArray<"+T::s_class()+">"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast< ObjArray >(this,a_class)) return p; return 0; } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return ObjArray_cid()+T::id_class();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return 0; } virtual iro* copy() const {return new ObjArray(*this);} virtual bool stream(buffer& a_buffer) { ifac::args args; bool accept_null = false; return stream(a_buffer,args,accept_null); } public: ObjArray(ifac& a_fac,bool a_owner) :m_fac(a_fac) ,m_owner(a_owner){ #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif } virtual ~ObjArray(){ _clear(); #ifdef TOOLS_MEM mem::decrement(s_class().c_str()); #endif } public: ObjArray(const ObjArray& a_from) :iro(a_from) ,std::vector() ,m_fac(a_from.m_fac) ,m_owner(a_from.m_owner) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif if(a_from.m_owner) { typedef typename std::vector::const_iterator it_t; for(it_t it=a_from.begin();it!=a_from.end();++it) { if(!(*it)) { std::vector::push_back(0); } else { iro* _obj = (*it)->copy(); T* obj = safe_cast(*_obj); if(!obj) { //a_buffer.out() << "tools::rroot::ObjArray::ObjArray :" // << " inlib::cast failed." // << std::endl; delete _obj; } else { std::vector::push_back(obj); } } } } else { std::vector::operator=(a_from); } } ObjArray& operator=(const ObjArray& a_from){ if(&a_from==this) return *this; _clear(); m_owner = a_from.m_owner; if(a_from.m_owner) { typedef typename std::vector::const_iterator it_t; for(it_t it=a_from.begin();it!=a_from.end();++it) { if(!(*it)) { std::vector::push_back(0); } else { iro* _obj = (*it)->copy(); T* obj = safe_cast(*_obj); if(!obj) { //a_buffer.out() << "tools::rroot::ObjArray::operator= :" // << " inlib::cast failed." // << std::endl; delete _obj; } else { std::vector::push_back(obj); } } } } else { std::vector::operator=(a_from); } return *this; } public: void cleanup() {_clear();} public: bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) { _clear(); short v; unsigned int sp, bc; if(!a_buffer.read_version(v,sp,bc)) return false; //::printf("debug : ObjArray::stream : version %d, byte count %d\n",v,c); {uint32 id,bits; if(!Object_stream(a_buffer,id,bits)) return false;} std::string name; if(!a_buffer.read(name)) return false; int nobjects; if(!a_buffer.read(nobjects)) return false; int lowerBound; if(!a_buffer.read(lowerBound)) return false; //::printf("debug : ObjArray : name \"%s\", nobject %d, lowerBound %d\n", // name.c_str(),nobjects,lowerBound); for (int i=0;i(*obj); if(!to) { a_buffer.out() << "tools::rroot::ObjArray::stream :" << " inlib::cast failed." << " " << obj->s_cls() << " is not a " << T::s_class() << "." << std::endl; delete obj; } else { std::vector::push_back(to); } } else { //a_accept_null for branch::stream m_baskets. if(a_accept_null) std::vector::push_back(0); } } return a_buffer.check_byte_count(sp,bc,s_store_class()); } protected: void _clear() { if(m_owner) { tools::clear(*this); } else { std::vector::clear(); } } protected: ifac& m_fac; bool m_owner; }; class List : public virtual iro, public std::vector { static const std::string& s_store_class() { static const std::string s_v("TList"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::List"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) return p; return 0; } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return List_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} else return 0; } //virtual void* cast(cid) const {return List_cid();} public: virtual iro* copy() const {return new List(*this);} virtual bool stream(buffer& a_buffer) { _clear(); short v; unsigned int s, c; if(!a_buffer.read_version(v,s,c)) return false; //::printf("debug : List::stream : version %d, byte count %d\n",v,c); {uint32 id,bits; if(!Object_stream(a_buffer,id,bits)) return false;} std::string name; if(!a_buffer.read(name)) return false; int nobjects; if(!a_buffer.read(nobjects)) return false; //::printf("debug : List : name \"%s\", nobject %d\n", // name.c_str(),nobjects); ifac::args args; for (int i=0;i() ,m_fac(a_from.m_fac) ,m_owner(a_from.m_owner) { #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif } List& operator=(const List&){return *this;} protected: void _clear() { if(m_owner) { tools::clear(*this); } else { std::vector::clear(); } } protected: ifac& m_fac; bool m_owner; }; class HashList : public List { static const std::string& s_store_class() { static const std::string s_v("THashList"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::HashList"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) return p; return List::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return HashList_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return List::cast(a_class); } public: virtual bool stream(buffer& a_buffer) { uint32 startpos = a_buffer.length(); unsigned int s, c; short v; if(!a_buffer.read_version(v,s,c)) return false; //if(!List::stream(a_buffer)) return false; a_buffer.set_offset(startpos+c+sizeof(unsigned int)); if(!a_buffer.check_byte_count(s,c,s_store_class())) return false; return true; } public: HashList(ifac& a_fac,bool a_owner):List(a_fac,a_owner){ #ifdef TOOLS_MEM mem::increment(s_class().c_str()); #endif } virtual ~HashList(){ #ifdef TOOLS_MEM mem::decrement(s_class().c_str()); #endif } protected: HashList(const HashList& a_from):iro(a_from),List(a_from){} HashList& operator=(const HashList&){return *this;} }; inline bool dummy_TXxx_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_del = true) { ifac::args args; iro* obj; bool status = a_buffer.read_object(a_fac,args,obj); if(a_del) delete obj; return status; } template inline bool pointer_stream(buffer& a_buffer, ifac& a_fac,ifac::args& a_args, const std::string& a_T_class, T*& a_obj){ iro* obj; if(!a_buffer.read_object(a_fac,a_args,obj)) { a_buffer.out() << "tools::rroot::pointer_stream :" << " read_object failed." << std::endl; a_obj = 0; return false; } if(!obj) { a_obj = 0; } else { a_obj = (T*)obj->cast(a_T_class); if(!a_obj) { a_buffer.out() << "tools::rroot::pointer_stream : " << " inlib::cast to " << a_T_class << " failed." << ". Object is a " << obj->s_cls() << "." << std::endl; return false; } } return true; } template inline bool pointer_stream(buffer& a_buffer, ifac& a_fac,ifac::args& a_args, tools::cid a_T_class, T*& a_obj){ iro* obj; if(!a_buffer.read_object(a_fac,a_args,obj)) { a_buffer.out() << "tools::rroot::pointer_stream :" << " read_object failed." << std::endl; a_obj = 0; return false; } if(!obj) { a_obj = 0; } else { a_obj = (T*)obj->cast(a_T_class); if(!a_obj) { a_buffer.out() << "tools::rroot::pointer_stream : " << " inlib::cast to " << a_T_class << " failed." << ". Object is a " << obj->s_cls() << "." << std::endl; return false; } } return true; } template inline bool pointer_stream(buffer& a_buffer, ifac& a_fac,ifac::args& a_args,T*& a_obj){ //return pointer_stream(a_buffer,a_fac,a_args,T::s_class(),a_obj); return pointer_stream(a_buffer,a_fac,a_args,T::id_class(),a_obj); } inline bool dummy_TObjArray_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) { iros oa(a_fac,a_owner); ifac::args args; return oa.stream(a_buffer,args); } inline bool dummy_TList_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) { List l(a_fac,a_owner); return l.stream(a_buffer); } inline bool dummy_THashList_pointer_stream(buffer& a_buffer,ifac& a_fac,bool a_owner = true) { HashList l(a_fac,a_owner); return l.stream(a_buffer); } }} #endif