/opencollada/GeneratedSaxParser/src/GeneratedSaxParserLibxmlSaxParser.cpp

https://github.com/AsherBond/MondocosmOS · C++ · 242 lines · 184 code · 44 blank · 14 comment · 19 complexity · 49d0d0b3e7439e03539bcce9690fa329 MD5 · raw file

  1. /*
  2. Copyright (c) 2008-2009 NetAllied Systems GmbH
  3. This file is part of GeneratedSaxParser.
  4. Licensed under the MIT Open Source License,
  5. for details please see LICENSE file or the website
  6. http://www.opensource.org/licenses/mit-license.php
  7. */
  8. #include <cstdarg>
  9. #include <cstring>
  10. #include "GeneratedSaxParserLibxmlSaxParser.h"
  11. #include "GeneratedSaxParserParser.h"
  12. #include "GeneratedSaxParserIErrorHandler.h"
  13. #include <libxml/parserInternals.h> // for xmlCreateFileParserCtxt
  14. namespace GeneratedSaxParser
  15. {
  16. xmlSAXHandler LibxmlSaxParser::SAXHANDLER =
  17. {
  18. 0, //internalSubsetSAXFunc internalSubset;
  19. 0, //isStandaloneSAXFunc isStandalone;
  20. 0, //hasInternalSubsetSAXFunc hasInternalSubset;
  21. 0, //hasExternalSubsetSAXFunc hasExternalSubset;
  22. 0, //resolveEntitySAXFunc resolveEntity;
  23. 0, //getEntitySAXFunc getEntity;
  24. 0, //entityDeclSAXFunc entityDecl;
  25. 0, //notationDeclSAXFunc notationDecl;
  26. 0, //attributeDeclSAXFunc attributeDecl;
  27. 0, //elementDeclSAXFunc elementDecl;
  28. 0, //unparsedEntityDeclSAXFunc unparsedEntityDecl;
  29. 0, //setDocumentLocatorSAXFunc setDocumentLocator;
  30. 0, //startDocumentSAXFunc startDocument;
  31. 0, //endDocumentSAXFunc endDocument;
  32. &LibxmlSaxParser::startElement, //startElementSAXFunc startElement;
  33. &LibxmlSaxParser::endElement, //endElementSAXFunc endElement;
  34. 0, //referenceSAXFunc reference;
  35. &LibxmlSaxParser::characters, //charactersSAXFunc characters;
  36. 0, //ignorableWhitespaceSAXFunc ignorableWhitespace;
  37. 0, //processingInstructionSAXFunc processingInstruction;
  38. 0, //commentSAXFunc comment;
  39. 0, //warningSAXFunc warning;
  40. &LibxmlSaxParser::errorFunction, //errorSAXFunc error;
  41. &LibxmlSaxParser::errorFunction //fatalErrorSAXFunc fatalError;
  42. };
  43. //--------------------------------------------------------------------
  44. LibxmlSaxParser::LibxmlSaxParser(Parser* parser)
  45. : SaxParser(parser),
  46. mParserContext(0)
  47. {
  48. }
  49. //--------------------------------------------------------------------
  50. LibxmlSaxParser::~LibxmlSaxParser()
  51. {
  52. xmlCleanupParser();
  53. }
  54. bool LibxmlSaxParser::parseFile( const char* fileName )
  55. {
  56. mParserContext = xmlCreateFileParserCtxt(fileName);
  57. if ( !mParserContext )
  58. {
  59. ParserError error(ParserError::SEVERITY_CRITICAL,
  60. ParserError::ERROR_COULD_NOT_OPEN_FILE,
  61. 0,
  62. 0,
  63. 0,
  64. 0,
  65. fileName);
  66. IErrorHandler* errorHandler = getParser()->getErrorHandler();
  67. if ( errorHandler )
  68. {
  69. errorHandler->handleError(error);
  70. }
  71. return false;
  72. }
  73. // We let libxml replace the entities
  74. mParserContext->replaceEntities = 1;
  75. if (mParserContext->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
  76. {
  77. xmlFree(mParserContext->sax);
  78. }
  79. mParserContext->sax = &SAXHANDLER;
  80. mParserContext->userData = (void*)this;
  81. initializeParserContext();
  82. xmlParseDocument(mParserContext);
  83. mParserContext->sax = 0;
  84. if ( mParserContext->myDoc )
  85. {
  86. xmlFreeDoc(mParserContext->myDoc);
  87. mParserContext->myDoc = 0;
  88. }
  89. xmlFreeParserCtxt(mParserContext);
  90. mParserContext = 0;
  91. return true;
  92. }
  93. bool LibxmlSaxParser::parseBuffer( const char* uri, const char* buffer, int length )
  94. {
  95. mParserContext = xmlCreateMemoryParserCtxt( buffer, length );
  96. if ( !mParserContext )
  97. {
  98. ParserError error(ParserError::SEVERITY_CRITICAL,
  99. ParserError::ERROR_COULD_NOT_OPEN_FILE,
  100. 0,
  101. 0,
  102. 0,
  103. 0,
  104. uri);
  105. IErrorHandler* errorHandler = getParser()->getErrorHandler();
  106. if ( errorHandler )
  107. {
  108. errorHandler->handleError(error);
  109. }
  110. return false;
  111. }
  112. // We let libxml replace the entities
  113. mParserContext->replaceEntities = 1;
  114. if (mParserContext->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
  115. {
  116. xmlFree(mParserContext->sax);
  117. }
  118. mParserContext->sax = &SAXHANDLER;
  119. mParserContext->userData = (void*)this;
  120. initializeParserContext();
  121. xmlParseDocument(mParserContext);
  122. mParserContext->sax = 0;
  123. if ( mParserContext->myDoc )
  124. {
  125. xmlFreeDoc(mParserContext->myDoc);
  126. mParserContext->myDoc = 0;
  127. }
  128. xmlFreeParserCtxt(mParserContext);
  129. mParserContext = 0;
  130. return true;
  131. }
  132. void LibxmlSaxParser::initializeParserContext()
  133. {
  134. mParserContext->linenumbers = true;
  135. mParserContext->validate = false;
  136. }
  137. void LibxmlSaxParser::startElement( void* user_data, const ::xmlChar* name, const ::xmlChar** attrs )
  138. {
  139. LibxmlSaxParser* thisObject = (LibxmlSaxParser*)user_data;
  140. Parser* parser = thisObject->getParser();
  141. if ( !parser->elementBegin((const ParserChar*)name, (const ParserChar**)attrs) )
  142. thisObject->abortParsing();
  143. }
  144. void LibxmlSaxParser::endElement( void* user_data, const ::xmlChar* name)
  145. {
  146. LibxmlSaxParser* thisObject = (LibxmlSaxParser*)user_data;
  147. Parser* parser = thisObject->getParser();
  148. if ( !parser->elementEnd((const ParserChar*)name) )
  149. thisObject->abortParsing();
  150. }
  151. void LibxmlSaxParser::characters( void* user_data, const ::xmlChar* name, int length )
  152. {
  153. LibxmlSaxParser* thisObject = (LibxmlSaxParser*)user_data;
  154. Parser* parser = thisObject->getParser();
  155. if ( !parser->textData((const ParserChar*)name, (size_t)length) )
  156. thisObject->abortParsing();
  157. }
  158. void LibxmlSaxParser::abortParsing()
  159. {
  160. xmlStopParser(mParserContext);
  161. }
  162. size_t LibxmlSaxParser::getLineNumer() const
  163. {
  164. return (size_t)xmlSAX2GetLineNumber(mParserContext);
  165. }
  166. size_t LibxmlSaxParser::getColumnNumer() const
  167. {
  168. return (size_t)xmlSAX2GetColumnNumber(mParserContext);
  169. }
  170. void LibxmlSaxParser::errorFunction( void *userData, const char *msg, ... )
  171. {
  172. // if msg is just one string, get it. Otherwise ignore it.
  173. char* message = 0;
  174. va_list argList;
  175. if (strcmp(msg, "%s") == 0)
  176. {
  177. va_start(argList, msg);
  178. message = va_arg(argList, char*);
  179. }
  180. LibxmlSaxParser* thisObject = (LibxmlSaxParser*)(userData);
  181. ParserError error(ParserError::SEVERITY_CRITICAL,
  182. ParserError::ERROR_XML_PARSER_ERROR,
  183. 0,
  184. 0,
  185. 0,
  186. 0,
  187. message != 0 ? message : msg);
  188. if (message != 0)
  189. {
  190. va_end(argList);
  191. }
  192. IErrorHandler* errHandler = thisObject->getParser()->getErrorHandler();
  193. if ( errHandler )
  194. errHandler->handleError(error);
  195. }
  196. } // namespace GeneratedSaxParser