00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(INCLUDED_XML_XMLPARSER_H)
00023 #define INCLUDED_XML_XMLPARSER_H
00024
00025 #include <cstdio>
00026 #include <string.h>
00027 #include "ixml.h"
00028 #include <libxml/parser.h>
00029 #include "convert.h"
00030
00031 class TextInputStream;
00032
00033 class SAXElement : public XMLElement {
00034 public:
00035 SAXElement(const std::string& name, const char** atts)
00036 : m_name(name), m_atts(atts) {
00037 }
00038 const std::string name() const {
00039 return m_name;
00040 }
00041 const std::string attribute(const std::string& name) const {
00042 if (m_atts != 0) {
00043 for (const char** att = m_atts; *att != 0; att += 2) {
00044 if (strcmp(*att, name.c_str()) == 0) {
00045 return *(++att);
00046 }
00047 }
00048 }
00049 return "";
00050 }
00051 void forEachAttribute(XMLAttrVisitor& visitor) const {
00052 if (m_atts != 0) {
00053 for (const char** att = m_atts; *att != 0; att += 2) {
00054 visitor.visit(*att, *(att + 1));
00055 }
00056 }
00057 }
00058 private:
00059 const std::string m_name;
00060 const char** m_atts;
00061 };
00062
00063 #include <stdarg.h>
00064
00065 class FormattedVA {
00066 public:
00067 const char* m_format;
00068 va_list& m_arguments;
00069 FormattedVA(const char* format, va_list& m_arguments)
00070 : m_format(format), m_arguments(m_arguments) {
00071 }
00072 };
00073
00074 class Formatted {
00075 public:
00076 const char* m_format;
00077 va_list m_arguments;
00078 Formatted(const char* format, ...)
00079 : m_format(format) {
00080 va_start(m_arguments, format);
00081 }
00082 ~Formatted() {
00083 va_end(m_arguments);
00084 }
00085 };
00086
00087 template<typename TextOutputStreamType>
00088 inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const FormattedVA& formatted) {
00089 char buffer[1024];
00090 ostream.write(buffer, vsnprintf(buffer, 1023, formatted.m_format, formatted.m_arguments));
00091 return ostream;
00092 }
00093
00094 template<typename TextOutputStreamType>
00095 inline TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const Formatted& formatted) {
00096 char buffer[1024];
00097 ostream.write(buffer, vsnprintf(buffer, 1023, formatted.m_format, formatted.m_arguments));
00098 return ostream;
00099 }
00100
00101 class XMLSAXImporter {
00102 XMLImporter& m_importer;
00103 xmlSAXHandler m_sax;
00104
00105 static void startElement(void *user_data, const xmlChar *name, const xmlChar **atts) {
00106 SAXElement element(reinterpret_cast<const char*>(name), reinterpret_cast<const char**>(atts));
00107 reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer.pushElement(element);
00108 }
00109 static void endElement(void *user_data, const xmlChar *name) {
00110 reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer.popElement(reinterpret_cast<const char*>(name));
00111 }
00112 static void characters(void *user_data, const xmlChar *ch, int len) {
00113 reinterpret_cast<XMLSAXImporter*>(user_data)->m_importer
00114 << ConvertUTF8ToLocale(StringRange(reinterpret_cast<const char*>(ch), reinterpret_cast<const char*>(ch + len)));
00115 }
00116
00117 static void warning(void *user_data, const char *msg, ...) {
00118 va_list args;
00119 va_start(args, msg);
00120 globalWarningStream() << "XML WARNING: " << FormattedVA(msg, args);
00121 va_end(args);
00122 }
00123 static void error(void *user_data, const char *msg, ...) {
00124 va_list args;
00125 va_start(args, msg);
00126 globalErrorStream() << "XML ERROR: " << FormattedVA(msg, args);
00127 va_end(args);
00128 }
00129
00130 public:
00131 XMLSAXImporter(XMLImporter& importer) : m_importer(importer) {
00132 m_sax.internalSubset = 0;
00133 m_sax.isStandalone = 0;
00134 m_sax.hasInternalSubset = 0;
00135 m_sax.hasExternalSubset = 0;
00136 m_sax.resolveEntity = 0;
00137 m_sax.getEntity = 0;
00138 m_sax.entityDecl = 0;
00139 m_sax.notationDecl = 0;
00140 m_sax.attributeDecl = 0;
00141 m_sax.elementDecl = 0;
00142 m_sax.unparsedEntityDecl = 0;
00143 m_sax.setDocumentLocator = 0;
00144 m_sax.startDocument = 0;
00145 m_sax.endDocument = 0;
00146 m_sax.startElement = startElement;
00147 m_sax.endElement = endElement;
00148 m_sax.reference = 0;
00149 m_sax.characters = characters;
00150 m_sax.ignorableWhitespace = 0;
00151 m_sax.processingInstruction = 0;
00152 m_sax.comment = 0;
00153 m_sax.warning = warning;
00154 m_sax.error = error;
00155 m_sax.fatalError = 0;
00156 m_sax.getParameterEntity = 0;
00157 m_sax.cdataBlock = 0;
00158 m_sax.externalSubset = 0;
00159 m_sax.initialized = 1;
00160 }
00161
00162 xmlSAXHandler* callbacks() {
00163 return &m_sax;
00164 }
00165 void* context() {
00166 return this;
00167 }
00168 };
00169
00170 class XMLStreamParser : public XMLExporter {
00171 enum unnamed0 { BUFSIZE = 1024 };
00172 public:
00173 XMLStreamParser(TextInputStream& istream)
00174 : m_istream(istream) {
00175 }
00176 virtual void exportXML(XMLImporter& importer) {
00177 bool wellFormed = false;
00178
00179 char chars[BUFSIZE];
00180 std::size_t res = m_istream.read(chars, 4);
00181 if (res > 0) {
00182 XMLSAXImporter sax(importer);
00183
00184 xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(sax.callbacks(), sax.context(), chars, static_cast<int>(res), 0);
00185 ctxt->replaceEntities = 1;
00186
00187 while ((res = m_istream.read(chars, BUFSIZE)) > 0) {
00188 xmlParseChunk(ctxt, chars, static_cast<int>(res), 0);
00189 }
00190 xmlParseChunk(ctxt, chars, 0, 1);
00191
00192 wellFormed = (ctxt->wellFormed == 1);
00193
00194 xmlFreeParserCtxt(ctxt);
00195 }
00196
00197
00198 }
00199 private:
00200 TextInputStream& m_istream;
00201 };
00202
00203
00204
00205 #endif