diff options
Diffstat (limited to 'Source/Core/Common/Config/Section.cpp')
| -rw-r--r-- | Source/Core/Common/Config/Section.cpp | 286 |
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!"); +} +} |
