465 lines
14 KiB
Plaintext
465 lines
14 KiB
Plaintext
// 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<float>");
|
|
return s_v;
|
|
}
|
|
inline const std::string& leaf_double_cls() {
|
|
static const std::string s_v("tools::rroot::leaf<double>");
|
|
return s_v;
|
|
}
|
|
inline const std::string& leaf_int_cls() {
|
|
static const std::string s_v("tools::rroot::leaf<int>");
|
|
return s_v;
|
|
}
|
|
inline const std::string& leaf_bool_cls() {
|
|
static const std::string s_v("tools::rroot::leaf<bool>");
|
|
return s_v;
|
|
}
|
|
|
|
template <class T>
|
|
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<T> >(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<leaf>(this,a_class)) {return p;}
|
|
return base_leaf::cast(a_class);
|
|
}
|
|
public:
|
|
virtual iro* copy() const {return new leaf<T>(*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<int>* leaf_i = safe_cast<base_leaf, leaf<int> >(*m_leaf_count);
|
|
if(!leaf_i) {
|
|
m_out << "tools::rroot::leaf::read_buffer : leaf_count not a leaf<int>." << std::endl;
|
|
return false;
|
|
}
|
|
int len;
|
|
if(!leaf_i->value(0,len)) {
|
|
m_out << "tools::rroot::leaf::read_buffer : leaf<int>.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<T>(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<T>& a_v) const {
|
|
if(!m_value) {a_v.clear();return false;}
|
|
a_v.resize(m_size);
|
|
for(uint32 index=0;index<m_size;index++) a_v[index] = m_value[index];
|
|
return true;
|
|
}
|
|
T get_max() const {return m_max;}
|
|
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
|
|
uint32 m_size; //size of m_value array.
|
|
};
|
|
|
|
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<leaf_string>(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<leaf_string>(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<leaf_element>(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<leaf_element>(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<leaf_object>(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<leaf_object>(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<int>* cast_leaf_int(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<int> >(a_leaf);}
|
|
inline leaf<float>* cast_leaf_float(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<float> >(a_leaf);}
|
|
inline leaf<double>* cast_leaf_double(base_leaf& a_leaf) {return safe_cast<base_leaf, leaf<double> >(a_leaf);}
|
|
|
|
}}
|
|
|
|
#endif
|