xrpld
Loading...
Searching...
No Matches
BasicConfig.h
1#pragma once
2
3#include <xrpl/basics/contract.h>
4
5#include <boost/lexical_cast.hpp>
6
7#include <algorithm>
8#include <cstddef>
9#include <optional>
10#include <ostream>
11#include <stdexcept>
12#include <string>
13#include <unordered_map>
14#include <utility>
15#include <vector>
16
17namespace xrpl {
18
20
21//------------------------------------------------------------------------------
22
28{
29private:
35
37
38public:
42 explicit Section(std::string name = "");
43
47 [[nodiscard]] std::string const&
48 name() const
49 {
50 return name_;
51 }
52
57 [[nodiscard]] std::vector<std::string> const&
58 lines() const
59 {
60 return lines_;
61 }
62
67 [[nodiscard]] std::vector<std::string> const&
68 values() const
69 {
70 return values_;
71 }
72
76 void
78 {
79 if (lines_.empty())
80 {
81 lines_.emplace_back(std::move(value));
82 }
83 else
84 {
85 lines_[0] = std::move(value);
86 }
87 }
88
95 [[nodiscard]] std::string
96 legacy() const
97 {
98 if (lines_.empty())
99 return "";
100 if (lines_.size() > 1)
101 {
103 "A legacy value must have exactly one line. Section: " + name_);
104 }
105 return lines_[0];
106 }
107
112 void
113 set(std::string const& key, std::string const& value);
114
121 void
123
127 void
128 append(std::string const& line)
129 {
131 }
132
136 [[nodiscard]] bool
137 exists(std::string const& name) const;
138
139 template <class T = std::string>
140 [[nodiscard]] std::optional<T>
141 get(std::string const& name) const
142 {
143 auto const iter = lookup_.find(name);
144 if (iter == lookup_.end())
145 return std::nullopt;
146 return boost::lexical_cast<T>(iter->second);
147 }
148
152 template <class T>
153 [[nodiscard]] T
154 valueOr(std::string const& name, T const& other) const
155 {
156 auto const v = get<T>(name);
157 return v.has_value() ? *v : other;
158 }
159
160 // indicates if trailing comments were seen
161 // during the appending of any lines/values
162 [[nodiscard]] bool
164 {
166 }
167
168 friend std::ostream&
169 operator<<(std::ostream&, Section const& section);
170
171 // Returns `true` if there are no key/value pairs.
172 [[nodiscard]] bool
173 empty() const
174 {
175 return lookup_.empty();
176 }
177
178 // Returns the number of key/value pairs.
179 [[nodiscard]] std::size_t
180 size() const
181 {
182 return lookup_.size();
183 }
184
185 // For iteration of key/value pairs.
186 [[nodiscard]] const_iterator
187 begin() const
188 {
189 return lookup_.cbegin();
190 }
191
192 // For iteration of key/value pairs.
193 [[nodiscard]] const_iterator
194 cbegin() const
195 {
196 return lookup_.cbegin();
197 }
198
199 // For iteration of key/value pairs.
200 [[nodiscard]] const_iterator
201 end() const
202 {
203 return lookup_.cend();
204 }
205
206 // For iteration of key/value pairs.
207 [[nodiscard]] const_iterator
208 cend() const
209 {
210 return lookup_.cend();
211 }
212};
213
214//------------------------------------------------------------------------------
215
222{
223private:
225
226public:
230 [[nodiscard]] bool
231 exists(std::string const& name) const;
232
238 Section&
239 section(std::string const& name);
240
241 [[nodiscard]] Section const&
242 section(std::string const& name) const;
243
244 Section const&
245 operator[](std::string const& name) const
246 {
247 return section(name);
248 }
249
250 Section&
252 {
253 return section(name);
254 }
255
256
262 void
263 overwrite(std::string const& section, std::string const& key, std::string const& value);
264
268 void
270
280 void
281 legacy(std::string const& section, std::string value);
282
291 [[nodiscard]] std::string
292 legacy(std::string const& sectionName) const;
293
294 friend std::ostream&
295 operator<<(std::ostream& ss, BasicConfig const& c);
296
297 // indicates if trailing comments were seen
298 // in any loaded Sections
299 [[nodiscard]] bool
301 {
302 return std::ranges::any_of(map_, [](auto s) { return s.second.hadTrailingComments(); });
303 }
304
305protected:
306 void
307 build(IniFileSections const& ifs);
308};
309
310//------------------------------------------------------------------------------
311
318template <class T>
319bool
320set(T& target, std::string const& name, Section const& section)
321{
322 bool foundAndValid = false;
323 try
324 {
325 auto const val = section.get<T>(name);
326 foundAndValid = val.has_value();
327 if (foundAndValid)
328 target = *val;
329 }
330 catch (boost::bad_lexical_cast const&) // NOLINT(bugprone-empty-catch)
331 {
332 }
333 return foundAndValid;
334}
335
342template <class T>
343bool
344set(T& target, T const& defaultValue, std::string const& name, Section const& section)
345{
346 bool const foundAndValid = set<T>(target, name, section);
347 if (!foundAndValid)
348 target = defaultValue;
349 return foundAndValid;
350}
351
357// NOTE This routine might be more clumsy than the previous two
358template <class T = std::string>
359T
360get(Section const& section, std::string const& name, T const& defaultValue = T{})
361{
362 try
363 {
364 return section.valueOr<T>(name, defaultValue);
365 }
366 catch (boost::bad_lexical_cast const&) // NOLINT(bugprone-empty-catch)
367 {
368 }
369 return defaultValue;
370}
371
372inline std::string
373get(Section const& section, std::string const& name, char const* defaultValue)
374{
375 try
376 {
377 auto const val = section.get(name);
378 if (val.has_value())
379 return *val;
380 }
381 catch (boost::bad_lexical_cast const&) // NOLINT(bugprone-empty-catch)
382 {
383 }
384 return defaultValue;
385}
386
387template <class T>
388bool
389getIfExists(Section const& section, std::string const& name, T& v)
390{
391 return set<T>(v, name, section);
392}
393
394template <>
395inline bool
396getIfExists<bool>(Section const& section, std::string const& name, bool& v)
397{
398 int intVal = 0;
399 auto stat = getIfExists(section, name, intVal);
400 if (stat)
401 v = bool(intVal);
402 return stat;
403}
404
405} // namespace xrpl
T any_of(T... args)
Holds unparsed configuration information.
friend std::ostream & operator<<(std::ostream &ss, BasicConfig const &c)
Section const & operator[](std::string const &name) const
bool hadTrailingComments() const
void deprecatedClearSection(std::string const &section)
Remove all the key/value pairs from the section.
void build(IniFileSections const &ifs)
void overwrite(std::string const &section, std::string const &key, std::string const &value)
Overwrite a key/value pair with a command line argument If the section does not exist it is created.
std::unordered_map< std::string, Section > map_
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
Section & operator[](std::string const &name)
void legacy(std::string const &section, std::string value)
Set a value that is not a key/value pair.
Section & section(std::string const &name)
Returns the section with the given name.
Holds a collection of configuration values.
Definition BasicConfig.h:28
Section(std::string name="")
Create an empty section.
const_iterator end() const
std::optional< T > get(std::string const &name) const
decltype(lookup_)::const_iterator const_iterator
Definition BasicConfig.h:36
const_iterator cbegin() const
bool hadTrailingComments_
Definition BasicConfig.h:34
bool empty() const
void append(std::string const &line)
Append a line to this section.
std::unordered_map< std::string, std::string > lookup_
Definition BasicConfig.h:31
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition BasicConfig.h:68
std::string const & name() const
Returns the name of this section.
Definition BasicConfig.h:48
std::vector< std::string > values_
Definition BasicConfig.h:33
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition BasicConfig.h:58
std::string name_
Definition BasicConfig.h:30
friend std::ostream & operator<<(std::ostream &, Section const &section)
void set(std::string const &key, std::string const &value)
Set a key/value pair.
const_iterator begin() const
bool hadTrailingComments() const
std::size_t size() const
T valueOr(std::string const &name, T const &other) const
Returns a value if present, else another value.
std::string legacy() const
Get the legacy value for this section.
Definition BasicConfig.h:96
void legacy(std::string value)
Set the legacy value for this section.
Definition BasicConfig.h:77
std::vector< std::string > lines_
Definition BasicConfig.h:32
const_iterator cend() const
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
bool getIfExists< bool >(Section const &section, std::string const &name, bool &v)
bool getIfExists(Section const &section, std::string const &name, T &v)
Dir::ConstIterator const_iterator
Definition Dir.cpp:16
std::unordered_map< std::string, std::vector< std::string > > IniFileSections
Definition BasicConfig.h:19
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52