Skip to content

Commit f356a7f

Browse files
authoredJan 21, 2025
Merge pull request #6 from liner-exe/patch2-0-0
v2.0.0
2 parents 0dd5763 + 2f67317 commit f356a7f

File tree

1 file changed

+171
-14
lines changed

1 file changed

+171
-14
lines changed
 

‎include/parser.hpp

+171-14
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1+
// Ini Parser for Modern C++
2+
// Version 2.0.0
3+
// https://github.com/liner-exe/IniParser
4+
// 2024-2024 liner-exe
5+
// License: MIT
6+
7+
18
#ifndef INI_PARSER_LINEREXE
29
#define INI_PARSER_LINEREXE
310

411
#include <fstream>
512
#include <iostream>
613
#include <string>
7-
#include <map>
14+
#include <vector>
15+
#include <algorithm>
816

917
class IniParser
1018
{
11-
std::map <std::string, std::map<std::string, std::string>> m_data;
19+
public:
20+
using KeyValuePair = std::pair<std::string, std::string>;
21+
using Section = std::pair<std::string, std::vector<KeyValuePair>>;
22+
23+
private:
24+
std::vector<Section> m_data;
1225

1326
static void trim(std::string& str)
1427
{
@@ -22,16 +35,26 @@ class IniParser
2235
const size_t last = str.find_last_not_of(" \t\r\n");
2336
str = str.substr(first, last - first + 1);
2437
}
38+
39+
static std::string toLower(const std::string &str)
40+
{
41+
std::string result = str;
42+
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
43+
return result;
44+
}
45+
46+
static bool contains(const std::vector<std::string>& vec, const std::string& sub)
47+
{
48+
return std::find(vec.begin(), vec.end(), sub) != vec.end();
49+
}
50+
2551
public:
2652
void read(const std::string& filename)
2753
{
2854
std::ifstream file(filename);
2955

30-
std::map<std::string, std::string> innerData;
31-
std::string line;
32-
std::string section;
33-
std::string key;
34-
std::string value;
56+
std::vector<KeyValuePair> innerData;
57+
std::string line, section;
3558

3659
while (getline(file, line))
3760
{
@@ -41,37 +64,171 @@ class IniParser
4164
continue;
4265
}
4366

44-
size_t openBracketPos = line.find('[');
45-
size_t closeBracketPos = line.find(']');
67+
const size_t openBracketPos = line.find('[');
68+
const size_t closeBracketPos = line.find(']');
4669

4770
if (openBracketPos == std::string::npos)
4871
{
4972
size_t equalSign = line.find('=');
50-
key = line.substr(0, equalSign);
51-
value = line.substr(equalSign + 1);
73+
std::string key = line.substr(0, equalSign);
74+
std::string value = line.substr(equalSign + 1);
5275

5376
trim(key);
5477
trim(value);
5578

56-
innerData[key] = value;
79+
innerData.emplace_back(key, value);
5780
continue;
5881
}
5982

6083
if (!section.empty())
6184
{
62-
m_data[section] = innerData;
85+
m_data.emplace_back(section, innerData);
6386
innerData.clear();
6487
}
6588

6689
section = line.substr(openBracketPos + 1, closeBracketPos - 1);
90+
trim(section);
91+
}
92+
93+
if (!section.empty())
94+
{
95+
m_data.emplace_back(section, innerData);
96+
innerData.clear();
6797
}
6898

6999
file.close();
70100
}
71101

72102
std::string get(const std::string& section, const std::string& key)
73103
{
74-
return m_data[section][key];
104+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
105+
{
106+
if (storedSection == section)
107+
{
108+
for (const auto& [storedKey, storedValue] : storedKeyValuePair)
109+
{
110+
if (storedKey == key)
111+
{
112+
return storedValue;
113+
}
114+
}
115+
}
116+
}
117+
118+
return "-1";
119+
}
120+
121+
std::vector<std::string> getSectionNames()
122+
{
123+
std::vector<std::string> result;
124+
125+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
126+
{
127+
result.push_back(storedSection);
128+
}
129+
130+
return result;
131+
}
132+
133+
std::vector<KeyValuePair> getSectionData(const std::string& section) const
134+
{
135+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
136+
{
137+
if (storedSection == section) {
138+
return storedKeyValuePair;
139+
}
140+
}
141+
142+
throw std::invalid_argument("Section not found");
143+
}
144+
145+
bool hasSection(const std::string &sectionName) const
146+
{
147+
for (const auto& [storedSection, storedKeyValuePair] : m_data) {
148+
if (storedSection == sectionName)
149+
{
150+
return true;
151+
}
152+
}
153+
154+
return false;
155+
}
156+
157+
bool hasKey(const std::string& section, const std::string& key)
158+
{
159+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
160+
{
161+
if (storedSection == section)
162+
{
163+
for (const auto& [storedKey, storedValue] : storedKeyValuePair)
164+
{
165+
if (storedKey == key)
166+
{
167+
return true;
168+
}
169+
}
170+
}
171+
}
172+
173+
return false;
174+
}
175+
176+
bool getBoolean(const std::string& section, const std::string& key)
177+
{
178+
std::vector<std::string> trueValues { "1", "yes", "true", "on" };
179+
std::vector<std::string> falseValues { "0", "no", "false", "off" };
180+
181+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
182+
{
183+
if (storedSection == section)
184+
{
185+
for (const auto& [storedKey, storedValue] : storedKeyValuePair)
186+
{
187+
if (storedKey == key)
188+
{
189+
std::string storedValue_ = toLower(storedValue);
190+
if (contains(trueValues, storedValue_))
191+
{
192+
return true;
193+
}
194+
if (contains(falseValues, storedValue_))
195+
{
196+
return false;
197+
}
198+
}
199+
}
200+
}
201+
}
202+
203+
throw std::invalid_argument("Can't get boolean");
204+
}
205+
206+
int getInteger(const std::string& section, const std::string& key)
207+
{
208+
for (const auto& [storedSection, storedKeyValuePair] : m_data)
209+
{
210+
if (storedSection == section)
211+
{
212+
for (const auto& [storedKey, storedValue] : storedKeyValuePair)
213+
{
214+
if (storedKey == key)
215+
{
216+
try
217+
{
218+
return std::stoi(storedValue);
219+
} catch (const std::invalid_argument&)
220+
{
221+
throw std::invalid_argument("Invalid integer value");
222+
} catch (const std::out_of_range&)
223+
{
224+
throw std::invalid_argument("Integer value out of range");
225+
}
226+
}
227+
}
228+
}
229+
}
230+
231+
return -1;
75232
}
76233

77234
void show() const

0 commit comments

Comments
 (0)
Please sign in to comment.