File indexing completed on 2024-04-28 04:58:11

0001 /* This file is part of the KDE project
0002     SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include "konq_historyloader_p.h"
0008 #include "konq_historyentry.h"
0009 
0010 #include <QDataStream>
0011 #include <QFile>
0012 #include <QStandardPaths>
0013 
0014 #include <zlib.h> // for crc32
0015 
0016 #include "libkonq_debug.h"
0017 
0018 class KonqHistoryLoaderPrivate
0019 {
0020 public:
0021     KonqHistoryList m_history;
0022 };
0023 
0024 KonqHistoryLoader::KonqHistoryLoader(QObject *parent)
0025     : QObject(parent), d(new KonqHistoryLoaderPrivate)
0026 {
0027     loadHistory();
0028 }
0029 
0030 KonqHistoryLoader::~KonqHistoryLoader()
0031 {
0032     delete d;
0033 }
0034 
0035 /**
0036  * Ensures that the items are sorted by the lastVisited date
0037  * (oldest goes first)
0038  */
0039 static bool lastVisitedOrder(const KonqHistoryEntry &lhs, const KonqHistoryEntry &rhs)
0040 {
0041     return lhs.lastVisited < rhs.lastVisited;
0042 }
0043 
0044 bool KonqHistoryLoader::loadHistory()
0045 {
0046     d->m_history.clear();
0047 
0048     const QString filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/konqueror/konq_history");
0049     QFile file(filename);
0050     if (!file.open(QIODevice::ReadOnly)) {
0051         if (file.exists()) {
0052             qCWarning(LIBKONQ_LOG) << "Can't open" << filename;
0053         }
0054         return false;
0055     }
0056 
0057     QDataStream fileStream(&file);
0058     QByteArray data; // only used for version == 2
0059     // we construct the stream object now but fill in the data later.
0060     QDataStream crcStream(&data, QIODevice::ReadOnly);
0061     KonqHistoryEntry::Flags flags = KonqHistoryEntry::NoFlags;
0062 
0063     if (!fileStream.atEnd()) {
0064         quint32 version;
0065         fileStream >> version;
0066 
0067         QDataStream *stream = &fileStream;
0068 
0069         bool crcChecked = false;
0070         bool crcOk = false;
0071 
0072         if (version >= 2 && version <= 4) {
0073             quint32 crc;
0074             crcChecked = true;
0075             fileStream >> crc >> data;
0076             crcOk = crc32(0, reinterpret_cast<unsigned char *>(data.data()), data.size()) == crc;
0077             stream = &crcStream; // pick up the right stream
0078         }
0079 
0080         // We can't read v3 history anymore, because operator<<(KURL) disappeared.
0081 
0082         if (version == 4) {
0083             // Use QUrl marshalling for V4 format.
0084             flags = KonqHistoryEntry::NoFlags;
0085         }
0086 
0087 #if 0 // who cares for versions 1 and 2 nowadays...
0088         if (version != 0 && version < 3) { //Versions 1,2 (but not 0) are also valid
0089             //Turn on backwards compatibility mode..
0090             marshalURLAsStrings = true;
0091             // it doesn't make sense to save to save maxAge and maxCount  in the
0092             // binary file, this would make backups impossible (they would clear
0093             // themselves on startup, because all entries expire).
0094             // [But V1 and V2 formats did it, so we do a dummy read]
0095             quint32 dummy;
0096             *stream >> dummy;
0097             *stream >> dummy;
0098 
0099             //OK.
0100             version = 3;
0101         }
0102 #endif
0103 
0104         if (historyVersion() != int(version) || (crcChecked && !crcOk)) {
0105             qCWarning(LIBKONQ_LOG) << "The history version doesn't match, aborting loading";
0106             file.close();
0107             return false;
0108         }
0109 
0110         while (!stream->atEnd()) {
0111             KonqHistoryEntry entry;
0112             entry.load(*stream, flags);
0113             // qCDebug(LIBKONQ_LOG) << "loaded entry:" << entry.url << ", Title:" << entry.title;
0114             d->m_history.append(entry);
0115         }
0116 
0117         //qCDebug(LIBKONQ_LOG) << "loaded:" << m_history.count() << "entries.";
0118 
0119         std::sort(d->m_history.begin(), d->m_history.end(), lastVisitedOrder);
0120     }
0121 
0122     // Theoretically, we should emit update() here, but as we only ever
0123     // load items on startup up to now, this doesn't make much sense.
0124     // emit KParts::HistoryProvider::update(some list);
0125     return true;
0126 }
0127 
0128 const KonqHistoryList &KonqHistoryLoader::entries() const
0129 {
0130     return d->m_history;
0131 }
0132 
0133 int KonqHistoryLoader::historyVersion()
0134 {
0135     return 4;
0136 }