9#include "QtCore/qscopedpointer.h"
22#define CACHE_POSTFIX ".d"_L1
23#define CACHE_VERSION 8
24#define DATA_DIR "data"_L1
26#define MAX_COMPRESSION_SIZE (1024 * 1024 * 3)
91 return d->cacheDirectory;
106#if defined(QNETWORKDISKCACHE_DEBUG)
107 qDebug() <<
"QNetworkDiskCache::setCacheDirectory()" << cacheDir;
110 if (cacheDir.isEmpty())
112 d->cacheDirectory = cacheDir;
114 d->cacheDirectory =
dir.absolutePath();
115 if (!
d->cacheDirectory.endsWith(u
'/'))
116 d->cacheDirectory += u
'/';
127#if defined(QNETWORKDISKCACHE_DEBUG)
128 qDebug(
"QNetworkDiskCache::cacheSize()");
131 if (
d->cacheDirectory.isEmpty())
133 if (
d->currentCacheSize < 0) {
135 that->d_func()->currentCacheSize = that->
expire();
137 return d->currentCacheSize;
145#if defined(QNETWORKDISKCACHE_DEBUG)
152 if (
d->cacheDirectory.isEmpty()) {
153 qWarning(
"QNetworkDiskCache::prepare() The cache directory is not set");
162 std::unique_ptr<QCacheItem> cacheItem = std::make_unique<QCacheItem>();
166 if (cacheItem->canCompress()) {
168 device = &(cacheItem->data);
171 cacheItem->file =
new(std::nothrow) QSaveFile(
fileName, &cacheItem->data);
173 qWarning(
"QNetworkDiskCache::prepare() unable to open temporary file");
177 cacheItem->writeHeader(cacheItem->file);
180 d->inserting[
device] = cacheItem.release();
189#if defined(QNETWORKDISKCACHE_DEBUG)
195 qWarning() <<
"QNetworkDiskCache::insert() called on a device we don't know about" <<
device;
199 d->storeItem(
it.value());
215 for (
uint i = 0;
i < 16 ;
i++) {
218 helper.
mkdir(subdir);
226 Q_ASSERT(cacheItem->metaData.saveToDisk());
233 qWarning() <<
"QNetworkDiskCache: couldn't remove the cache file " <<
fileName;
239 if (!cacheItem->file) {
240 cacheItem->file =
new QSaveFile(
fileName, &cacheItem->data);
242 cacheItem->writeHeader(cacheItem->file);
243 cacheItem->writeCompressedData(cacheItem->file);
248 && cacheItem->file->isOpen()
254 if (cacheItem->file->commit())
257 delete std::exchange(cacheItem->file,
nullptr);
268#if defined(QNETWORKDISKCACHE_DEBUG)
269 qDebug() <<
"QNetworkDiskCache::remove()" <<
url;
278 d->inserting.erase(
it);
283 if (
d->lastItem.metaData.url() ==
url)
285 return d->removeFile(
d->cacheFileName(
url));
293#if defined(QNETWORKDISKCACHE_DEBUG)
294 qDebug() <<
"QNetworkDiskCache::removFile()" <<
file;
315#if defined(QNETWORKDISKCACHE_DEBUG)
316 qDebug() <<
"QNetworkDiskCache::metaData()" <<
url;
319 if (
d->lastItem.metaData.url() ==
url)
320 return d->lastItem.metaData;
331#if defined(QNETWORKDISKCACHE_DEBUG)
338 if (!
d->lastItem.read(&
file,
false)) {
343 return d->lastItem.metaData;
351#if defined(QNETWORKDISKCACHE_DEBUG)
352 qDebug() <<
"QNetworkDiskCache::data()" <<
url;
355 std::unique_ptr<QBuffer>
buffer;
358 if (
d->lastItem.metaData.url() ==
url &&
d->lastItem.data.isOpen()) {
360 buffer->setData(
d->lastItem.data.data());
362 QScopedPointer<QFile>
file(
new QFile(
d->cacheFileName(
url)));
366 if (!
d->lastItem.read(
file.data(),
true)) {
371 if (
d->lastItem.data.isOpen()) {
374 buffer->setData(
d->lastItem.data.data());
389#if defined(QNETWORKDISKCACHE_DEBUG)
395#if defined(QNETWORKDISKCACHE_DEBUG)
396 qDebug(
"QNetworkDiskCache::updateMetaData(), no device!");
403#if defined(QNETWORKDISKCACHE_DEBUG)
404 qDebug() <<
"QNetworkDiskCache::updateMetaData(), no new device!" <<
url;
409 while (!oldDevice->atEnd()) {
411 newDevice->write(
data,
s);
425 return d->maximumCacheSize;
438 bool expireCache = (
size <
d->maximumCacheSize);
439 d->maximumCacheSize =
size;
441 d->currentCacheSize =
expire();
466 return d->currentCacheSize;
469 qWarning(
"QNetworkDiskCache::expire() The cache directory is not set");
480 std::chrono::milliseconds msecs;
484 std::vector<CacheItem> cacheItems;
497 cacheItems.push_back(CacheItem{msecs,
info.filePath(),
size});
502 if (totalSize < goal)
505 auto byFileTime = [&](
const auto &
a,
const auto &
b) {
return a.msecs <
b.msecs; };
506 std::sort(cacheItems.begin(), cacheItems.end(), byFileTime);
508 [[maybe_unused]]
int removedFiles = 0;
509 for (
const CacheItem &cached : cacheItems) {
512 totalSize -= cached.size;
513 if (totalSize < goal)
516#if defined(QNETWORKDISKCACHE_DEBUG)
517 if (removedFiles > 0) {
518 qDebug() <<
"QNetworkDiskCache::expire()"
519 <<
"Removed:" << removedFiles
520 <<
"Kept:" << cacheItems.count() - removedFiles;
531#if defined(QNETWORKDISKCACHE_DEBUG)
532 qDebug(
"QNetworkDiskCache::clear()");
536 d->maximumCacheSize = 0;
537 d->currentCacheSize =
expire();
538 d->maximumCacheSize =
size;
548 cleanUrl.setFragment(
QString());
580 if (sizeValue.empty())
591 if (!
type.startsWith(
"text/")
592 && !(
type.startsWith(
"application/")
593 && (
type.endsWith(
"javascript") ||
type.endsWith(
"ecmascript")))) {
612 out << static_cast<qint32>(
out.version());
649 if (streamVersion >
in.version())
651 in.setVersion(streamVersion);
665 if (!
device->fileName().endsWith(expectedFilename))
673#include "moc_qnetworkdiskcache.cpp"
IOBluetoothDevice * device
The QAbstractNetworkCache class provides the interface for cache implementations.
\inmodule QtCore \reentrant
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
void writeCompressedData(QFileDevice *device) const
bool canCompress() const
We compress small text and JavaScript files.
bool read(QFileDevice *device, bool readData)
Returns false if the file is a cache file, but is an older version and should be removed otherwise tr...
QNetworkCacheMetaData metaData
void writeHeader(QFileDevice *device) const
static QByteArray hash(QByteArrayView data, Algorithm method)
Returns the hash of data using method.
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
qint64 toMSecsSinceEpoch() const
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
The QDirListing class provides an STL-style iterator for directory entries.
IteratorFlag
This enum class describes flags can be used to configure the behavior of QDirListing.
bool mkdir(const QString &dirName) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool mkpath(const QString &dirPath) const
Creates the directory path dirPath.
void close() override
Calls QFileDevice::flush() and closes the file.
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
bool remove()
Removes the file specified by fileName().
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
\inmodule QtCore \reentrant
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
bool removeFile(const QString &file)
Put all of the misc file removing into one function to be extra safe.
QString cacheFileName(const QUrl &url) const
Generates fully qualified path of cached resource from a URL.
static QString uniqueFileName(const QUrl &url)
Given a URL, generates a unique enough filename (and subdirectory)
void prepareLayout()
Create subdirectories and other housekeeping on the filesystem.
void storeItem(QCacheItem *item)
The QNetworkDiskCache class provides a very basic disk cache.
void insert(QIODevice *device) override
\reimp
QNetworkCacheMetaData metaData(const QUrl &url) override
\reimp
void updateMetaData(const QNetworkCacheMetaData &metaData) override
\reimp
QIODevice * prepare(const QNetworkCacheMetaData &metaData) override
\reimp
void setCacheDirectory(const QString &cacheDir)
Sets the directory where cached files will be stored to cacheDir.
virtual qint64 expire()
Cleans the cache so that its size is under the maximum cache size.
void clear() override
\reimp
QString cacheDirectory() const
Returns the location where cached files will be stored.
QNetworkCacheMetaData fileMetaData(const QString &fileName) const
Returns the QNetworkCacheMetaData for the cache file fileName.
QNetworkDiskCache(QObject *parent=nullptr)
Creates a new disk cache.
~QNetworkDiskCache()
Destroys the cache object.
QIODevice * data(const QUrl &url) override
\reimp
void setMaximumCacheSize(qint64 size)
Sets the maximum size of the disk cache to be size.
qint64 maximumCacheSize() const
Returns the current maximum size for the disk cache.
bool remove(const QUrl &url) override
\reimp
qint64 cacheSize() const override
\reimp
const_iterator cend() const noexcept
iterator erase(const_iterator i)
const_iterator constFind(const T &value) const
const_iterator cbegin() const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setPassword(const QString &password, ParsingMode mode=DecodedMode)
Sets the URL's password to password.
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
QHash< int, QWidget * > hash
[35multi]
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes)
#define MAX_COMPRESSION_SIZE
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat GLfloat GLfloat h
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
QTextStream out(stdout)
[7]
QUrl url("example.com")
[constructor-url-reference]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]