Implement reading of config values

This commit is contained in:
Ted John 2017-02-12 21:44:56 +00:00
parent d5ee210797
commit f8f60a69a7
1 changed files with 125 additions and 13 deletions

View File

@ -11,12 +11,39 @@ class ConfigEnum
}; };
struct Span
{
size_t Start = 0;
size_t Length = 0;
Span() = default;
Span(size_t start, size_t length)
: Start(start),
Length(length)
{
}
};
struct LineRange
{
size_t Start = 0;
size_t End = 0;
LineRange() = default;
LineRange(size_t start, size_t end)
: Start(start),
End(end)
{
}
};
class IniReader class IniReader
{ {
private: private:
std::vector<uint8> _buffer; std::vector<uint8> _buffer;
std::vector<std::tuple<size_t, size_t>> _lines; std::vector<Span> _lines;
std::unordered_map<std::string, size_t> _sections; std::unordered_map<std::string, LineRange> _sections;
std::unordered_map<std::string, std::string> _values;
public: public:
IniReader(const std::string &path) IniReader(const std::string &path)
@ -47,24 +74,43 @@ public:
return false; return false;
} }
size_t startLine = it->second; ParseValues(it->second);
UNUSED(startLine);
return true; return true;
} }
bool GetBoolean(const std::string &name, bool defaultValue) bool GetBoolean(const std::string &name, bool defaultValue)
{ {
auto it = _values.find(name);
if (it == _values.end())
{
return defaultValue;
}
std::string value = it->second;
return String::Equals(value, "true", true);
} }
sint32 GetSint32(const std::string &name, sint32 defaultValue, const ConfigEnum * configEnum = nullptr) sint32 GetSint32(const std::string &name, sint32 defaultValue, const ConfigEnum * configEnum = nullptr)
{ {
auto it = _values.find(name);
if (it == _values.end())
{
return defaultValue;
}
std::string value = it->second;
return std::stoi(value);
} }
std::string GetString(const std::string &name, const std::string &defaultValue) std::string GetString(const std::string &name, const std::string &defaultValue)
{ {
auto it = _values.find(name);
if (it == _values.end())
{
return defaultValue;
}
return it->second;
} }
private: private:
@ -105,6 +151,9 @@ private:
void ParseSections() void ParseSections()
{ {
std::string sectionName;
LineRange lineRange;
for (size_t i = 0; i < _lines.size(); i++) for (size_t i = 0; i < _lines.size(); i++)
{ {
std::string line = GetLine(i); std::string line = GetLine(i);
@ -112,29 +161,92 @@ private:
if (line.size() > 3 && line[0] == '[') if (line.size() > 3 && line[0] == '[')
{ {
size_t endIndex = line.find_first_of(']'); size_t endIndex = line.find_first_of(']');
std::string sectionName = line.substr(1, endIndex - 1); if (endIndex != std::string::npos)
_sections[sectionName] = i; {
// Add last section
if (!sectionName.empty())
{
lineRange.End = i - 1;
_sections[sectionName] = lineRange;
}
// Set up new section
sectionName = line.substr(1, endIndex - 1);
lineRange.Start = i;
}
} }
} }
// Add final section
if (!sectionName.empty())
{
lineRange.End = _lines.size() - 1;
_sections[sectionName] = lineRange;
}
}
void ParseValues(LineRange range)
{
for (size_t i = range.Start + 1; i <= range.End; i++)
{
ParseValue(i);
}
}
void ParseValue(size_t lineIndex)
{
std::string line = GetLine(lineIndex);
// Chop off comment
size_t hashIndex = line.find_first_of('#');
if (hashIndex != std::string::npos)
{
line = line.substr(0, hashIndex);
}
// Find assignment character
size_t equalsIndex = line.find_first_of('=');
if (equalsIndex == std::string::npos)
{
return;
}
// Get the key and value
std::string key = String::Trim(line.substr(0, equalsIndex));
std::string value = String::Trim(line.substr(equalsIndex + 1));
_values[key] = value;
} }
std::string GetLine(size_t index) std::string GetLine(size_t index)
{ {
utf8 * szBuffer = (utf8 *)_buffer.data(); utf8 * szBuffer = (utf8 *)_buffer.data();
auto span = _lines[index]; auto span = _lines[index];
auto line = std::string(szBuffer + std::get<0>(span), std::get<1>(span)); auto line = std::string(szBuffer + span.Start, span.Length);
return line; return line;
} }
}; };
extern "C" extern "C"
{ {
#include "../config.h"
bool config_open(const utf8 * path) bool config_open(const utf8 * path)
{ {
auto iniReader = IniReader(path); try
bool b = iniReader.ReadSection("general"); {
UNUSED(b); auto iniReader = IniReader(path);
if (iniReader.ReadSection("general"))
return false; {
gConfigGeneral.always_show_gridlines = iniReader.GetBoolean("always_show_gridlines", false);
gConfigGeneral.window_width = iniReader.GetSint32("window_width", -1);
gConfigGeneral.window_height = iniReader.GetSint32("window_height", -1);
}
return true;
}
catch (const Exception &)
{
return false;
}
} }
} }