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