|
3 | 3 | #include <string> |
4 | 4 | #include <format> |
5 | 5 | #include <cctype> |
| 6 | +#include <vector> |
6 | 7 | #include <fstream> |
| 8 | +#include <sstream> |
7 | 9 | #include <stdexcept> |
8 | 10 | #include <functional> |
9 | 11 | #include <filesystem> |
10 | 12 | #include <string_view> |
| 13 | +#include <unordered_map> |
11 | 14 |
|
12 | 15 | namespace INIpp |
13 | 16 | { |
| 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 | + |
14 | 140 | class Exception : public std::runtime_error |
15 | 141 | { |
16 | 142 | public: |
@@ -73,7 +199,12 @@ namespace INIpp |
73 | 199 | public: |
74 | 200 | void ParseKVPair(const std::string& section, const std::string& key, const std::string& value) override; |
75 | 201 |
|
76 | | - private: |
| 202 | + inline DOM::Document& Get() |
| 203 | + { |
| 204 | + return m_document; |
| 205 | + } |
77 | 206 |
|
| 207 | + private: |
| 208 | + DOM::Document m_document; |
78 | 209 | }; |
79 | 210 | } |
0 commit comments