aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/tools/persistence.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/tools/persistence.h')
-rw-r--r--src/lib/corelib/tools/persistence.h130
1 files changed, 101 insertions, 29 deletions
diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h
index 2687d6120..e8d938ad3 100644
--- a/src/lib/corelib/tools/persistence.h
+++ b/src/lib/corelib/tools/persistence.h
@@ -42,6 +42,8 @@
#include "error.h"
#include <logging/logger.h>
+#include <tools/qbsassert.h>
+#include <tools/qttools.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qflags.h>
@@ -137,20 +139,34 @@ private:
template <typename T> T *idLoad();
template <class T> std::shared_ptr<T> idLoadS();
+ template <typename T> T idLoadValue();
+
+ void doLoadValue(QString &s);
+ void doLoadValue(QStringList &l);
+ void doLoadValue(QProcessEnvironment &env);
template<typename T> void storeSharedObject(const T *object);
void storeVariant(const QVariant &variant);
QVariant loadVariant();
- void storeString(const QString &t);
- QString loadString(int id);
- QString idLoadString();
+ template <typename T> void idStoreValue(const T &value);
+
+ void doStoreValue(const QString &s);
+ void doStoreValue(const QStringList &l);
+ void doStoreValue(const QProcessEnvironment &env);
+
+ template<typename T> std::vector<T> &idStorage();
+ template<typename T> QHash<T, PersistentObjectId> &idMap();
+ template<typename T> PersistentObjectId &lastStoredId();
// Recursion termination
void store() {}
void load() {}
+ static const PersistentObjectId ValueNotFoundId = -1;
+ static const PersistentObjectId EmptyValueId = -2;
+
QDataStream m_stream;
HeadData m_headData;
std::vector<void *> m_loadedRaw;
@@ -161,6 +177,12 @@ private:
std::vector<QString> m_stringStorage;
QHash<QString, int> m_inverseStringStorage;
PersistentObjectId m_lastStoredStringId;
+ std::vector<QProcessEnvironment> m_envStorage;
+ QHash<QProcessEnvironment, int> m_inverseEnvStorage;
+ PersistentObjectId m_lastStoredEnvId;
+ std::vector<QStringList> m_stringListStorage;
+ QHash<QStringList, int> m_inverseStringListStorage;
+ PersistentObjectId m_lastStoredStringListId;
Logger &m_logger;
template<typename T, typename Enable>
@@ -209,6 +231,42 @@ template <typename T> inline T *PersistentPool::idLoad()
return t;
}
+template<> inline std::vector<QString> &PersistentPool::idStorage() { return m_stringStorage; }
+template<> inline QHash<QString, PersistentPool::PersistentObjectId> &PersistentPool::idMap()
+{
+ return m_inverseStringStorage;
+}
+template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QString>()
+{
+ return m_lastStoredStringId;
+}
+template<> inline std::vector<QStringList> &PersistentPool::idStorage()
+{
+ return m_stringListStorage;
+}
+template<> inline QHash<QStringList, PersistentPool::PersistentObjectId> &PersistentPool::idMap()
+{
+ return m_inverseStringListStorage;
+}
+template<> inline PersistentPool::PersistentObjectId &PersistentPool::lastStoredId<QStringList>()
+{
+ return m_lastStoredStringListId;
+}
+template<> inline std::vector<QProcessEnvironment> &PersistentPool::idStorage()
+{
+ return m_envStorage;
+}
+template<> inline QHash<QProcessEnvironment, PersistentPool::PersistentObjectId>
+&PersistentPool::idMap()
+{
+ return m_inverseEnvStorage;
+}
+template<> inline PersistentPool::PersistentObjectId
+&PersistentPool::lastStoredId<QProcessEnvironment>()
+{
+ return m_lastStoredEnvId;
+}
+
template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS()
{
PersistentObjectId id;
@@ -227,6 +285,41 @@ template <class T> inline std::shared_ptr<T> PersistentPool::idLoadS()
return t;
}
+template<typename T> inline T PersistentPool::idLoadValue()
+{
+ int id;
+ m_stream >> id;
+ if (id == EmptyValueId)
+ return T();
+ QBS_CHECK(id >= 0);
+ if (id >= static_cast<int>(idStorage<T>().size())) {
+ T value;
+ doLoadValue(value);
+ idStorage<T>().resize(id + 1);
+ idStorage<T>()[id] = value;
+ return value;
+ }
+ return idStorage<T>().at(id);
+}
+
+template<typename T>
+void PersistentPool::idStoreValue(const T &value)
+{
+ if (value.isEmpty()) {
+ m_stream << EmptyValueId;
+ return;
+ }
+ int id = idMap<T>().value(value, ValueNotFoundId);
+ if (id < 0) {
+ id = lastStoredId<T>()++;
+ idMap<T>().insert(value, id);
+ m_stream << id;
+ doStoreValue(value);
+ } else {
+ m_stream << id;
+ }
+}
+
// We need a helper class template, because we require partial specialization for some of
// the aggregate types, which is not possible with function templates.
// The generic implementation assumes that T is of class type and has load() and store()
@@ -320,10 +413,11 @@ template<typename T> struct PPHelper<T *>
static void load(T* &value, PersistentPool *pool) { value = pool->idLoad<T>(); }
};
-template<> struct PPHelper<QString>
+template<typename T> struct PPHelper<T, std::enable_if_t<std::is_same<T, QString>::value
+ || std::is_same<T, QStringList>::value || std::is_same<T, QProcessEnvironment>::value>>
{
- static void store(const QString &s, PersistentPool *pool) { pool->storeString(s); }
- static void load(QString &s, PersistentPool *pool) { s = pool->idLoadString(); }
+ static void store(const T &v, PersistentPool *pool) { pool->idStoreValue(v); }
+ static void load(T &v, PersistentPool *pool) { v = pool->idLoadValue<T>(); }
};
template<> struct PPHelper<QVariant>
@@ -335,30 +429,9 @@ template<> struct PPHelper<QVariant>
template<> struct PPHelper<QRegExp>
{
static void store(const QRegExp &re, PersistentPool *pool) { pool->store(re.pattern()); }
- static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->idLoadString()); }
+ static void load(QRegExp &re, PersistentPool *pool) { re.setPattern(pool->load<QString>()); }
};
-template<> struct PPHelper<QProcessEnvironment>
-{
- static void store(const QProcessEnvironment &env, PersistentPool *pool)
- {
- const QStringList &keys = env.keys();
- pool->store(keys.size());
- for (const QString &key : keys) {
- pool->store(key);
- pool->store(env.value(key));
- }
- }
- static void load(QProcessEnvironment &env, PersistentPool *pool)
- {
- const int count = pool->load<int>();
- for (int i = 0; i < count; ++i) {
- const auto &key = pool->load<QString>();
- const auto &value = pool->load<QString>();
- env.insert(key, value);
- }
- }
-};
template<typename T, typename U> struct PPHelper<std::pair<T, U>>
{
static void store(const std::pair<T, U> &pair, PersistentPool *pool)
@@ -387,7 +460,6 @@ template<typename T> struct PPHelper<QFlags<T>>
};
template<typename T> struct IsSimpleContainer : std::false_type { };
-template<> struct IsSimpleContainer<QStringList> : std::true_type { };
template<typename T> struct IsSimpleContainer<QList<T>> : std::true_type { };
template<typename T> struct IsSimpleContainer<std::vector<T>> : std::true_type { };