1#include <Config/INI.hpp>
2#include <Misc/Utils.hpp>
6 name = Utils::String::trim(name);
29 name = Utils::String::trim(name);
30 value = Utils::String::trim(value);
32 std::pair<Level::ValueMap::const_iterator, bool> res =
33 this->values.insert(std::make_pair(name, value));
39 this->values[name] = value;
42 this->ordered_values.push_back(res.first);
45void INI::Parser::raise_error(std::string msg)
47 std::string buffer = (
"Error '" +
50 Utils::String::toString(this->lines));
52 throw std::runtime_error(buffer);
62 input_file(filename.c_str()),
67 throw std::runtime_error(
"Failed to open file: " + filename);
69 parse(this->top_level);
76 parse(this->top_level);
81 return this->top_level;
86 dump(stream, top(),
"");
89void INI::Parser::parseLevelLine(std::string& sname,
size_t& depth)
93 for (; depth < line_.length(); ++depth)
94 if (line_[depth] !=
'[')
break;
96 sname = line_.substr(depth, line_.length() - 2*depth);
101 while (std::getline(*input, line_))
105 if (line_[0] ==
'#' || line_[0] ==
';')
continue;
107 line_ = Utils::String::trim(line_);
109 if (line_.empty())
continue;
117 parseLevelLine(sname, depth);
122 if (depth > level.
depth + 1)
123 raise_error(
"section with wrong depth");
125 if (level.
depth == depth - 1)
126 level_current = &level.
sections[sname];
130 level_current = level.
parent;
132 size_t n = (level.
depth - depth);
134 for (
size_t i = 0; i < n; ++i)
135 level_current = level_current->
parent;
137 parent = level_current;
139 level_current = &level_current->
sections[sname];
143 if (level_current->
depth != 0)
144 raise_error(
"duplicate section name on the same level");
146 if (!level_current->
parent)
148 level_current->
depth = depth;
149 level_current->
parent = parent;
154 parse(*level_current);
161 size_t pos = line_.find(
'=');
163 if (pos == std::string::npos)
164 raise_error(
"no '=' found");
166 std::string key = line_.substr(0, pos);
167 std::string value = line_.substr((pos + 1), (line_.length()-pos-1));
179 for (
size_t i = 0; i < l.
depth; ++i)
185 for (
size_t i = 0; i < l.
depth; ++i)
191 for (INI::Level::Values::const_iterator it = l.
ordered_values.begin();
194 s << (*it)->first <<
'=' << (*it)->second << std::endl;
200 assert((*it)->second.depth == l.
depth+1);
202 dump(s, (*it)->second, (*it)->first);
208 std::ofstream file_out(filename.c_str());
210 throw std::runtime_error(std::string(
"Couldn't open '" + filename +
"'"));
212 this->dump(file_out);
217 this->top_level =
Level();
void dump(std::ostream &stream)
Outputs the contents of the INI file to #stream.
void saveAs(std::string filename)
Save all the internal INI contents on a file with #filename.
Parser()
Creates a blank new INI file.
Level & top()
Returns the top level of this INI file.
void create()
Creates a blank INI registry.
Contains a "scope" of the INI file.
Sections ordered_sections
All Sections in the original order of the INI file.
SectionMap sections
All the Levels inside this Level.
void addKey(std::string name, std::string value)
Creates a new key #name with #value.
Level * parent
The parent Level of this one.
void addGroup(std::string name)
Creates a new child group with #name.
size_t depth
Counter of how many nested levels this one is.
Values ordered_values
All values in the original order of the INI file.