Skip to content

Commit 87e1017

Browse files
committed
INIpp 2/2
1 parent d119610 commit 87e1017

File tree

3 files changed

+142
-32
lines changed

3 files changed

+142
-32
lines changed

09_INIpp/INIpp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,8 @@ void INIpp::SAXParser::ParseKVPair(const std::string& section, const std::string
164164
m_callback(section, key, value);
165165
}
166166
}
167+
168+
void INIpp::DOMParser::ParseKVPair(const std::string& section, const std::string& key, const std::string& value)
169+
{
170+
m_document[section].Append(DOM::KVPair(key, value));
171+
}

09_INIpp/INIpp.hpp

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,140 @@
33
#include <string>
44
#include <format>
55
#include <cctype>
6+
#include <vector>
67
#include <fstream>
8+
#include <sstream>
79
#include <stdexcept>
810
#include <functional>
911
#include <filesystem>
1012
#include <string_view>
13+
#include <unordered_map>
1114

1215
namespace INIpp
1316
{
17+
namespace DOM
18+
{
19+
class KVPair
20+
{
21+
public:
22+
KVPair() = default;
23+
KVPair(const std::string_view& key, const std::string_view& value) :
24+
m_key(key), m_value(value)
25+
{}
26+
27+
inline const std::string& Key() const noexcept
28+
{
29+
return m_key;
30+
}
31+
inline const std::string& Value() const noexcept
32+
{
33+
return m_value;
34+
}
35+
36+
template<typename T>
37+
T Get(const T& defaultValue = T())
38+
{
39+
T temp = defaultValue;
40+
std::stringstream ss;
41+
ss << m_value;
42+
ss >> temp;
43+
return temp;
44+
}
45+
46+
template<>
47+
std::string Get(const std::string& defaultValue)
48+
{
49+
return m_value;
50+
}
51+
52+
private:
53+
std::string m_key;
54+
std::string m_value;
55+
};
56+
57+
class Section
58+
{
59+
public:
60+
using Key = std::string;
61+
62+
Section() = default;
63+
Section(const std::string_view& name) :
64+
m_name(name)
65+
{}
66+
67+
inline const std::string& Name() const noexcept
68+
{
69+
return m_name;
70+
}
71+
72+
inline KVPair& operator[](const Key& key)
73+
{
74+
return m_kvPairs.find(key)->second;
75+
}
76+
inline const KVPair& operator[](const Key& key) const
77+
{
78+
return m_kvPairs.find(key)->second;
79+
}
80+
81+
std::vector<Key> Keys() const
82+
{
83+
std::vector<Key> keys;
84+
for (auto& pair : m_kvPairs)
85+
{
86+
keys.push_back(pair.first);
87+
}
88+
return keys;
89+
}
90+
91+
void Append(KVPair&& value)
92+
{
93+
m_kvPairs.emplace(value.Key(), std::move(value));
94+
}
95+
96+
private:
97+
std::string m_name;
98+
std::unordered_map<Key, KVPair> m_kvPairs;
99+
};
100+
101+
class Document
102+
{
103+
public:
104+
using Key = std::string;
105+
106+
inline Section& operator[](const Key& name)
107+
{
108+
// Existing section
109+
auto it = m_sections.find(name);
110+
if (it != m_sections.end())
111+
{
112+
return it->second;
113+
}
114+
115+
// New section
116+
auto& section = m_sections[name];
117+
section = std::move(Section(name));
118+
return section;
119+
}
120+
inline const Section& operator[](const Key& name) const
121+
{
122+
return m_sections.find(name)->second;
123+
}
124+
125+
std::vector<Key> Sections() const
126+
{
127+
std::vector<Key> sections;
128+
for (auto& section : m_sections)
129+
{
130+
sections.push_back(section.first);
131+
}
132+
return sections;
133+
}
134+
135+
private:
136+
std::unordered_map<Key, Section> m_sections;
137+
};
138+
}
139+
14140
class Exception : public std::runtime_error
15141
{
16142
public:
@@ -73,7 +199,12 @@ namespace INIpp
73199
public:
74200
void ParseKVPair(const std::string& section, const std::string& key, const std::string& value) override;
75201

76-
private:
202+
inline DOM::Document& Get()
203+
{
204+
return m_document;
205+
}
77206

207+
private:
208+
DOM::Document m_document;
78209
};
79210
}

09_INIpp/main.cpp

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,12 @@
33
#include <iostream>
44
#include <sstream>
55

6-
class MyFancySettingsProvider
7-
{
8-
public:
9-
MyFancySettingsProvider(std::ostream& os) :
10-
m_os(os)
11-
{}
12-
13-
void Kickoff(const std::filesystem::path& configFile = "./config.ini")
14-
{
15-
INIpp::SAXParser parser(
16-
std::bind(&MyFancySettingsProvider::OnKVPair, this,
17-
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
18-
parser.AddFile(configFile);
19-
}
20-
21-
private:
22-
void OnKVPair(const std::string& s, const std::string& k, const std::string& v)
23-
{
24-
m_os << s << ": " << k << " = " << v << std::endl;
25-
}
26-
27-
private:
28-
std::ostream& m_os;
29-
};
30-
316
int main()
327
{
33-
std::stringstream ss;
8+
INIpp::DOMParser parser;
9+
parser.AddFile("./config.ini");
3410

35-
MyFancySettingsProvider sp(ss);
36-
sp.Kickoff();
37-
38-
std::ofstream of("./myfile.ini");
39-
of << ss.str();
11+
INIpp::DOM::Document doc = parser.Get();
12+
auto port = doc["owner"]["name"].Get<std::string>();
13+
std::cout << "Port: " << port;
4014
}

0 commit comments

Comments
 (0)