Version: 8.3.0
xmlParserBase.cxx
Go to the documentation of this file.
1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 
20 #include "xmlParserBase.hxx"
21 #include "Exception.hxx"
22 
23 #include <stdexcept>
24 #include <iostream>
25 #include <cstdarg>
26 #include <cstdio>
27 #include <cassert>
28 
29 //#define _DEVDEBUG_
30 #include "YacsTrace.hxx"
31 
32 extern "C"
33 {
34 #include <libxml/parserInternals.h> // for xmlCreateFileParserCtxt
35 }
36 _xmlParserCtxt* xmlParserBase::_xmlParser;
37 void xmlParserBase::XML_SetUserData(_xmlParserCtxt* ctxt,
38  xmlParserBase* parser)
39 {
40  ctxt->userData = parser;
41 }
42 
43 // --- generic part -----------------------------------------------------------
44 
45 using namespace std;
46 using YACS::Exception;
47 
48 std::stack<xmlParserBase*> xmlParserBase::_stackParser;
49 std::list<xmlParserBase*> xmlParserBase::_garbage;
50 
55 {
56  //DEBTRACE("xmlParserBase::start_document");
57  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
58 }
59 
63 void XMLCALL xmlParserBase::end_document (void* userData)
64 {
65  //DEBTRACE("xmlParserBase::end_document");
66  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
67 }
68 
73  const xmlChar* name,
74  const xmlChar** p)
75 {
76  //DEBTRACE("xmlParserBase::start_element " << name);
77  cleanGarbage();
78  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
79  const XML_Char *aName = tochar(name);
80  currentParser->incrCount(aName);
81  currentParser->onStart(aName, p);
82 }
83 
84 
88 void XMLCALL xmlParserBase::end_element (void* userData,
89  const xmlChar* name)
90 {
91  //DEBTRACE("xmlParserBase::end_element");
92  const XML_Char *aName = tochar(name);
93  xmlParserBase *childParser = static_cast<xmlParserBase *> (userData);
94  _garbage.push_back(_stackParser.top());
95  DEBTRACE("xmlParserBase::end_element " << _garbage.size());
96  _stackParser.pop();
97  XML_SetUserData(_xmlParser, _stackParser.top());
98  childParser->onEnd(aName);
99  childParser->end();
100  }
101 
102 
108 void XMLCALL xmlParserBase::characters (void* userData,
109  const xmlChar* ch,
110  int len)
111 {
112  //DEBTRACE("xmlParserBase::characters " << len);
113  xmlParserBase *currentParser = (xmlParserBase *) (userData);
114  string data((char*)ch,len);
115  currentParser->charData(data);
116 }
117 
118 
122 void XMLCALL xmlParserBase::comment (void* userData,
123  const xmlChar* value)
124 {
125  //DEBTRACE("xmlParserBase::comment");
126  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
127 }
128 
129 
133 void XMLCALL xmlParserBase::warning (void* userData,
134  const char* fmt, ...)
135 {
136  DEBTRACE("xmlParserBase::warning");
137  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
138  va_list args;
139  va_start(args, fmt);
140  string format = "%s";
141  if (format == fmt)
142  {
143  char* parv;
144  parv = va_arg(args, char*);
145  cerr << parv ;
146  }
147  else cerr << __FILE__ << " [" << __LINE__ << "] : "
148  << "error format not taken into account: " << fmt << endl;
149  va_end(args);
150 }
151 
152 
156 void XMLCALL xmlParserBase::error (void* userData,
157  const char* fmt, ...)
158 {
159  DEBTRACE("xmlParserBase::error");
160  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
161  va_list args;
162  va_start(args, fmt);
163  string format = "%s";
164  if (format == fmt)
165  {
166  char* parv;
167  parv = va_arg(args, char*);
168  cerr << parv ;
169  xmlParserBase *currentParser = (xmlParserBase *) userData;
170  //cerr << currentParser->element << endl;
171  }
172  else cerr << __FILE__ << " [" << __LINE__ << "] : "
173  << "error format not taken into account: " << fmt << endl;
174  va_end(args);
175 }
176 
177 
181 void XMLCALL xmlParserBase::fatal_error (void* userData,
182  const char* fmt, ...)
183 {
184  DEBTRACE("xmlParserBase::fatal_error");
185  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
186  va_list args;
187  va_start(args, fmt);
188  string format = "%s";
189  if (format == fmt)
190  {
191  char* parv;
192  parv = va_arg(args, char*);
193  cerr << parv ;
194  }
195  else cerr << __FILE__ << " [" << __LINE__ << "] : "
196  << "error format not taken into account: " << fmt << endl;
197  va_end(args);
198 }
199 
204 void XMLCALL xmlParserBase::cdata_block (void* userData,
205  const xmlChar* value,
206  int len)
207 {
208  //DEBTRACE("xmlParserBase::cdata_block");
209  xmlParserBase *currentParser = static_cast<xmlParserBase *> (userData);
210  string data((char*)value,len);
211  currentParser->charData(data);
212 }
213 
215 {
216  while (!_garbage.empty())
217  {
218  delete (_garbage.front());
219  _garbage.pop_front();
220  }
221 }
222 
227 void xmlParserBase::getAttributes(const xmlChar** p)
228 {
229  if (p) while (*p)
230  {
231  string attributeName = (char*)*p;
232  //cerr << "attribute name " << attributeName << endl;
233  p++;
234  string attributeValue = (char*)*p;
235  //cerr << "attribute value " << attributeValue << endl;
236  p++;
237  _mapAttrib[attributeName] = attributeValue;
238  }
239 }
240 
245 void xmlParserBase::setAttribute(std::string key, std::string value)
246 {
247  _mapAttrib[key] = value;
248 }
249 
254 std::string xmlParserBase::getAttribute(std::string key)
255 {
256  if (_mapAttrib.find(key) == _mapAttrib.end())
257  {
258  string what = "Attribute does not exist: " + key;
259  throw Exception(what);
260  }
261  return _mapAttrib[key];
262 }
263 
267 void xmlParserBase::addData(std::string value)
268 {
269  // DEBTRACE("xmlParserBase::addData()");
270  _data += value;
271 }
272 
277 void xmlParserBase::init (const xmlChar** p, xmlParserBase* father)
278 {
279  _father = father;
280 }
281 
285 void xmlParserBase::onStart (const XML_Char* elem, const xmlChar** p)
286 {
287 }
288 
292 void xmlParserBase::onEnd (const XML_Char* name)
293 {
294 }
295 
299 void xmlParserBase::charData (std::string data)
300 {
301 }
302 
308 {
309  if(counts.find(elem)==counts.end())
310  counts[elem]=1;
311  else
312  counts[elem]=counts[elem]+1;
313 }
314 
319 {
320 }
321 
325 void xmlParserBase::stopParse(std::string what)
326 {
327  xmlStopParser(_xmlParser);
328 }
329 
330 // ----------------------------------------------------------------------------
331 
336 xmlReader::xmlReader(xmlParserBase* parser): _rootParser(parser)
337 {
338 }
339 
344 void xmlReader::parse(std::string xmlFile)
345 {
346  _rootParser->init(0);
348 
349  xmlSAXHandler baseHandler =
350  {
351  0, // internal_subset,
352  0, // isStandalone
353  0, // hasInternalSubset
354  0, // hasExternalSubset
355  0, // resolveEntity
356  0, // getEntity
357  0, // entityDecl
358  0, // notationDecl
359  0, // attributeDecl
360  0, // elementDecl
361  0, // unparsedEntityDecl
362  0, // setDocumentLocator
363  xmlParserBase::start_document, // startDocument
364  xmlParserBase::end_document, // endDocument
365  xmlParserBase::start_element, // startElement
366  xmlParserBase::end_element, // endElement
367  0, // reference
368  xmlParserBase::characters, // characters
369  0, // ignorableWhitespace
370  0, // processingInstruction
371  xmlParserBase::comment, // comment
372  xmlParserBase::warning, // warning
373  xmlParserBase::error, // error
374  xmlParserBase::fatal_error, // fatalError
375  0, // getParameterEntity
376  xmlParserBase::cdata_block, // cdataBlock
377  0 // externalSubset
378  };
379 
380  // --- sequence from libxml++, to have a libxml context
381 
382  _xmlParserCtxt* saxContext;
383  saxContext = xmlCreateFileParserCtxt(xmlFile.c_str());
384  if (!saxContext)
385  {
387  string what = "problem while trying to open the file for parsing " + xmlFile;
388  throw Exception(what);
389  }
390  xmlSAXHandlerPtr old_sax = saxContext->sax;
391  saxContext->sax = &baseHandler;
393  saxContext->userData = _rootParser;
394 
395  xmlParseDocument(saxContext);
397  if ( saxContext->myDoc != NULL ) {
398  xmlFreeDoc( saxContext->myDoc );
399  saxContext->myDoc = NULL;
400  }
401  if ( saxContext != NULL ) {
402  saxContext->sax = old_sax;
403  xmlFreeParserCtxt( saxContext );
404  }
405  DEBTRACE("xmlParserBase::end of parse, garbage size = " << _rootParser->getGarbageSize());
406 }
407 
408 // ----------------------------------------------------------------------------