xmlparser.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. Copyright (C) 2001-2006, William Joseph.
  3. All Rights Reserved.
  4. This file is part of GtkRadiant.
  5. GtkRadiant is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. GtkRadiant is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GtkRadiant; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #if !defined(INCLUDED_XML_XMLPARSER_H)
  18. #define INCLUDED_XML_XMLPARSER_H
  19. #include <cstdio>
  20. #include <string.h>
  21. #include "ixml.h"
  22. #include "libxml/parser.h"
  23. #include "convert.h"
  24. class TextInputStream;
  25. class SAXElement : public XMLElement
  26. {
  27. public:
  28. SAXElement(const char* name, const char** atts)
  29. : m_name(name), m_atts(atts)
  30. {
  31. }
  32. const char* name() const
  33. {
  34. return m_name;
  35. }
  36. const char* attribute(const char* name) const
  37. {
  38. if(m_atts != 0)
  39. {
  40. for(const char** att = m_atts; *att != 0; att+=2)
  41. {
  42. if(strcmp(*att, name) == 0)
  43. {
  44. return *(++att);
  45. }
  46. }
  47. }
  48. return "";
  49. }
  50. void forEachAttribute(XMLAttrVisitor& visitor) const
  51. {
  52. if(m_atts != 0)
  53. {
  54. for(const char** att = m_atts; *att != 0; att+=2)
  55. {
  56. visitor.visit(*att, *(att+1));
  57. }
  58. }
  59. }
  60. private:
  61. const char* m_name;
  62. const char** m_atts;
  63. };
  64. #include <stdarg.h>
  65. class FormattedVA
  66. {
  67. public:
  68. const char* m_format;
  69. va_list& m_arguments;
  70. FormattedVA(const char* format, va_list& m_arguments)
  71. : m_format(format), m_arguments(m_arguments)
  72. {
  73. }
  74. };
  75. class Formatted
  76. {
  77. public:
  78. const char* m_format;
  79. va_list m_arguments;
  80. Formatted(const char* format, ...)
  81. : m_format(format)
  82. {
  83. va_start(m_arguments, format);
  84. }
  85. ~Formatted()
  86. {
  87. va_end(m_arguments);
  88. }
  89. };
  90. #ifdef WIN32
  91. #if _MSC_VER < 1400
  92. #define vsnprintf std::vsnprintf
  93. #endif
  94. #endif
  95. template<typename TextOutputStreamType>
  96. inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const FormattedVA& formatted)
  97. {
  98. char buffer[1024];
  99. ostream.write(buffer, vsnprintf(buffer, 1023, formatted.m_format, formatted.m_arguments));
  100. return ostream;
  101. }
  102. template<typename TextOutputStreamType>
  103. inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const Formatted& formatted)
  104. {
  105. char buffer[1024];
  106. ostream.write(buffer, vsnprintf(buffer, 1023, formatted.m_format, formatted.m_arguments));
  107. return ostream;
  108. }
  109. class XMLSAXImporter
  110. {
  111. XMLImporter& m_importer;
  112. xmlSAXHandler m_sax;
  113. static void startElement(void *user_data, const xmlChar *name, const xmlChar **atts)
  114. {
  115. SAXElement element(reinterpret_cast<const char*>(name), reinterpret_cast<const char**>(atts));
  116. reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer.pushElement(element);
  117. }
  118. static void endElement(void *user_data, const xmlChar *name)
  119. {
  120. reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer.popElement(reinterpret_cast<const char*>(name));
  121. }
  122. static void characters(void *user_data, const xmlChar *ch, int len)
  123. {
  124. reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer
  125. << ConvertUTF8ToLocale(StringRange(reinterpret_cast<const char*>(ch), reinterpret_cast<const char*>(ch + len)));
  126. }
  127. static void warning(void *user_data, const char *msg, ...)
  128. {
  129. va_list args;
  130. va_start(args, msg);
  131. globalErrorStream() << "XML WARNING: " << FormattedVA(msg, args);
  132. va_end(args);
  133. }
  134. static void error(void *user_data, const char *msg, ...)
  135. {
  136. va_list args;
  137. va_start(args, msg);
  138. globalErrorStream() << "XML ERROR: " << FormattedVA(msg, args);
  139. va_end(args);
  140. }
  141. public:
  142. XMLSAXImporter(XMLImporter& importer) : m_importer(importer)
  143. {
  144. m_sax.internalSubset = 0;
  145. m_sax.isStandalone = 0;
  146. m_sax.hasInternalSubset = 0;
  147. m_sax.hasExternalSubset = 0;
  148. m_sax.resolveEntity = 0;
  149. m_sax.getEntity = 0;
  150. m_sax.entityDecl = 0;
  151. m_sax.notationDecl = 0;
  152. m_sax.attributeDecl = 0;
  153. m_sax.elementDecl = 0;
  154. m_sax.unparsedEntityDecl = 0;
  155. m_sax.setDocumentLocator = 0;
  156. m_sax.startDocument = 0;
  157. m_sax.endDocument = 0;
  158. m_sax.startElement = startElement;
  159. m_sax.endElement = endElement;
  160. m_sax.reference = 0;
  161. m_sax.characters = characters;
  162. m_sax.ignorableWhitespace = 0;
  163. m_sax.processingInstruction = 0;
  164. m_sax.comment = 0;
  165. m_sax.warning = warning;
  166. m_sax.error = error;
  167. m_sax.fatalError = 0;
  168. m_sax.getParameterEntity = 0;
  169. m_sax.cdataBlock = 0;
  170. m_sax.externalSubset = 0;
  171. m_sax.initialized = 1;
  172. }
  173. xmlSAXHandler* callbacks()
  174. {
  175. return &m_sax;
  176. }
  177. void* context()
  178. {
  179. return this;
  180. }
  181. };
  182. class XMLStreamParser : public XMLExporter
  183. {
  184. static const int BUFSIZE = 1024;
  185. public:
  186. XMLStreamParser(TextInputStream& istream)
  187. : m_istream(istream)
  188. {
  189. }
  190. virtual void exportXML(XMLImporter& importer)
  191. {
  192. bool wellFormed = false;
  193. char chars[BUFSIZE];
  194. std::size_t res = m_istream.read(chars, 4);
  195. if (res > 0)
  196. {
  197. XMLSAXImporter sax(importer);
  198. xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(sax.callbacks(), sax.context(), chars, static_cast<int>(res), 0);
  199. ctxt->replaceEntities = 1;
  200. while ((res = m_istream.read(chars, BUFSIZE)) > 0)
  201. {
  202. xmlParseChunk(ctxt, chars, static_cast<int>(res), 0);
  203. }
  204. xmlParseChunk(ctxt, chars, 0, 1);
  205. wellFormed = (ctxt->wellFormed == 1);
  206. xmlFreeParserCtxt(ctxt);
  207. }
  208. //return wellFormed;
  209. }
  210. private:
  211. TextInputStream& m_istream;
  212. };
  213. #endif