commit 9a8ef6677e6d3541f0138598f717043e81dab8b6
parent 71da9301f3b6790b105bc11576e24c948d76a261
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 5 Dec 2015 15:24:16 -0500
enhance how array keys in the configuration files are handled
support deletions and handle tampering better
Diffstat:
3 files changed, 81 insertions(+), 33 deletions(-)
diff --git a/src/config.cpp b/src/config.cpp
@@ -12,6 +12,8 @@
using namespace std;
+static const char *SIZE_KEY = "size";
+
static const char *REMOTES_GRP = "remotes";
static const char *NAME_KEY = "name";
static const char *URL_KEY = "url";
@@ -22,24 +24,14 @@ static const char *VER_KEY = "version";
static string ArrayKey(const string &key, const size_t i)
{
- return to_string(i) + key;
+ return key + to_string(i);
}
static const int BUFFER_SIZE = 2083;
-string Config::getString(const char *group, const string &key) const
+Config::Config()
+ : m_remotesIniSize(0), m_registryIniSize(0)
{
- char buffer[BUFFER_SIZE];
- GetPrivateProfileString(group, key.c_str(), "",
- buffer, sizeof(buffer), m_path.c_str());
-
- return buffer;
-}
-
-void Config::setString(const char *group,
- const string &key, const string &val) const
-{
- WritePrivateProfileString(group, key.c_str(), val.c_str(), m_path.c_str());
}
void Config::fillDefaults()
@@ -62,7 +54,7 @@ void Config::read(const Path &path)
readRegistry();
}
-void Config::write() const
+void Config::write()
{
writeRemotes();
writeRegistry();
@@ -75,50 +67,96 @@ void Config::addRemote(Remote remote)
void Config::readRemotes()
{
- size_t i = 0;
+ m_remotesIniSize = getUInt(REMOTES_GRP, SIZE_KEY);
- do {
+ for(size_t i = 0; i < m_remotesIniSize; i++) {
const string name = getString(REMOTES_GRP, ArrayKey(NAME_KEY, i));
const string url = getString(REMOTES_GRP, ArrayKey(URL_KEY, i));
- if(name.empty() || url.empty())
- break;
-
- addRemote({name, url});
- } while(++i);
+ if(!name.empty() && !url.empty())
+ addRemote({name, url});
+ }
}
-void Config::writeRemotes() const
+void Config::writeRemotes()
{
size_t i = 0;
+ m_remotesIniSize = max(m_remotes.size(), m_remotesIniSize);
for(auto it = m_remotes.begin(); it != m_remotes.end(); it++, i++) {
setString(REMOTES_GRP, ArrayKey(NAME_KEY, i), it->first);
setString(REMOTES_GRP, ArrayKey(URL_KEY, i), it->second);
}
+
+ cleanupArray(REMOTES_GRP, NAME_KEY, i, m_remotesIniSize);
+ cleanupArray(REMOTES_GRP, URL_KEY, i, m_remotesIniSize);
+
+ setUInt(REGISTRY_GRP, SIZE_KEY, m_remotesIniSize = i);
}
void Config::readRegistry()
{
- size_t i = 0;
+ m_registryIniSize = getUInt(REGISTRY_GRP, SIZE_KEY);
- do {
+ for(size_t i = 0; i < m_registryIniSize; i++) {
const string pack = getString(REGISTRY_GRP, ArrayKey(PACK_KEY, i));
const string ver = getString(REGISTRY_GRP, ArrayKey(VER_KEY, i));
- if(pack.empty() || ver.empty())
- break;
-
- m_registry.push(pack, ver);
- } while(++i);
+ if(!pack.empty() && !ver.empty())
+ m_registry.push(pack, ver);
+ }
}
-void Config::writeRegistry() const
+void Config::writeRegistry()
{
size_t i = 0;
+ m_registryIniSize = max(m_registry.size(), m_registryIniSize);
for(auto it = m_registry.begin(); it != m_registry.end(); it++, i++) {
setString(REGISTRY_GRP, ArrayKey(PACK_KEY, i), it->first);
setString(REGISTRY_GRP, ArrayKey(VER_KEY, i), it->second);
}
+
+ cleanupArray(REGISTRY_GRP, PACK_KEY, i, m_registryIniSize);
+ cleanupArray(REGISTRY_GRP, VER_KEY, i, m_registryIniSize);
+
+ setUInt(REGISTRY_GRP, SIZE_KEY, m_registryIniSize = i);
+}
+
+string Config::getString(const char *group, const string &key) const
+{
+ char buffer[BUFFER_SIZE];
+ GetPrivateProfileString(group, key.c_str(), "",
+ buffer, sizeof(buffer), m_path.c_str());
+
+ return buffer;
+}
+
+void Config::setString(const char *group,
+ const string &key, const string &val) const
+{
+ WritePrivateProfileString(group, key.c_str(), val.c_str(), m_path.c_str());
+}
+
+size_t Config::getUInt(const char *group, const string &key) const
+{
+ const int i = GetPrivateProfileInt(group, key.c_str(), 0, m_path.c_str());
+ return max(0, i);
+}
+
+void Config::setUInt(const char *grp, const string &key, const size_t val) const
+{
+ setString(grp, key, to_string(val));
+}
+
+void Config::deleteKey(const char *group, const string &key) const
+{
+ WritePrivateProfileString(group, key.c_str(), 0, m_path.c_str());
+}
+
+void Config::cleanupArray(const char *group, const string &key,
+ const size_t begin, const size_t end) const
+{
+ for(size_t i = begin; i < end; i++)
+ deleteKey(group, ArrayKey(key, i));
}
diff --git a/src/config.hpp b/src/config.hpp
@@ -10,8 +10,10 @@ class Path;
class Config {
public:
+ Config();
+
void read(const Path &);
- void write() const;
+ void write();
void addRemote(Remote);
const RemoteMap &remotes() const { return m_remotes; }
@@ -20,18 +22,25 @@ public:
private:
std::string getString(const char *, const std::string &) const;
void setString(const char *, const std::string &, const std::string &) const;
+ size_t getUInt(const char *, const std::string &) const;
+ void setUInt(const char *, const std::string &, const size_t) const;
+ void deleteKey(const char *, const std::string &) const;
+ void cleanupArray(const char *, const std::string &,
+ const size_t begin, const size_t end) const;
void fillDefaults();
std::string m_path;
void readRemotes();
- void writeRemotes() const;
+ void writeRemotes();
RemoteMap m_remotes;
+ size_t m_remotesIniSize;
void readRegistry();
- void writeRegistry() const;
+ void writeRegistry();
Registry m_registry;
+ size_t m_registryIniSize;
};
#endif
diff --git a/src/registry.hpp b/src/registry.hpp
@@ -13,6 +13,7 @@ public:
void push(Package *pkg);
void push(const std::string &key, const std::string &value);
+ size_t size() const { return m_map.size(); }
std::string versionOf(Package *pkg) const;
Map::const_iterator begin() const { return m_map.begin(); }