Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/toolx/xml/loader

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/toolx/xml/loader (Version 11.3.0) and /externals/g4tools/include/toolx/xml/loader (Version 1.1)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  2 // See the file tools.license for terms.          
  3                                                   
  4 #ifndef toolx_xml_loader                          
  5 #define toolx_xml_loader                          
  6                                                   
  7 #include <tools/xml/tree>                         
  8 #include <tools/file>                             
  9 #include <tools/mnmx>                             
 10                                                   
 11 #include <cstdio>                                 
 12 #include <cctype> //iscntrl                       
 13                                                   
 14 #include <expat.h>                                
 15                                                   
 16 #ifdef TOOLS_MEM                                  
 17 #include <tools/mem>                              
 18 namespace toolx {                                 
 19 extern "C" {                                      
 20 inline void* xml_malloc(size_t a_size){           
 21   tools::mem::increment(tools::s_malloc().c_st    
 22   return ::malloc(a_size);                        
 23 }                                                 
 24 inline void* xml_realloc(void* a_ptr,size_t a_    
 25   if(a_ptr==NULL) tools::mem::increment(tools:    
 26   return ::realloc(a_ptr,a_size);                 
 27 }                                                 
 28 inline void xml_free(void* a_ptr){                
 29   if(a_ptr!=NULL) tools::mem::decrement(tools:    
 30   ::free(a_ptr);                                  
 31 }                                                 
 32 }}                                                
 33 #endif                                            
 34                                                   
 35 namespace toolx {                                 
 36 namespace xml {                                   
 37                                                   
 38 class loader {                                    
 39 #ifdef TOOLS_MEM                                  
 40   TOOLS_SCLASS(toolx::xml::loader)                
 41 #endif                                            
 42 public:                                           
 43   loader(tools::xml::factory& a_factory,          
 44          std::ostream& a_out,bool a_verbose =     
 45   :m_factory(a_factory)                           
 46   ,m_out(a_out)                                   
 47   ,m_verbose(a_verbose)                           
 48   ,m_take_cntrl(false)                            
 49                                                   
 50   ,m_errors(0)                                    
 51   ,m_top(0) // Used to cleanup in case XML par    
 52   ,m_current(0)                                   
 53   ,m_compressed_reader(0)                         
 54   ,m_depth(0)                                     
 55   ,m_abort(false)                                 
 56   {                                               
 57 #ifdef TOOLS_MEM                                  
 58     tools::mem::increment(s_class().c_str());     
 59 #endif                                            
 60   }                                               
 61                                                   
 62   virtual ~loader(){                              
 63     delete m_compressed_reader;                   
 64     clear();                                      
 65 #ifdef TOOLS_MEM                                  
 66     tools::mem::decrement(s_class().c_str());     
 67 #endif                                            
 68   }                                               
 69                                                   
 70 protected:                                        
 71   loader(const loader& a_from)                    
 72   :m_factory(a_from.m_factory)                    
 73   ,m_out(a_from.m_out)                            
 74   ,m_verbose(a_from.m_verbose)                    
 75   ,m_take_cntrl(a_from.m_take_cntrl)              
 76                                                   
 77   ,m_errors(0)                                    
 78   ,m_top(0) // Used to cleanup in case XML par    
 79   ,m_current(0)                                   
 80   ,m_compressed_reader(0)                         
 81   ,m_depth(0)                                     
 82   ,m_abort(false)                                 
 83   {                                               
 84 #ifdef TOOLS_MEM                                  
 85     tools::mem::increment(s_class().c_str());     
 86 #endif                                            
 87   }                                               
 88   loader& operator=(const loader& a_from){        
 89     if(&a_from==this) return *this;               
 90                                                   
 91     m_verbose = a_from.m_verbose;                 
 92     m_take_cntrl = a_from.m_take_cntrl;           
 93                                                   
 94     m_errors = 0;                                 
 95     m_top = 0;                                    
 96     m_current = 0;                                
 97     m_compressed_reader = 0;                      
 98     m_depth = 0;                                  
 99     m_abort = false;                              
100                                                   
101     return *this;                                 
102   }                                               
103                                                   
104 public:                                           
105   virtual bool visit_end_element(tools::xml::t    
106     a_keep = true;                                
107     return true;                                  
108   }                                               
109                                                   
110 public:                                           
111   void set_take_cntrl_chars(bool a_value) {m_t    
112                                                   
113   std::ostream& out() const {return m_out;}       
114   void set_compressed_reader(tools::file::read    
115     delete m_compressed_reader;                   
116     m_compressed_reader = aReader; //take owne    
117   }                                               
118                                                   
119   unsigned int errors() const {return m_errors    
120                                                   
121   void set_tags(const std::vector<std::string>    
122   void add_tag(const std::string& a_tag){m_tag    
123                                                   
124   bool load_file(const std::string& a_file,boo    
125     clear();                                      
126     if(!parse_file(a_file,                        
127                     (XML_StartElementHandler)s    
128                     (XML_EndElementHandler)end    
129                     this,a_compressed)) {         
130       clear();                                    
131       return false;                               
132     }                                             
133     if(m_current) m_current->set_file(a_file);    
134     return true;                                  
135   }                                               
136                                                   
137   bool load_string(const std::string& a_string    
138     clear();                                      
139     if(!parse_buffer(a_string.size(),a_string.    
140                     (XML_StartElementHandler)s    
141                     (XML_EndElementHandler)end    
142                     this)) {                      
143       clear();                                    
144       return false;                               
145     }                                             
146     return true;                                  
147   }                                               
148                                                   
149   bool load_buffer(size_t aSize,const char* aB    
150     clear();                                      
151     if(!parse_buffer(aSize,aBuffer,               
152                     (XML_StartElementHandler)s    
153                     (XML_EndElementHandler)end    
154                     this)) {                      
155       clear();                                    
156       return false;                               
157     }                                             
158     return true;                                  
159   }                                               
160                                                   
161   const tools::xml::tree* top_item() const {re    
162                                                   
163   tools::xml::tree* top_item(){return m_curren    
164                                                   
165   void empty(){m_top = 0;m_current = 0;}          
166                                                   
167   bool is_tag(const std::string& a_string) con    
168     size_t number = m_tags.size();                
169     for(size_t index=0;index<number;index++) {    
170       if(a_string==m_tags[index]) return true;    
171     }                                             
172     return false;                                 
173   }                                               
174                                                   
175 protected:                                        
176   void clear(){                                   
177     // In case of problem, deleting m_current     
178     delete m_top;                                 
179     m_top = 0;                                    
180     m_current = 0;                                
181   }                                               
182                                                   
183   bool parse_buffer(size_t aSize,const char* a    
184                     XML_StartElementHandler a_    
185                     void* a_tag){                 
186     m_errors = 0;                                 
187     if(!aSize) return true; //nothing to do.      
188     m_depth = 0;                                  
189     m_abort = false;                              
190                                                   
191 #ifdef TOOLS_MEM                                  
192     XML_Memory_Handling_Suite mem;                
193     mem.malloc_fcn = xml_malloc;                  
194     mem.realloc_fcn = xml_realloc;                
195     mem.free_fcn = xml_free;                      
196     XML_Parser _parser = XML_ParserCreate_MM(N    
197 #else                                             
198     XML_Parser _parser = XML_ParserCreate(NULL    
199 #endif                                            
200                                                   
201     XML_SetUserData(_parser,a_tag);               
202     XML_SetElementHandler(_parser,a_start,a_en    
203     XML_SetCharacterDataHandler(_parser,(XML_C    
204   //XML_SetProcessingInstructionHandler(_parse    
205     char* buf = (char*)aBuffer;                   
206     size_t l = aSize;                             
207     int done = 0;                                 
208     do {                                          
209       size_t len = tools::mn<size_t>(l,BUFSIZ)    
210       done = len < BUFSIZ ? 1 : 0;                
211       if(XML_Parse(_parser, buf, (int)len, don    
212         m_out << "parse_buffer :"                 
213             << " " << XML_ErrorString(XML_GetE    
214             << " at line " << (int)XML_GetCurr    
215             << " at byte index " << (int)XML_G    
216             << std::endl;                         
217        {XML_Index pos = XML_GetCurrentByteInde    
218         XML_Index pmn = tools::mx<XML_Index>(p    
219         XML_Index pmx = tools::mn<XML_Index>(p    
220         std::string c = " ";                      
221        {for(XML_Index p=pmn;p<=pmx;p++) {c[0]     
222         m_out << std::endl;}                      
223        {for(XML_Index p=pmn;p<pos;p++) m_out <    
224         m_out << "^" << std::endl;}}              
225         XML_ParserFree(_parser);                  
226         return false;                             
227       }                                           
228       if(m_abort) {                               
229         XML_ParserFree(_parser);                  
230         return false;                             
231       }                                           
232       buf += len;                                 
233       l -= len;                                   
234     } while (!done);                              
235     XML_ParserFree(_parser);                      
236     return true;                                  
237   }                                               
238                                                   
239   bool parse_file(const std::string& a_file,      
240                   XML_StartElementHandler a_st    
241                   void* a_tag,bool a_compresse    
242     if(m_verbose) {                               
243       m_out << "parse_file :"                     
244             << " parse file " << tools::sout(a    
245     }                                             
246     m_errors = 0;                                 
247                                                   
248     bool use_zlib = false;                        
249     if(a_compressed) {                            
250       if(m_verbose) {                             
251         m_out << "parse_file :"                   
252               << " uncompress requested for fi    
253               << tools::sout(a_file) << "."       
254               << std::endl;                       
255       }                                           
256       use_zlib = true;                            
257     } else {                                      
258       // may be compressed anyway :               
259       bool compressed;                            
260       if(!tools::file::is_gzip(a_file,compress    
261         m_out << "parse_file :"                   
262               << " tools::file::is_gzip() fail    
263               << std::endl;                       
264         return false;                             
265       }                                           
266       if(compressed) use_zlib = true;             
267     }                                             
268                                                   
269     tools::file::reader* freader = 0;             
270     bool delete_freader = false;                  
271     if(use_zlib) {                                
272       if(!m_compressed_reader) {                  
273         m_out << "parse_file :"                   
274               << " no compressed reader given.    
275               << std::endl;                       
276         return false;                             
277       }                                           
278       freader = m_compressed_reader;              
279     } else {                                      
280       freader = new tools::FILE_reader();         
281       delete_freader = true;                      
282     }                                             
283     if(!freader->open(a_file)) {                  
284       m_out << "parse_file :"                     
285             << " can't open file " << a_file <    
286       if(delete_freader) delete freader;          
287       return false;                               
288     }                                             
289                                                   
290     m_depth = 0;                                  
291     m_abort = false;                              
292                                                   
293 #ifdef TOOLS_MEM                                  
294     XML_Memory_Handling_Suite mem;                
295     mem.malloc_fcn = xml_malloc;                  
296     mem.realloc_fcn = xml_realloc;                
297     mem.free_fcn = xml_free;                      
298     XML_Parser _parser = XML_ParserCreate_MM(N    
299 #else                                             
300     XML_Parser _parser = XML_ParserCreate(NULL    
301 #endif                                            
302                                                   
303     XML_SetUserData(_parser,a_tag);               
304     XML_SetElementHandler(_parser,a_start,a_en    
305     XML_SetCharacterDataHandler(_parser,(XML_C    
306     //XML_SetProcessingInstructionHandler(_par    
307     //      processingInstructionHandler);        
308                                                   
309                                                   
310     //char buf[1024 * BUFSIZ];                    
311     char buf[BUFSIZ];                             
312     int done = 0;                                 
313     do {                                          
314       size_t len;                                 
315       if(!freader->read(buf,sizeof(buf),len))     
316         XML_ParserFree(_parser);                  
317         freader->close();                         
318         if(delete_freader) delete freader;        
319         return false;                             
320       }                                           
321       done = len < sizeof(buf) ? 1 : 0;           
322       if(XML_Parse(_parser, buf, (int)len, don    
323         m_out << "parse_file :"                   
324             << " in file " << tools::sout(a_fi    
325             << " " << XML_ErrorString(XML_GetE    
326             << " at line " << (int)XML_GetCurr    
327             << std::endl;                         
328         XML_ParserFree(_parser);                  
329         freader->close();                         
330         if(delete_freader) delete freader;        
331         return false;                             
332       }                                           
333       if(m_abort) {                               
334         XML_ParserFree(_parser);                  
335         freader->close();                         
336         if(delete_freader) delete freader;        
337         return false;                             
338       }                                           
339     } while (!done);                              
340     XML_ParserFree(_parser);                      
341     freader->close();                             
342     if(m_verbose) {                               
343       m_out << "parse_file :"                     
344           << " parse file " << tools::sout(a_f    
345     }                                             
346     if(delete_freader) delete freader;            
347     return true;                                  
348   }                                               
349                                                   
350 protected:                                        
351   static void character_data_handler(void* aUs    
352     loader* This = (loader*)aUserData;            
353     std::string _s;                               
354     _s.resize(aLength);                           
355     size_t count = 0;                             
356     char* p = (char*)a_string;                    
357     for (int i = 0; i < aLength; i++, p++) {      
358       if(This->m_take_cntrl || (!iscntrl(*p)))    
359         _s[count] = *p;                           
360         count++;                                  
361       }                                           
362     }                                             
363     if(count) {                                   
364       _s.resize(count);                           
365       This->m_value += _s;                        
366     }                                             
367   }                                               
368                                                   
369   static void start_element(void* aUserData,co    
370     loader* This = (loader*)aUserData;            
371     if(This->m_abort) return; //Do nothing.       
372                                                   
373     This->m_depth++;                              
374     This->m_value = "";                           
375                                                   
376     std::string name = a_name; //Can't be empt    
377     if(This->is_tag(name)) {                      
378                                                   
379       if(!This->m_current) {                      
380         if(This->m_depth==1) {                    
381           // Ok. Head.                            
382         } else {                                  
383           This->m_out << "start_element :"        
384               << " no tag with a depth of " <<    
385               << std::endl;                       
386           This->m_abort = true;                   
387           return;                                 
388         }                                         
389       } else {                                    
390         int delta = This->m_current->depth() -    
391         if(delta>=1) {                            
392           This->m_out << "start_element :"        
393               << " for element " << tools::sou    
394               << " tag with a delta depth of "    
395               << std::endl;                       
396           This->m_abort = true;                   
397           return;                                 
398         }                                         
399       }                                           
400                                                   
401       std::vector<tools::xml::tree::atb> atbs;    
402      {const XML_Char** a_atts = a_atbs;           
403       while((*a_atts)&&(*(a_atts+1))) {           
404         atbs.push_back(tools::xml::tree::atb(*    
405         a_atts+=2;                                
406       }}                                          
407                                                   
408       tools::xml::tree* parent = This->m_curre    
409       tools::xml::tree* _tree = This->m_factor    
410       if(!_tree) {                                
411         This->m_out << "start_element :"          
412             << " can't create a tree for tag "    
413             << std::endl;                         
414         This->m_abort = true;                     
415         return;                                   
416       }                                           
417                                                   
418       //out << "start_element :" << std::endl;    
419       //_tree->print_xml(*(This->m_printer),"d    
420                                                   
421       if(parent) parent->add_child(_tree);        
422                                                   
423 /*                                                
424       if(This->m_current && !This->m_current->    
425         This->m_out << "start_element :"          
426             << " warning : current tree withou    
427             << " Potential mem leak."             
428             << std::endl;                         
429       }                                           
430 */                                                
431                                                   
432       This->m_current = _tree;                    
433       _tree->set_depth(This->m_depth); // Inte    
434                                                   
435       if(!This->m_top) This->m_top = _tree;       
436                                                   
437     } else {                                      
438                                                   
439       if(!This->m_current) {                      
440                                                   
441         // Can't be in a non-tag without a tag    
442         This->m_out << "start_element :"          
443             << " for element " << tools::sout(    
444             << " non-tag without some parent t    
445             << std::endl;                         
446         This->m_abort = true;                     
447         return;                                   
448                                                   
449       } else {                                    
450                                                   
451         int delta =  This->m_depth - This->m_c    
452         if(delta>1) {                             
453                                                   
454           This->m_out << "start_element :"        
455               << " for element " << tools::sou    
456               << " grand child of a tag."         
457               << std::endl;                       
458           This->m_abort = true;                   
459           return;                                 
460                                                   
461         } else if(delta==1) { //ok                
462                                                   
463           This->m_atbs.clear();                   
464          {const XML_Char** a_atts = a_atbs;       
465           while((*a_atts)&&(*(a_atts+1))) {       
466             This->m_atbs.push_back(tools::xml:    
467             a_atts+=2;                            
468           }}                                      
469                                                   
470         } else {                                  
471                                                   
472           This->m_out << "start_element :"        
473               << " for element " << tools::sou    
474               << " non-tag with a delta depth     
475               << std::endl;                       
476           This->m_abort = true;                   
477           return;                                 
478                                                   
479         }                                         
480       }                                           
481                                                   
482     }                                             
483   }                                               
484                                                   
485                                                   
486   static void end_element(void* aUserData,cons    
487     loader* This = (loader*)aUserData;            
488     if(This->m_abort) return; //Do nothing.       
489                                                   
490     if(This->m_current) {                         
491                                                   
492       tools::xml::tree* tr = This->m_current;     
493       int delta = This->m_depth - tr->depth();    
494       if(delta==0) { //Back to a tag :            
495                                                   
496         tools::xml::tree* parent = tr->parent(    
497                                                   
498         bool keep = false;                        
499         bool cont = This->visit_end_element(*t    
500         if(keep) {                                
501           if(parent) {                            
502 /*                                                
503             if(!This->m_current->parent()) {      
504               This->m_out << "end_element :"      
505                   << " warning : current tree     
506                   << " Potential mem leak."       
507                   << std::endl;                   
508             }                                     
509 */                                                
510             This->m_current = parent;             
511           }                                       
512         } else {                                  
513           //FIXME : the top could be recreated    
514           if(This->m_top==tr) This->m_top = 0;    
515                                                   
516           if(parent) {                            
517             parent->remove_child(tr); //delete    
518           } else {                                
519             delete tr;                            
520           }                                       
521                                                   
522 /*                                                
523           if(!This->m_current->parent()) {        
524             This->m_out << "end_element :"        
525                    << " warning : current tree    
526                    << " Potential mem leak."      
527                    << std::endl;                  
528           }                                       
529 */                                                
530                                                   
531           This->m_current = parent; //parent c    
532         }                                         
533                                                   
534         if(!cont) This->m_abort = true;           
535                                                   
536       } else if(delta==1) { //Back to a child     
537                                                   
538         //FIXME : correct m_value ? (Can we pi    
539         tr->add_element(std::string(a_name),Th    
540         //This->m_value = "";                     
541                                                   
542       } else {                                    
543                                                   
544         This->m_out << "end_element :"            
545             << " problem for element " << tool    
546             << " : delta depth of " << delta      
547             << std::endl;                         
548         This->m_abort = true;                     
549                                                   
550       }                                           
551                                                   
552     }                                             
553                                                   
554                                                   
555     This->m_depth--;                              
556   }                                               
557                                                   
558 protected:                                        
559   tools::xml::factory& m_factory;                 
560   std::ostream& m_out;                            
561 protected:                                        
562   bool m_verbose;                                 
563   bool m_take_cntrl;                              
564   unsigned int m_errors;                          
565   std::vector<std::string> m_tags;                
566   tools::xml::tree* m_top;                        
567   tools::xml::tree* m_current;                    
568   //std::vector<tools::xml::tree::atb> m_atbs;    
569   std::vector< std::pair<std::string,std::stri    
570   std::string m_value;                            
571   tools::file::reader* m_compressed_reader;       
572   unsigned int m_depth;                           
573   bool m_abort;                                   
574 };                                                
575                                                   
576 }}                                                
577                                                   
578 #endif