C++ Utilities  5.10.5
Useful C++ classes and routines such as argument parser, IO and conversion utilities
inifile.h
Go to the documentation of this file.
1 #ifndef IOUTILITIES_INIFILE_H
2 #define IOUTILITIES_INIFILE_H
3 
4 #include "../global.h"
5 #include "../misc/flagenumclass.h"
6 
7 #include <algorithm>
8 #include <iosfwd>
9 #include <map>
10 #include <optional>
11 #include <string>
12 #include <vector>
13 
14 namespace CppUtilities {
15 
17 public:
18  using ScopeName = std::string;
19  using ScopeData = std::multimap<std::string, std::string>;
20  using Scope = std::pair<ScopeName, ScopeData>;
21  using ScopeList = std::vector<Scope>;
22 
23  IniFile();
24  ScopeList &data();
25  const ScopeList &data() const;
26  void parse(std::istream &inputStream);
27  void make(std::ostream &outputStream);
28 
29 private:
30  ScopeList m_data;
31 };
32 
37 {
38 }
39 
47 {
48  return m_data;
49 }
50 
55 inline const IniFile::ScopeList &IniFile::data() const
56 {
57  return m_data;
58 }
59 
60 enum class IniFileParseOptions {
61  None = 0,
62 };
63 
64 enum class IniFileMakeOptions {
65  None = 0,
66 };
67 
68 enum class IniFileFieldFlags {
69  None = 0,
70  HasValue = (1 << 0),
71 };
72 
73 enum class IniFileSectionFlags {
74  None = 0,
75  Implicit = (1 << 0),
76  Truncated = (1 << 1),
77 };
78 
80  struct Field {
81  std::string key;
82  std::string value;
83  std::string precedingCommentBlock;
85  std::size_t paddedKeyLength = 0;
87  };
88  using FieldList = std::vector<Field>;
89  struct Section {
90  FieldList::iterator findField(std::string_view key);
91  FieldList::const_iterator findField(std::string_view key) const;
92  FieldList::iterator findField(FieldList::iterator after, std::string_view key);
93  FieldList::const_iterator findField(FieldList::iterator after, std::string_view key) const;
94  FieldList::iterator fieldEnd();
95  FieldList::const_iterator fieldEnd() const;
96 
97  std::string name;
99  std::string precedingCommentBlock;
102  };
103  using SectionList = std::vector<Section>;
104 
105  SectionList::iterator findSection(std::string_view sectionName);
106  SectionList::const_iterator findSection(std::string_view sectionName) const;
107  SectionList::iterator findSection(SectionList::iterator after, std::string_view sectionName);
108  SectionList::const_iterator findSection(SectionList::iterator after, std::string_view sectionName) const;
109  SectionList::iterator sectionEnd();
110  SectionList::const_iterator sectionEnd() const;
111  std::optional<FieldList::iterator> findField(std::string_view sectionName, std::string_view key);
112  std::optional<FieldList::const_iterator> findField(std::string_view sectionName, std::string_view key) const;
113  void parse(std::istream &inputStream, IniFileParseOptions options = IniFileParseOptions::None);
114  void make(std::ostream &outputStream, IniFileMakeOptions options = IniFileMakeOptions::None);
115 
117 };
118 
122 inline AdvancedIniFile::SectionList::iterator AdvancedIniFile::findSection(std::string_view sectionName)
123 {
124  return std::find_if(sections.begin(), sections.end(), [&sectionName](const auto &scope) { return scope.name == sectionName; });
125 }
126 
130 inline AdvancedIniFile::SectionList::const_iterator AdvancedIniFile::findSection(std::string_view sectionName) const
131 {
132  return const_cast<AdvancedIniFile *>(this)->findSection(sectionName);
133 }
134 
138 inline AdvancedIniFile::SectionList::iterator AdvancedIniFile::findSection(SectionList::iterator after, std::string_view sectionName)
139 {
140  return std::find_if(after + 1, sections.end(), [&sectionName](const auto &scope) { return scope.name == sectionName; });
141 }
142 
146 inline AdvancedIniFile::SectionList::const_iterator AdvancedIniFile::findSection(SectionList::iterator after, std::string_view sectionName) const
147 {
148  return const_cast<AdvancedIniFile *>(this)->findSection(after, sectionName);
149 }
150 
154 inline AdvancedIniFile::SectionList::iterator AdvancedIniFile::sectionEnd()
155 {
156  return sections.end();
157 }
158 
162 inline AdvancedIniFile::SectionList::const_iterator AdvancedIniFile::sectionEnd() const
163 {
164  return sections.end();
165 }
166 
170 inline std::optional<AdvancedIniFile::FieldList::iterator> AdvancedIniFile::findField(std::string_view sectionName, std::string_view key)
171 {
172  const SectionList::iterator scope = findSection(sectionName);
173  if (scope == sectionEnd()) {
174  return std::nullopt;
175  }
176  const FieldList::iterator field = scope->findField(key);
177  if (field == scope->fieldEnd()) {
178  return std::nullopt;
179  }
180  return field;
181 }
182 
186 inline std::optional<AdvancedIniFile::FieldList::const_iterator> AdvancedIniFile::findField(std::string_view sectionName, std::string_view key) const
187 {
188  return const_cast<AdvancedIniFile *>(this)->findField(sectionName, key);
189 }
190 
194 inline AdvancedIniFile::FieldList::iterator AdvancedIniFile::Section::findField(std::string_view key)
195 {
196  return std::find_if(fields.begin(), fields.end(), [&key](const auto &field) { return field.key == key; });
197 }
198 
202 inline AdvancedIniFile::FieldList::const_iterator AdvancedIniFile::Section::findField(std::string_view key) const
203 {
204  return const_cast<Section *>(this)->findField(key);
205 }
206 
210 inline AdvancedIniFile::FieldList::iterator AdvancedIniFile::Section::findField(FieldList::iterator after, std::string_view key)
211 {
212  return std::find_if(after + 1, fields.end(), [&key](const auto &field) { return field.key == key; });
213 }
214 
218 inline AdvancedIniFile::FieldList::const_iterator AdvancedIniFile::Section::findField(FieldList::iterator after, std::string_view key) const
219 {
220  return const_cast<Section *>(this)->findField(after, key);
221 }
222 
226 inline AdvancedIniFile::FieldList::iterator AdvancedIniFile::Section::fieldEnd()
227 {
228  return fields.end();
229 }
230 
234 inline AdvancedIniFile::FieldList::const_iterator AdvancedIniFile::Section::fieldEnd() const
235 {
236  return fields.end();
237 }
238 
239 } // namespace CppUtilities
240 
245 
246 #endif // IOUTILITIES_INIFILE_H
The IniFile class allows parsing and writing INI files.
Definition: inifile.h:16
std::string ScopeName
Definition: inifile.h:18
std::multimap< std::string, std::string > ScopeData
Definition: inifile.h:19
IniFile()
Constructs an empty ini file.
Definition: inifile.h:36
ScopeList & data()
Returns the data of the file.
Definition: inifile.h:46
std::pair< ScopeName, ScopeData > Scope
Definition: inifile.h:20
std::vector< Scope > ScopeList
Definition: inifile.h:21
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(CppUtilities, IniFileParseOptions)
Contains all utilities provides by the c++utilities library.
IniFileSectionFlags
Definition: inifile.h:73
IniFileMakeOptions
Definition: inifile.h:64
IniFileParseOptions
Definition: inifile.h:60
IniFileFieldFlags
Definition: inifile.h:68
The AdvancedIniFile::Field class represents a field within an INI file.
Definition: inifile.h:80
The AdvancedIniFile::Section class represents a section within an INI file.
Definition: inifile.h:89
FieldList::iterator findField(std::string_view key)
Returns an iterator to the first field with the key key.
Definition: inifile.h:194
FieldList::iterator fieldEnd()
Returns an iterator that points one past the last field.
Definition: inifile.h:226
The AdvancedIniFile class allows parsing and writing INI files.
Definition: inifile.h:79
std::optional< FieldList::iterator > findField(std::string_view sectionName, std::string_view key)
Returns an iterator to the first field within the first section with matching sectionName and key.
Definition: inifile.h:170
SectionList::iterator sectionEnd()
Returns an iterator that points one past the last section.
Definition: inifile.h:154
std::vector< Section > SectionList
Definition: inifile.h:103
std::vector< Field > FieldList
Definition: inifile.h:88
SectionList::iterator findSection(std::string_view sectionName)
Returns an iterator to the first section with the name sectionName.
Definition: inifile.h:122