1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#include "HttpMetaCache.h"
#include <pathutils.h>
#include <QFile>
#include <qjsondocument.h>
#include <qjsonarray.h>
#include <qjsonobject.h>
#include <qfileinfo.h>
#include <qtemporaryfile.h>
#include <qsavefile.h>
HttpMetaCache::HttpMetaCache(QString path)
{
m_index_file = path;
}
HttpMetaCache::~HttpMetaCache()
{
Save();
}
void HttpMetaCache::addEntry ( QString base, QString resource_path, QString etag )
{
// no base. no base path. can't store
if(!m_entries.contains(base))
return;
QString real_path = PathCombine(m_entries[base].base_path, resource_path);
QFileInfo finfo(real_path);
// just ignore it, it's garbage if it's not a proper file
if(!finfo.isFile() || !finfo.isReadable())
{
// TODO: log problem
return;
}
Save();
}
void HttpMetaCache::addBase ( QString base, QString base_root )
{
// TODO: report error
if(m_entries.contains(base))
return;
// TODO: check if the base path is valid
EntryMap foo;
foo.base_path = base_root;
m_entries[base] = foo;
}
void HttpMetaCache::Load()
{
QFile index(m_index_file);
if(!index.open(QIODevice::ReadOnly))
return;
QJsonDocument json = QJsonDocument::fromJson(index.readAll());
if(!json.isObject())
return;
auto root = json.object();
// check file version first
auto version_val =root.value("version");
if(!version_val.isString())
return;
if(version_val.toString() != "1")
return;
// read the entry array
auto entries_val =root.value("entries");
if(!version_val.isArray())
return;
QJsonArray array = json.array();
for(auto element: array)
{
if(!element.isObject());
return;
auto element_obj = element.toObject();
QString base = element_obj.value("base").toString();
if(!m_entries.contains(base))
continue;
auto & entrymap = m_entries[base];
auto foo = new MetaEntry;
foo->base = base;
QString path = foo->path = element_obj.value("path").toString();
foo->md5sum = element_obj.value("md5sum").toString();
foo->etag = element_obj.value("etag").toString();
foo->last_changed_timestamp = element_obj.value("last_changed_timestamp").toDouble();
entrymap.entry_list[path] = MetaEntryPtr( foo );
}
}
void HttpMetaCache::Save()
{
QSaveFile tfile(m_index_file);
if(!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
return;
QJsonObject toplevel;
toplevel.insert("version",QJsonValue(QString("1")));
QJsonArray entriesArr;
for(auto group : m_entries)
{
for(auto entry : group.entry_list)
{
QJsonObject entryObj;
entryObj.insert("base", QJsonValue(entry->base));
entryObj.insert("path", QJsonValue(entry->path));
entryObj.insert("md5sum", QJsonValue(entry->md5sum));
entryObj.insert("etag", QJsonValue(entry->etag));
entryObj.insert("last_changed_timestamp", QJsonValue(double(entry->last_changed_timestamp)));
entriesArr.append(entryObj);
}
}
toplevel.insert("entries",entriesArr);
QJsonDocument doc(toplevel);
QByteArray jsonData = doc.toJson();
qint64 result = tfile.write(jsonData);
if(result == -1)
return;
if(result != jsonData.size())
return;
tfile.commit();
}
MetaEntryPtr HttpMetaCache::getEntryForResource ( QString base, QString resource_path )
{
if(!m_entries.contains(base))
return MetaEntryPtr();
auto & entrymap = m_entries[base];
if(!entrymap.entry_list.contains(resource_path))
return MetaEntryPtr();
return entrymap.entry_list[resource_path];
}
|