/*************************************************************************** sax.cpp - description ------------------- begin : Sun Mar 17 2002 copyright : (C) 2002 by Vladimir Shutoff email : vovan@shutoff.ru ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "sax.h" class SAXParserPrivate { public: SAXParserPrivate(SAXParser *parser); ~SAXParserPrivate(); bool parse(const char *data, unsigned size, bool bChunk); xmlSAXHandler m_handler; xmlParserCtxtPtr m_context; SAXParser *m_parser; static void p_element_start(void *data, const unsigned char *el, const unsigned char **attr); static void p_element_end(void *data, const unsigned char *el); static void p_char_data(void *data, const unsigned char *str, int len); }; SAXParserPrivate::SAXParserPrivate(SAXParser *parser) { m_parser = parser; memset(&m_handler, 0, sizeof(m_handler)); m_handler.startElement = p_element_start; m_handler.endElement = p_element_end; m_handler.characters = p_char_data; m_context = xmlCreatePushParserCtxt(&m_handler, m_parser, "", 0, ""); } SAXParserPrivate::~SAXParserPrivate() { xmlFreeParserCtxt(m_context); } bool SAXParserPrivate::parse(const char *data, unsigned size, bool bChunk) { if (size == 0) return true; return (xmlParseChunk(m_context, data, size, !bChunk) == 0); } void SAXParserPrivate::p_element_start(void *data, const xmlChar *el, const xmlChar **attr) { #if LIBXML_VERSION > 20604 if (!strcmp((char*)el, "Z")) return; #endif ((SAXParser*)data)->element_start((char*)el, (const char**)attr); } void SAXParserPrivate::p_element_end(void *data, const xmlChar *el) { #if LIBXML_VERSION > 20604 if (!strcmp((char*)el, "Z")) return; #endif ((SAXParser*)data)->element_end((char*)el); } void SAXParserPrivate::p_char_data(void *data, const xmlChar *str, int len) { ((SAXParser*)data)->char_data((char*)str, len); } SAXParser::SAXParser() { p = NULL; } SAXParser::~SAXParser() { reset(); } void SAXParser::reset() { if (p){ delete p; p = NULL; } } bool SAXParser::parse(const char *data, unsigned size, bool bChunk) { if (!bChunk) reset(); if (p == NULL) p = new SAXParserPrivate(this); if (!p->parse(data, size, bChunk)){ reset(); return false; } #if LIBXML_VERSION > 20604 if (bChunk && (data[size - 1] == '>') && !p->parse("", 4, true)){ reset(); return false; } #endif if (!bChunk) reset(); return true; } void SAXParser::cleanup() { xmlCleanupParser(); }