// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_rroot_base_leaf #define tools_rroot_base_leaf #include "named" namespace tools { namespace rroot { class base_leaf : public virtual iro { public: static const std::string& s_class() { static const std::string s_v("tools::rroot::base_leaf"); 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 base_leaf_cid();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} else return 0; } public: virtual bool stream(buffer& a_buffer) { if(m_own_leaf_count) { if(a_buffer.map_objs()) a_buffer.remove_in_map(m_leaf_count); delete m_leaf_count; } m_leaf_count = 0; m_own_leaf_count = false; int fOffset; bool fIsUnsigned; short v; unsigned int _s,_c; if(!a_buffer.read_version(v,_s,_c)) return false; //FIXME if (v > 1) { //TLeaf::Class()->ReadBuffer(b, this, R__v, R__s, R__c); //FIXME } else { //====process old versions before automatic schema evolution if(!Named_stream(a_buffer,m_name,m_title)) return false; // Ok with v 1 & 2 if(!a_buffer.read(m_length)) return false; if(!a_buffer.read(m_length_type)) return false; if(!a_buffer.read(fOffset)) return false; if(!a_buffer.read(m_is_range)) return false; if(!a_buffer.read(fIsUnsigned)) return false; {ifac::args args; iro* obj; bool created; if(!a_buffer.read_object(m_fac,args,obj,created)) { m_out << "tools::rroot::base_leaf::stream :" << " can't read object." << std::endl; return false; } if(!obj) { } else { m_leaf_count = safe_cast(*obj); if(!m_leaf_count) { m_out << "tools::rroot::base_leaf::stream :" << " can't cast base_leaf." << std::endl; m_leaf_count = 0; if(created) { if(a_buffer.map_objs()) a_buffer.remove_in_map(obj); delete obj; } return false; } if(created) m_own_leaf_count = true; }} if(!a_buffer.check_byte_count(_s,_c,"TLeaf")) return false; if(!m_length) m_length = 1; return true; } public: virtual bool read_buffer(buffer&) = 0; virtual bool print_value(std::ostream&,uint32) const = 0; virtual uint32 num_elem() const = 0; public: base_leaf(std::ostream& a_out,ifac& a_fac) :m_out(a_out) ,m_fac(a_fac) ,m_name("") ,m_title("") ,m_length(0) ,m_length_type(0) ,m_is_range(false) ,m_leaf_count(0) ,m_own_leaf_count(false) { } virtual ~base_leaf(){ if(m_own_leaf_count) delete m_leaf_count; } protected: base_leaf(const base_leaf& a_from) :iro(a_from) ,m_out(a_from.m_out) ,m_fac(a_from.m_fac) ,m_length(0) ,m_length_type(0) ,m_is_range(false) ,m_leaf_count(0) ,m_own_leaf_count(false) {} base_leaf& operator=(const base_leaf&){return *this;} public: const std::string& name() const {return m_name;} const std::string& title() const {return m_title;} const base_leaf* leaf_count() const {return m_leaf_count;} protected: std::ostream& m_out; ifac& m_fac; protected: //Named std::string m_name; std::string m_title; uint32 m_length; // Number of fixed length elements uint32 m_length_type; // Number of bytes for this data type bool m_is_range; // (=true if leaf has a range, false otherwise) base_leaf* m_leaf_count; // Pointer to Leaf count if variable length bool m_own_leaf_count; }; }} #endif