Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_xml_tree 4 #ifndef tools_xml_tree 5 #define tools_xml_tree 5 #define tools_xml_tree 6 6 7 #include "element" 7 #include "element" 8 8 9 #include "../sout" 9 #include "../sout" 10 #include "../strip" 10 #include "../strip" 11 #include "../S_STRING" 11 #include "../S_STRING" 12 #include "../forit" 12 #include "../forit" 13 13 14 #include <list> 14 #include <list> 15 #include <ostream> 15 #include <ostream> 16 16 17 namespace tools { 17 namespace tools { 18 namespace xml { 18 namespace xml { 19 19 20 // A tree is : 20 // A tree is : 21 // <tree atb1="" atb2="" ...> 21 // <tree atb1="" atb2="" ...> 22 // ... 22 // ... 23 // <tree...> 23 // <tree...> 24 // </tree> 24 // </tree> 25 // ... 25 // ... 26 // <element atb1="" atb2="" ...> value </ 26 // <element atb1="" atb2="" ...> value </element> 27 // ... 27 // ... 28 // </tree> 28 // </tree> 29 // 29 // 30 // tree.attribute_value(<name>,s) 30 // tree.attribute_value(<name>,s) 31 // retrieve the value of atb <name> of a < 31 // retrieve the value of atb <name> of a <tag> 32 // tree.attribute_value(<element>,<name>,s) 32 // tree.attribute_value(<element>,<name>,s) 33 // retrieve the value of an atb <name> of 33 // retrieve the value of an atb <name> of a <element> of a <tree> 34 // 34 // 35 35 36 class tree; 36 class tree; 37 37 38 class factory { 38 class factory { 39 public: 39 public: 40 virtual ~factory(){} 40 virtual ~factory(){} 41 public: 41 public: 42 typedef std::pair<std::string,std::string> a 42 typedef std::pair<std::string,std::string> atb; 43 public: 43 public: 44 virtual tree* create(const std::string& a_ta 44 virtual tree* create(const std::string& a_tag_name,const std::vector<atb>& a_atbs,tree* a_parent) = 0; 45 }; 45 }; 46 46 47 class tree : public virtual ielem { 47 class tree : public virtual ielem { 48 public: 48 public: 49 TOOLS_SCLASS(tools::xml::tree) 49 TOOLS_SCLASS(tools::xml::tree) 50 public: 50 public: 51 static cid id_class() {return 1;} 51 static cid id_class() {return 1;} 52 virtual void* cast(cid a_class) const { 52 virtual void* cast(cid a_class) const { 53 if(void* p = cmp_cast<tree>(this,a_class)) 53 if(void* p = cmp_cast<tree>(this,a_class)) {return p;} 54 else return 0; 54 else return 0; 55 } 55 } 56 public: 56 public: 57 typedef std::pair<std::string,std::string> a 57 typedef std::pair<std::string,std::string> atb; 58 typedef bool (*exec_func)(tree&,void*); 58 typedef bool (*exec_func)(tree&,void*); 59 enum copy_what { copy_attributes, copy_eleme 59 enum copy_what { copy_attributes, copy_elements, copy_children, copy_all }; 60 public: 60 public: 61 tree(const std::string& a_tag_name,factory& 61 tree(const std::string& a_tag_name,factory& a_factory,tree* a_parent) 62 :m_tag_name(a_tag_name) 62 :m_tag_name(a_tag_name) 63 ,m_factory(a_factory) 63 ,m_factory(a_factory) 64 ,m_parent(a_parent) 64 ,m_parent(a_parent) 65 ,m_save(true) 65 ,m_save(true) 66 ,m_data_1(0) 66 ,m_data_1(0) 67 ,m_data_2(0) 67 ,m_data_2(0) 68 ,m_data_int(0) 68 ,m_data_int(0) 69 ,m_depth(0) 69 ,m_depth(0) 70 { 70 { 71 #ifdef TOOLS_MEM 71 #ifdef TOOLS_MEM 72 mem::increment(s_class().c_str()); 72 mem::increment(s_class().c_str()); 73 #endif 73 #endif 74 } 74 } 75 75 76 virtual ~tree(){ 76 virtual ~tree(){ 77 clear(); 77 clear(); 78 #ifdef TOOLS_MEM 78 #ifdef TOOLS_MEM 79 mem::decrement(s_class().c_str()); 79 mem::decrement(s_class().c_str()); 80 #endif 80 #endif 81 } 81 } 82 82 83 protected: 83 protected: 84 tree(const tree& a_from) 84 tree(const tree& a_from) 85 :ielem(a_from) 85 :ielem(a_from) 86 ,m_tag_name(a_from.m_tag_name) 86 ,m_tag_name(a_from.m_tag_name) 87 ,m_factory(a_from.m_factory) 87 ,m_factory(a_from.m_factory) 88 ,m_parent(0) 88 ,m_parent(0) 89 ,m_save(0) 89 ,m_save(0) 90 ,m_data_1(0) 90 ,m_data_1(0) 91 ,m_data_2(0) 91 ,m_data_2(0) 92 ,m_data_int(0) 92 ,m_data_int(0) 93 ,m_depth(0) 93 ,m_depth(0) 94 { 94 { 95 #ifdef TOOLS_MEM 95 #ifdef TOOLS_MEM 96 mem::increment(s_class().c_str()); 96 mem::increment(s_class().c_str()); 97 #endif 97 #endif 98 } 98 } 99 99 100 tree& operator=(const tree&){return *this;} 100 tree& operator=(const tree&){return *this;} 101 101 102 public: 102 public: 103 virtual bool invalidate() {return true;} 103 virtual bool invalidate() {return true;} 104 104 105 const std::list<ielem*>& childs() const {ret 105 const std::list<ielem*>& childs() const {return m_childs;} 106 106 107 //////////////////////////////////////////// 107 /////////////////////////////////////////////////////// 108 /// attributes ///////////////////////////// 108 /// attributes //////////////////////////////////////// 109 //////////////////////////////////////////// 109 /////////////////////////////////////////////////////// 110 const std::vector<atb>& attributes() const { 110 const std::vector<atb>& attributes() const {return m_atbs;} 111 111 112 void add_attribute(const std::string& a_name 112 void add_attribute(const std::string& a_name,const std::string& a_value){ 113 // No check is done about an existing a_na 113 // No check is done about an existing a_name. 114 m_atbs.push_back(atb(a_name,a_value)); 114 m_atbs.push_back(atb(a_name,a_value)); 115 } 115 } 116 116 117 bool is_attribute(const std::string& a_name) 117 bool is_attribute(const std::string& a_name) const { 118 size_t number = m_atbs.size(); 118 size_t number = m_atbs.size(); 119 for(size_t index=0;index<number;index++) { 119 for(size_t index=0;index<number;index++) { 120 if(m_atbs[index].first==a_name) return t 120 if(m_atbs[index].first==a_name) return true; 121 } 121 } 122 return false; 122 return false; 123 } 123 } 124 124 125 void set_attributes(const std::vector<atb>& 125 void set_attributes(const std::vector<atb>& a_atbs) { 126 m_atbs = a_atbs; 126 m_atbs = a_atbs; 127 } 127 } 128 const std::string& tag_name() const {return 128 const std::string& tag_name() const {return m_tag_name;} 129 129 130 bool attribute_value(const std::string& a_at 130 bool attribute_value(const std::string& a_atb,std::string& a_value) const { 131 a_value.clear(); 131 a_value.clear(); 132 size_t linen = m_atbs.size(); 132 size_t linen = m_atbs.size(); 133 for(size_t count=0;count<linen;count++) { 133 for(size_t count=0;count<linen;count++) { 134 if(m_atbs[count].first==a_atb) { 134 if(m_atbs[count].first==a_atb) { 135 a_value = m_atbs[count].second; 135 a_value = m_atbs[count].second; 136 return true; 136 return true; 137 } 137 } 138 } 138 } 139 return false; 139 return false; 140 } 140 } 141 141 142 template <class T> 142 template <class T> 143 bool attribute_value(const std::string& a_at 143 bool attribute_value(const std::string& a_atb,T& a_value) const { 144 std::string sv; 144 std::string sv; 145 if(!attribute_value(a_atb,sv)) {a_value=T( 145 if(!attribute_value(a_atb,sv)) {a_value=T();return false;} 146 return to<T>(sv,a_value); 146 return to<T>(sv,a_value); 147 } 147 } 148 148 149 void remove_attributes(const std::string& a_ 149 void remove_attributes(const std::string& a_atb) { 150 std::vector<atb>::iterator it; 150 std::vector<atb>::iterator it; 151 for(it=m_atbs.begin();it!=m_atbs.end();) { 151 for(it=m_atbs.begin();it!=m_atbs.end();) { 152 if((*it).first==a_atb) { 152 if((*it).first==a_atb) { 153 it = m_atbs.erase(it); 153 it = m_atbs.erase(it); 154 } else { 154 } else { 155 ++it; 155 ++it; 156 } 156 } 157 } 157 } 158 } 158 } 159 159 160 bool remove_attribute(const std::string& a_n 160 bool remove_attribute(const std::string& a_name){ 161 //TOOLS_STL : to be checked : 161 //TOOLS_STL : to be checked : 162 std::vector<atb>::iterator it = m_atbs.beg 162 std::vector<atb>::iterator it = m_atbs.begin(); 163 size_t linen = m_atbs.size(); 163 size_t linen = m_atbs.size(); 164 for(size_t count=0;count<linen;count++,++i 164 for(size_t count=0;count<linen;count++,++it) { 165 if(m_atbs[count].first==a_name) { 165 if(m_atbs[count].first==a_name) { 166 m_atbs.erase(it); 166 m_atbs.erase(it); 167 return true; //Found and removed. 167 return true; //Found and removed. 168 } 168 } 169 } 169 } 170 return false; //Not found. 170 return false; //Not found. 171 } 171 } 172 172 173 //////////////////////////////////////////// 173 /////////////////////////////////////////////////////// 174 /// elements /////////////////////////////// 174 /// elements ////////////////////////////////////////// 175 //////////////////////////////////////////// 175 /////////////////////////////////////////////////////// 176 void add_element(const std::string& a_name,c 176 void add_element(const std::string& a_name,const std::vector<atb>& a_atbs,const std::string& a_value){ 177 m_childs.push_back(new element(a_name,a_at 177 m_childs.push_back(new element(a_name,a_atbs,a_value)); 178 } 178 } 179 179 180 bool element_value(const std::string& a_name 180 bool element_value(const std::string& a_name,std::string& a_value) const { 181 tools_lforcit(ielem*,m_childs,it) { 181 tools_lforcit(ielem*,m_childs,it) { 182 if(element* _elem = id_cast<ielem,elemen 182 if(element* _elem = id_cast<ielem,element>(*(*it))) { 183 if(a_name==_elem->name()) { 183 if(a_name==_elem->name()) { 184 a_value = _elem->value(); 184 a_value = _elem->value(); 185 return true; 185 return true; 186 } 186 } 187 } 187 } 188 } 188 } 189 a_value.clear(); 189 a_value.clear(); 190 return false; 190 return false; 191 } 191 } 192 192 193 /* 193 /* 194 //NOTE : print is a Python keyword. 194 //NOTE : print is a Python keyword. 195 void dump(std::ostream& a_out){ 195 void dump(std::ostream& a_out){ 196 a_out << "dump :" 196 a_out << "dump :" 197 << " -----> " << this << " parent : 197 << " -----> " << this << " parent : " << m_parent << std::endl; 198 a_out << " data1 : " << m_data_1 198 a_out << " data1 : " << m_data_1 199 << " data2 : " << m_data_2 199 << " data2 : " << m_data_2 200 << " dataInt : " << m_data_int 200 << " dataInt : " << m_data_int 201 << std::endl; 201 << std::endl; 202 202 203 {size_t atbn = m_atbs.size(); 203 {size_t atbn = m_atbs.size(); 204 for(size_t index=0;index<atbn;index++) { 204 for(size_t index=0;index<atbn;index++) { 205 a_out << " attribute : " << sout(m_atbs[ 205 a_out << " attribute : " << sout(m_atbs[index].first) << " " 206 << sout(m_atbs[index].second) << s 206 << sout(m_atbs[index].second) << std::endl; 207 }} 207 }} 208 208 209 {tools_lforit(element*,m_elems,it) { 209 {tools_lforit(element*,m_elems,it) { 210 a_out << " element : \"" << (*it)->name( 210 a_out << " element : \"" << (*it)->name() << "\" \"" 211 << (*it)->value() << "\"" << std:: 211 << (*it)->value() << "\"" << std::endl; 212 }} 212 }} 213 213 214 {tools_lforit(tree*,m_children,it) { 214 {tools_lforit(tree*,m_children,it) { 215 (*it)->dump(a_out); 215 (*it)->dump(a_out); 216 }} 216 }} 217 } 217 } 218 218 219 const std::list<element*>& elements() const 219 const std::list<element*>& elements() const {return m_elems;} 220 220 221 */ 221 */ 222 222 223 bool element_atb_value(const std::string& a_ 223 bool element_atb_value(const std::string& a_elem,const std::string& a_atb,std::string& a_value) const { 224 a_value.clear(); 224 a_value.clear(); 225 tools_lforcit(ielem*,m_childs,it) { 225 tools_lforcit(ielem*,m_childs,it) { 226 if(element* _elem = id_cast<ielem,elemen 226 if(element* _elem = id_cast<ielem,element>(*(*it))) { 227 if(a_elem==_elem->name()) { 227 if(a_elem==_elem->name()) { 228 if(_elem->attribute_value(a_atb,a_va 228 if(_elem->attribute_value(a_atb,a_value)) return true; 229 } 229 } 230 } 230 } 231 } 231 } 232 return false; 232 return false; 233 } 233 } 234 234 235 template <class T> 235 template <class T> 236 bool element_atb_value(const std::string& a_ 236 bool element_atb_value(const std::string& a_elem,const std::string& a_atb,T& a_value) const { 237 std::string sv; 237 std::string sv; 238 if(!element_atb_value(a_elem,a_atb,sv)) {a 238 if(!element_atb_value(a_elem,a_atb,sv)) {a_value=T();return false;} 239 return to<T>(sv,a_value); 239 return to<T>(sv,a_value); 240 } 240 } 241 241 242 //////////////////////////////////////////// 242 ////////////////////////////////////////////////// 243 /// for osc //////////////////////////////// 243 /// for osc ////////////////////////////////////// 244 //////////////////////////////////////////// 244 ////////////////////////////////////////////////// 245 bool is_element(const std::string& a_name) c 245 bool is_element(const std::string& a_name) const { 246 tools_lforcit(ielem*,m_childs,it) { 246 tools_lforcit(ielem*,m_childs,it) { 247 if(element* _elem = id_cast<ielem,elemen 247 if(element* _elem = id_cast<ielem,element>(*(*it))) { 248 if(a_name==_elem->name()) return true; 248 if(a_name==_elem->name()) return true; 249 } 249 } 250 } 250 } 251 return false; 251 return false; 252 } 252 } 253 253 254 bool set_element_value(const std::string& a_ 254 bool set_element_value(const std::string& a_name,const std::string& a_value,int a_index = 0){ 255 int index = 0; 255 int index = 0; 256 tools_lforcit(ielem*,m_childs,it) { 256 tools_lforcit(ielem*,m_childs,it) { 257 if(element* _elem = id_cast<ielem,elemen 257 if(element* _elem = id_cast<ielem,element>(*(*it))) { 258 if(a_name==_elem->name()) { 258 if(a_name==_elem->name()) { 259 if(index==a_index) { 259 if(index==a_index) { 260 _elem->set_value(a_value); 260 _elem->set_value(a_value); 261 return true; 261 return true; 262 } else { 262 } else { 263 index ++; 263 index ++; 264 } 264 } 265 } 265 } 266 } 266 } 267 } 267 } 268 // Not found, add one : 268 // Not found, add one : 269 std::vector<atb> atts; 269 std::vector<atb> atts; 270 add_element(a_name,atts,a_value); 270 add_element(a_name,atts,a_value); 271 return true; 271 return true; 272 } 272 } 273 273 274 bool set_attribute_value(const std::string& 274 bool set_attribute_value(const std::string& a_atb,const std::string& a_value) { 275 tools_vforit(atb,m_atbs,it) { 275 tools_vforit(atb,m_atbs,it) { 276 if((*it).first==a_atb) { 276 if((*it).first==a_atb) { 277 (*it).second = a_value; 277 (*it).second = a_value; 278 return true; 278 return true; 279 } 279 } 280 } 280 } 281 // Not found, add one : 281 // Not found, add one : 282 m_atbs.push_back(atb(a_atb,a_value)); 282 m_atbs.push_back(atb(a_atb,a_value)); 283 return true; 283 return true; 284 } 284 } 285 285 286 bool has_empty_attribute_value(std::ostream& 286 bool has_empty_attribute_value(std::ostream& a_out) const{ 287 empty_visitor visitor(a_out); 287 empty_visitor visitor(a_out); 288 visitor.m_status = true; 288 visitor.m_status = true; 289 const_cast<tree*>(this)->post_execute(chec 289 const_cast<tree*>(this)->post_execute(check_item,&visitor); 290 return visitor.m_status; 290 return visitor.m_status; 291 } 291 } 292 292 293 class empty_visitor { 293 class empty_visitor { 294 public: 294 public: 295 empty_visitor(std::ostream& a_out) 295 empty_visitor(std::ostream& a_out) 296 :f_out(a_out),m_status(true){} 296 :f_out(a_out),m_status(true){} 297 public: 297 public: 298 std::ostream& f_out; 298 std::ostream& f_out; 299 bool m_status; 299 bool m_status; 300 }; 300 }; 301 301 302 void post_execute(exec_func a_function,void* 302 void post_execute(exec_func a_function,void* a_tag) { 303 if(!a_function) return; 303 if(!a_function) return; 304 304 305 if(!a_function(*this,a_tag)) return; 305 if(!a_function(*this,a_tag)) return; 306 306 307 tools_lforcit(ielem*,m_childs,it) { 307 tools_lforcit(ielem*,m_childs,it) { 308 if(tree* _tree = id_cast<ielem,tree>(*(* 308 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 309 _tree->post_execute(a_function,a_tag); 309 _tree->post_execute(a_function,a_tag); 310 } 310 } 311 } 311 } 312 } 312 } 313 313 314 static bool check_item(tree& a_tree,void* a_ 314 static bool check_item(tree& a_tree,void* a_tag){ 315 empty_visitor* visitor = (empty_visitor*)a 315 empty_visitor* visitor = (empty_visitor*)a_tag; 316 316 317 {const std::vector<atb>& atbs = a_tree.attr 317 {const std::vector<atb>& atbs = a_tree.attributes(); 318 size_t atbn = atbs.size(); 318 size_t atbn = atbs.size(); 319 for(size_t index=0;index<atbn;index++) { 319 for(size_t index=0;index<atbn;index++) { 320 const std::string& _atb = atbs[index].fi 320 const std::string& _atb = atbs[index].first; 321 const std::string& atbv = atbs[index].se 321 const std::string& atbv = atbs[index].second; 322 if(atbv.empty()) { 322 if(atbv.empty()) { 323 visitor->f_out << "check_item :" 323 visitor->f_out << "check_item :" 324 << " for XML item " << sout(a_tree 324 << " for XML item " << sout(a_tree.tag_name()) 325 << ", attribute " << sout(_atb) << 325 << ", attribute " << sout(_atb) << " has an empty value." 326 << std::endl; 326 << std::endl; 327 visitor->m_status = false; 327 visitor->m_status = false; 328 } 328 } 329 }} 329 }} 330 330 331 {tools_lforcit(ielem*,a_tree.m_childs,it) { 331 {tools_lforcit(ielem*,a_tree.m_childs,it) { 332 if(element* _elem = id_cast<ielem,element> 332 if(element* _elem = id_cast<ielem,element>(*(*it))) { 333 const std::vector<atb>& atbs = _elem->at 333 const std::vector<atb>& atbs = _elem->attributes(); 334 size_t atbn = atbs.size(); 334 size_t atbn = atbs.size(); 335 for(size_t index=0;index<atbn;index++) { 335 for(size_t index=0;index<atbn;index++) { 336 const std::string& _atb = atbs[index]. 336 const std::string& _atb = atbs[index].first; 337 const std::string& atbv = atbs[index]. 337 const std::string& atbv = atbs[index].second; 338 if(atbv.empty()) { 338 if(atbv.empty()) { 339 visitor->f_out << "ItemM::check_item 339 visitor->f_out << "ItemM::check_item :" 340 << " for XML item " << sout(a_tr 340 << " for XML item " << sout(a_tree.tag_name()) 341 << ", attribute " << sout(_atb) 341 << ", attribute " << sout(_atb) << " has an empty value." 342 << std::endl; 342 << std::endl; 343 visitor->m_status = false; 343 visitor->m_status = false; 344 } 344 } 345 } 345 } 346 }}} 346 }}} 347 347 348 return true; 348 return true; 349 } 349 } 350 350 351 static void collect_by_tag(tree& a_tree,cons 351 static void collect_by_tag(tree& a_tree,const std::string& a_tag,std::vector<tree*>& a_items) { 352 if(a_tree.tag_name()==a_tag) a_items.push_ 352 if(a_tree.tag_name()==a_tag) a_items.push_back(&a_tree); 353 tools_lforcit(ielem*,a_tree.m_childs,it) { 353 tools_lforcit(ielem*,a_tree.m_childs,it) { 354 if(tree* _tree = id_cast<ielem,tree>(*(* 354 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 355 collect_by_tag(*_tree,a_tag,a_items); 355 collect_by_tag(*_tree,a_tag,a_items); 356 } 356 } 357 } 357 } 358 } 358 } 359 359 360 tree* find_by_tag(const std::string& a_tag) 360 tree* find_by_tag(const std::string& a_tag) const { 361 if(tag_name()==a_tag) return const_cast<tr 361 if(tag_name()==a_tag) return const_cast<tree*>(this); 362 // Look children : 362 // Look children : 363 tools_lforcit(ielem*,m_childs,it) { 363 tools_lforcit(ielem*,m_childs,it) { 364 if(tree* _tree = id_cast<ielem,tree>(*(*it 364 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 365 tree* itemML = _tree->find_by_tag(a_tag) 365 tree* itemML = _tree->find_by_tag(a_tag); 366 if(itemML) return itemML; 366 if(itemML) return itemML; 367 }} 367 }} 368 return 0; 368 return 0; 369 } 369 } 370 370 371 static void unique(std::vector<tree*>& a_ite 371 static void unique(std::vector<tree*>& a_items) { 372 std::vector<tree*> items2; 372 std::vector<tree*> items2; 373 373 374 tools_vforcit(tree*,a_items,it) { 374 tools_vforcit(tree*,a_items,it) { 375 std::string name; 375 std::string name; 376 if(!(*it)->attribute_value("name",name)) 376 if(!(*it)->attribute_value("name",name)) continue; 377 if(name.empty()) continue; 377 if(name.empty()) continue; 378 378 379 bool found = false; 379 bool found = false; 380 {tools_vforit(tree*,items2,it2) { 380 {tools_vforit(tree*,items2,it2) { 381 std::string name2; 381 std::string name2; 382 (*it2)->attribute_value("name",name2); 382 (*it2)->attribute_value("name",name2); 383 if(name2==name) { 383 if(name2==name) { 384 found = true; 384 found = true; 385 break; 385 break; 386 } 386 } 387 }} 387 }} 388 if(!found) { 388 if(!found) { 389 items2.push_back(*it); 389 items2.push_back(*it); 390 } 390 } 391 } 391 } 392 392 393 a_items = items2; 393 a_items = items2; 394 } 394 } 395 395 396 tree* find_item(const std::string& a_name) c 396 tree* find_item(const std::string& a_name) const { 397 {size_t linen = m_atbs.size(); 397 {size_t linen = m_atbs.size(); 398 for(unsigned int count=0;count<linen;count 398 for(unsigned int count=0;count<linen;count++) { 399 if(m_atbs[count].first=="name") { 399 if(m_atbs[count].first=="name") { 400 if(m_atbs[count].second==a_name) retur 400 if(m_atbs[count].second==a_name) return const_cast<tree*>(this); 401 break; 401 break; 402 } 402 } 403 }} 403 }} 404 404 405 // Look children : 405 // Look children : 406 tools_lforcit(ielem*,m_childs,it) { 406 tools_lforcit(ielem*,m_childs,it) { 407 if(tree* _tree = id_cast<ielem,tree>(*(*it 407 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 408 tree* item = _tree->find_item(a_name); 408 tree* item = _tree->find_item(a_name); 409 if(item) return item; 409 if(item) return item; 410 }} 410 }} 411 return 0; 411 return 0; 412 } 412 } 413 413 414 tree* find_item_with_tag(const std::string& 414 tree* find_item_with_tag(const std::string& a_tag, 415 const std::string& 415 const std::string& a_name) const { 416 if(a_tag==tag_name()) { 416 if(a_tag==tag_name()) { 417 std::string _s; 417 std::string _s; 418 attribute_value("name",_s); 418 attribute_value("name",_s); 419 if(a_name==_s) return const_cast<tree*>( 419 if(a_name==_s) return const_cast<tree*>(this); 420 } 420 } 421 421 422 // Look children : 422 // Look children : 423 tools_lforcit(ielem*,m_childs,it) { 423 tools_lforcit(ielem*,m_childs,it) { 424 if(tree* _tree = id_cast<ielem,tree>(*(*it 424 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 425 tree* item = _tree->find_item_with_tag(a 425 tree* item = _tree->find_item_with_tag(a_tag,a_name); 426 if(item) return item; 426 if(item) return item; 427 }} 427 }} 428 return 0; 428 return 0; 429 } 429 } 430 430 431 void remove_elements(const std::string& a_na 431 void remove_elements(const std::string& a_name){ 432 // TOOLS_STL : to be checked : 432 // TOOLS_STL : to be checked : 433 std::list<ielem*>::iterator it; 433 std::list<ielem*>::iterator it; 434 for(it=m_childs.begin();it!=m_childs.end() 434 for(it=m_childs.begin();it!=m_childs.end();) { 435 if(element* _elem = id_cast<ielem,elemen 435 if(element* _elem = id_cast<ielem,element>(*(*it))) { 436 if(a_name==_elem->name()) { 436 if(a_name==_elem->name()) { 437 it = m_childs.erase(it); 437 it = m_childs.erase(it); 438 delete _elem; 438 delete _elem; 439 } else { 439 } else { 440 ++it; 440 ++it; 441 } 441 } 442 } else { 442 } else { 443 ++it; 443 ++it; 444 } 444 } 445 } 445 } 446 } 446 } 447 447 448 void add_child(tree* a_tree) {m_childs.push_ 448 void add_child(tree* a_tree) {m_childs.push_back(a_tree);} 449 449 450 tree* create_copy(tree* a_parent) { 450 tree* create_copy(tree* a_parent) { 451 tree* itemML = m_factory.create(m_tag_name 451 tree* itemML = m_factory.create(m_tag_name,m_atbs,a_parent); 452 if(!itemML) return 0; 452 if(!itemML) return 0; 453 itemML->m_atbs = m_atbs; 453 itemML->m_atbs = m_atbs; 454 //FIXME : m_save 454 //FIXME : m_save 455 455 456 {tools_lforcit(ielem*,m_childs,it) { 456 {tools_lforcit(ielem*,m_childs,it) { 457 if(element* _elem = id_cast<ielem,element> 457 if(element* _elem = id_cast<ielem,element>(*(*it))) { 458 itemML->m_childs.push_back(new element(* 458 itemML->m_childs.push_back(new element(*_elem)); 459 }}} 459 }}} 460 460 461 {tools_lforcit(ielem*,m_childs,it) { 461 {tools_lforcit(ielem*,m_childs,it) { 462 if(tree* _tree = id_cast<ielem,tree>(*(*it 462 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 463 //FIXME : could we have mismatch parent/ 463 //FIXME : could we have mismatch parent/child ? 464 tree* obj = _tree->create_copy(itemML); 464 tree* obj = _tree->create_copy(itemML); 465 if(!obj) { 465 if(!obj) { 466 delete itemML; 466 delete itemML; 467 return 0; 467 return 0; 468 } 468 } 469 itemML->add_child(obj); 469 itemML->add_child(obj); 470 }}} 470 }}} 471 471 472 return itemML; 472 return itemML; 473 } 473 } 474 474 475 bool copy(const tree& a_from, 475 bool copy(const tree& a_from, 476 copy_what a_what = copy_all, 476 copy_what a_what = copy_all, 477 bool a_clear = true){ 477 bool a_clear = true){ 478 478 479 // Copy data (atbs, propertis, children) o 479 // Copy data (atbs, propertis, children) of a_from onto this. 480 if((a_what==copy_all)||(a_what==copy_attri 480 if((a_what==copy_all)||(a_what==copy_attributes)) { 481 if(a_clear) m_atbs.clear(); 481 if(a_clear) m_atbs.clear(); 482 tools_vforcit(atb,a_from.m_atbs,it) m_at 482 tools_vforcit(atb,a_from.m_atbs,it) m_atbs.push_back(*it); 483 } 483 } 484 484 485 if((a_what==copy_all)||(a_what==copy_eleme 485 if((a_what==copy_all)||(a_what==copy_elements)) { 486 if(a_clear) delete_sub_elems(); 486 if(a_clear) delete_sub_elems(); 487 tools_lforcit(ielem*,a_from.m_childs,it) 487 tools_lforcit(ielem*,a_from.m_childs,it) { 488 if(element* _elem = id_cast<ielem,elem 488 if(element* _elem = id_cast<ielem,element>(*(*it))) { 489 m_childs.push_back(new element(*_ele 489 m_childs.push_back(new element(*_elem)); 490 } 490 } 491 } 491 } 492 } 492 } 493 493 494 if((a_what==copy_all)||(a_what==copy_child 494 if((a_what==copy_all)||(a_what==copy_children)) { 495 if(a_clear) delete_sub_trees(); 495 if(a_clear) delete_sub_trees(); 496 tools_lforcit(ielem*,a_from.m_childs,it) 496 tools_lforcit(ielem*,a_from.m_childs,it) { 497 if(tree* _tree = id_cast<ielem,tree>(* 497 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 498 //FIXME : could we have mismatch par 498 //FIXME : could we have mismatch parent/child ? 499 tree* obj = _tree->create_copy(this) 499 tree* obj = _tree->create_copy(this); 500 if(!obj) { 500 if(!obj) { 501 // Something wrong, cleanup this. 501 // Something wrong, cleanup this. 502 clear(); 502 clear(); 503 return false; 503 return false; 504 } 504 } 505 add_child(obj); 505 add_child(obj); 506 } 506 } 507 } 507 } 508 } 508 } 509 509 510 //FIXME : m_save 510 //FIXME : m_save 511 511 512 return true; 512 return true; 513 } 513 } 514 514 515 515 516 void replace(const std::string& a_old,const 516 void replace(const std::string& a_old,const std::string& a_new) { 517 // Used by the obuild template system. 517 // Used by the obuild template system. 518 {size_t atbn = m_atbs.size(); 518 {size_t atbn = m_atbs.size(); 519 for(size_t index=0;index<atbn;index++) { 519 for(size_t index=0;index<atbn;index++) { 520 std::string& value = m_atbs[index].secon 520 std::string& value = m_atbs[index].second; 521 replace_(value,a_old,a_new); 521 replace_(value,a_old,a_new); 522 }} 522 }} 523 523 524 tools_lforit(ielem*,m_childs,it) { 524 tools_lforit(ielem*,m_childs,it) { 525 if(tree* _tree = id_cast<ielem,tree>(*(* 525 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 526 _tree->replace(a_old,a_new); 526 _tree->replace(a_old,a_new); 527 } else if(element* _elem = id_cast<ielem 527 } else if(element* _elem = id_cast<ielem,element>(*(*it))) { 528 _elem->replace(a_old,a_new); 528 _elem->replace(a_old,a_new); 529 } 529 } 530 } 530 } 531 } 531 } 532 532 533 static void collect_by_attribute(tree& a_tre 533 static void collect_by_attribute(tree& a_tree, 534 const std:: 534 const std::string& a_tag, 535 std::vector 535 std::vector<tree*>& a_items) { 536 std::string value; 536 std::string value; 537 if(a_tree.attribute_value(a_tag,value)) a_ 537 if(a_tree.attribute_value(a_tag,value)) a_items.push_back(&a_tree); 538 tools_lforcit(ielem*,a_tree.m_childs,it) { 538 tools_lforcit(ielem*,a_tree.m_childs,it) { 539 if(tree* _tree = id_cast<ielem,tree>(*(* 539 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 540 collect_by_attribute(*_tree,a_tag,a_it 540 collect_by_attribute(*_tree,a_tag,a_items); 541 } 541 } 542 } 542 } 543 } 543 } 544 544 545 bool element_values(const std::string& a_nam 545 bool element_values(const std::string& a_name, 546 std::vector<std::string> 546 std::vector<std::string>& a_values) const { 547 a_values.clear(); 547 a_values.clear(); 548 tools_lforcit(ielem*,m_childs,it) { 548 tools_lforcit(ielem*,m_childs,it) { 549 if(element* _elem = id_cast<ielem,elemen 549 if(element* _elem = id_cast<ielem,element>(*(*it))) { 550 if(a_name==_elem->name()) { 550 if(a_name==_elem->name()) { 551 a_values.push_back(_elem->value()); 551 a_values.push_back(_elem->value()); 552 } 552 } 553 } 553 } 554 } 554 } 555 return true; 555 return true; 556 } 556 } 557 557 558 void post_execute_backward(exec_func a_funct 558 void post_execute_backward(exec_func a_function,void* a_tag){ 559 if(!a_function) return; 559 if(!a_function) return; 560 tools_lforcit(ielem*,m_childs,it) { 560 tools_lforcit(ielem*,m_childs,it) { 561 if(tree* _tree = id_cast<ielem,tree>(*(* 561 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 562 _tree->post_execute_backward(a_functio 562 _tree->post_execute_backward(a_function,a_tag); 563 } 563 } 564 } 564 } 565 if(!a_function(*this,a_tag)) return; 565 if(!a_function(*this,a_tag)) return; 566 } 566 } 567 567 568 tree* find_by_attribute(const std::string& a 568 tree* find_by_attribute(const std::string& a_atb,const std::string& a_value, 569 bool a_up_down = true, 569 bool a_up_down = true,bool a_left_right = true) const { 570 if(a_up_down) { 570 if(a_up_down) { 571 std::string _s; 571 std::string _s; 572 attribute_value(a_atb,_s); 572 attribute_value(a_atb,_s); 573 if(_s==a_value) return const_cast<tree*> 573 if(_s==a_value) return const_cast<tree*>(this); 574 574 575 if(a_left_right) { 575 if(a_left_right) { 576 tools_lforcit(ielem*,m_childs,it) { 576 tools_lforcit(ielem*,m_childs,it) { 577 if(tree* _tree = id_cast<ielem,tree> 577 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 578 tree* itemML = 578 tree* itemML = 579 _tree->find_by_attribute(a_atb,a 579 _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right); 580 if(itemML) return itemML; 580 if(itemML) return itemML; 581 } 581 } 582 } 582 } 583 } else { 583 } else { 584 std::list<ielem*>::const_reverse_itera 584 std::list<ielem*>::const_reverse_iterator it; 585 for(it=m_childs.rbegin();it!=m_childs. 585 for(it=m_childs.rbegin();it!=m_childs.rend();++it) { 586 if(tree* _tree = id_cast<ielem,tree>(* 586 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 587 tree* itemML = 587 tree* itemML = 588 _tree->find_by_attribute(a_atb,a_v 588 _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right); 589 if(itemML) return itemML; 589 if(itemML) return itemML; 590 }} 590 }} 591 } 591 } 592 } else { 592 } else { 593 if(a_left_right) { 593 if(a_left_right) { 594 tools_lforcit(ielem*,m_childs,it) { 594 tools_lforcit(ielem*,m_childs,it) { 595 if(tree* _tree = id_cast<ielem,tree>(* 595 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 596 tree* itemML = 596 tree* itemML = 597 _tree->find_by_attribute(a_atb,a_v 597 _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right); 598 if(itemML) return itemML; 598 if(itemML) return itemML; 599 }} 599 }} 600 } else { 600 } else { 601 std::list<ielem*>::const_reverse_itera 601 std::list<ielem*>::const_reverse_iterator it; 602 for(it=m_childs.rbegin();it!=m_childs. 602 for(it=m_childs.rbegin();it!=m_childs.rend();++it) { 603 if(tree* _tree = id_cast<ielem,tree>(* 603 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 604 tree* itemML = 604 tree* itemML = 605 _tree->find_by_attribute(a_atb,a_v 605 _tree->find_by_attribute(a_atb,a_value,a_up_down,a_left_right); 606 if(itemML) return itemML; 606 if(itemML) return itemML; 607 }} 607 }} 608 } 608 } 609 609 610 std::string _s; 610 std::string _s; 611 attribute_value(a_atb,_s); 611 attribute_value(a_atb,_s); 612 if(_s==a_value) return const_cast<tree*> 612 if(_s==a_value) return const_cast<tree*>(this); 613 613 614 } 614 } 615 return 0; 615 return 0; 616 } 616 } 617 617 618 void dump_xml(std::ostream& a_out,const std: 618 void dump_xml(std::ostream& a_out,const std::string& a_spaces = "") { 619 619 620 // begin tag : 620 // begin tag : 621 a_out << a_spaces << "<" << m_tag_name; 621 a_out << a_spaces << "<" << m_tag_name; 622 {size_t atbn = m_atbs.size(); 622 {size_t atbn = m_atbs.size(); 623 for(size_t index=0;index<atbn;index++) { 623 for(size_t index=0;index<atbn;index++) { 624 a_out << " " << m_atbs[index].first << " 624 a_out << " " << m_atbs[index].first << "=" 625 << sout(m_atbs[index].second); 625 << sout(m_atbs[index].second); 626 }} 626 }} 627 a_out << ">" << std::endl; 627 a_out << ">" << std::endl; 628 628 629 {tools_lforcit(ielem*,m_childs,it) { 629 {tools_lforcit(ielem*,m_childs,it) { 630 if(element* _elem = id_cast<ielem,element> 630 if(element* _elem = id_cast<ielem,element>(*(*it))) { 631 631 632 const std::vector<atb>& atbs = _elem->at 632 const std::vector<atb>& atbs = _elem->attributes(); 633 633 634 bool isCallback = false; 634 bool isCallback = false; 635 635 636 a_out << a_spaces << " <" << _elem->nam 636 a_out << a_spaces << " <" << _elem->name(); 637 size_t atbn = atbs.size(); 637 size_t atbn = atbs.size(); 638 for(size_t index=0;index<atbn;index++) { 638 for(size_t index=0;index<atbn;index++) { 639 a_out << " " << atbs[index].first << " 639 a_out << " " << atbs[index].first << "=" 640 << sout(atbs[index].second); 640 << sout(atbs[index].second); 641 if(atbs[index].first=="exec") isCallba 641 if(atbs[index].first=="exec") isCallback = true; 642 } 642 } 643 if(_elem->value().empty()) { 643 if(_elem->value().empty()) { 644 a_out << "/>" << std::endl; 644 a_out << "/>" << std::endl; 645 } else { 645 } else { 646 a_out << ">"; 646 a_out << ">"; 647 std::string value = to_xml(_elem->valu 647 std::string value = to_xml(_elem->value()); 648 if(isCallback) { 648 if(isCallback) { 649 if(value.find("\\n\\")==std::string: 649 if(value.find("\\n\\")==std::string::npos) { 650 a_out << value; 650 a_out << value; 651 } else { 651 } else { 652 a_out << std::endl; 652 a_out << std::endl; 653 replace_(value,"\\n\\","@OnX@"); 653 replace_(value,"\\n\\","@OnX@"); 654 replace_(value,"@OnX@","\\n\\\n"); 654 replace_(value,"@OnX@","\\n\\\n"); 655 strip(value,trailing,' '); 655 strip(value,trailing,' '); 656 a_out << value; 656 a_out << value; 657 size_t l = value.size(); 657 size_t l = value.size(); 658 if(l && value[l-1]!='\n') a_out << 658 if(l && value[l-1]!='\n') a_out << std::endl; 659 a_out << a_spaces << " "; 659 a_out << a_spaces << " "; 660 } 660 } 661 } else { 661 } else { 662 a_out << value; 662 a_out << value; 663 } 663 } 664 a_out << "</" << _elem->name() << ">" 664 a_out << "</" << _elem->name() << ">" << std::endl; 665 } 665 } 666 }}} 666 }}} 667 667 668 // End tag : 668 // End tag : 669 a_out << a_spaces << "</" << m_tag_name << 669 a_out << a_spaces << "</" << m_tag_name << ">" << std::endl; 670 } 670 } 671 671 672 bool set_element_atb_value(const std::string 672 bool set_element_atb_value(const std::string& a_elem, 673 const std::string& 673 const std::string& a_atb, 674 const std::string& 674 const std::string& a_value,int a_index = 0){ 675 if(a_elem.empty()) { 675 if(a_elem.empty()) { 676 size_t linen = m_atbs.size(); 676 size_t linen = m_atbs.size(); 677 for(size_t count=0;count<linen;count++) 677 for(size_t count=0;count<linen;count++) { 678 if(m_atbs[count].first==a_atb) { 678 if(m_atbs[count].first==a_atb) { 679 m_atbs[count].second = a_value; 679 m_atbs[count].second = a_value; 680 return true; 680 return true; 681 } 681 } 682 } 682 } 683 // Not found, add it : 683 // Not found, add it : 684 m_atbs.push_back(atb(a_atb,a_value)); 684 m_atbs.push_back(atb(a_atb,a_value)); 685 return true; 685 return true; 686 } else { 686 } else { 687 int index = 0; 687 int index = 0; 688 tools_lforcit(ielem*,m_childs,it) { 688 tools_lforcit(ielem*,m_childs,it) { 689 if(element* _elem = id_cast<ielem,elemen 689 if(element* _elem = id_cast<ielem,element>(*(*it))) { 690 if(a_elem==_elem->name()) { 690 if(a_elem==_elem->name()) { 691 if(index==a_index) { 691 if(index==a_index) { 692 _elem->set_attribute_value(a_atb,a 692 _elem->set_attribute_value(a_atb,a_value); 693 return true; 693 return true; 694 } else { 694 } else { 695 index++; 695 index++; 696 } 696 } 697 } 697 } 698 }} 698 }} 699 return false; 699 return false; 700 } 700 } 701 } 701 } 702 702 703 // NOTE : used in osc. Should be removed. 703 // NOTE : used in osc. Should be removed. 704 void sub_trees(std::list<tree*>& a_list) con 704 void sub_trees(std::list<tree*>& a_list) const { 705 a_list.clear(); 705 a_list.clear(); 706 tools_lforcit(ielem*,m_childs,it) { 706 tools_lforcit(ielem*,m_childs,it) { 707 if(tree* _tree = id_cast<ielem,tree>(*(*it 707 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 708 a_list.push_back(_tree); 708 a_list.push_back(_tree); 709 }} 709 }} 710 } 710 } 711 void sub_elems(std::list<element*>& a_list) 711 void sub_elems(std::list<element*>& a_list) const { 712 a_list.clear(); 712 a_list.clear(); 713 tools_lforcit(ielem*,m_childs,it) { 713 tools_lforcit(ielem*,m_childs,it) { 714 if(element* _elem = id_cast<ielem,element> 714 if(element* _elem = id_cast<ielem,element>(*(*it))) { 715 a_list.push_back(_elem); 715 a_list.push_back(_elem); 716 }} 716 }} 717 } 717 } 718 718 719 bool replace_child(tree* a_old,tree* a_new) 719 bool replace_child(tree* a_old,tree* a_new) { 720 tools_lforit(ielem*,m_childs,it) { 720 tools_lforit(ielem*,m_childs,it) { 721 if(tree* _tree = id_cast<ielem,tree>(*(*it 721 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 722 if(_tree==a_old) { 722 if(_tree==a_old) { 723 (*it) = a_new; 723 (*it) = a_new; 724 return true; //replacement done. 724 return true; //replacement done. 725 } 725 } 726 }} 726 }} 727 return false; //no replacement done. 727 return false; //no replacement done. 728 } 728 } 729 729 730 // used in OnX/Widget. 730 // used in OnX/Widget. 731 virtual void* cast(const std::string& a_clas 731 virtual void* cast(const std::string& a_class) const { 732 if(void* p = cmp_cast<tree>(this,a_class)) 732 if(void* p = cmp_cast<tree>(this,a_class)) {return p;} 733 else return 0; 733 else return 0; 734 } 734 } 735 735 736 void delete_element(const std::string& a_nam 736 void delete_element(const std::string& a_name) { 737 tools_lforit(ielem*,m_childs,it) { 737 tools_lforit(ielem*,m_childs,it) { 738 if(element* _elem = id_cast<ielem,element> 738 if(element* _elem = id_cast<ielem,element>(*(*it))) { 739 if(a_name==_elem->name()) { 739 if(a_name==_elem->name()) { 740 m_childs.erase(it); 740 m_childs.erase(it); 741 delete _elem; 741 delete _elem; 742 break; 742 break; 743 } 743 } 744 }} 744 }} 745 } 745 } 746 746 747 void delete_element(element* a_element) { 747 void delete_element(element* a_element) { 748 tools_lforit(ielem*,m_childs,it) { 748 tools_lforit(ielem*,m_childs,it) { 749 if(element* _elem = id_cast<ielem,element> 749 if(element* _elem = id_cast<ielem,element>(*(*it))) { 750 if(_elem==a_element) { 750 if(_elem==a_element) { 751 m_childs.erase(it); 751 m_childs.erase(it); 752 delete _elem; 752 delete _elem; 753 break; 753 break; 754 } 754 } 755 }} 755 }} 756 } 756 } 757 757 758 void delete_sub_trees(){ 758 void delete_sub_trees(){ 759 std::list<ielem*>::iterator it; 759 std::list<ielem*>::iterator it; 760 for(it=m_childs.begin();it!=m_childs.end() 760 for(it=m_childs.begin();it!=m_childs.end();) { 761 if(tree* _tree = id_cast<ielem,tree>(*( 761 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 762 it = m_childs.erase(it); 762 it = m_childs.erase(it); 763 delete _tree; 763 delete _tree; 764 } else { 764 } else { 765 it++; 765 it++; 766 } 766 } 767 } 767 } 768 } 768 } 769 769 770 void delete_sub_elems(){ 770 void delete_sub_elems(){ 771 std::list<ielem*>::iterator it; 771 std::list<ielem*>::iterator it; 772 for(it=m_childs.begin();it!=m_childs.end() 772 for(it=m_childs.begin();it!=m_childs.end();) { 773 if(element* _elem = id_cast<ielem,elemen 773 if(element* _elem = id_cast<ielem,element>(*(*it))) { 774 it = m_childs.erase(it); 774 it = m_childs.erase(it); 775 delete _elem; 775 delete _elem; 776 } else { 776 } else { 777 it++; 777 it++; 778 } 778 } 779 } 779 } 780 } 780 } 781 781 782 const tree* find_by_element_in_same_level(co 782 const tree* find_by_element_in_same_level(const std::string& a_name, 783 co 783 const std::string& a_value) const { 784 // Look children : 784 // Look children : 785 tools_lforcit(ielem*,m_childs,it) { 785 tools_lforcit(ielem*,m_childs,it) { 786 if(tree* _tree = id_cast<ielem,tree>(*(*it 786 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 787 std::string _s; 787 std::string _s; 788 if(_tree->element_value(a_name,_s) && (a 788 if(_tree->element_value(a_name,_s) && (a_value==_s)) return _tree; 789 }} 789 }} 790 return 0; 790 return 0; 791 } 791 } 792 792 793 bool element_value_boolean(const std::string 793 bool element_value_boolean(const std::string& a_name,bool& a_value) const { 794 std::string value; 794 std::string value; 795 if(!element_value(a_name,value)) return fa 795 if(!element_value(a_name,value)) return false; 796 return to(value,a_value); 796 return to(value,a_value); 797 } 797 } 798 798 799 void update_tree(const tree& a_old) { 799 void update_tree(const tree& a_old) { 800 // We map the opened elements in the old t 800 // We map the opened elements in the old tree within this tree. 801 // Algorithm based on the existence of a " 801 // Algorithm based on the existence of a "label" element. 802 tools_lforit(ielem*,m_childs,it) { 802 tools_lforit(ielem*,m_childs,it) { 803 if(tree* _tree = id_cast<ielem,tree>(*(*it 803 if(tree* _tree = id_cast<ielem,tree>(*(*it))) { 804 std::string slabel; 804 std::string slabel; 805 if(_tree->element_value("label",slabel)) 805 if(_tree->element_value("label",slabel)) { 806 // Try to find a same label in the sam 806 // Try to find a same label in the same level : 807 const tree* item = 807 const tree* item = 808 a_old.find_by_element_in_same_level( 808 a_old.find_by_element_in_same_level("label",slabel); 809 if(item) { 809 if(item) { 810 bool sopened; 810 bool sopened; 811 if(item->element_value_boolean("open 811 if(item->element_value_boolean("opened",sopened) && sopened) { 812 _tree->set_element_value("opened", 812 _tree->set_element_value("opened","true"); 813 } 813 } 814 if(a_old.number_of_trees()) _tree->u 814 if(a_old.number_of_trees()) _tree->update_tree(*item); 815 } 815 } 816 } 816 } 817 }} 817 }} 818 } 818 } 819 819 820 //////////////////////////////////////////// 820 ////////////////////////////////////////////////// 821 /// end osc //////////////////////////////// 821 /// end osc ////////////////////////////////////// 822 //////////////////////////////////////////// 822 ////////////////////////////////////////////////// 823 823 824 //////////////////////////////////////////// 824 /////////////////////////////////////////////////////// 825 /// sub trees ////////////////////////////// 825 /// sub trees ///////////////////////////////////////// 826 //////////////////////////////////////////// 826 /////////////////////////////////////////////////////// 827 827 828 tree* parent() const {return m_parent;} 828 tree* parent() const {return m_parent;} 829 829 830 void set_parent(tree* a_parent) {m_parent = 830 void set_parent(tree* a_parent) {m_parent = a_parent;} 831 831 832 unsigned int number_of_trees() const { 832 unsigned int number_of_trees() const { 833 unsigned int number = 0; 833 unsigned int number = 0; 834 tools_lforcit(ielem*,m_childs,it) { 834 tools_lforcit(ielem*,m_childs,it) { 835 if(id_cast<ielem,tree>(*(*it))) number++ 835 if(id_cast<ielem,tree>(*(*it))) number++; 836 } 836 } 837 return number; 837 return number; 838 } 838 } 839 839 840 void remove_child(tree*& a_tree,bool a_delet 840 void remove_child(tree*& a_tree,bool a_delete = true){ 841 m_childs.remove(a_tree); 841 m_childs.remove(a_tree); 842 if(a_delete) { 842 if(a_delete) { 843 delete a_tree; 843 delete a_tree; 844 a_tree = 0; 844 a_tree = 0; 845 } 845 } 846 } 846 } 847 847 848 /* 848 /* 849 849 850 bool is_first_child(const tree& a_tree) { 850 bool is_first_child(const tree& a_tree) { 851 if(m_children.empty()) return false; 851 if(m_children.empty()) return false; 852 return ( (*(m_children.begin()))==&a_tree) 852 return ( (*(m_children.begin()))==&a_tree) ? true : false; 853 } 853 } 854 854 855 bool is_last_child(const tree& a_tree) { 855 bool is_last_child(const tree& a_tree) { 856 if(m_children.empty()) return false; 856 if(m_children.empty()) return false; 857 return ( m_children.back()==&a_tree) ? tru 857 return ( m_children.back()==&a_tree) ? true : false; 858 } 858 } 859 */ 859 */ 860 860 861 /* TOOLS_STL : no std::list::insert. 861 /* TOOLS_STL : no std::list::insert. 862 void add_after(tree* a_tree,tree* a_entry){ 862 void add_after(tree* a_tree,tree* a_entry){ 863 tools_lforit(tree*,m_children,it) { 863 tools_lforit(tree*,m_children,it) { 864 if((*it)==a_tree) { 864 if((*it)==a_tree) { 865 m_children.insert(it,a_entry); 865 m_children.insert(it,a_entry); 866 return; 866 return; 867 } 867 } 868 } 868 } 869 } 869 } 870 870 871 //TOOLS_STL : no std::list::iterator::operat 871 //TOOLS_STL : no std::list::iterator::operator--. 872 872 873 tree* previous_child(const tree& a_tree){ 873 tree* previous_child(const tree& a_tree){ 874 tools_lforit(tree*,m_children,it) { 874 tools_lforit(tree*,m_children,it) { 875 if((*it)==&a_tree) { 875 if((*it)==&a_tree) { 876 if(it==m_children.begin()) return 0; 876 if(it==m_children.begin()) return 0; 877 --it; 877 --it; 878 return *it; 878 return *it; 879 } 879 } 880 } 880 } 881 return 0; 881 return 0; 882 } 882 } 883 883 884 tree* next_child(const tree& a_tree){ 884 tree* next_child(const tree& a_tree){ 885 tools_lforit(tree*,m_children,it) { 885 tools_lforit(tree*,m_children,it) { 886 if((*it)==&a_tree) { 886 if((*it)==&a_tree) { 887 std::list<tree*>::iterator last = m_ch 887 std::list<tree*>::iterator last = m_children.end(); 888 --last; 888 --last; 889 if(it==last) return 0; 889 if(it==last) return 0; 890 ++it; 890 ++it; 891 return *it; 891 return *it; 892 } 892 } 893 } 893 } 894 return 0; 894 return 0; 895 } 895 } 896 */ 896 */ 897 897 898 void set_data(void* a_data_1,void* a_data_2, 898 void set_data(void* a_data_1,void* a_data_2,int a_data_int) { 899 m_data_1 = a_data_1; 899 m_data_1 = a_data_1; 900 m_data_2 = a_data_2; 900 m_data_2 = a_data_2; 901 m_data_int = a_data_int; 901 m_data_int = a_data_int; 902 } 902 } 903 void get_data(void*& a_data_1,void*& a_data_ 903 void get_data(void*& a_data_1,void*& a_data_2,int& a_data_int) const { 904 a_data_1 = m_data_1; 904 a_data_1 = m_data_1; 905 a_data_2 = m_data_2; 905 a_data_2 = m_data_2; 906 a_data_int = m_data_int; 906 a_data_int = m_data_int; 907 } 907 } 908 void* get_data1() const {return m_data_1;} 908 void* get_data1() const {return m_data_1;} 909 void* get_data2() const {return m_data_2;} 909 void* get_data2() const {return m_data_2;} 910 int get_data_int() const {return m_data_int; 910 int get_data_int() const {return m_data_int;} 911 void set_depth(unsigned int a_depth) {m_dept 911 void set_depth(unsigned int a_depth) {m_depth = a_depth;} 912 unsigned int depth() const {return m_depth;} 912 unsigned int depth() const {return m_depth;} 913 void set_save_flag(bool a_value) {m_save = a 913 void set_save_flag(bool a_value) {m_save = a_value;} 914 bool save_flag() const {return m_save;} 914 bool save_flag() const {return m_save;} 915 void set_file(const std::string& a_file) {m_ 915 void set_file(const std::string& a_file) {m_file = a_file;} 916 const std::string& file() const {return m_fi 916 const std::string& file() const {return m_file;} 917 917 918 protected: 918 protected: 919 void clear(){ 919 void clear(){ 920 m_atbs.clear(); 920 m_atbs.clear(); 921 921 922 // TOOLS_STL : no std::list::erase. 922 // TOOLS_STL : no std::list::erase. 923 //{std::list<tree*>::iterator it; 923 //{std::list<tree*>::iterator it; 924 // for(it=m_children.begin(); 924 // for(it=m_children.begin(); 925 // it!=m_children.end(); 925 // it!=m_children.end(); 926 // it = m_children.erase(it)) 926 // it = m_children.erase(it)) 927 // delete (*it);} 927 // delete (*it);} 928 // 928 // 929 //{std::list<element*>::iterator it; 929 //{std::list<element*>::iterator it; 930 // for(it=m_elems.begin();it!=m_elems.end() 930 // for(it=m_elems.begin();it!=m_elems.end();it = m_elems.erase(it)) 931 // delete (*it);} 931 // delete (*it);} 932 932 933 while(!m_childs.empty()) { 933 while(!m_childs.empty()) { 934 ielem* item = m_childs.front(); 934 ielem* item = m_childs.front(); 935 m_childs.remove(item); 935 m_childs.remove(item); 936 delete item; 936 delete item; 937 } 937 } 938 } 938 } 939 939 940 protected: 940 protected: 941 std::string m_tag_name; 941 std::string m_tag_name; 942 factory& m_factory; 942 factory& m_factory; 943 tree* m_parent; 943 tree* m_parent; 944 //std::list<tree*> m_children; 944 //std::list<tree*> m_children; 945 //std::list<element*> m_elems; 945 //std::list<element*> m_elems; 946 std::list<ielem*> m_childs; 946 std::list<ielem*> m_childs; 947 std::vector<atb> m_atbs; 947 std::vector<atb> m_atbs; 948 std::string m_file; 948 std::string m_file; 949 bool m_save; 949 bool m_save; 950 void* m_data_1; 950 void* m_data_1; 951 void* m_data_2; 951 void* m_data_2; 952 int m_data_int; 952 int m_data_int; 953 int m_depth; 953 int m_depth; 954 }; 954 }; 955 955 956 class looper { 956 class looper { 957 public: 957 public: 958 looper(const tree& a_tree) 958 looper(const tree& a_tree) 959 :m_it(a_tree.childs().begin()) 959 :m_it(a_tree.childs().begin()) 960 ,m_end(a_tree.childs().end()) 960 ,m_end(a_tree.childs().end()) 961 {} 961 {} 962 virtual ~looper(){} 962 virtual ~looper(){} 963 protected: 963 protected: 964 looper(const looper& a_from) 964 looper(const looper& a_from) 965 :m_it(a_from.m_it) 965 :m_it(a_from.m_it) 966 ,m_end(a_from.m_end) 966 ,m_end(a_from.m_end) 967 {} 967 {} 968 looper& operator=(const looper&){return *thi 968 looper& operator=(const looper&){return *this;} 969 public: 969 public: 970 tree* next_tree() { 970 tree* next_tree() { 971 for(;m_it!=m_end;++m_it) { 971 for(;m_it!=m_end;++m_it) { 972 tree* _tree = id_cast<ielem,tree>(*(*m_i 972 tree* _tree = id_cast<ielem,tree>(*(*m_it)); 973 if(_tree) {m_it++;return _tree;} 973 if(_tree) {m_it++;return _tree;} 974 } 974 } 975 return 0; 975 return 0; 976 } 976 } 977 element* next_element() { 977 element* next_element() { 978 for(;m_it!=m_end;++m_it) { 978 for(;m_it!=m_end;++m_it) { 979 element* _elem = id_cast<ielem,element>( 979 element* _elem = id_cast<ielem,element>(*(*m_it)); 980 if(_elem) {m_it++;return _elem;} 980 if(_elem) {m_it++;return _elem;} 981 } 981 } 982 return 0; 982 return 0; 983 } 983 } 984 protected: 984 protected: 985 std::list<ielem*>::const_iterator m_it; 985 std::list<ielem*>::const_iterator m_it; 986 std::list<ielem*>::const_iterator m_end; 986 std::list<ielem*>::const_iterator m_end; 987 }; 987 }; 988 988 989 class default_factory : public virtual factory 989 class default_factory : public virtual factory { 990 #ifdef TOOLS_MEM 990 #ifdef TOOLS_MEM 991 TOOLS_SCLASS(tools::xml::default_factory) 991 TOOLS_SCLASS(tools::xml::default_factory) 992 #endif 992 #endif 993 public: 993 public: 994 virtual tree* create(const std::string& a_ta 994 virtual tree* create(const std::string& a_tag_name,const std::vector<tree::atb>& a_atbs,tree* a_parent) { 995 // It does not add the new tree in parent. 995 // It does not add the new tree in parent. 996 tree* itemML = new tree(a_tag_name,*this,a 996 tree* itemML = new tree(a_tag_name,*this,a_parent); 997 itemML->set_attributes(a_atbs); 997 itemML->set_attributes(a_atbs); 998 return itemML; 998 return itemML; 999 } 999 } 1000 public: 1000 public: 1001 default_factory(){ 1001 default_factory(){ 1002 #ifdef TOOLS_MEM 1002 #ifdef TOOLS_MEM 1003 mem::increment(s_class().c_str()); 1003 mem::increment(s_class().c_str()); 1004 #endif 1004 #endif 1005 } 1005 } 1006 virtual ~default_factory(){ 1006 virtual ~default_factory(){ 1007 #ifdef TOOLS_MEM 1007 #ifdef TOOLS_MEM 1008 mem::decrement(s_class().c_str()); 1008 mem::decrement(s_class().c_str()); 1009 #endif 1009 #endif 1010 } 1010 } 1011 public: 1011 public: 1012 default_factory(const default_factory& a_fr 1012 default_factory(const default_factory& a_from) 1013 :factory(a_from){ 1013 :factory(a_from){ 1014 #ifdef TOOLS_MEM 1014 #ifdef TOOLS_MEM 1015 mem::increment(s_class().c_str()); 1015 mem::increment(s_class().c_str()); 1016 #endif 1016 #endif 1017 } 1017 } 1018 default_factory& operator=(const default_fa 1018 default_factory& operator=(const default_factory&){return *this;} 1019 }; 1019 }; 1020 1020 1021 }} 1021 }} 1022 1022 1023 #endif 1023 #endif