// 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: 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) { delete [] m_value; m_value = 0; 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; m_value = new T[m_length]; return true; } public: //base_leaf virtual bool read_buffer(buffer& a_buffer) { if(!m_leaf_count && (m_ndata == 1)) { /* if(!aBuffer.read(m_value[0])) { m_out << "Rio::Leaf::readBasket : \"" << name() << "\" :" << " read value failed." << std::endl; return false; } return true; */ m_out << "tools::rroot::leaf::read_buffer :" << " case(1) not yet handled." << std::endl; return false; }else { if(m_leaf_count) { m_out << "tools::rroot::leaf::read_buffer :" << " case(2) not yet handled." << std::endl; return false; /* int len = m_leaf_count->number(); if (len > m_leaf_count->maximum()) { m_out << "Rio::Leaf::readBasket : \"" << name() << "\", len = " << len << " and max = " << m_leaf_count->maximum() << std::endl; len = m_leaf_count->maximum(); } m_ndata = len * fLength; if(!aBuffer.readFastArray(m_value,len * fLength)) { m_out << "Rio::Leaf::readBasket : \"" << name() << "\" :" << " readFastArray failed." << std::endl; return false; } return true; */ } else { if(m_length) { if(!m_value) { delete [] m_value; m_value = new T[m_length]; //we assume m_length is constant. } 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; } //::printf("debug : value : %d %g\n",m_value[0],m_value[0]); } } return true; } virtual bool print_value(std::ostream& a_out,uint32 a_index) const { //if(!m_value) return false; a_out << m_value[a_index]; return true; } virtual uint32 num_elem() const {return m_length;} public: leaf(std::ostream& a_out,ifac& a_fac) :base_leaf(a_out,a_fac) ,m_min(T()),m_max(T()) ,m_value(0) {} virtual ~leaf(){ delete [] m_value; } protected: leaf(const leaf& a_from):iro(a_from),base_leaf(a_from){} leaf& operator=(const leaf&){return *this;} public: T value(uint32 a_index = 0) const { //WARNING : fast getter. No check are done on m_value and a_index. return m_value[a_index]; } protected: T m_min; //Minimum value if leaf range is specified T m_max; //Maximum value if leaf range is specified T* m_value; //!Pointer to data buffer //T** fPointer; //!Addresss of pointer to data buffer! }; class leaf_string : public base_leaf { static const std::string& s_store_class() { static const std::string s_v("TLeafC"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::leaf_string"); 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_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) { if(!m_length) { m_out << "tools::rroot::leaf_string::read_buffer :" << " m_length is zero." << std::endl; return false; } if(len >= m_length) len = m_length-1; 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 { } 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 }; // for SWIG : inline leaf* cast_leaf_float(base_leaf& a_leaf) {return safe_cast >(a_leaf);} inline leaf* cast_leaf_int(base_leaf& a_leaf) {return safe_cast >(a_leaf);} }} #endif