dolphin/Source/Core/Common/Config/Section.cpp

280 lines
5.8 KiB
C++

// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#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
{
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!");
}
}