rippled
Loading...
Searching...
No Matches
BasicConfig.h
1#pragma once
2
3#include <xrpl/basics/contract.h>
4
5#include <boost/beast/core/string.hpp>
6#include <boost/lexical_cast.hpp>
7
8#include <algorithm>
9#include <optional>
10#include <string>
11#include <unordered_map>
12#include <vector>
13
14namespace xrpl {
15
17
18//------------------------------------------------------------------------------
19
24{
25private:
31
33
34public:
36 explicit Section(std::string const& name = "");
37
39 std::string const&
40 name() const
41 {
42 return name_;
43 }
44
49 lines() const
50 {
51 return lines_;
52 }
53
58 values() const
59 {
60 return values_;
61 }
62
66 void
68 {
69 if (lines_.empty())
70 lines_.emplace_back(std::move(value));
71 else
72 lines_[0] = std::move(value);
73 }
74
82 legacy() const
83 {
84 if (lines_.empty())
85 return "";
86 if (lines_.size() > 1)
87 Throw<std::runtime_error>("A legacy value must have exactly one line. Section: " + name_);
88 return lines_[0];
89 }
90
94 void
95 set(std::string const& key, std::string const& value);
96
102 void
104
106 void
107 append(std::string const& line)
108 {
110 }
111
113 bool
114 exists(std::string const& name) const;
115
116 template <class T = std::string>
118 get(std::string const& name) const
119 {
120 auto const iter = lookup_.find(name);
121 if (iter == lookup_.end())
122 return std::nullopt;
123 return boost::lexical_cast<T>(iter->second);
124 }
125
127 template <class T>
128 T
129 value_or(std::string const& name, T const& other) const
130 {
131 auto const v = get<T>(name);
132 return v.has_value() ? *v : other;
133 }
134
135 // indicates if trailing comments were seen
136 // during the appending of any lines/values
137 bool
139 {
141 }
142
143 friend std::ostream&
144 operator<<(std::ostream&, Section const& section);
145
146 // Returns `true` if there are no key/value pairs.
147 bool
148 empty() const
149 {
150 return lookup_.empty();
151 }
152
153 // Returns the number of key/value pairs.
155 size() const
156 {
157 return lookup_.size();
158 }
159
160 // For iteration of key/value pairs.
162 begin() const
163 {
164 return lookup_.cbegin();
165 }
166
167 // For iteration of key/value pairs.
169 cbegin() const
170 {
171 return lookup_.cbegin();
172 }
173
174 // For iteration of key/value pairs.
176 end() const
177 {
178 return lookup_.cend();
179 }
180
181 // For iteration of key/value pairs.
183 cend() const
184 {
185 return lookup_.cend();
186 }
187};
188
189//------------------------------------------------------------------------------
190
196{
197private:
199
200public:
202 bool
203 exists(std::string const& name) const;
204
209 Section&
210 section(std::string const& name);
211
212 Section const&
213 section(std::string const& name) const;
214
215 Section const&
216 operator[](std::string const& name) const
217 {
218 return section(name);
219 }
220
221 Section&
223 {
224 return section(name);
225 }
232 void
233 overwrite(std::string const& section, std::string const& key, std::string const& value);
234
237 void
239
249 void
250 legacy(std::string const& section, std::string value);
251
261 legacy(std::string const& sectionName) const;
262
263 friend std::ostream&
264 operator<<(std::ostream& ss, BasicConfig const& c);
265
266 // indicates if trailing comments were seen
267 // in any loaded Sections
268 bool
270 {
271 return std::any_of(map_.cbegin(), map_.cend(), [](auto s) { return s.second.had_trailing_comments(); });
272 }
273
274protected:
275 void
276 build(IniFileSections const& ifs);
277};
278
279//------------------------------------------------------------------------------
280
286template <class T>
287bool
288set(T& target, std::string const& name, Section const& section)
289{
290 bool found_and_valid = false;
291 try
292 {
293 auto const val = section.get<T>(name);
294 if ((found_and_valid = val.has_value()))
295 target = *val;
296 }
297 catch (boost::bad_lexical_cast&)
298 {
299 }
300 return found_and_valid;
301}
302
308template <class T>
309bool
310set(T& target, T const& defaultValue, std::string const& name, Section const& section)
311{
312 bool found_and_valid = set<T>(target, name, section);
313 if (!found_and_valid)
314 target = defaultValue;
315 return found_and_valid;
316}
317
322// NOTE This routine might be more clumsy than the previous two
323template <class T = std::string>
324T
325get(Section const& section, std::string const& name, T const& defaultValue = T{})
326{
327 try
328 {
329 return section.value_or<T>(name, defaultValue);
330 }
331 catch (boost::bad_lexical_cast&)
332 {
333 }
334 return defaultValue;
335}
336
337inline std::string
338get(Section const& section, std::string const& name, char const* defaultValue)
339{
340 try
341 {
342 auto const val = section.get(name);
343 if (val.has_value())
344 return *val;
345 }
346 catch (boost::bad_lexical_cast&)
347 {
348 }
349 return defaultValue;
350}
351
352template <class T>
353bool
354get_if_exists(Section const& section, std::string const& name, T& v)
355{
356 return set<T>(v, name, section);
357}
358
359template <>
360inline bool
361get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
362{
363 int intVal = 0;
364 auto stat = get_if_exists(section, name, intVal);
365 if (stat)
366 v = bool(intVal);
367 return stat;
368}
369
370} // namespace xrpl
T any_of(T... args)
T cbegin(T... args)
Holds unparsed configuration information.
friend std::ostream & operator<<(std::ostream &ss, BasicConfig const &c)
Section const & operator[](std::string const &name) 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)
bool had_trailing_comments() const
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:24
const_iterator end() const
std::optional< T > get(std::string const &name) const
decltype(lookup_)::const_iterator const_iterator
Definition BasicConfig.h:32
const_iterator cbegin() const
friend std::ostream & operator<<(std::ostream &, Section const &section)
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:27
bool had_trailing_comments() const
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition BasicConfig.h:58
std::string const & name() const
Returns the name of this section.
Definition BasicConfig.h:40
std::vector< std::string > values_
Definition BasicConfig.h:29
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition BasicConfig.h:49
std::string name_
Definition BasicConfig.h:26
const_iterator begin() const
std::size_t size() const
T value_or(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:82
void legacy(std::string value)
Set the legacy value for this section.
Definition BasicConfig.h:67
bool had_trailing_comments_
Definition BasicConfig.h:30
std::vector< std::string > lines_
Definition BasicConfig.h:28
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.
T emplace_back(T... args)
T empty(T... args)
T end(T... args)
T find(T... args)
T is_same_v
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,...
bool get_if_exists< bool >(Section const &section, std::string const &name, bool &v)
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
bool get_if_exists(Section const &section, std::string const &name, T &v)
T size(T... args)