Warning, /include/Geant4/tools/xml/tree is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_xml_tree
0005 #define tools_xml_tree
0006
0007 #include "element"
0008
0009 #include "../S_STRING"
0010 #include "../forit"
0011
0012 #include <list>
0013 #include <ostream>
0014
0015 namespace tools {
0016 namespace xml {
0017
0018 // A tree is :
0019 // <tree atb1="" atb2="" ...>
0020 // ...
0021 // <tree...>
0022 // </tree>
0023 // ...
0024 // <element atb1="" atb2="" ...> value </element>
0025 // ...
0026 // </tree>
0027 //
0028 // tree.attribute_value(<name>,s)
0029 // retrieve the value of atb <name> of a <tag>
0030 // tree.attribute_value(<element>,<name>,s)
0031 // retrieve the value of an atb <name> of a <element> of a <tree>
0032 //
0033
0034 class tree;
0035
0036 class factory {
0037 public:
0038 virtual ~factory(){}
0039 public:
0040 typedef std::pair<std::string,std::string> atb;
0041 public:
0042 virtual tree* create(const std::string& a_tag_name,const std::vector<atb>& a_atbs,tree* a_parent) = 0;
0043 };
0044
0045 class tree : public virtual ielem {
0046 public:
0047 TOOLS_SCLASS(tools::xml::tree)
0048 public:
0049 static cid id_class() {return 1;}
0050 virtual void* cast(cid a_class) const {
0051 if(void* p = cmp_cast<tree>(this,a_class)) {return p;}
0052 else return 0;
0053 }
0054 public:
0055 typedef std::pair<std::string,std::string> atb;
0056 public:
0057 tree(const std::string& a_tag_name,factory& a_factory,tree* a_parent)
0058 :m_tag_name(a_tag_name)
0059 ,m_factory(a_factory)
0060 ,m_parent(a_parent)
0061 ,m_depth(0)
0062 {
0063 }
0064
0065 virtual ~tree(){
0066 clear();
0067 }
0068
0069 protected:
0070 tree(const tree& a_from)
0071 :ielem(a_from)
0072 ,m_tag_name(a_from.m_tag_name)
0073 ,m_factory(a_from.m_factory)
0074 ,m_parent(0)
0075 ,m_depth(0)
0076 {
0077 }
0078
0079 tree& operator=(const tree&){return *this;}
0080
0081 public:
0082 const std::list<ielem*>& childs() const {return m_childs;}
0083
0084 ///////////////////////////////////////////////////////
0085 /// attributes ////////////////////////////////////////
0086 ///////////////////////////////////////////////////////
0087 void set_attributes(const std::vector<atb>& a_atbs) {
0088 m_atbs = a_atbs;
0089 }
0090 const std::string& tag_name() const {return m_tag_name;}
0091
0092 bool attribute_value(const std::string& a_atb,std::string& a_value) const {
0093 a_value.clear();
0094 size_t linen = m_atbs.size();
0095 for(size_t count=0;count<linen;count++) {
0096 if(m_atbs[count].first==a_atb) {
0097 a_value = m_atbs[count].second;
0098 return true;
0099 }
0100 }
0101 return false;
0102 }
0103
0104 template <class T>
0105 bool attribute_value(const std::string& a_atb,T& a_value) const {
0106 std::string sv;
0107 if(!attribute_value(a_atb,sv)) {a_value=T();return false;}
0108 return to<T>(sv,a_value);
0109 }
0110
0111 ///////////////////////////////////////////////////////
0112 /// elements //////////////////////////////////////////
0113 ///////////////////////////////////////////////////////
0114 void add_element(const std::string& a_name,const std::vector<atb>& a_atbs,const std::string& a_value){
0115 m_childs.push_back(new element(a_name,a_atbs,a_value));
0116 }
0117
0118 void add_child(tree* a_tree) {m_childs.push_back(a_tree);}
0119
0120 ///////////////////////////////////////////////////////
0121 /// sub trees /////////////////////////////////////////
0122 ///////////////////////////////////////////////////////
0123
0124 tree* parent() const {return m_parent;}
0125
0126 unsigned int number_of_trees() const {
0127 unsigned int number = 0;
0128 tools_lforcit(ielem*,m_childs,it) {
0129 if(id_cast<ielem,tree>(*(*it))) number++;
0130 }
0131 return number;
0132 }
0133
0134 void remove_child(tree*& a_tree,bool a_delete = true){
0135 m_childs.remove(a_tree);
0136 if(a_delete) {
0137 delete a_tree;
0138 a_tree = 0;
0139 }
0140 }
0141 void set_depth(unsigned int a_depth) {m_depth = a_depth;}
0142 unsigned int depth() const {return m_depth;}
0143 void set_file(const std::string& a_file) {m_file = a_file;}
0144 const std::string& file() const {return m_file;}
0145
0146 protected:
0147 void clear(){
0148 m_atbs.clear();
0149 while(!m_childs.empty()) {
0150 ielem* item = m_childs.front();
0151 m_childs.remove(item);
0152 delete item;
0153 }
0154 }
0155
0156 protected:
0157 std::string m_tag_name;
0158 factory& m_factory;
0159 tree* m_parent;
0160 std::list<ielem*> m_childs;
0161 std::vector<atb> m_atbs;
0162 std::string m_file;
0163 int m_depth;
0164 };
0165
0166 class looper {
0167 public:
0168 looper(const tree& a_tree)
0169 :m_it(a_tree.childs().begin())
0170 ,m_end(a_tree.childs().end())
0171 {}
0172 virtual ~looper(){}
0173 protected:
0174 looper(const looper& a_from)
0175 :m_it(a_from.m_it)
0176 ,m_end(a_from.m_end)
0177 {}
0178 looper& operator=(const looper&){return *this;}
0179 public:
0180 tree* next_tree() {
0181 for(;m_it!=m_end;++m_it) {
0182 tree* _tree = id_cast<ielem,tree>(*(*m_it));
0183 if(_tree) {m_it++;return _tree;}
0184 }
0185 return 0;
0186 }
0187 element* next_element() {
0188 for(;m_it!=m_end;++m_it) {
0189 element* _elem = id_cast<ielem,element>(*(*m_it));
0190 if(_elem) {m_it++;return _elem;}
0191 }
0192 return 0;
0193 }
0194 protected:
0195 std::list<ielem*>::const_iterator m_it;
0196 std::list<ielem*>::const_iterator m_end;
0197 };
0198
0199 class default_factory : public virtual factory {
0200 public:
0201 virtual tree* create(const std::string& a_tag_name,const std::vector<tree::atb>& a_atbs,tree* a_parent) {
0202 // It does not add the new tree in parent.
0203 tree* itemML = new tree(a_tag_name,*this,a_parent);
0204 itemML->set_attributes(a_atbs);
0205 return itemML;
0206 }
0207 public:
0208 default_factory(){
0209 }
0210 virtual ~default_factory(){
0211 }
0212 public:
0213 default_factory(const default_factory& a_from)
0214 :factory(a_from){
0215 }
0216 default_factory& operator=(const default_factory&){return *this;}
0217 };
0218
0219 }}
0220
0221 #endif