Browse Source

New class: Fb2TemporaryFile

Kandrashin Denis 13 years ago
parent
commit
346474b8b8
7 changed files with 169 additions and 58 deletions
  1. 3 1
      fb2edit.pro
  2. 30 14
      source/fb2save.cpp
  3. 5 2
      source/fb2save.h
  4. 85 0
      source/fb2temp.cpp
  5. 38 0
      source/fb2temp.hpp
  6. 2 33
      source/fb2view.cpp
  7. 6 8
      source/fb2view.hpp

+ 3 - 1
fb2edit.pro

@@ -7,6 +7,7 @@ HEADERS = \
     source/fb2head.hpp \
     source/fb2main.hpp \
     source/fb2read.hpp \
+    source/fb2temp.hpp \
     source/fb2tree.hpp \
     source/fb2view.hpp
 
@@ -16,8 +17,9 @@ SOURCES = \
     source/fb2head.cpp \
     source/fb2main.cpp \
     source/fb2read.cpp \
-    source/fb2tree.cpp \
     source/fb2save.cpp \
+    source/fb2temp.cpp \
+    source/fb2tree.cpp \
     source/fb2view.cpp \
     source/fb2xml.cpp \
     source/fb2xml2.cpp

+ 30 - 14
source/fb2save.cpp

@@ -4,6 +4,10 @@
 #include "fb2save.h"
 #include "fb2view.hpp"
 
+#include <QAbstractNetworkCache>
+#include <QNetworkReply>
+#include <QNetworkRequest>
+
 //---------------------------------------------------------------------------
 //  Fb2SaveWriter
 //---------------------------------------------------------------------------
@@ -65,22 +69,34 @@ void Fb2SaveWriter::writeLineEnd()
     m_line++;
 }
 
-QString Fb2SaveWriter::getFile(const QString &path)
+QByteArray Fb2SaveWriter::downloadFile(const QString &src)
+{
+    QUrl url(src);
+    QNetworkRequest request(url);
+    QNetworkAccessManager * network = m_view.page()->networkAccessManager();
+    QNetworkReply * reply = network->get(request);
+    return reply->readAll();
+}
+
+QString Fb2SaveWriter::getFileName(const QString &path)
 {
     StringHash::const_iterator it = m_files.find(path);
-    if (it == m_files.end()) {
-        QString name = m_view.fileName(path);
-        if (name.isEmpty()) return QString();
-        m_files[name] = path;
-        m_names << name;
-        return name;
-    }
-    return it.value();
+    if (it != m_files.end()) return it.value();
+
+    QString hash = m_view.files().hash(path);
+    if (hash.isEmpty()) return QString();
+
+    QString name = m_view.files().name(hash);
+    if (name.isEmpty()) return QString();
+
+    m_files[name] = path;
+    m_names << name;
+    return name;
 }
 
-QString Fb2SaveWriter::getData(const QString &name)
+QString Fb2SaveWriter::getFileData(const QString &name)
 {
-    return m_view.fileData(name);
+    return m_view.files().data(name);
 }
 
 void Fb2SaveWriter::writeFiles()
@@ -89,7 +105,7 @@ void Fb2SaveWriter::writeFiles()
     for (it = m_names.constBegin(); it != m_names.constEnd(); it++) {
         QString name = *it;
         if (name.isEmpty()) continue;
-        QString data = getData(name);
+        QString data = getFileData(name);
         if (data.isEmpty()) continue;
         writeStartElement("binary", 2);
         if (m_folds) m_folds->append(m_line);
@@ -235,8 +251,8 @@ Fb2SaveHandler::AnchorHandler::AnchorHandler(BodyHandler *parent, const QString
 Fb2SaveHandler::ImageHandler::ImageHandler(BodyHandler *parent, const QString &name, const QXmlAttributes &atts)
     : BodyHandler(parent, name, atts, "image")
 {
-    QString href = Value(atts, "src");
-    QString file = m_writer.getFile(href);
+    QString src = Value(atts, "src");
+    QString file = m_writer.getFileName(src);
     file.prepend('#');
     m_writer.writeAttribute("l:href", file);
     m_writer.writeEndElement(0);

+ 5 - 2
source/fb2save.h

@@ -2,6 +2,7 @@
 #define Fb2Save_H
 
 #include "fb2xml.h"
+#include "fb2temp.hpp"
 
 #include <QByteArray>
 #include <QHash>
@@ -20,14 +21,16 @@ public:
     explicit Fb2SaveWriter(Fb2WebView &view, QIODevice *device);
     explicit Fb2SaveWriter(Fb2WebView &view, QString *string);
     virtual ~Fb2SaveWriter();
+    QString getFileName(const QString &src);
     void writeStartElement(const QString &name, int level);
     void writeEndElement(int level);
     void writeLineEnd();
-    QString getFile(const QString &path);
-    QString getData(const QString &name);
     void writeFiles();
 private:
     void Init();
+    QByteArray downloadFile(const QString &src);
+    QString getFileData(const QString &name);
+    QString newFileName();
 private:
     QList<int> *m_folds;
     Fb2WebView &m_view;

+ 85 - 0
source/fb2temp.cpp

@@ -0,0 +1,85 @@
+#include "fb2temp.hpp"
+
+#include <QCryptographicHash>
+
+//---------------------------------------------------------------------------
+//  Fb2TemporaryFile
+//---------------------------------------------------------------------------
+
+Fb2TemporaryFile::Fb2TemporaryFile(const QString &name)
+    : QTemporaryFile()
+    , m_name(name)
+{
+    open();
+}
+
+qint64 Fb2TemporaryFile::write(const QByteArray &data)
+{
+    m_hash = QCryptographicHash::hash(data, QCryptographicHash::Md5).toBase64();
+    qint64 size = QTemporaryFile::write(data);
+    close();
+    open();
+    return size;
+}
+
+//---------------------------------------------------------------------------
+//  Fb2TemporaryList
+//---------------------------------------------------------------------------
+
+Fb2TemporaryList::Fb2TemporaryList()
+{
+}
+
+Fb2TemporaryList::~Fb2TemporaryList()
+{
+    Fb2TemporaryIterator it(*this);
+    while (it.hasNext()) delete it.next();
+}
+
+Fb2TemporaryFile & Fb2TemporaryList::get(const QString &name)
+{
+    Fb2TemporaryIterator it(*this);
+    while (it.hasNext()) {
+        Fb2TemporaryFile *file = it.next();
+        if (file->name() == name) return *file;
+    }
+    Fb2TemporaryFile * file = new Fb2TemporaryFile(name);
+    append(file);
+    return *file;
+}
+
+void Fb2TemporaryList::set(QString name, QByteArray data)
+{
+    get(name).write(data);
+}
+
+QString Fb2TemporaryList::hash(const QString &path) const
+{
+    Fb2TemporaryIterator it(*this);
+    while (it.hasNext()) {
+        Fb2TemporaryFile *file = it.next();
+        if (file->fileName() == path) return file->hash();
+    }
+    return QString();
+}
+
+QString Fb2TemporaryList::name(const QString &hash) const
+{
+    Fb2TemporaryIterator it(*this);
+    while (it.hasNext()) {
+        Fb2TemporaryFile *file = it.next();
+        if (file->hash() == hash) return file->name();
+    }
+    return QString();
+}
+
+QString Fb2TemporaryList::data(const QString &name) const
+{
+    Fb2TemporaryIterator it(*this);
+    while (it.hasNext()) {
+        Fb2TemporaryFile *file = it.next();
+        if (file->name() == name) return file->readAll().toBase64();
+    }
+    return QString();
+}
+

+ 38 - 0
source/fb2temp.hpp

@@ -0,0 +1,38 @@
+#ifndef FB2TEMP_H
+#define FB2TEMP_H
+
+#include <QByteArray>
+#include <QList>
+#include <QString>
+#include <QTemporaryFile>
+
+class Fb2TemporaryFile : public QTemporaryFile
+{
+    Q_OBJECT
+public:
+    explicit Fb2TemporaryFile(const QString &name);
+    inline qint64 write(const QByteArray &data);
+    const QString & hash() const { return m_hash; }
+    const QString & name() const { return m_name; }
+private:
+    const QString m_name;
+    QString m_hash;
+};
+
+class Fb2TemporaryList : public QList<Fb2TemporaryFile*>
+{
+public:
+    explicit Fb2TemporaryList();
+    virtual ~Fb2TemporaryList();
+
+    Fb2TemporaryFile & get(const QString &name);
+    void set(QString name, QByteArray data);
+
+    QString hash(const QString &path) const;
+    QString name(const QString &hash) const;
+    QString data(const QString &name) const;
+};
+
+typedef QListIterator<Fb2TemporaryFile*> Fb2TemporaryIterator;
+
+#endif // FB2TEMP_H

+ 2 - 33
source/fb2view.cpp

@@ -57,7 +57,6 @@ Fb2WebView::Fb2WebView(QWidget *parent)
 
 Fb2WebView::~Fb2WebView()
 {
-    foreach (QTemporaryFile *file, m_files) delete file;
 }
 
 QWebElement Fb2WebView::doc()
@@ -125,43 +124,14 @@ bool Fb2WebView::save(QString *string)
     return ok;
 }
 
-QTemporaryFile * Fb2WebView::file(const QString &name)
-{
-    TemporaryHash::const_iterator it = m_files.find(name);
-    if (it == m_files.end()) {
-        it = m_files.insert(name, new QTemporaryFile());
-        it.value()->open();
-    }
-    return it.value();
-}
-
 QString Fb2WebView::temp(QString name)
 {
-    return file(name)->fileName();
+    return m_files.get(name).fileName();
 }
 
 void Fb2WebView::data(QString name, QByteArray data)
 {
-    QTemporaryFile * temp = file(name);
-    temp->write(data);
-    temp->close();
-    temp->open();
-}
-
-QString Fb2WebView::fileName(const QString &path)
-{
-    QHashIterator<QString, QTemporaryFile*> it(m_files);
-    while (it.hasNext()) {
-        it.next();
-        if (it.value()->fileName() == path) return it.key();
-    }
-    return QString();
-}
-
-QString Fb2WebView::fileData(const QString &name)
-{
-    QTemporaryFile * temp = file(name);
-    return temp->readAll().toBase64();
+    m_files.set(name, data);
 }
 
 void Fb2WebView::html(QString name, QString html)
@@ -256,4 +226,3 @@ void Fb2WebView::execCommand(const QString &cmd, const QString &arg)
     QString js = QString("document.execCommand(\"%1\", false, \"%2\")").arg(cmd).arg(arg);
     frame->evaluateJavaScript(js);
 }
-

+ 6 - 8
source/fb2view.hpp

@@ -1,15 +1,14 @@
 #ifndef FB2VIEW_H
 #define FB2VIEW_H
 
-#include <QByteArray>
-#include <QHash>
 #include <QResizeEvent>
-#include <QTemporaryFile>
 #include <QTimer>
 #include <QThread>
 #include <QWebElement>
 #include <QWebView>
 
+#include "fb2temp.hpp"
+
 class Fb2BaseWebView : public QWebView
 {
     Q_OBJECT
@@ -58,12 +57,12 @@ class Fb2WebView : public Fb2BaseWebView
 public:
     explicit Fb2WebView(QWidget *parent = 0);
     virtual ~Fb2WebView();
+
+    const Fb2TemporaryList & files() const { return m_files; }
     void load(const QString &filename, const QString &xml = QString());
     bool save(QByteArray *array, QList<int> *folds = 0);
     bool save(QIODevice *device);
     bool save(QString *string);
-    QString fileName(const QString &path);
-    QString fileData(const QString &name);
     QString toBodyXml();
 
     bool UndoEnabled();
@@ -93,12 +92,11 @@ private slots:
 
 private:
     void execCommand(const QString &cmd, const QString &arg);
-    QTemporaryFile * file(const QString &name);
+    Fb2TemporaryFile * file(const QString &name);
     QWebElement doc();
 
 private:
-    typedef QHash<QString, QTemporaryFile*> TemporaryHash;
-    TemporaryHash m_files;
+    Fb2TemporaryList m_files;
     QThread *m_thread;
 };