summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Config/Section.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/Config/Section.cpp')
-rw-r--r--Source/Core/Common/Config/Section.cpp286
1 files changed, 286 insertions, 0 deletions
diff --git a/Source/Core/Common/Config/Section.cpp b/Source/Core/Common/Config/Section.cpp
new file mode 100644
index 0000000000..5c7f52eb63
--- /dev/null
+++ b/Source/Core/Common/Config/Section.cpp
@@ -0,0 +1,286 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <array>
+#include <cstddef>
+#include <map>
+#include <memory>
+
+#include "Common/Assert.h"
+#include "Common/Config/Config.h"
+#include "Common/Config/Layer.h"
+#include "Common/Config/Section.h"
+#include "Common/StringUtil.h"
+
+namespace Config
+{
+const std::string& Section::NULL_STRING = "";
+
+Section::Section(LayerType layer, System system, const std::string& name)
+ : m_layer(layer), m_system(system), m_name(name)
+{
+}
+
+bool Section::Exists(const std::string& key) const
+{
+ return m_values.find(key) != m_values.end();
+}
+
+bool Section::Delete(const std::string& key)
+{
+ auto it = m_values.find(key);
+ if (it == m_values.end())
+ return false;
+
+ m_values.erase(it);
+
+ m_deleted_keys.push_back(key);
+ m_dirty = true;
+ return true;
+}
+
+void Section::Set(const std::string& key, const std::string& value)
+{
+ auto it = m_values.find(key);
+ if (it != m_values.end() && it->second != value)
+ {
+ it->second = value;
+ m_dirty = true;
+ }
+ else if (it == m_values.end())
+ {
+ m_values[key] = value;
+ m_dirty = true;
+ }
+}
+
+void Section::Set(const std::string& key, u32 newValue)
+{
+ Section::Set(key, StringFromFormat("0x%08x", newValue));
+}
+
+void Section::Set(const std::string& key, float newValue)
+{
+ Section::Set(key, StringFromFormat("%#.9g", newValue));
+}
+
+void Section::Set(const std::string& key, double newValue)
+{
+ Section::Set(key, StringFromFormat("%#.17g", newValue));
+}
+
+void Section::Set(const std::string& key, int newValue)
+{
+ Section::Set(key, StringFromInt(newValue));
+}
+
+void Section::Set(const std::string& key, bool newValue)
+{
+ Section::Set(key, StringFromBool(newValue));
+}
+
+void Section::Set(const std::string& key, const std::string& newValue,
+ const std::string& defaultValue)
+{
+ if (newValue != defaultValue)
+ Set(key, newValue);
+ else
+ Delete(key);
+}
+
+void Section::SetLines(const std::vector<std::string>& lines)
+{
+ m_lines = lines;
+ m_dirty = true;
+}
+
+bool Section::Get(const std::string& key, std::string* value,
+ const std::string& default_value) const
+{
+ const auto& it = m_values.find(key);
+ if (it != m_values.end())
+ {
+ *value = it->second;
+ return true;
+ }
+ else if (&default_value != &NULL_STRING)
+ {
+ *value = default_value;
+ return true;
+ }
+
+ return false;
+}
+
+bool Section::Get(const std::string& key, int* value, int defaultValue) const
+{
+ std::string temp;
+ bool retval = Get(key, &temp);
+
+ if (retval && TryParse(temp, value))
+ return true;
+
+ *value = defaultValue;
+ return false;
+}
+
+bool Section::Get(const std::string& key, u32* value, u32 defaultValue) const
+{
+ std::string temp;
+ bool retval = Get(key, &temp);
+
+ if (retval && TryParse(temp, value))
+ return true;
+
+ *value = defaultValue;
+ return false;
+}
+
+bool Section::Get(const std::string& key, bool* value, bool defaultValue) const
+{
+ std::string temp;
+ bool retval = Get(key, &temp);
+
+ if (retval && TryParse(temp, value))
+ return true;
+
+ *value = defaultValue;
+ return false;
+}
+
+bool Section::Get(const std::string& key, float* value, float defaultValue) const
+{
+ std::string temp;
+ bool retval = Get(key, &temp);
+
+ if (retval && TryParse(temp, value))
+ return true;
+
+ *value = defaultValue;
+ return false;
+}
+
+bool Section::Get(const std::string& key, double* value, double defaultValue) const
+{
+ std::string temp;
+ bool retval = Get(key, &temp);
+
+ if (retval && TryParse(temp, value))
+ return true;
+
+ *value = defaultValue;
+ return false;
+}
+
+// Return a list of all lines in a section
+bool Section::GetLines(std::vector<std::string>* lines, const bool remove_comments) const
+{
+ lines->clear();
+
+ for (std::string line : m_lines)
+ {
+ line = StripSpaces(line);
+
+ if (remove_comments)
+ {
+ size_t commentPos = line.find('#');
+ if (commentPos == 0)
+ {
+ continue;
+ }
+
+ if (commentPos != std::string::npos)
+ {
+ line = StripSpaces(line.substr(0, commentPos));
+ }
+ }
+
+ lines->push_back(line);
+ }
+
+ return true;
+}
+
+bool Section::HasLines() const
+{
+ return !m_lines.empty();
+}
+
+const std::string& Section::GetName() const
+{
+ return m_name;
+}
+
+const SectionValueMap& Section::GetValues() const
+{
+ return m_values;
+}
+
+const std::vector<std::string>& Section::GetDeletedKeys() const
+{
+ return m_deleted_keys;
+}
+
+bool Section::IsDirty() const
+{
+ return m_dirty;
+}
+void Section::ClearDirty()
+{
+ m_dirty = false;
+}
+
+RecursiveSection::RecursiveSection(LayerType layer, System system, const std::string& name)
+ : Section(layer, system, name)
+{
+}
+
+bool RecursiveSection::Exists(const std::string& key) const
+{
+ auto layers_it = Config::GetLayers()->find(LayerType::Meta);
+ do
+ {
+ const Section* layer_section = layers_it->second->GetSection(m_system, m_name);
+ if (layer_section && layer_section->Exists(key))
+ {
+ return true;
+ }
+ } while (--layers_it != Config::GetLayers()->end());
+
+ return false;
+}
+
+bool RecursiveSection::Get(const std::string& key, std::string* value,
+ const std::string& default_value) const
+{
+ static constexpr std::array<LayerType, 7> search_order = {{
+ // Skip the meta layer
+ LayerType::CurrentRun, LayerType::CommandLine, LayerType::Movie, LayerType::Netplay,
+ LayerType::LocalGame, LayerType::GlobalGame, LayerType::Base,
+ }};
+
+ for (auto layer_id : search_order)
+ {
+ auto layers_it = Config::GetLayers()->find(layer_id);
+ if (layers_it == Config::GetLayers()->end())
+ continue;
+
+ const Section* layer_section = layers_it->second->GetSection(m_system, m_name);
+ if (layer_section && layer_section->Exists(key))
+ {
+ return layer_section->Get(key, value, default_value);
+ }
+ }
+
+ return Section::Get(key, value, default_value);
+}
+
+void RecursiveSection::Set(const std::string& key, const std::string& value)
+{
+ // The RecursiveSection can't set since it is used to recursively get values from the layer
+ // map.
+ // It is only a part of the meta layer, and the meta layer isn't allowed to set any values.
+ _assert_msg_(COMMON, false, "Don't try to set values here!");
+}
+}