File indexing completed on 2024-11-24 04:53:08
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "DiskPartCache.h" 0024 #include <QDebug> 0025 #include <QDir> 0026 0027 namespace 0028 { 0029 /** @short Convert the QFile::FileError to a string representation */ 0030 QString fileErrorToString(const QFile::FileError e) 0031 { 0032 switch (e) { 0033 case QFile::NoError: 0034 return QStringLiteral("QFile::NoError"); 0035 case QFile::ReadError: 0036 return QStringLiteral("QFile::ReadError"); 0037 case QFile::WriteError: 0038 return QStringLiteral("QFile::WriteError"); 0039 case QFile::FatalError: 0040 return QStringLiteral("QFile::FatalError"); 0041 case QFile::ResourceError: 0042 return QStringLiteral("QFile::ResourceError"); 0043 case QFile::OpenError: 0044 return QStringLiteral("QFile::OpenError"); 0045 case QFile::AbortError: 0046 return QStringLiteral("QFile::AbortError"); 0047 case QFile::TimeOutError: 0048 return QStringLiteral("QFile::TimeOutError"); 0049 case QFile::UnspecifiedError: 0050 return QStringLiteral("QFile::UnspecifiedError"); 0051 case QFile::RemoveError: 0052 return QStringLiteral("QFile::RemoveError"); 0053 case QFile::RenameError: 0054 return QStringLiteral("QFile::RenameError"); 0055 case QFile::PositionError: 0056 return QStringLiteral("QFile::PositionError"); 0057 case QFile::ResizeError: 0058 return QStringLiteral("QFile::ResizeError"); 0059 case QFile::PermissionsError: 0060 return QStringLiteral("QFile::PermissionsError"); 0061 case QFile::CopyError: 0062 return QStringLiteral("QFile::CopyError"); 0063 } 0064 return QObject::tr("Unrecognized QFile error"); 0065 } 0066 } 0067 0068 namespace Imap 0069 { 0070 namespace Mailbox 0071 { 0072 0073 DiskPartCache::DiskPartCache(const QString &cacheDir_) 0074 : cacheDir(cacheDir_) 0075 { 0076 if (!cacheDir.endsWith(QLatin1Char('/'))) 0077 cacheDir.append(QLatin1Char('/')); 0078 } 0079 0080 void DiskPartCache::clearAllMessages(const QString &mailbox) 0081 { 0082 QDir dir(dirForMailbox(mailbox)); 0083 Q_FOREACH(const QString& fname, dir.entryList(QStringList() << QLatin1String("*.cache"))) { 0084 if (! dir.remove(fname)) { 0085 m_errorHandler(QObject::tr("Couldn't remove file %1 for mailbox %2").arg(fname, mailbox)); 0086 } 0087 } 0088 } 0089 0090 void DiskPartCache::clearMessage(const QString mailbox, const uint uid) 0091 { 0092 QDir dir(dirForMailbox(mailbox)); 0093 Q_FOREACH(const QString& fname, dir.entryList(QStringList() << QString::fromUtf8("%1_*.cache").arg(QString::number(uid)))) { 0094 if (! dir.remove(fname)) { 0095 m_errorHandler(QObject::tr("Couldn't remove file %1 for message %2, mailbox %3").arg(fname, QString::number(uid), mailbox)); 0096 } 0097 } 0098 } 0099 0100 QByteArray DiskPartCache::messagePart(const QString &mailbox, const uint uid, const QByteArray &partId) const 0101 { 0102 QFile buf(fileForPart(mailbox, uid, partId)); 0103 if (! buf.open(QIODevice::ReadOnly)) { 0104 return QByteArray(); 0105 } 0106 return qUncompress(buf.readAll()); 0107 } 0108 0109 void DiskPartCache::setMsgPart(const QString &mailbox, const uint uid, const QByteArray &partId, const QByteArray &data) 0110 { 0111 QString myPath = dirForMailbox(mailbox); 0112 QDir dir(myPath); 0113 dir.mkpath(myPath); 0114 QString fileName(fileForPart(mailbox, uid, partId)); 0115 QFile buf(fileName); 0116 if (! buf.open(QIODevice::WriteOnly)) { 0117 m_errorHandler(QObject::tr("Couldn't save the part %1 of message %2 (mailbox %3) into file %4: %5 (%6)").arg( 0118 QString::fromUtf8(partId), QString::number(uid), mailbox, fileName, buf.errorString(), 0119 fileErrorToString(buf.error()))); 0120 } 0121 buf.write(qCompress(data)); 0122 } 0123 0124 void DiskPartCache::forgetMessagePart(const QString &mailbox, const uint uid, const QByteArray &partId) 0125 { 0126 QFile(fileForPart(mailbox, uid, partId)).remove(); 0127 } 0128 0129 QString DiskPartCache::dirForMailbox(const QString &mailbox) const 0130 { 0131 return cacheDir + QString::fromUtf8(mailbox.toUtf8().toBase64()); 0132 } 0133 0134 QString DiskPartCache::fileForPart(const QString &mailbox, const uint uid, const QByteArray &partId) const 0135 { 0136 return QStringLiteral("%1/%2_%3.cache").arg(dirForMailbox(mailbox), QString::number(uid), QString::fromUtf8(partId)); 0137 } 0138 0139 void DiskPartCache::setErrorHandler(const std::function<void(const QString &)> &handler) 0140 { 0141 m_errorHandler = handler; 0142 } 0143 0144 } 0145 } 0146