25#include <unordered_map>
30std::string
ini::serialize(
const std::unordered_map<std::string, std::string> &contents) {
33 std::vector<std::string> sortedKeys;
34 sortedKeys.reserve(contents.size());
35 for (
const auto& entry : contents) {
36 sortedKeys.push_back(entry.first);
38 std::sort(sortedKeys.begin(), sortedKeys.end());
41 std::ostringstream stream;
42 for (
const auto& key : sortedKeys) {
43 stream << key <<
" = " << contents.at(key) <<
"\r\n";
49std::unique_ptr<std::unordered_map<std::string, std::string>>
ini::deserialize(
const std::string contents) {
50 std::unordered_map<std::string, std::string> result;
51 std::string currentKey;
52 std::string currentValue;
53 std::string currentValueWhitespace;
55 enum class ParserState {
65 ParserState state = ParserState::kKeyStart;
66 for (
char c : contents) {
68 case ParserState::kKeyStart:
69 if (std::isspace(c)) {
72 }
else if (std::isalpha(
static_cast<unsigned char>(c))) {
74 state = ParserState::kKey;
79 case ParserState::kKey:
81 state = ParserState::kValueStart;
82 }
else if (std::isspace(c)) {
83 state = ParserState::kKeyEnd;
84 }
else if (std::isalpha(
static_cast<unsigned char>(c))) {
90 case ParserState::kKeyEnd:
92 state = ParserState::kValueStart;
93 }
else if (!std::isspace(c)) {
97 case ParserState::kValueStart:
98 if (!std::isspace(c)) {
100 state = ParserState::kValue;
103 case ParserState::kValue:
105 state = ParserState::kValueEnd;
106 }
else if (c ==
'\n') {
107 result[currentKey] = currentValue;
110 currentValueWhitespace =
"";
111 state = ParserState::kKeyStart;
112 }
else if (std::isspace(c)) {
113 currentValueWhitespace += c;
114 state = ParserState::kValueWhitespace;
119 case ParserState::kValueWhitespace:
121 currentValueWhitespace =
"";
122 state = ParserState::kValueEnd;
123 }
else if (c ==
'\n') {
124 result[currentKey] = currentValue;
127 currentValueWhitespace =
"";
128 state = ParserState::kKeyStart;
129 }
else if (std::isspace(c)) {
130 currentValueWhitespace += c;
132 currentValue += currentValueWhitespace;
134 currentValueWhitespace =
"";
135 state = ParserState::kValue;
138 case ParserState::kValueEnd:
140 result[currentKey] = currentValue;
143 currentValueWhitespace =
"";
144 state = ParserState::kKeyStart;
154 if (state == ParserState::kValueStart || state == ParserState::kValue || state == ParserState::kValueWhitespace) {
155 result[currentKey] = currentValue;
156 state = ParserState::kKeyStart;
160 if (state != ParserState::kKeyStart) {
164 return std::unique_ptr<std::unordered_map<std::string, std::string>>(
165 new std::unordered_map<std::string, std::string>(std::move(result))
std::string serialize(const std::unordered_map< std::string, std::string > &contents)
Outputs simple flat ini data.
std::unique_ptr< std::unordered_map< std::string, std::string > > deserialize(const std::string contents)
Simple parser for flat ini data.