fb2temp.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "fb2temp.hpp"
  2. #include <QCryptographicHash>
  3. #include <QFileInfo>
  4. #include <QImageReader>
  5. #include <QUrl>
  6. #include <QtDebug>
  7. #include "fb2view.hpp"
  8. //---------------------------------------------------------------------------
  9. // Fb2TemporaryFile
  10. //---------------------------------------------------------------------------
  11. Fb2TemporaryFile::Fb2TemporaryFile(const QString &name)
  12. : QTemporaryFile()
  13. , m_name(name)
  14. {
  15. }
  16. qint64 Fb2TemporaryFile::write(const QByteArray &data)
  17. {
  18. open();
  19. if (m_hash.isEmpty()) m_hash = md5(data);
  20. qint64 size = QTemporaryFile::write(data);
  21. close();
  22. return size;
  23. }
  24. QString Fb2TemporaryFile::md5(const QByteArray &data)
  25. {
  26. return QCryptographicHash::hash(data, QCryptographicHash::Md5).toBase64();
  27. }
  28. QByteArray Fb2TemporaryFile::data()
  29. {
  30. open();
  31. QByteArray data = readAll();
  32. close();
  33. return data;
  34. }
  35. //---------------------------------------------------------------------------
  36. // Fb2TemporaryList
  37. //---------------------------------------------------------------------------
  38. Fb2TemporaryList::Fb2TemporaryList()
  39. {
  40. }
  41. Fb2TemporaryList::~Fb2TemporaryList()
  42. {
  43. Fb2TemporaryIterator it(*this);
  44. while (it.hasNext()) delete it.next();
  45. }
  46. QString Fb2TemporaryList::add(const QString &path, const QByteArray &data)
  47. {
  48. QString hash = Fb2TemporaryFile::md5(data);
  49. QString name = this->name(hash);
  50. if (name.isEmpty()) {
  51. name = newName(path);
  52. Fb2TemporaryFile * temp = new Fb2TemporaryFile(name);
  53. temp->setHash(hash);
  54. temp->write(data);
  55. append(temp);
  56. }
  57. return name;
  58. }
  59. QString Fb2TemporaryList::newName(const QString &path)
  60. {
  61. QFileInfo info(path);
  62. QString name = info.fileName();
  63. if (!exists(name)) return name;
  64. QString base = info.baseName();
  65. QString suff = info.suffix();
  66. for (int i = 1; ; i++) {
  67. QString name = QString("%1(%2).%3").arg(base).arg(i).arg(suff);
  68. if (exists(name)) continue;
  69. return name;
  70. }
  71. }
  72. Fb2TemporaryFile * Fb2TemporaryList::get(const QString &name) const
  73. {
  74. Fb2TemporaryIterator it(*this);
  75. while (it.hasNext()) {
  76. Fb2TemporaryFile * file = it.next();
  77. if (file->name() == name) return file;
  78. }
  79. return NULL;
  80. }
  81. QByteArray Fb2TemporaryList::data(const QString &name) const
  82. {
  83. Fb2TemporaryIterator it(*this);
  84. while (it.hasNext()) {
  85. Fb2TemporaryFile *file = it.next();
  86. if (file->name() == name) return file->data();
  87. }
  88. return QByteArray();
  89. }
  90. const QString & Fb2TemporaryList::set(const QString &name, const QByteArray &data, const QString &hash)
  91. {
  92. Fb2TemporaryFile * file = get(name);
  93. if (!file) append(file = new Fb2TemporaryFile(name));
  94. file->setHash(hash);
  95. file->write(data);
  96. return file->hash();
  97. }
  98. QString Fb2TemporaryList::name(const QString &hash) const
  99. {
  100. Fb2TemporaryIterator it(*this);
  101. while (it.hasNext()) {
  102. Fb2TemporaryFile *file = it.next();
  103. if (file->hash() == hash) return file->name();
  104. }
  105. return QString();
  106. }
  107. bool Fb2TemporaryList::exists(const QString &name) const
  108. {
  109. Fb2TemporaryIterator it(*this);
  110. while (it.hasNext()) {
  111. Fb2TemporaryFile *file = it.next();
  112. if (file->name() == name) return true;
  113. }
  114. return false;
  115. }
  116. #if 0
  117. //---------------------------------------------------------------------------
  118. // Fb2NetworkDiskCache
  119. //---------------------------------------------------------------------------
  120. QNetworkCacheMetaData Fb2NetworkDiskCache::metaData(const QUrl &url)
  121. {
  122. qCritical() << url.toString();
  123. return QNetworkDiskCache::metaData(url);
  124. }
  125. QIODevice * Fb2NetworkDiskCache::data(const QUrl &url)
  126. {
  127. qCritical() << url.toString();
  128. return QNetworkDiskCache::data(url);
  129. }
  130. #endif
  131. //---------------------------------------------------------------------------
  132. // Fb2ImageReply
  133. //---------------------------------------------------------------------------
  134. Fb2ImageReply::Fb2ImageReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &data)
  135. : QNetworkReply()
  136. , content(data)
  137. , offset(0)
  138. {
  139. setOperation(op);
  140. setRequest(request);
  141. setUrl(request.url());
  142. open(ReadOnly | Unbuffered);
  143. setHeader(QNetworkRequest::ContentLengthHeader, QVariant(content.size()));
  144. setAttribute(QNetworkRequest::CacheSaveControlAttribute, QVariant(false));
  145. QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
  146. QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
  147. }
  148. qint64 Fb2ImageReply::readData(char *data, qint64 maxSize)
  149. {
  150. if (offset >= content.size()) return -1;
  151. QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
  152. qint64 number = qMin(maxSize, content.size() - offset);
  153. memcpy(data, content.constData() + offset, number);
  154. offset += number;
  155. return number;
  156. }
  157. //---------------------------------------------------------------------------
  158. // Fb2NetworkAccessManager
  159. //
  160. // http://doc.trolltech.com/qq/32/qq32-webkit-protocols.html
  161. //---------------------------------------------------------------------------
  162. Fb2NetworkAccessManager::Fb2NetworkAccessManager(Fb2WebView &view)
  163. : QNetworkAccessManager(&view)
  164. , m_view(view)
  165. {
  166. }
  167. QNetworkReply * Fb2NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
  168. {
  169. if (request.url().scheme() == "fb2") return imageRequest(op, request);
  170. return QNetworkAccessManager::createRequest(op, request, outgoingData);
  171. }
  172. QNetworkReply * Fb2NetworkAccessManager::imageRequest(Operation op, const QNetworkRequest &request)
  173. {
  174. QString name = request.url().path();
  175. QByteArray data = m_view.files().data(name);
  176. return new Fb2ImageReply(op, request, data);
  177. }