// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_rroot_obj_array #define tools_rroot_obj_array #include "object" #include "../vmanip" #include "../scast" #include "cids" namespace tools { namespace rroot { template class obj_array : public virtual iro,public std::vector { typedef typename std::vector parent; private: static const std::string& s_store_class() { static const std::string s_v("TObjArray"); return s_v; } public: static const std::string& s_class() { static const std::string s_v("tools::rroot::obj_array<"+T::s_class()+">"); return s_v; } public: //iro virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast< obj_array >(this,a_class)) return p; return 0; } virtual const std::string& s_cls() const {return s_class();} public: static cid id_class() {return obj_array_cid()+T::id_class();} virtual void* cast(cid a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return 0; } virtual iro* copy() const {return new obj_array(*this);} virtual bool stream(buffer& a_buffer) { ifac::args args; bool accept_null = false; return stream(a_buffer,args,accept_null); } public: obj_array(ifac& a_fac) :m_fac(a_fac) { } virtual ~obj_array(){ _clear(); } public: obj_array(const obj_array& a_from) :iro(a_from) ,parent() ,m_fac(a_from.m_fac) { typedef typename parent::const_iterator it_t; for(it_t it=a_from.begin();it!=a_from.end();++it) { if(!(*it)) { parent::push_back(0); m_owns.push_back(false); } else { iro* _obj = (*it)->copy(); T* obj = safe_cast(*_obj); if(!obj) { m_fac.out() << "tools::rroot::obj_array::obj_array :" << " tools::cast failed." << std::endl; delete _obj; parent::push_back(0); m_owns.push_back(false); } else { parent::push_back(obj); m_owns.push_back(true); } } } } obj_array& operator=(const obj_array& a_from){ if(&a_from==this) return *this; _clear(); typedef typename parent::const_iterator it_t; for(it_t it=a_from.begin();it!=a_from.end();++it) { if(!(*it)) { parent::push_back(0); m_owns.push_back(false); } else { iro* _obj = (*it)->copy(); T* obj = safe_cast(*_obj); if(!obj) { m_fac.out() << "tools::rroot::obj_array::operator= :" << " tools::cast failed." << std::endl; delete _obj; parent::push_back(0); m_owns.push_back(false); } else { parent::push_back(obj); m_owns.push_back(true); } } } return *this; } public: void cleanup() {_clear();} public: bool stream(buffer& a_buffer,const ifac::args& a_args,bool a_accept_null = false) { _clear(); short v; unsigned int sp, bc; if(!a_buffer.read_version(v,sp,bc)) return false; {uint32 id,bits; if(!Object_stream(a_buffer,id,bits)) return false;} std::string name; if(!a_buffer.read(name)) return false; int nobjects; if(!a_buffer.read(nobjects)) return false; int lowerBound; if(!a_buffer.read(lowerBound)) return false; for (int i=0;i(*obj); if(!to) { a_buffer.out() << "tools::rroot::obj_array::stream :" << " tools::cast failed." << " " << obj->s_cls() << " is not a " << T::s_class() << "." << std::endl; if(created) { if(a_buffer.map_objs()) a_buffer.remove_in_map(obj); delete obj; } } else { if(created) { parent::push_back(to); m_owns.push_back(true); } else { //someone else manage this object. parent::push_back(to); m_owns.push_back(false); } } } else { //a_accept_null for branch::stream m_baskets. if(a_accept_null) { parent::push_back(0); m_owns.push_back(false); } } } return a_buffer.check_byte_count(sp,bc,s_store_class()); } protected: void _clear() { typedef typename parent::iterator it_t; typedef std::vector::iterator itb_t; while(!parent::empty()) { it_t it = parent::begin(); itb_t itb = m_owns.begin(); T* entry = (*it); bool own = (*itb); parent::erase(it); m_owns.erase(itb); if(own) delete entry; } } protected: ifac& m_fac; std::vector m_owns; }; }} #endif