QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
20#include <QtDebug>
21#include <QFile>
22#include <QDir>
23#include <QDateTime>
24
26{
27
28}
29
30QByteArray QgsRangeRequestCache::entry( const QNetworkRequest &request )
31{
32 QString hash = rangeFileName( request );
33 QByteArray arr = readFile( hash );
34 return arr;
35}
36
37bool QgsRangeRequestCache::hasEntry( const QNetworkRequest &request )
38{
39 QDir dir( mCacheDir );
40 return dir.exists( rangeFileName( request ) );
41}
42
43void QgsRangeRequestCache::registerEntry( const QNetworkRequest &request, QByteArray data )
44{
45 QString hash = rangeFileName( request );
46 writeFile( hash, data );
47 expire();
48}
49
51{
52 QDir dir( mCacheDir );
53 for ( QFileInfo info : dir.entryInfoList() )
54 {
55 removeFile( info.filePath() );
56 }
57}
58
59bool QgsRangeRequestCache::setCacheDirectory( const QString &path )
60{
61 QString cachePath = path;
62 if ( !cachePath.endsWith( QDir::separator() ) )
63 {
64 cachePath.push_back( QDir::separator() );
65 }
66 mCacheDir = cachePath;
67
68 if ( !QDir().mkpath( mCacheDir ) )
69 {
70 mError = QObject::tr( "Unable to create cache directory \"%1\"" ).arg( mCacheDir );
71 return false;
72 }
73 return true;
74}
75
76void QgsRangeRequestCache::setCacheSize( qint64 cacheSize )
77{
78 mMaxDataSize = cacheSize;
79 expire();
80}
81
82QString QgsRangeRequestCache::rangeFileName( const QNetworkRequest &request ) const
83{
84 return mCacheDir + QStringLiteral( "%1-%2" ).arg( qHash( request.url().toString() ) ).arg( QString::fromUtf8( request.rawHeader( "Range" ) ) );
85}
86
87QByteArray QgsRangeRequestCache::readFile( const QString &fileName )
88{
89 QFile file( fileName );
90 if ( !file.open( QFile::OpenModeFlag::ReadOnly ) )
91 {
92 mError = QObject::tr( "Unable to read cache file \"%1\"" ).arg( fileName );
93 return QByteArray();
94 }
95 return file.readAll();
96}
97
98bool QgsRangeRequestCache::writeFile( const QString &fileName, QByteArray data )
99{
100 QFile file( fileName );
101 if ( !file.open( QFile::OpenModeFlag::WriteOnly ) )
102 {
103 mError = QObject::tr( "Unable to open cache file \"%1\"" ).arg( fileName );
104 return false;
105 }
106 qint64 written = file.write( data );
107 file.close();
108 if ( written != data.size() )
109 {
110 mError = QObject::tr( "Unable to write to cache file \"%1\", error: \"%2\"" ).arg( fileName, file.errorString() );
111 return false;
112 }
113 return true;
114}
115
116bool QgsRangeRequestCache::removeFile( const QString &fileName )
117{
118 if ( fileName.isEmpty() )
119 return false;
120 bool wasRemoved = QFile::remove( fileName );
121 if ( !wasRemoved )
122 {
123 mError = QObject::tr( "Unable to remove cache file \"%1\"" ).arg( fileName );
124 }
125 return wasRemoved;
126}
127
128void QgsRangeRequestCache::expire()
129{
130 QFileInfoList filesList = cacheEntries();
131 qint64 totalSize = 0;
132 for ( QFileInfo &info : filesList )
133 {
134 totalSize += info.size();
135 }
136 while ( totalSize > mMaxDataSize )
137 {
138 QFileInfo info = filesList.back();
139 filesList.pop_back();
140 totalSize -= info.size();
141 removeFile( info.filePath() );
142 }
143}
144
145QFileInfoList QgsRangeRequestCache::cacheEntries()
146{
147 QStringList list;
148 QDir dir( mCacheDir );
149 QFileInfoList filesList = dir.entryInfoList( QDir::Filter::Files, QDir::SortFlags() );
150 std::sort( filesList.begin(), filesList.end(), []( QFileInfo & f1, QFileInfo & f2 )
151 {
152 QDateTime t1 = f1.fileTime( QFile::FileTime::FileAccessTime );
153 if ( !t1.isValid() )
154 t1 = f1.fileTime( QFile::FileTime::FileBirthTime );
155 QDateTime t2 = f2.fileTime( QFile::FileTime::FileAccessTime );
156 if ( !t2.isValid() )
157 t2 = f2.fileTime( QFile::FileTime::FileBirthTime );
158 return t1 > t2;
159 } );
160 return filesList;
161}
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.
QgsRangeRequestCache()
Constructor.
void setCacheSize(qint64 maxBytes)
Sets the cache size.
uint qHash(const QVariant &variant)
Hash for QVariant.
Definition: qgis.cpp:217