// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_rroot_leaf #define tools_rroot_leaf #include "base_leaf" #include "../stype" #include "../cids" namespace tools { namespace rroot { inline const std::string& leaf_store_class(char) { static const std::string s_v("TLeafB"); return s_v; } inline const std::string& leaf_store_class(short) { static const std::string s_v("TLeafS"); return s_v; } inline const std::string& leaf_store_class(int) { static const std::string s_v("TLeafI"); return s_v; } inline const std::string& leaf_store_class(float) { static const std::string s_v("TLeafF"); return s_v; } inline const std::string& leaf_store_class(double) { static const std::string s_v("TLeafD"); return s_v; } inline const std::string& leaf_store_class(bool) { static const std::string s_v("TLeafO"); return s_v; } inline const std::string& leaf_float_cls() { static const std::string s_v("tools::rroot::leaf"); return s_v; } inline const std::string& leaf_double_cls() { static const std::string s_v("tools::rroot::leaf"); return s_v; } inline const std::string& leaf_int_cls() { static const std::string s_v("tools::rroot::leaf"); return s_v; } inline const std::string& leaf_bool_cls() { static const std::string s_v("tools::rroot::leaf"); return s_v; } template class leaf : public base_leaf { public: typedef T value_t; public: static const std::string& s_class() { static const std::string s_v("tools::rroot::leaf<"+stype(T())+">"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast< leaf >(this,a_class)) {return p;} return base_leaf::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return base_leaf_cid()+_cid(T());} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_leaf::cast(a_class); } public: virtual iro* copy() const {return new leaf(*this);} virtual bool stream(buffer& a_buffer) { short v; unsigned int _s,_c; if(!a_buffer.read_version(v,_s,_c)) return false; if(!base_leaf::stream(a_buffer)) return false; if(!a_buffer.read(m_min)) return false; if(!a_buffer.read(m_max)) return false; if(!a_buffer.check_byte_count(_s,_c,leaf_store_class(T()))) return false; return true; } public: //base_leaf virtual bool read_buffer(buffer& a_buffer) { if(m_leaf_count) { leaf* leaf_i = safe_cast >(*m_leaf_count); if(!leaf_i) { m_out << "tools::rroot::leaf::read_buffer : leaf_count not a leaf." << std::endl; return false; } int len; if(!leaf_i->value(0,len)) { m_out << "tools::rroot::leaf::read_buffer : leaf.value() failed." << " m_leaf_count " << m_leaf_count << " leaf_i " << leaf_i << " Name " << sout(leaf_i->name()) << " Size " << leaf_i->num_elem() << std::endl; return false; } if (len > leaf_i->get_max()) { //protection. m_out << "tools::rroot::leaf::read_buffer : warning : " << sout(name()) << ", len = " << len << " > max = " << leaf_i->get_max() << std::endl; len = leaf_i->get_max(); } uint32 ndata = len * m_length; if(ndata>m_size) { delete [] m_value; m_value = new T[ndata]; } m_size = ndata; if(!a_buffer.read_fast_array(m_value,ndata)) { m_out << "tools::rroot::leaf::read_buffer : \"" << name() << "\" :" << " read_fast_array failed." << std::endl; return false; } return true; } else { if(m_length) { if(m_length>m_size) { delete [] m_value; m_value = new T[m_length]; } m_size = m_length; if(!a_buffer.read_fast_array(m_value,m_length)) { m_out << "tools::rroot::leaf::read_buffer :" << " read_fast_array failed. m_length " << m_length << std::endl; return false; } return true; } else { m_out << "tools::rroot::leaf::read_buffer :" << " read_fast_array failed. m_length is zero." << std::endl; return false; } } return true; } virtual bool print_value(std::ostream& a_out,uint32 a_index) const { if(!m_value) return false; if(a_index>=m_size) return false; a_out << m_value[a_index]; return true; } virtual uint32 num_elem() const {return m_size;} public: leaf(std::ostream& a_out,ifac& a_fac) :base_leaf(a_out,a_fac) ,m_min(T()),m_max(T()) ,m_value(0),m_size(0) {} virtual ~leaf(){ delete [] m_value; } protected: leaf(const leaf& a_from) :iro(a_from) ,base_leaf(a_from) ,m_min(T()),m_max(T()) ,m_value(0),m_size(0) {} leaf& operator=(const leaf&){return *this;} public: bool value(uint32 a_index,T& a_value) const { if(!m_value) {a_value = T();return false;} if(a_index>=m_size) {a_value = T();return false;} a_value = m_value[a_index]; return true; } bool value(std::vector& a_v) const { if(!m_value) {a_v.clear();return false;} a_v.resize(m_size); for(uint32 index=0;index(this,a_class)) {return p;} return base_leaf::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return leaf_string_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_leaf::cast(a_class); } public: virtual iro* copy() const {return new leaf_string(*this);} virtual bool stream(buffer& a_buffer) { short v; unsigned int _s,_c; if(!a_buffer.read_version(v,_s,_c)) return false; if(!base_leaf::stream(a_buffer)) return false; if(!a_buffer.read(m_min)) return false; if(!a_buffer.read(m_max)) return false; if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; return true; } public: //base_leaf virtual bool read_buffer(buffer& a_buffer) { delete [] m_value; m_value = 0; unsigned char lenchar; if(!a_buffer.read(lenchar)) { m_out << "tools::rroot::leaf_string::read_buffer :" << " read(uchar) failed." << std::endl; return false; } uint32 len = 0; if(lenchar < 255) { len = lenchar; } else { if(!a_buffer.read(len)) { m_out << "tools::rroot::leaf_string::read_buffer :" << " read(int) failed." << std::endl; return false; } } if(len) { m_value = new char[len+1]; if(!a_buffer.read_fast_array(m_value,len)) { m_out << "tools::rroot::leaf_string::read_buffer :" << " read_fast_array failed." << std::endl; delete [] m_value; m_value = 0; return false; } m_value[len] = 0; } else { m_value = new char[1]; m_value[0] = 0; } return true; } virtual bool print_value(std::ostream& a_out,uint32) const { if(m_value) a_out << m_value; return true; } virtual uint32 num_elem() const {return 1;} public: leaf_string(std::ostream& a_out,ifac& a_fac) :base_leaf(a_out,a_fac) ,m_min(0),m_max(0),m_value(0){} virtual ~leaf_string(){ delete [] m_value; } protected: leaf_string(const leaf_string& a_from) :iro(a_from),base_leaf(a_from) ,m_min(0),m_max(0),m_value(0){} leaf_string& operator=(const leaf_string&){return *this;} public: const char* value() const {return m_value;} protected: int m_min; int m_max; char* m_value; }; class leaf_element : public base_leaf { static const std::string& s_store_class() { static const std::string s_v("TLeafElement"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::leaf_element"); 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 base_leaf::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return leaf_element_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_leaf::cast(a_class); } public: virtual iro* copy() const {return new leaf_element(*this);} virtual bool stream(buffer& a_buffer) { short v; unsigned int _s,_c; if(!a_buffer.read_version(v,_s,_c)) return false; if(!base_leaf::stream(a_buffer)) return false; if(!a_buffer.read(fID)) return false; if(!a_buffer.read(fType)) return false; if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; return true; } public: //base_leaf virtual bool read_buffer(buffer&) { m_out << "tools::rroot::leaf_element::read_buffer : dummy." << std::endl; return false; } virtual bool print_value(std::ostream&,uint32) const {return true;} virtual uint32 num_elem() const {return 0;} public: leaf_element(std::ostream& a_out,ifac& a_fac) :base_leaf(a_out,a_fac),fID(0),fType(0){} virtual ~leaf_element(){} protected: leaf_element(const leaf_element& a_from) :iro(a_from),base_leaf(a_from),fID(0),fType(0){} leaf_element& operator=(const leaf_element&){return *this;} public: //int id() const {return fID;} int leaf_type() const {return fType;} protected: int fID; //element serial number in fInfo int fType; //leaf type }; }} #include "iobject" namespace tools { namespace rroot { class leaf_object : public base_leaf { static const std::string& s_store_class() { static const std::string s_v("TLeafObject"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::leaf_object"); 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 base_leaf::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return leaf_object_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_leaf::cast(a_class); } public: virtual iro* copy() const {return new leaf_object(*this);} virtual bool stream(buffer& a_buffer) { short v; unsigned int _s,_c; if(!a_buffer.read_version(v,_s,_c)) return false; if(!base_leaf::stream(a_buffer)) return false; if(!a_buffer.read(fVirtual)) return false; if(!a_buffer.check_byte_count(_s,_c,s_store_class())) return false; return true; } public: //base_leaf virtual bool read_buffer(buffer& a_buffer) { if(!m_obj) { m_out << "tools::rroot::leaf_object::read_buffer : m_obj is null." << std::endl; return false; } std::string fClassName; if (fVirtual) { unsigned char n; if(!a_buffer.read(n)) { m_out << "tools::rroot::leaf_object::read_buffer :" << " read(unsigned char) failed." << std::endl; return false; } char classname[128]; if(!a_buffer.read_fast_array(classname,n+1)) { m_out << "tools::rroot::leaf_object::read_buffer :" << " readFastArray failed." << std::endl; return false; } fClassName = classname; } if(m_obj->store_class_name()!=fClassName) { m_out << "tools::rroot::leaf_object::read_buffer : WARNING : class mismatch :" << " fClassName " << sout(fClassName) << ". m_obj.store_class_name() " << sout(m_obj->store_class_name()) << std::endl; } if(!m_obj->stream(a_buffer)) { m_out << "tools::rroot::leaf_object::read_buffer :" << " object stream failed." << " Object store class was " << m_obj->store_class_name() << "." << std::endl; return false; } return true; } virtual bool print_value(std::ostream&,uint32) const { m_out << m_obj << std::endl; return true; } virtual uint32 num_elem() const {return 0;} public: leaf_object(std::ostream& a_out,ifac& a_fac) :base_leaf(a_out,a_fac),m_obj(0),fVirtual(true){} virtual ~leaf_object(){} protected: leaf_object(const leaf_object& a_from) :iro(a_from),base_leaf(a_from),m_obj(0),fVirtual(true){} leaf_object& operator=(const leaf_object&){return *this;} public: void set_object(iobject* a_obj) {m_obj = a_obj;} //do not get ownership. protected: iobject* m_obj; protected: bool fVirtual; // Support for Virtuality }; // for SWIG : inline leaf* cast_leaf_int(base_leaf& a_leaf) {return safe_cast >(a_leaf);} inline leaf* cast_leaf_float(base_leaf& a_leaf) {return safe_cast >(a_leaf);} inline leaf* cast_leaf_double(base_leaf& a_leaf) {return safe_cast >(a_leaf);} }} #endif