Kandrashin Denis 13 лет назад
Родитель
Сommit
4c0ecca276
4 измененных файлов с 45 добавлено и 24 удалено
  1. 9 15
      source/fb2read.cpp
  2. 2 5
      source/fb2view.cpp
  3. 32 2
      source/fb2xml2.cpp
  4. 2 2
      source/fb2xml2.h

+ 9 - 15
source/fb2read.cpp

@@ -39,28 +39,22 @@ bool Fb2ReadThread::parse()
 {
     QXmlStreamWriter writer(&m_html);
     Fb2ReadHandler handler(*this, writer);
+    #ifdef _WIN32
+        QXmlSimpleReader reader;
+    #else
+        XML2::XmlReader reader;
+    #endif
+    reader.setContentHandler(&handler);
+    reader.setErrorHandler(&handler);
     if (m_xml.isEmpty()) {
         QFile file(m_filename);
         if (!file.open(QFile::ReadOnly | QFile::Text)) {
             qCritical() << QObject::tr("Cannot read file %1: %2.").arg(m_filename).arg(file.errorString());
             return false;
         }
-        #ifdef _WIN32
-            QXmlSimpleReader reader;
-            reader.setContentHandler(&handler);
-            reader.setErrorHandler(&handler);
-            QXmlInputSource source(&file);
-            return reader.parse(source);
-        #else
-            XML2::XmlReader reader;
-            reader.setContentHandler(&handler);
-            reader.setErrorHandler(&handler);
-            return reader.parse(file);
-        #endif
+        QXmlInputSource source(&file);
+        return reader.parse(source);
     } else {
-        QXmlSimpleReader reader;
-        reader.setContentHandler(&handler);
-        reader.setErrorHandler(&handler);
         QXmlInputSource source;
         source.setData(m_xml);
         return reader.parse(source);

+ 2 - 5
source/fb2view.cpp

@@ -103,16 +103,13 @@ bool Fb2WebView::save(QIODevice *device)
 
 bool Fb2WebView::save(QString *string)
 {
-    QByteArray data;
-    Fb2SaveHandler handler(*this, &data);
+    Fb2SaveHandler handler(*this, string);
     QXmlInputSource source;
     source.setData(toBodyXml());
     XML2::HtmlReader reader;
     reader.setContentHandler(&handler);
     reader.setErrorHandler(&handler);
-    bool ok = reader.parse(source);
-    if (ok) *string = QString::fromUtf8(data.data());
-    return ok;
+    return reader.parse(source);
 }
 
 QTemporaryFile * Fb2WebView::file(const QString &name)

+ 32 - 2
source/fb2xml2.cpp

@@ -73,7 +73,6 @@ void HtmlReaderPrivate::parse(const QXmlInputSource* input)
 {
     htmlSAXHandler handler;
     QByteArray arr = input->data().toUtf8();
-    const char* data = arr.data();
 
     std::memset(&handler, 0, sizeof(handler));
     handler.startDocument         = &HtmlReaderPrivate::startDocument;
@@ -87,7 +86,7 @@ void HtmlReaderPrivate::parse(const QXmlInputSource* input)
     handler.ignorableWhitespace   = &HtmlReaderPrivate::ignorableWhitespace;
     handler.internalSubset        = &HtmlReaderPrivate::internalSubset;
 
-    this->context = htmlCreatePushParserCtxt(&handler, this, data, xmlStrlen(reinterpret_cast<const xmlChar*>(data)), "", XML_CHAR_ENCODING_UTF8);
+    this->context = htmlCreatePushParserCtxt(&handler, this, arr.data(), arr.size(), "", XML_CHAR_ENCODING_UTF8);
     htmlParseChunk(this->context, NULL, 0, 1);
     htmlFreeParserCtxt(this->context);
     xmlCleanupParser();
@@ -364,6 +363,7 @@ private:
 
     static QString C2S(const xmlChar* text, int size = -1);
 
+    bool parse(const QXmlInputSource* input);
     bool parse(QIODevice& input);
     void process(xmlTextReaderPtr reader);
 
@@ -444,6 +444,18 @@ int XmlReaderPrivate::onRead(void * context, char * buffer, int len)
     return device->read(buffer, len);
 }
 
+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.data(), 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;
+}
+
 bool XmlReaderPrivate::parse(QIODevice& input)
 {
     int options = XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NONET;
@@ -566,6 +578,24 @@ QXmlDeclHandler* XmlReader::declHandler(void) const
     return d->declhandler;
 }
 
+bool XmlReader::parse(const QXmlInputSource& input)
+{
+    return this->parse(&input);
+}
+
+bool XmlReader::parse(const QXmlInputSource* input)
+{
+    Q_D(XmlReader);
+
+    if (d->contenthandler) {
+        d->contenthandler->setDocumentLocator(d->locator.data());
+    }
+
+    d->parse(input);
+
+    return true;
+}
+
 bool XmlReader::parse(QIODevice& input)
 {
     Q_D(XmlReader);

+ 2 - 2
source/fb2xml2.h

@@ -90,8 +90,8 @@ public:
     virtual QXmlDeclHandler* declHandler(void) const;
 
     virtual bool parse(QIODevice& input);
-    virtual bool parse(const QXmlInputSource&) { return false; }
-    virtual bool parse(const QXmlInputSource*) { return false; }
+    virtual bool parse(const QXmlInputSource&);
+    virtual bool parse(const QXmlInputSource*);
 
 
 private: