// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_wroot_leaf #define tools_wroot_leaf #include "base_leaf" #include "../cids" namespace tools { namespace wroot { 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_string_store_class() { static const std::string s_v("TLeafC"); return s_v; } inline const std::string& leaf_element_store_class() { static const std::string s_v("TLeafElement"); return s_v; } template class leaf : public base_leaf { typedef base_leaf parent; 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: //ibo virtual const std::string& store_cls() const {return leaf_store_class(T());} virtual bool stream(buffer& a_buffer) const { unsigned int c; if(!a_buffer.write_version(1,c)) return false; if(!parent::stream(a_buffer)) return false; if(!a_buffer.write(m_min)) return false; if(!a_buffer.write(m_max)) return false; if(!a_buffer.set_byte_count(c)) return false; return true; } public: //base_leaf virtual bool fill_buffer(buffer& a_buffer) const {return a_buffer.write(m_value);} public: leaf(std::ostream& a_out,const std::string& a_name,const std::string& a_title) :parent(a_out,a_name,a_title) ,m_min(T()),m_max(T()) ,m_value(T()) { m_length = 1; m_length_type = sizeof(T); } virtual ~leaf(){} protected: leaf(const leaf& a_from):ibo(a_from),parent(a_from){} leaf& operator=(const leaf&){return *this;} public: void fill(const T& a_value) {m_value = a_value;} protected: T m_min; //Minimum value if leaf range is specified T m_max; //Maximum value if leaf range is specified T m_value; }; class leaf_string : public base_leaf { typedef base_leaf parent; 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: //ibo virtual const std::string& store_cls() const {return leaf_string_store_class();} virtual bool stream(buffer& a_buffer) const { unsigned int c; if(!a_buffer.write_version(1,c)) return false; if(!parent::stream(a_buffer)) return false; if(!a_buffer.write(m_min)) return false; if(!a_buffer.write(m_max)) return false; if(!a_buffer.set_byte_count(c)) return false; return true; } public: //base_leaf virtual bool fill_buffer(buffer& a_buffer) const { size_t len = ::strlen(m_value.c_str()); leaf_string& self = const_cast(*this); if(len >= (size_t)m_max) self.m_max = int(len)+1; if(len >= m_length) self.m_length = uint32(len)+1; if(len < 255) { if(!a_buffer.write((unsigned char)len)) return false; } else { if(!a_buffer.write(255)) return false; if(!a_buffer.write(uint32(len))) return false; } if(len) if(!a_buffer.write_fast_array(m_value.c_str(),uint32(len))) return false; return true; } public: leaf_string(std::ostream& a_out,const std::string& a_name,const std::string& a_title) :parent(a_out,a_name,a_title) ,m_min(0),m_max(0) { m_length_type = 1; } virtual ~leaf_string(){} protected: leaf_string(const leaf_string& a_from):ibo(a_from),parent(a_from){} leaf_string& operator=(const leaf_string&){return *this;} public: void fill(const std::string& a_value) {m_value = a_value;} int get_max() const {return m_max;} void set_max(int a_value) {m_max = a_value;} protected: int m_min; //Minimum value if leaf range is specified int m_max; //Maximum value if leaf range is specified std::string m_value; }; class leaf_element : public base_leaf { typedef base_leaf parent; 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 const std::string& store_cls() const {return leaf_element_store_class();} virtual bool stream(buffer& a_buffer) const { unsigned int c; if(!a_buffer.write_version(1,c)) return false; if(!parent::stream(a_buffer)) return false; if(!a_buffer.write(fID)) return false; if(!a_buffer.write(fType)) return false; if(!a_buffer.set_byte_count(c)) return false; return true; } public: //base_leaf virtual bool fill_buffer(buffer&) const { m_out << "tools::wroot::leaf_element::fill_buffer : dummy." << std::endl; return false; } public: leaf_element(std::ostream& a_out,const std::string& a_name,const std::string& a_title,int a_id,int a_type) :parent(a_out,a_name,a_title) ,fID(a_id) ,fType(a_type) {} virtual ~leaf_element(){} protected: leaf_element(const leaf_element& a_from):ibo(a_from),parent(a_from){} leaf_element& operator=(const leaf_element& a_from){ parent::operator=(a_from); return *this; } protected: int fID; //element serial number in fInfo int fType; //leaf type }; }} #endif