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 11.1)


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