Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/xml/tree

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/xml/tree (Version 11.3.0) and /externals/g4tools/include/tools/xml/tree (Version 9.2)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  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 </    
 27 //      ...                                       
 28 //    </tree>                                     
 29 //                                                
 30 //   tree.attribute_value(<name>,s)               
 31 //     retrieve the value of atb <name> of a <    
 32 //   tree.attribute_value(<element>,<name>,s)     
 33 //     retrieve the value of an atb <name> of     
 34 //                                                
 35                                                   
 36 class tree;                                       
 37                                                   
 38 class factory {                                   
 39 public:                                           
 40   virtual ~factory(){}                            
 41 public:                                           
 42   typedef std::pair<std::string,std::string> a    
 43 public:                                           
 44   virtual tree* create(const std::string& a_ta    
 45 };                                                
 46                                                   
 47 class tree : public virtual ielem {               
 48 public:                                           
 49   TOOLS_SCLASS(tools::xml::tree)                  
 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))    
 54     else return 0;                                
 55   }                                               
 56 public:                                           
 57   typedef std::pair<std::string,std::string> a    
 58   typedef bool (*exec_func)(tree&,void*);         
 59   enum copy_what { copy_attributes, copy_eleme    
 60 public:                                           
 61   tree(const std::string& a_tag_name,factory&     
 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 {ret    
106                                                   
107   ////////////////////////////////////////////    
108   /// attributes /////////////////////////////    
109   ////////////////////////////////////////////    
110   const std::vector<atb>& attributes() const {    
111                                                   
112   void add_attribute(const std::string& a_name    
113     // No check is done about an existing a_na    
114     m_atbs.push_back(atb(a_name,a_value));        
115   }                                               
116                                                   
117   bool is_attribute(const std::string& a_name)    
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 t    
121     }                                             
122     return false;                                 
123   }                                               
124                                                   
125   void set_attributes(const std::vector<atb>&     
126     m_atbs = a_atbs;                              
127   }                                               
128   const std::string& tag_name() const {return     
129                                                   
130   bool attribute_value(const std::string& a_at    
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_at    
144     std::string sv;                               
145     if(!attribute_value(a_atb,sv)) {a_value=T(    
146     return to<T>(sv,a_value);                     
147   }                                               
148                                                   
149   void remove_attributes(const std::string& a_    
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_n    
161     //TOOLS_STL : to be checked :                 
162     std::vector<atb>::iterator it = m_atbs.beg    
163     size_t linen = m_atbs.size();                 
164     for(size_t count=0;count<linen;count++,++i    
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                                                   
173   ////////////////////////////////////////////    
174   /// elements ///////////////////////////////    
175   ////////////////////////////////////////////    
176   void add_element(const std::string& a_name,c    
177     m_childs.push_back(new element(a_name,a_at    
178   }                                               
179                                                   
180   bool element_value(const std::string& a_name    
181     tools_lforcit(ielem*,m_childs,it) {           
182       if(element* _elem = id_cast<ielem,elemen    
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 :     
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[    
206             << sout(m_atbs[index].second) << s    
207     }}                                            
208                                                   
209    {tools_lforit(element*,m_elems,it) {           
210       a_out << " element : \"" << (*it)->name(    
211             << (*it)->value() << "\"" << std::    
212     }}                                            
213                                                   
214    {tools_lforit(tree*,m_children,it) {           
215       (*it)->dump(a_out);                         
216     }}                                            
217   }                                               
218                                                   
219   const std::list<element*>& elements() const     
220                                                   
221 */                                                
222                                                   
223   bool element_atb_value(const std::string& a_    
224     a_value.clear();                              
225     tools_lforcit(ielem*,m_childs,it) {           
226       if(element* _elem = id_cast<ielem,elemen    
227         if(a_elem==_elem->name()) {               
228           if(_elem->attribute_value(a_atb,a_va    
229         }                                         
230       }                                           
231     }                                             
232     return false;                                 
233   }                                               
234                                                   
235   template <class T>                              
236   bool element_atb_value(const std::string& a_    
237     std::string sv;                               
238     if(!element_atb_value(a_elem,a_atb,sv)) {a    
239     return to<T>(sv,a_value);                     
240   }                                               
241                                                   
242   ////////////////////////////////////////////    
243   /// for osc ////////////////////////////////    
244   ////////////////////////////////////////////    
245   bool is_element(const std::string& a_name) c    
246     tools_lforcit(ielem*,m_childs,it) {           
247       if(element* _elem = id_cast<ielem,elemen    
248         if(a_name==_elem->name()) return true;    
249       }                                           
250     }                                             
251     return false;                                 
252   }                                               
253                                                   
254   bool set_element_value(const std::string& a_    
255     int index = 0;                                
256     tools_lforcit(ielem*,m_childs,it) {           
257       if(element* _elem = id_cast<ielem,elemen    
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&     
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&    
287     empty_visitor visitor(a_out);                 
288     visitor.m_status = true;                      
289     const_cast<tree*>(this)->post_execute(chec    
290     return visitor.m_status;                      
291   }                                               
292                                                   
293   class empty_visitor {                           
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*    
303     if(!a_function) return;                       
304                                                   
305     if(!a_function(*this,a_tag)) return;          
306                                                   
307     tools_lforcit(ielem*,m_childs,it) {           
308       if(tree* _tree = id_cast<ielem,tree>(*(*    
309         _tree->post_execute(a_function,a_tag);    
310       }                                           
311     }                                             
312   }                                               
313                                                   
314   static bool check_item(tree& a_tree,void* a_    
315     empty_visitor* visitor = (empty_visitor*)a    
316                                                   
317    {const std::vector<atb>& atbs = a_tree.attr    
318     size_t atbn = atbs.size();                    
319     for(size_t index=0;index<atbn;index++) {      
320       const std::string& _atb = atbs[index].fi    
321       const std::string& atbv = atbs[index].se    
322       if(atbv.empty()) {                          
323         visitor->f_out << "check_item :"          
324             << " for XML item " << sout(a_tree    
325             << ", attribute " << sout(_atb) <<    
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>    
333       const std::vector<atb>& atbs = _elem->at    
334       size_t atbn = atbs.size();                  
335       for(size_t index=0;index<atbn;index++) {    
336         const std::string& _atb = atbs[index].    
337         const std::string& atbv = atbs[index].    
338         if(atbv.empty()) {                        
339           visitor->f_out << "ItemM::check_item    
340               << " for XML item " << sout(a_tr    
341               << ", attribute " << sout(_atb)     
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,cons    
352     if(a_tree.tag_name()==a_tag) a_items.push_    
353     tools_lforcit(ielem*,a_tree.m_childs,it) {    
354       if(tree* _tree = id_cast<ielem,tree>(*(*    
355         collect_by_tag(*_tree,a_tag,a_items);     
356       }                                           
357     }                                             
358   }                                               
359                                                   
360   tree* find_by_tag(const std::string& a_tag)     
361     if(tag_name()==a_tag) return const_cast<tr    
362     // Look children :                            
363     tools_lforcit(ielem*,m_childs,it) {           
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_ite    
372     std::vector<tree*> items2;                    
373                                                   
374     tools_vforcit(tree*,a_items,it) {             
375       std::string name;                           
376       if(!(*it)->attribute_value("name",name))    
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) c    
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) retur    
401         break;                                    
402       }                                           
403     }}                                            
404                                                   
405     // Look children :                            
406     tools_lforcit(ielem*,m_childs,it) {           
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&     
415                            const std::string&     
416     if(a_tag==tag_name()) {                       
417       std::string _s;                             
418       attribute_value("name",_s);                 
419       if(a_name==_s) return const_cast<tree*>(    
420     }                                             
421                                                   
422     // Look children :                            
423     tools_lforcit(ielem*,m_childs,it) {           
424     if(tree* _tree = id_cast<ielem,tree>(*(*it    
425       tree* item = _tree->find_item_with_tag(a    
426       if(item) return item;                       
427     }}                                            
428     return 0;                                     
429   }                                               
430                                                   
431   void remove_elements(const std::string& a_na    
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,elemen    
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_    
449                                                   
450   tree* create_copy(tree* a_parent) {             
451     tree* itemML = m_factory.create(m_tag_name    
452     if(!itemML) return 0;                         
453     itemML->m_atbs = m_atbs;                      
454     //FIXME : m_save                              
455                                                   
456    {tools_lforcit(ielem*,m_childs,it) {           
457     if(element* _elem = id_cast<ielem,element>    
458       itemML->m_childs.push_back(new element(*    
459     }}}                                           
460                                                   
461    {tools_lforcit(ielem*,m_childs,it) {           
462     if(tree* _tree = id_cast<ielem,tree>(*(*it    
463       //FIXME : could we have mismatch parent/    
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) o    
480     if((a_what==copy_all)||(a_what==copy_attri    
481       if(a_clear) m_atbs.clear();                 
482       tools_vforcit(atb,a_from.m_atbs,it) m_at    
483     }                                             
484                                                   
485     if((a_what==copy_all)||(a_what==copy_eleme    
486       if(a_clear) delete_sub_elems();             
487       tools_lforcit(ielem*,a_from.m_childs,it)    
488         if(element* _elem = id_cast<ielem,elem    
489           m_childs.push_back(new element(*_ele    
490         }                                         
491       }                                           
492     }                                             
493                                                   
494     if((a_what==copy_all)||(a_what==copy_child    
495       if(a_clear) delete_sub_trees();             
496       tools_lforcit(ielem*,a_from.m_childs,it)    
497         if(tree* _tree = id_cast<ielem,tree>(*    
498           //FIXME : could we have mismatch par    
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     
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].secon    
521       replace_(value,a_old,a_new);                
522     }}                                            
523                                                   
524     tools_lforit(ielem*,m_childs,it) {            
525       if(tree* _tree = id_cast<ielem,tree>(*(*    
526         _tree->replace(a_old,a_new);              
527       } else if(element* _elem = id_cast<ielem    
528         _elem->replace(a_old,a_new);              
529       }                                           
530     }                                             
531   }                                               
532                                                   
533   static void collect_by_attribute(tree& a_tre    
534                                    const std::    
535                                    std::vector    
536     std::string value;                            
537     if(a_tree.attribute_value(a_tag,value)) a_    
538     tools_lforcit(ielem*,a_tree.m_childs,it) {    
539       if(tree* _tree = id_cast<ielem,tree>(*(*    
540         collect_by_attribute(*_tree,a_tag,a_it    
541       }                                           
542     }                                             
543   }                                               
544                                                   
545   bool element_values(const std::string& a_nam    
546                       std::vector<std::string>    
547     a_values.clear();                             
548     tools_lforcit(ielem*,m_childs,it) {           
549       if(element* _elem = id_cast<ielem,elemen    
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_funct    
559     if(!a_function) return;                       
560     tools_lforcit(ielem*,m_childs,it) {           
561       if(tree* _tree = id_cast<ielem,tree>(*(*    
562         _tree->post_execute_backward(a_functio    
563       }                                           
564     }                                             
565     if(!a_function(*this,a_tag)) return;          
566   }                                               
567                                                   
568   tree* find_by_attribute(const std::string& a    
569                         bool a_up_down = true,    
570     if(a_up_down) {                               
571       std::string _s;                             
572       attribute_value(a_atb,_s);                  
573       if(_s==a_value) return const_cast<tree*>    
574                                                   
575       if(a_left_right) {                          
576         tools_lforcit(ielem*,m_childs,it) {       
577           if(tree* _tree = id_cast<ielem,tree>    
578             tree* itemML =                        
579               _tree->find_by_attribute(a_atb,a    
580             if(itemML) return itemML;             
581           }                                       
582         }                                         
583       } else {                                    
584         std::list<ielem*>::const_reverse_itera    
585         for(it=m_childs.rbegin();it!=m_childs.    
586         if(tree* _tree = id_cast<ielem,tree>(*    
587           tree* itemML =                          
588             _tree->find_by_attribute(a_atb,a_v    
589           if(itemML) return itemML;               
590         }}                                        
591       }                                           
592     } else {                                      
593       if(a_left_right) {                          
594         tools_lforcit(ielem*,m_childs,it) {       
595         if(tree* _tree = id_cast<ielem,tree>(*    
596           tree* itemML =                          
597             _tree->find_by_attribute(a_atb,a_v    
598           if(itemML) return itemML;               
599         }}                                        
600       } else {                                    
601         std::list<ielem*>::const_reverse_itera    
602         for(it=m_childs.rbegin();it!=m_childs.    
603         if(tree* _tree = id_cast<ielem,tree>(*    
604           tree* itemML =                          
605             _tree->find_by_attribute(a_atb,a_v    
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*>    
613                                                   
614     }                                             
615     return 0;                                     
616   }                                               
617                                                   
618   void dump_xml(std::ostream& a_out,const std:    
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                                                   
629    {tools_lforcit(ielem*,m_childs,it) {           
630     if(element* _elem = id_cast<ielem,element>    
631                                                   
632       const std::vector<atb>& atbs = _elem->at    
633                                                   
634       bool isCallback = false;                    
635                                                   
636       a_out << a_spaces << "  <" << _elem->nam    
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") isCallba    
642       }                                           
643       if(_elem->value().empty()) {                
644         a_out << "/>" << std::endl;               
645       } else {                                    
646         a_out << ">";                             
647         std::string value = to_xml(_elem->valu    
648         if(isCallback) {                          
649           if(value.find("\\n\\")==std::string:    
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 <<    
659             a_out << a_spaces << "  ";            
660           }                                       
661         } else {                                  
662           a_out << value;                         
663         }                                         
664         a_out << "</" << _elem->name() << ">"     
665       }                                           
666     }}}                                           
667                                                   
668     // End tag :                                  
669     a_out << a_spaces << "</" << m_tag_name <<    
670   }                                               
671                                                   
672   bool set_element_atb_value(const std::string    
673                             const std::string&    
674                             const std::string&    
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;                              
688       tools_lforcit(ielem*,m_childs,it) {         
689       if(element* _elem = id_cast<ielem,elemen    
690         if(a_elem==_elem->name()) {               
691           if(index==a_index) {                    
692             _elem->set_attribute_value(a_atb,a    
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) con    
705     a_list.clear();                               
706     tools_lforcit(ielem*,m_childs,it) {           
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)     
712     a_list.clear();                               
713     tools_lforcit(ielem*,m_childs,it) {           
714     if(element* _elem = id_cast<ielem,element>    
715       a_list.push_back(_elem);                    
716     }}                                            
717   }                                               
718                                                   
719   bool replace_child(tree* a_old,tree* a_new)     
720     tools_lforit(ielem*,m_childs,it) {            
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_clas    
732     if(void* p = cmp_cast<tree>(this,a_class))    
733     else return 0;                                
734   }                                               
735                                                   
736   void delete_element(const std::string& a_nam    
737     tools_lforit(ielem*,m_childs,it) {            
738     if(element* _elem = id_cast<ielem,element>    
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) {       
748     tools_lforit(ielem*,m_childs,it) {            
749     if(element* _elem = id_cast<ielem,element>    
750       if(_elem==a_element) {                      
751         m_childs.erase(it);                       
752         delete _elem;                             
753         break;                                    
754       }                                           
755     }}                                            
756   }                                               
757                                                   
758   void delete_sub_trees(){                        
759     std::list<ielem*>::iterator it;               
760     for(it=m_childs.begin();it!=m_childs.end()    
761        if(tree* _tree = id_cast<ielem,tree>(*(    
762          it = m_childs.erase(it);                 
763          delete _tree;                            
764        } else {                                   
765          it++;                                    
766        }                                          
767     }                                             
768   }                                               
769                                                   
770   void delete_sub_elems(){                        
771     std::list<ielem*>::iterator it;               
772     for(it=m_childs.begin();it!=m_childs.end()    
773       if(element* _elem = id_cast<ielem,elemen    
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(co    
783                                             co    
784     // Look children :                            
785     tools_lforcit(ielem*,m_childs,it) {           
786     if(tree* _tree = id_cast<ielem,tree>(*(*it    
787       std::string _s;                             
788       if(_tree->element_value(a_name,_s) && (a    
789     }}                                            
790     return 0;                                     
791   }                                               
792                                                   
793   bool element_value_boolean(const std::string    
794     std::string value;                            
795     if(!element_value(a_name,value)) return fa    
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 t    
801     // Algorithm based on the existence of a "    
802     tools_lforit(ielem*,m_childs,it) {            
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 sam    
807         const tree* item =                        
808           a_old.find_by_element_in_same_level(    
809         if(item) {                                
810           bool sopened;                           
811           if(item->element_value_boolean("open    
812             _tree->set_element_value("opened",    
813           }                                       
814           if(a_old.number_of_trees()) _tree->u    
815         }                                         
816       }                                           
817     }}                                            
818   }                                               
819                                                   
820   ////////////////////////////////////////////    
821   /// end osc ////////////////////////////////    
822   ////////////////////////////////////////////    
823                                                   
824   ////////////////////////////////////////////    
825   /// sub trees //////////////////////////////    
826   ////////////////////////////////////////////    
827                                                   
828   tree* parent() const {return m_parent;}         
829                                                   
830   void set_parent(tree* a_parent) {m_parent =     
831                                                   
832   unsigned int number_of_trees() const {          
833     unsigned int number = 0;                      
834     tools_lforcit(ielem*,m_childs,it) {           
835       if(id_cast<ielem,tree>(*(*it))) number++    
836     }                                             
837     return number;                                
838   }                                               
839                                                   
840   void remove_child(tree*& a_tree,bool a_delet    
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)    
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) ? tru    
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::operat    
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_ch    
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,    
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_    
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_dept    
912   unsigned int depth() const {return m_depth;}    
913   void set_save_flag(bool a_value) {m_save = a    
914   bool save_flag() const {return m_save;}         
915   void set_file(const std::string& a_file) {m_    
916   const std::string& file() const {return m_fi    
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()    
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;                         
942   factory& m_factory;                             
943   tree* m_parent;                                 
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;                                 
952   int m_data_int;                                 
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 *thi    
969 public:                                           
970   tree* next_tree() {                             
971     for(;m_it!=m_end;++m_it) {                    
972       tree* _tree = id_cast<ielem,tree>(*(*m_i    
973       if(_tree) {m_it++;return _tree;}            
974     }                                             
975     return 0;                                     
976   }                                               
977   element* next_element() {                       
978     for(;m_it!=m_end;++m_it) {                    
979       element* _elem = id_cast<ielem,element>(    
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                                  
991   TOOLS_SCLASS(tools::xml::default_factory)       
992 #endif                                            
993 public:                                           
994   virtual tree* create(const std::string& a_ta    
995     // It does not add the new tree in parent.    
996     tree* itemML = new tree(a_tag_name,*this,a    
997     itemML->set_attributes(a_atbs);               
998     return itemML;                                
999   }                                               
1000 public:                                          
1001   default_factory(){                             
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:                                          
1012   default_factory(const default_factory& a_fr    
1013   :factory(a_from){                              
1014 #ifdef TOOLS_MEM                                 
1015     mem::increment(s_class().c_str());           
1016 #endif                                           
1017   }                                              
1018   default_factory& operator=(const default_fa    
1019 };                                               
1020                                                  
1021 }}                                               
1022                                                  
1023 #endif