QGIS API Documentation 3.39.0-Master (d85f3c2a281)
Loading...
Searching...
No Matches
qgsrangerequestcache.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrangerequestcache.cpp
3 --------------------
4 begin : April 2022
5 copyright : (C) 2022 by Belgacem Nedjima
6 email : belgacem dot nedjima at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
19#include "qgsnetworkdiskcache.h"
20
21#include <QtDebug>
22#include <QFile>
23#include <QDir>
24#include <QDateTime>
25
30
31QByteArray QgsRangeRequestCache::entry( const QNetworkRequest &request )
32{
33 QString hash = rangeFileName( request );
34 QByteArray arr = readFile( hash );
35 return arr;
36}
37
38bool QgsRangeRequestCache::hasEntry( const QNetworkRequest &request )
39{
40 QDir dir( mCacheDir );
41 return dir.exists( rangeFileName( request ) );
42}
43
44void QgsRangeRequestCache::registerEntry( const QNetworkRequest &request, QByteArray data )
45{
46 QString hash = rangeFileName( request );
47 writeFile( hash, data );
48 expire();
49}
50
52{
53 QDir dir( mCacheDir );
54 for ( QFileInfo info : dir.entryInfoList() )
55 {
56 removeFile( info.filePath() );
57 }
58}
59
60bool QgsRangeRequestCache::setCacheDirectory( const QString &path )
61{
62 QString cachePath = path;
63 if ( !cachePath.endsWith( QDir::separator() ) )
64 {
65 cachePath.push_back( QDir::separator() );
66 }
67 mCacheDir = cachePath;
68
69 if ( !QDir().mkpath( mCacheDir ) )
70 {
71 mError = QObject::tr( "Unable to create cache directory \"%1\"" ).arg( mCacheDir );
72 return false;
73 }
74 return true;
75}
76
77void QgsRangeRequestCache::setCacheSize( qint64 cacheSize )
78{
79 if ( cacheSize == 0 )
80 {
81 // Calculate maximum cache size based on available free space
82 cacheSize = QgsNetworkDiskCache::smartCacheSize( mCacheDir );
83 }
84
85 mMaxDataSize = cacheSize;
86 expire();
87}
88
89QString QgsRangeRequestCache::rangeFileName( const QNetworkRequest &request ) const
90{
91 return mCacheDir + QStringLiteral( "%1-%2" ).arg( qHash( request.url().toString() ) ).arg( QString::fromUtf8( request.rawHeader( "Range" ) ) );
92}
93
94QByteArray QgsRangeRequestCache::readFile( const QString &fileName )
95{
96 QFile file( fileName );
97 if ( !file.open( QFile::OpenModeFlag::ReadOnly ) )
98 {
99 mError = QObject::tr( "Unable to read cache file \"%1\"" ).arg( fileName );
100 return QByteArray();
101 }
102 return file.readAll();
103}
104
105bool QgsRangeRequestCache::writeFile( const QString &fileName, QByteArray data )
106{
107 QFile file( fileName );
108 if ( !file.open( QFile::OpenModeFlag::WriteOnly ) )
109 {
110 mError = QObject::tr( "Unable to open cache file \"%1\"" ).arg( fileName );
111 return false;
112 }
113 qint64 written = file.write( data );
114 file.close();
115 if ( written != data.size() )
116 {
117 mError = QObject::tr( "Unable to write to cache file \"%1\", error: \"%2\"" ).arg( fileName, file.errorString() );
118 return false;
119 }
120 return true;
121}
122
123bool QgsRangeRequestCache::removeFile( const QString &fileName )
124{
125 if ( fileName.isEmpty() )
126 return false;
127 bool wasRemoved = QFile::remove( fileName );
128 if ( !wasRemoved )
129 {
130 mError = QObject::tr( "Unable to remove cache file \"%1\"" ).arg( fileName );
131 }
132 return wasRemoved;
133}
134
135void QgsRangeRequestCache::expire()
136{
137 QFileInfoList filesList = cacheEntries();
138 qint64 totalSize = 0;
139 for ( QFileInfo &info : filesList )
140 {
141 totalSize += info.size();
142 }
143 while ( totalSize > mMaxDataSize )
144 {
145 QFileInfo info = filesList.back();
146 filesList.pop_back();
147 totalSize -= info.size();
148 removeFile( info.filePath() );
149 }
150}
151
152QFileInfoList QgsRangeRequestCache::cacheEntries()
153{
154 QDir dir( mCacheDir );
155 QFileInfoList filesList = dir.entryInfoList( QDir::Filter::Files, QDir::SortFlags() );
156 std::sort( filesList.begin(), filesList.end(), []( QFileInfo & f1, QFileInfo & f2 )
157 {
158 QDateTime t1 = f1.fileTime( QFile::FileTime::FileAccessTime );
159 if ( !t1.isValid() )
160 t1 = f1.fileTime( QFile::FileTime::FileBirthTime );
161 QDateTime t2 = f2.fileTime( QFile::FileTime::FileAccessTime );
162 if ( !t2.isValid() )
163 t2 = f2.fileTime( QFile::FileTime::FileBirthTime );
164 return t1 > t2;
165 } );
166 return filesList;
167}
static qint64 smartCacheSize(const QString &path)
Returns a smart cache size, in bytes, based on available free space.
void clear()
Clears the cache removing all of the files.
bool hasEntry(const QNetworkRequest &request)
Checks whether the range request exists in the cache.
bool setCacheDirectory(const QString &path)
Set the Cache Directory object.
QByteArray entry(const QNetworkRequest &request)
Returns the range request data stored in the cache and an empty byte array if the data is not in the ...
void registerEntry(const QNetworkRequest &request, QByteArray data)
Adds the range request data into the cache.
void setCacheSize(qint64 maxBytes)
Sets the cache size.
uint qHash(const QVariant &variant)
Hash for QVariant.
Definition qgis.cpp:198