1
0
Arkadiy Illarionov 2 жил өмнө
parent
commit
af3d1cc078

+ 12 - 13
source/fb2read.cpp

@@ -168,7 +168,7 @@ FbReadHandler::RootHandler::RootHandler(FbReadHandler &owner, const QString &nam
 {
 }
 
-FbXmlHandler::NodeHandler * FbReadHandler::RootHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbReadHandler::RootHandler::NewTag(const QString &name, const QXmlStreamAttributes &atts)
 {
     switch (toKeyword(name)) {
         case Binary: return new BinaryHandler(m_owner, name, atts);
@@ -260,7 +260,7 @@ FB2_BEGIN_KEYHASH(FbReadHandler::TextHandler)
     FB2_KEY( Code    , "code"          );
 FB2_END_KEYHASH
 
-FbReadHandler::TextHandler::TextHandler(FbReadHandler &owner, const QString &name, const QXmlAttributes &atts, const QString &tag)
+FbReadHandler::TextHandler::TextHandler(FbReadHandler &owner, const QString &name, const QXmlStreamAttributes &atts, const QString &tag)
     : BaseHandler(owner, name)
     , m_parent(NULL)
     , m_tag(tag)
@@ -269,7 +269,7 @@ FbReadHandler::TextHandler::TextHandler(FbReadHandler &owner, const QString &nam
     Init(name, atts);
 }
 
-FbReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag)
+FbReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts, const QString &tag)
     : BaseHandler(parent->m_owner, name)
     , m_parent(parent)
     , m_tag(tag)
@@ -278,26 +278,25 @@ FbReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name
     Init(name, atts);
 }
 
-void FbReadHandler::TextHandler::Init(const QString &name, const QXmlAttributes &atts)
+void FbReadHandler::TextHandler::Init(const QString &name, const QXmlStreamAttributes &atts)
 {
     Keyword key = toKeyword(name);
     writer().writeStartElement(m_tag);
-    int count = atts.count();
-    for (int i = 0; i < count; ++i) {
-        QString name = atts.qName(i);
+    for (const auto& attr : atts) {
+        QString name = attr.qualifiedName().toString();
         switch (key) {
-            case Anchor: { if (atts.localName(i) == "href") name = "href"; break; }
-            case Image:  { if (atts.localName(i) == "href") name = "src"; break; }
+            case Anchor: { if (attr.name() == "href") name = "href"; break; }
+            case Image:  { if (attr.name() == "href") name = "src"; break; }
             default: ;
         }
-        writer().writeAttribute(name, atts.value(i));
+        writer().writeAttribute(name, attr.value().toString());
     }
     if (m_tag == "p" && (name == "text-author" || name == "subtitle")) {
         writer().writeAttribute("fb:class", name);
     }
 }
 
-FbXmlHandler::NodeHandler * FbReadHandler::TextHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbReadHandler::TextHandler::NewTag(const QString &name, const QXmlStreamAttributes &atts)
 {
     m_empty = false;
     QString tag;
@@ -346,7 +345,7 @@ bool FbReadHandler::TextHandler::isNotes() const
 //  FbReadHandler::BinaryHandler
 //---------------------------------------------------------------------------
 
-FbReadHandler::BinaryHandler::BinaryHandler(FbReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+FbReadHandler::BinaryHandler::BinaryHandler(FbReadHandler &owner, const QString &name, const QXmlStreamAttributes &atts)
     : BaseHandler(owner, name)
     , m_file(Value(atts, "id"))
 {
@@ -402,7 +401,7 @@ FbReadHandler::~FbReadHandler()
     m_writer.writeEndElement();
 }
 
-FbXmlHandler::NodeHandler * FbReadHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbReadHandler::CreateRoot(const QString &name, const QXmlStreamAttributes &atts)
 {
     Q_UNUSED(atts);
     if (name == "fictionbook") return new RootHandler(*this, name);

+ 7 - 7
source/fb2read.hpp

@@ -71,7 +71,7 @@ private:
     public:
         explicit RootHandler(FbReadHandler &owner, const QString &name);
     protected:
-        virtual NodeHandler * NewTag(const QString & name, const QXmlAttributes &atts);
+        virtual NodeHandler * NewTag(const QString & name, const QXmlStreamAttributes &atts);
         virtual void EndTag(const QString &name);
     private:
         void writeScript(const QString &src);
@@ -107,14 +107,14 @@ private:
             Code,
        FB2_END_KEYLIST
     public:
-        explicit TextHandler(FbReadHandler &owner, const QString &name, const QXmlAttributes &atts, const QString &tag);
-        explicit TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag);
+        explicit TextHandler(FbReadHandler &owner, const QString &name, const QXmlStreamAttributes &atts, const QString &tag);
+        explicit TextHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts, const QString &tag);
     protected:
-        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+        virtual NodeHandler * NewTag(const QString &name, const QXmlStreamAttributes &atts);
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
     protected:
-        void Init(const QString &name, const QXmlAttributes &atts);
+        void Init(const QString &name, const QXmlStreamAttributes &atts);
         bool isNotes() const;
     protected:
         TextHandler *m_parent;
@@ -126,7 +126,7 @@ private:
     class BinaryHandler : public BaseHandler
     {
     public:
-        explicit BinaryHandler(FbReadHandler &owner, const QString &name, const QXmlAttributes &atts);
+        explicit BinaryHandler(FbReadHandler &owner, const QString &name, const QXmlStreamAttributes &atts);
     protected:
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
@@ -139,7 +139,7 @@ signals:
     void binary(const QString &name, const QByteArray &data);
 
 protected:
-    virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &atts);
+    virtual NodeHandler * CreateRoot(const QString &name, const QXmlStreamAttributes &atts);
 
 private:
     void addFile(const QString &name, const QByteArray &data);

+ 18 - 20
source/fb2save.cpp

@@ -111,7 +111,7 @@ QString FbHtmlHandler::local(const QString &name)
 
 void FbHtmlHandler::onAttr(const QString &name, const QString &value)
 {
-    m_atts.append(name, "", local(name), value);
+    m_atts.append(name, local(name), value);
 }
 
 void FbHtmlHandler::onNew(const QString &name)
@@ -362,7 +362,7 @@ FB2_BEGIN_KEYHASH(FbSaveHandler::TextHandler)
     FB2_KEY( Code    , "tt"     );
 FB2_END_KEYHASH
 
-FbSaveHandler::TextHandler::TextHandler(FbSaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag)
+FbSaveHandler::TextHandler::TextHandler(FbSaveWriter &writer, const QString &name, const QXmlStreamAttributes &atts, const QString &tag)
     : NodeHandler(name)
     , m_writer(writer)
     , m_tag(tag)
@@ -374,7 +374,7 @@ FbSaveHandler::TextHandler::TextHandler(FbSaveWriter &writer, const QString &nam
     writeAtts(atts);
 }
 
-FbSaveHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag)
+FbSaveHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts, const QString &tag)
     : NodeHandler(name)
     , m_writer(parent->m_writer)
     , m_tag(tag)
@@ -386,12 +386,11 @@ FbSaveHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name
     writeAtts(atts);
 }
 
-void FbSaveHandler::TextHandler::writeAtts(const QXmlAttributes &atts)
+void FbSaveHandler::TextHandler::writeAtts(const QXmlStreamAttributes &atts)
 {
-    int count = atts.count();
-    for (int i = 0; i < count; ++i) {
-        QString name = atts.qName(i);
-        QString value = atts.value(i);
+    for (const auto& attr : atts) {
+        QString name = attr.qualifiedName().toString();
+        QString value = attr.value().toString();
         if (m_tag == "image") {
             if (name == "src") {
                 name = "l:href";
@@ -404,7 +403,7 @@ void FbSaveHandler::TextHandler::writeAtts(const QXmlAttributes &atts)
     }
 }
 
-FbXmlHandler::NodeHandler * FbSaveHandler::TextHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbSaveHandler::TextHandler::NewTag(const QString &name, const QXmlStreamAttributes &atts)
 {
     m_hasChild = true;
     QString tag = QString();
@@ -451,7 +450,7 @@ FbSaveHandler::RootHandler::RootHandler(FbSaveWriter &writer, const QString &nam
 {
 }
 
-FbXmlHandler::NodeHandler * FbSaveHandler::RootHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbSaveHandler::RootHandler::NewTag(const QString &name, const QXmlStreamAttributes &atts)
 {
     Q_UNUSED(atts);
     return name == "body" ? new BodyHandler(m_writer, name) : NULL;
@@ -462,7 +461,7 @@ FbXmlHandler::NodeHandler * FbSaveHandler::RootHandler::NewTag(const QString &na
 //---------------------------------------------------------------------------
 
 FbSaveHandler::BodyHandler::BodyHandler(FbSaveWriter &writer, const QString &name)
-    : TextHandler(writer, name, QXmlAttributes(), "FictionBook")
+    : TextHandler(writer, name, QXmlStreamAttributes(), "FictionBook")
 {
     m_writer.writeAttribute("xmlns", "http://www.gribuser.ru/xml/fictionbook/2.0");
     m_writer.writeAttribute("xmlns:l", "http://www.w3.org/1999/xlink");
@@ -479,7 +478,7 @@ void FbSaveHandler::BodyHandler::EndTag(const QString &name)
 //  FbSaveHandler::SpanHandler
 //---------------------------------------------------------------------------
 
-FbSaveHandler::SpanHandler::SpanHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts)
+FbSaveHandler::SpanHandler::SpanHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts)
     : TextHandler(parent, name, atts, Value(atts, "class") == "Apple-style-span" ? "" : "style")
 {
 }
@@ -488,24 +487,23 @@ FbSaveHandler::SpanHandler::SpanHandler(TextHandler *parent, const QString &name
 //  FbSaveHandler::ParagHandler
 //---------------------------------------------------------------------------
 
-FbSaveHandler::ParagHandler::ParagHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts)
+FbSaveHandler::ParagHandler::ParagHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts)
     : TextHandler(parent, name, atts, "")
     , m_parent(parent->tag())
     , m_empty(true)
 {
-    int count = atts.count();
-    for (int i = 0; i < count; ++i) {
-        QString qName = atts.qName(i);
-        QString value = atts.value(i);
+    for (const auto& attr : atts) {
+        QString qName = attr.qualifiedName().toString();
+        QString value = attr.value().toString();
         if (qName == "fb:class") {
             m_class = value;
         } else {
-            m_atts.append(qName, "", "", value);
+            m_atts.append(qName, value);
         }
     }
 }
 
-FbXmlHandler::NodeHandler * FbSaveHandler::ParagHandler::NewTag(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbSaveHandler::ParagHandler::NewTag(const QString &name, const QXmlStreamAttributes &atts)
 {
     if (m_empty && name != "br") start();
     return TextHandler::NewTag(name, atts);
@@ -567,7 +565,7 @@ void FbSaveHandler::onFocus(int offset)
     m_writer.setFocus(offset - m_lastTextLength);
 }
 
-FbXmlHandler::NodeHandler * FbSaveHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
+FbXmlHandler::NodeHandler * FbSaveHandler::CreateRoot(const QString &name, const QXmlStreamAttributes &atts)
 {
     Q_UNUSED(atts);
     if (name == "html") return new RootHandler(m_writer, name);

+ 11 - 11
source/fb2save.hpp

@@ -63,7 +63,7 @@ private:
     static QString local(const QString &name);
 
 private:
-    QXmlAttributes m_atts;
+    QXmlStreamAttributes m_atts;
 };
 
 class FbSaveWriter : public QXmlStreamWriter
@@ -130,15 +130,15 @@ private:
             Code,
        FB2_END_KEYLIST
     public:
-        explicit TextHandler(FbSaveWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag);
-        explicit TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag);
+        explicit TextHandler(FbSaveWriter &writer, const QString &name, const QXmlStreamAttributes &atts, const QString &tag);
+        explicit TextHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts, const QString &tag);
         const QString & tag() { return m_tag; }
     protected:
-        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+        virtual NodeHandler * NewTag(const QString &name, const QXmlStreamAttributes &atts);
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
     protected:
-        virtual void writeAtts(const QXmlAttributes &atts);
+        virtual void writeAtts(const QXmlStreamAttributes &atts);
         virtual int nextLevel() const;
     protected:
         FbSaveWriter &m_writer;
@@ -153,7 +153,7 @@ private:
     public:
         explicit RootHandler(FbSaveWriter &writer, const QString &name);
     protected:
-        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+        virtual NodeHandler * NewTag(const QString &name, const QXmlStreamAttributes &atts);
     protected:
         FbSaveWriter &m_writer;
     };
@@ -169,15 +169,15 @@ private:
     class SpanHandler : public TextHandler
     {
     public:
-        explicit SpanHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts);
+        explicit SpanHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts);
     };
 
     class ParagHandler : public TextHandler
     {
     public:
-        explicit ParagHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts);
+        explicit ParagHandler(TextHandler *parent, const QString &name, const QXmlStreamAttributes &atts);
     protected:
-        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
+        virtual NodeHandler * NewTag(const QString &name, const QXmlStreamAttributes &atts);
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
     private:
@@ -185,13 +185,13 @@ private:
         void start();
     private:
         const QString m_parent;
-        QXmlAttributes m_atts;
+        QXmlStreamAttributes m_atts;
         QString m_class;
         bool m_empty;
     };
 
 protected:
-    virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &atts);
+    virtual NodeHandler * CreateRoot(const QString &name, const QXmlStreamAttributes &atts);
 
 private:
     void setDocumentInfo(QWebFrame *frame);

+ 13 - 16
source/fb2xml.cpp

@@ -5,18 +5,17 @@
 //  FbXmlHandler::NodeHandler
 //---------------------------------------------------------------------------
 
-QString FbXmlHandler::NodeHandler::Value(const QXmlAttributes &attributes, const QString &name)
+QString FbXmlHandler::NodeHandler::Value(const QXmlStreamAttributes &attributes, const QString &name)
 {
-    int count = attributes.count();
-    for (int i = 0; i < count; ++i ) {
-        if (attributes.localName(i).compare(name, Qt::CaseInsensitive) == 0) {
-            return attributes.value(i);
+    for (const auto& attr : attributes) {
+        if (attr.name().compare(name, Qt::CaseInsensitive) == 0) {
+            return attr.value().toString();
         }
     }
     return QString();
 }
 
-bool FbXmlHandler::NodeHandler::doStart(const QString &name, const QXmlAttributes &attributes)
+bool FbXmlHandler::NodeHandler::doStart(const QString &name, const QXmlStreamAttributes &attributes)
 {
     if (m_handler) return m_handler->doStart(name, attributes);
     m_handler = NewTag(name, attributes);
@@ -57,7 +56,7 @@ bool FbXmlHandler::NodeHandler::doEnd(const QString &name, bool & exists)
 //---------------------------------------------------------------------------
 
 FbXmlHandler::FbXmlHandler()
-    : QXmlDefaultHandler()
+    : QObject()
     , m_handler(0)
 {
 }
@@ -67,10 +66,8 @@ FbXmlHandler::~FbXmlHandler()
     if (m_handler) delete m_handler;
 }
 
-bool FbXmlHandler::startElement(const QString & namespaceURI, const QString & localName, const QString &qName, const QXmlAttributes &attributes)
+bool FbXmlHandler::startElement(const QString &, const QString &, const QString &qName, const QXmlStreamAttributes &attributes)
 {
-    Q_UNUSED(namespaceURI);
-    Q_UNUSED(localName);
     const QString name = qName.toLower();
     if (m_handler) return m_handler->doStart(name, attributes);
     m_handler = CreateRoot(name, attributes);
@@ -99,21 +96,21 @@ bool FbXmlHandler::endElement(const QString & namespaceURI, const QString & loca
     return m_handler && m_handler->doEnd(qName.toLower(), found);
 }
 
-bool FbXmlHandler::warning(const QXmlParseException& exception)
+bool FbXmlHandler::warning(const QString &msg, int row, int col)
 {
-    emit warning(exception.lineNumber(), exception.columnNumber(), exception.message());
+    emit warning(row, col, msg);
     return true;
 }
 
-bool FbXmlHandler::error(const QXmlParseException& exception)
+bool FbXmlHandler::error(const QString &msg, int row, int col)
 {
-    emit error(exception.lineNumber(), exception.columnNumber(), exception.message());
+    emit error(row, col, msg);
     return false;
 }
 
-bool FbXmlHandler::fatalError(const QXmlParseException &exception)
+bool FbXmlHandler::fatalError(const QString &msg, int row, int col)
 {
-    emit fatal(exception.lineNumber(), exception.columnNumber(), exception.message());
+    emit fatal(row, col, msg);
     return false;
 }
 

+ 10 - 11
source/fb2xml.hpp

@@ -2,11 +2,9 @@
 #define FB2XML_H
 
 #include <QHash>
-#include <QXmlDefaultHandler>
 #include <QXmlStreamReader>
 #include <QXmlStreamWriter>
 
-#include "fb2logs.hpp"
 
 #define FB2_BEGIN_KEYLIST private: enum Keyword {
 
@@ -27,19 +25,20 @@ x::KeywordHash::KeywordHash() {
 
 #define FB2_KEY(key,str) insert(str,key);
 
-class FbXmlHandler : public QObject, public QXmlDefaultHandler
+class FbXmlHandler : public QObject
 {
     Q_OBJECT
 
 public:
     explicit FbXmlHandler();
     virtual ~FbXmlHandler();
-    bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes);
+    bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlStreamAttributes &attributes);
     bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
     bool characters(const QString &str);
-    bool error(const QXmlParseException& exception);
-    bool warning(const QXmlParseException& exception);
-    bool fatalError(const QXmlParseException &exception);
+    bool comment(const QString &){return true;}
+    bool error(const QString &msg, int row, int col);
+    bool warning(const QString &msg, int row, int col);
+    bool fatalError(const QString &msg, int row, int col);
     QString errorString() const;
 
 signals:
@@ -51,16 +50,16 @@ protected:
     class NodeHandler
     {
     public:
-        static QString Value(const QXmlAttributes &attributes, const QString &name);
+        static QString Value(const QXmlStreamAttributes &attributes, const QString &name);
         explicit NodeHandler(const QString &name)
             : m_name(name), m_handler(0), m_closed(false) {}
         virtual ~NodeHandler()
             { if (m_handler) delete m_handler; }
-        bool doStart(const QString &name, const QXmlAttributes &attributes);
+        bool doStart(const QString &name, const QXmlStreamAttributes &attributes);
         bool doText(const QString &text);
         bool doEnd(const QString &name, bool & found);
     protected:
-        virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &attributes)
+        virtual NodeHandler * NewTag(const QString &name, const QXmlStreamAttributes &attributes)
             { Q_UNUSED(name); Q_UNUSED(attributes); return NULL; }
         virtual void TxtTag(const QString &text)
             { Q_UNUSED(text); }
@@ -75,7 +74,7 @@ protected:
     };
 
 protected:
-    virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &attributes) = 0;
+    virtual NodeHandler * CreateRoot(const QString &name, const QXmlStreamAttributes &attributes) = 0;
     static bool isWhiteSpace(const QString &str);
 
 protected:

+ 49 - 158
source/fb2xml2.cpp

@@ -3,10 +3,6 @@
 #ifdef FB2_USE_LIBXML2
 
 #include <cstring>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/HTMLparser.h>
-#include <libxml/xmlreader.h>
 #include <QtDebug>
 
 namespace XML2 {
@@ -15,134 +11,83 @@ namespace XML2 {
 //  XML2::XmlReader
 //---------------------------------------------------------------------------
 
-class XmlReaderLocator : public QXmlLocator {
-public:
-    XmlReaderLocator(XmlReader* r) : reader(r) {}
-    virtual int columnNumber(void) const;
-    virtual int lineNumber(void) const;
-private:
-    XmlReader* reader;
-};
-
 class XmlReaderPrivate {
 public:
     ~XmlReaderPrivate(void) {}
 private:
     XmlReaderPrivate(XmlReader* reader);
 
-    static void onError(void *arg, const char *msg, xmlParserSeverities severity, xmlTextReaderLocatorPtr locator);
-    static int onRead(void * context, char * buffer, int len);
-
-    static QString C2S(const xmlChar* text, int size = -1);
-
     bool parse(const QXmlInputSource *input);
     bool parse(QIODevice *input);
-    void process(xmlTextReaderPtr reader);
+    bool process(QXmlStreamReader& reader);
 
-    QScopedPointer<XmlReaderLocator> locator;
     Q_DECLARE_PUBLIC(XmlReader)
     XmlReader* q_ptr;
 
-    QXmlEntityResolver* entityresolver;
-    QXmlDTDHandler*     dtdhandler;
-    QXmlContentHandler* contenthandler;
-    QXmlErrorHandler*   errorhandler;
-    QXmlLexicalHandler* lexicalhandler;
-    QXmlDeclHandler*    declhandler;
-
-    xmlTextReaderPtr m_reader;
-
-    friend class XmlReaderLocator;
+    FbXmlHandler* contenthandler;
+    FbXmlHandler* errorhandler;
+    FbXmlHandler* lexicalhandler;
 };
 
 XmlReaderPrivate::XmlReaderPrivate(XmlReader* reader)
-    : q_ptr(reader), entityresolver(0), dtdhandler(0), contenthandler(0), errorhandler(0), lexicalhandler(0), declhandler(0), m_reader(0)
+    : q_ptr(reader)
+    , contenthandler(nullptr)
+    , errorhandler(nullptr)
+    , lexicalhandler(nullptr)
 {
-    this->locator.reset(new XmlReaderLocator(reader));
 }
 
-QString XmlReaderPrivate::C2S(const xmlChar* text, int size)
+bool XmlReaderPrivate::process(QXmlStreamReader &reader)
 {
-    return QString::fromLocal8Bit(reinterpret_cast<const char*>(text), size);
-}
+    while (!reader.atEnd()) {
+        reader.readNext();
 
-void XmlReaderPrivate::onError(void * arg, const char * msg, xmlParserSeverities severity, xmlTextReaderLocatorPtr locator)
-{
-    XmlReaderPrivate* r = reinterpret_cast<XmlReaderPrivate*>(arg);
-    if (r->errorhandler) {
-        QXmlParseException e(QString::fromLocal8Bit(msg), xmlTextReaderGetParserColumnNumber(r->m_reader), xmlTextReaderGetParserLineNumber(r->m_reader));
-        switch (severity) {
-            case XML_PARSER_SEVERITY_VALIDITY_WARNING: r->errorhandler->warning(e); break;
-            case XML_PARSER_SEVERITY_VALIDITY_ERROR: r->errorhandler->error(e); break;
-            case XML_PARSER_SEVERITY_WARNING: r->errorhandler->warning(e); break;
-            case XML_PARSER_SEVERITY_ERROR: r->errorhandler->error(e); break;
+        if (reader.hasError()) {
+            return errorhandler->error(reader.errorString(), reader.lineNumber(), reader.columnNumber());
         }
-    }
-}
 
-void XmlReaderPrivate::process(xmlTextReaderPtr reader)
-{
-    if (!contenthandler) return;
-    switch (xmlTextReaderNodeType(reader)) {
-        case XML_READER_TYPE_ELEMENT: {
-            QString localName = C2S(xmlTextReaderConstLocalName(reader));
-            QString qName = C2S(xmlTextReaderConstName(reader));
-            bool empty = xmlTextReaderIsEmptyElement(reader);
-            QXmlAttributes atts;
-            while (xmlTextReaderMoveToNextAttribute(reader)) {
-                QString localName = C2S(xmlTextReaderConstLocalName(reader));
-                QString qName = C2S(xmlTextReaderConstName(reader));
-                QString value = C2S(xmlTextReaderConstValue(reader));
-                atts.append(qName, "", localName, value);
+        switch (reader.tokenType()) {
+        case QXmlStreamReader::StartElement:
+            if (!contenthandler->startElement(reader.namespaceUri().toString(), reader.name().toString(),
+                                              reader.qualifiedName().toString(), reader.attributes())) {
+                return false;
+            }
+            break;
+        case QXmlStreamReader::EndElement:
+            if (!contenthandler->endElement(reader.namespaceUri().toString(), reader.name().toString(),
+                                            reader.qualifiedName().toString())) {
+                return false;
             }
-            contenthandler->startElement("", localName, qName, atts);
-            if (empty) contenthandler->endElement("", localName, qName);
-        } break;
-        case XML_READER_TYPE_TEXT: {
-            QString value = C2S(xmlTextReaderConstValue(reader));
-            contenthandler->characters(value);
-        } break;
-        case XML_READER_TYPE_END_ELEMENT: {
-            QString localName = C2S(xmlTextReaderConstLocalName(reader));
-            QString qName = C2S(xmlTextReaderConstName(reader));
-            contenthandler->endElement("", localName, qName);
-        } break;
-        case XML_READER_TYPE_COMMENT: {
-            if (lexicalhandler) {
-                QString value = C2S(xmlTextReaderConstValue(reader));
-                lexicalhandler->comment(value);
+        case QXmlStreamReader::Characters:
+            if (!contenthandler->characters(reader.text().toString())) {
+                return false;
             }
-        } break;
+            break;
+        case QXmlStreamReader::Comment:
+            if (lexicalhandler && !lexicalhandler->comment(reader.text().toString())) {
+                return false;
+            }
+            break;
+        default:
+            break;
+        }
     }
-}
 
-int XmlReaderPrivate::onRead(void * context, char * buffer, int len)
-{
-    QIODevice *device = reinterpret_cast<QIODevice*>(context);
-    return device->read(buffer, len);
+    return !reader.isEndDocument();
 }
 
 bool XmlReaderPrivate::parse(const QXmlInputSource *input)
 {
-    QByteArray arr = input->data().toUtf8();
-    int options = XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET;
-    m_reader = xmlReaderForMemory(arr.constData(), arr.size(), NULL, NULL, options);
-    if (!m_reader) return false;
-    xmlTextReaderSetErrorHandler(m_reader, &XmlReaderPrivate::onError, this);
-    while (xmlTextReaderRead(m_reader) == 1) process(m_reader);
-    xmlFreeTextReader(m_reader);
-    return true;
+    QXmlStreamReader reader(input->data().toUtf8());
+
+    return process(reader);
 }
 
 bool XmlReaderPrivate::parse(QIODevice *input)
 {
-    int options = XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET;
-    m_reader = xmlReaderForIO(&XmlReaderPrivate::onRead, NULL, input, NULL, NULL, options);
-    if (!m_reader) return false;
-    xmlTextReaderSetErrorHandler(m_reader, &XmlReaderPrivate::onError, this);
-    while (xmlTextReaderRead(m_reader) == 1) process(m_reader);
-    xmlFreeTextReader(m_reader);
-    return true;
+    QXmlStreamReader reader(input);
+
+    return process(reader);
 }
 
 XmlReader::XmlReader(void)
@@ -184,78 +129,42 @@ bool XmlReader::hasProperty(const QString&) const
     return false;
 }
 
-void XmlReader::setEntityResolver(QXmlEntityResolver* handler)
-{
-    Q_D(XmlReader);
-    d->entityresolver = handler;
-}
-
-QXmlEntityResolver* XmlReader::entityResolver(void) const
-{
-    const XmlReaderPrivate* d = this->d_func();
-    return d->entityresolver;
-}
-
-void XmlReader::setDTDHandler(QXmlDTDHandler* handler)
-{
-    Q_D(XmlReader);
-    d->dtdhandler = handler;
-}
-
-QXmlDTDHandler* XmlReader::DTDHandler(void) const
-{
-    const XmlReaderPrivate* d = this->d_func();
-    return d->dtdhandler;
-}
-
-void XmlReader::setContentHandler(QXmlContentHandler* handler)
+void XmlReader::setContentHandler(FbXmlHandler* handler)
 {
     Q_D(XmlReader);
     d->contenthandler = handler;
 }
 
-QXmlContentHandler* XmlReader::contentHandler(void) const
+FbXmlHandler* XmlReader::contentHandler(void) const
 {
     const XmlReaderPrivate* d = this->d_func();
     return d->contenthandler;
 }
 
-void XmlReader::setErrorHandler(QXmlErrorHandler* handler)
+void XmlReader::setErrorHandler(FbXmlHandler* handler)
 {
     Q_D(XmlReader);
     d->errorhandler = handler;
 }
 
-QXmlErrorHandler* XmlReader::errorHandler(void) const
+FbXmlHandler* XmlReader::errorHandler(void) const
 {
     const XmlReaderPrivate* d = this->d_func();
     return d->errorhandler;
 }
 
-void XmlReader::setLexicalHandler(QXmlLexicalHandler* handler)
+void XmlReader::setLexicalHandler(FbXmlHandler* handler)
 {
     Q_D(XmlReader);
     d->lexicalhandler = handler;
 }
 
-QXmlLexicalHandler* XmlReader::lexicalHandler(void) const
+FbXmlHandler* XmlReader::lexicalHandler(void) const
 {
     const XmlReaderPrivate* d = this->d_func();
     return d->lexicalhandler;
 }
 
-void XmlReader::setDeclHandler(QXmlDeclHandler* handler)
-{
-    Q_D(XmlReader);
-    d->declhandler = handler;
-}
-
-QXmlDeclHandler* XmlReader::declHandler(void) const
-{
-    const XmlReaderPrivate* d = this->d_func();
-    return d->declhandler;
-}
-
 bool XmlReader::parse(const QXmlInputSource& input)
 {
     return this->parse(&input);
@@ -265,10 +174,6 @@ bool XmlReader::parse(const QXmlInputSource* input)
 {
     Q_D(XmlReader);
 
-    if (d->contenthandler) {
-        d->contenthandler->setDocumentLocator(d->locator.data());
-    }
-
     d->parse(input);
 
     return true;
@@ -278,25 +183,11 @@ bool XmlReader::parse(QIODevice *input)
 {
     Q_D(XmlReader);
 
-    if (d->contenthandler) {
-        d->contenthandler->setDocumentLocator(d->locator.data());
-    }
-
     d->parse(input);
 
     return true;
 }
 
-int XmlReaderLocator::columnNumber(void) const
-{
-    return xmlTextReaderGetParserColumnNumber(this->reader->d_func()->m_reader);
-}
-
-int XmlReaderLocator::lineNumber(void) const
-{
-    return xmlTextReaderGetParserLineNumber(this->reader->d_func()->m_reader);
-}
-
 } // namespace XML2
 
 #endif // FB2_USE_LIBXML2

+ 19 - 45
source/fb2xml2.h

@@ -3,68 +3,42 @@
 
 #ifdef FB2_USE_LIBXML2
 
-/////////////////////////////////////////////////////////////////////////////
-//
-//   Append into project file:
-//     INCLUDEPATH += /usr/include/libxml2
-//     LIBS        += -lxml2
-//
-//   http://blog.sjinks.pro/c-cpp/qt/942-html-parser-qt/
-//
-//
-//     QByteArray data;
-//     QXmlInputSource src;
-//     HtmlReader reader;
-//     QDomDocument doc;
-//     src.setData(data);
-//     doc.setContent(&src, &reader);
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#include <QtXml/QXmlReader>
-#include <libxml/xmlstring.h>
+#include <QtXml>
+#include "fb2xml.hpp"
 
 namespace XML2 {
 
 class XmlReaderPrivate;
 
-class XmlReader : public QXmlReader
+class XmlReader
 {
 public:
     XmlReader(void);
-    virtual ~XmlReader(void);
+    ~XmlReader(void);
 
-    virtual bool feature(const QString& name, bool* ok = 0) const;
-    virtual void setFeature(const QString& name, bool value);
-    virtual bool hasFeature(const QString& name) const;
-    virtual void* property(const QString& name, bool* ok = 0) const;
-    virtual void setProperty(const QString& name, void* value);
-    virtual bool hasProperty(const QString& name) const;
+    bool feature(const QString& name, bool* ok = 0) const;
+    void setFeature(const QString& name, bool value);
+    bool hasFeature(const QString& name) const;
+    void* property(const QString& name, bool* ok = 0) const;
+    void setProperty(const QString& name, void* value);
+    bool hasProperty(const QString& name) const;
 
-    virtual void setEntityResolver(QXmlEntityResolver* handler);
-    virtual QXmlEntityResolver* entityResolver(void) const;
-    virtual void setDTDHandler(QXmlDTDHandler* handler);
-    virtual QXmlDTDHandler* DTDHandler(void) const;
-    virtual void setContentHandler(QXmlContentHandler* handler);
-    virtual QXmlContentHandler* contentHandler(void) const;
-    virtual void setErrorHandler(QXmlErrorHandler* handler);
-    virtual QXmlErrorHandler* errorHandler(void) const;
-    virtual void setLexicalHandler(QXmlLexicalHandler* handler);
-    virtual QXmlLexicalHandler* lexicalHandler(void) const;
-    virtual void setDeclHandler(QXmlDeclHandler* handler);
-    virtual QXmlDeclHandler* declHandler(void) const;
+    void setContentHandler(FbXmlHandler* handler);
+    FbXmlHandler* contentHandler(void) const;
+    void setErrorHandler(FbXmlHandler* handler);
+    FbXmlHandler* errorHandler(void) const;
+    void setLexicalHandler(FbXmlHandler* handler);
+    FbXmlHandler* lexicalHandler(void) const;
 
-    virtual bool parse(QIODevice *input);
-    virtual bool parse(const QXmlInputSource&);
-    virtual bool parse(const QXmlInputSource*);
+    bool parse(QIODevice *input);
+    bool parse(const QXmlInputSource&);
+    bool parse(const QXmlInputSource*);
 
 
 private:
     Q_DISABLE_COPY(XmlReader)
     Q_DECLARE_PRIVATE(XmlReader)
     QScopedPointer<XmlReaderPrivate> d_ptr;
-
-    friend class XmlReaderLocator;
 };
 
 } // namespace XML2