rippled
Loading...
Searching...
No Matches
BasicConfig.h
1#ifndef XRPL_BASICS_BASICCONFIG_H_INCLUDED
2#define XRPL_BASICS_BASICCONFIG_H_INCLUDED
3
4#include <xrpl/basics/contract.h>
5
6#include <boost/beast/core/string.hpp>
7#include <boost/lexical_cast.hpp>
8
9#include <algorithm>
10#include <optional>
11#include <string>
12#include <unordered_map>
13#include <vector>
14
15namespace ripple {
16
19
20//------------------------------------------------------------------------------
21
26{
27private:
33
35
36public:
38 explicit Section(std::string const& name = "");
39
41 std::string const&
42 name() const
43 {
44 return name_;
45 }
46
51 lines() const
52 {
53 return lines_;
54 }
55
60 values() const
61 {
62 return values_;
63 }
64
68 void
70 {
71 if (lines_.empty())
72 lines_.emplace_back(std::move(value));
73 else
74 lines_[0] = std::move(value);
75 }
76
84 legacy() const
85 {
86 if (lines_.empty())
87 return "";
88 if (lines_.size() > 1)
89 Throw<std::runtime_error>(
90 "A legacy value must have exactly one line. Section: " + name_);
91 return lines_[0];
92 }
93
97 void
98 set(std::string const& key, std::string const& value);
99
105 void
107
109 void
110 append(std::string const& line)
111 {
113 }
114
116 bool
117 exists(std::string const& name) const;
118
119 template <class T = std::string>
121 get(std::string const& name) const
122 {
123 auto const iter = lookup_.find(name);
124 if (iter == lookup_.end())
125 return std::nullopt;
126 return boost::lexical_cast<T>(iter->second);
127 }
128
130 template <class T>
131 T
132 value_or(std::string const& name, T const& other) const
133 {
134 auto const v = get<T>(name);
135 return v.has_value() ? *v : other;
136 }
137
138 // indicates if trailing comments were seen
139 // during the appending of any lines/values
140 bool
142 {
144 }
145
146 friend std::ostream&
147 operator<<(std::ostream&, Section const& section);
148
149 // Returns `true` if there are no key/value pairs.
150 bool
151 empty() const
152 {
153 return lookup_.empty();
154 }
155
156 // Returns the number of key/value pairs.
158 size() const
159 {
160 return lookup_.size();
161 }
162
163 // For iteration of key/value pairs.
165 begin() const
166 {
167 return lookup_.cbegin();
168 }
169
170 // For iteration of key/value pairs.
172 cbegin() const
173 {
174 return lookup_.cbegin();
175 }
176
177 // For iteration of key/value pairs.
179 end() const
180 {
181 return lookup_.cend();
182 }
183
184 // For iteration of key/value pairs.
186 cend() const
187 {
188 return lookup_.cend();
189 }
190};
191
192//------------------------------------------------------------------------------
193
199{
200private:
202
203public:
205 bool
206 exists(std::string const& name) const;
207
212 Section&
213 section(std::string const& name);
214
215 Section const&
216 section(std::string const& name) const;
217
218 Section const&
219 operator[](std::string const& name) const
220 {
221 return section(name);
222 }
223
224 Section&
226 {
227 return section(name);
228 }
235 void
236 overwrite(
237 std::string const& section,
238 std::string const& key,
239 std::string const& value);
240
243 void
245
255 void
256 legacy(std::string const& section, std::string value);
257
267 legacy(std::string const& sectionName) const;
268
269 friend std::ostream&
270 operator<<(std::ostream& ss, BasicConfig const& c);
271
272 // indicates if trailing comments were seen
273 // in any loaded Sections
274 bool
276 {
277 return std::any_of(map_.cbegin(), map_.cend(), [](auto s) {
278 return s.second.had_trailing_comments();
279 });
280 }
281
282protected:
283 void
284 build(IniFileSections const& ifs);
285};
286
287//------------------------------------------------------------------------------
288
294template <class T>
295bool
296set(T& target, std::string const& name, Section const& section)
297{
298 bool found_and_valid = false;
299 try
300 {
301 auto const val = section.get<T>(name);
302 if ((found_and_valid = val.has_value()))
303 target = *val;
304 }
305 catch (boost::bad_lexical_cast&)
306 {
307 }
308 return found_and_valid;
309}
310
316template <class T>
317bool
318set(T& target,
319 T const& defaultValue,
320 std::string const& name,
321 Section const& section)
322{
323 bool found_and_valid = set<T>(target, name, section);
324 if (!found_and_valid)
325 target = defaultValue;
326 return found_and_valid;
327}
328
333// NOTE This routine might be more clumsy than the previous two
334template <class T = std::string>
335T
336get(Section const& section,
337 std::string const& name,
338 T const& defaultValue = T{})
339{
340 try
341 {
342 return section.value_or<T>(name, defaultValue);
343 }
344 catch (boost::bad_lexical_cast&)
345 {
346 }
347 return defaultValue;
348}
349
350inline std::string
351get(Section const& section, std::string const& name, char const* defaultValue)
352{
353 try
354 {
355 auto const val = section.get(name);
356 if (val.has_value())
357 return *val;
358 }
359 catch (boost::bad_lexical_cast&)
360 {
361 }
362 return defaultValue;
363}
364
365template <class T>
366bool
367get_if_exists(Section const& section, std::string const& name, T& v)
368{
369 return set<T>(v, name, section);
370}
371
372template <>
373inline bool
374get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
375{
376 int intVal = 0;
377 auto stat = get_if_exists(section, name, intVal);
378 if (stat)
379 v = bool(intVal);
380 return stat;
381}
382
383} // namespace ripple
384
385#endif
T any_of(T... args)
T cbegin(T... args)
Holds unparsed configuration information.
friend std::ostream & operator<<(std::ostream &ss, BasicConfig const &c)
bool exists(std::string const &name) const
Returns true if a section with the given name exists.
bool had_trailing_comments() const
Section const & operator[](std::string const &name) const
void deprecatedClearSection(std::string const &section)
Remove all the key/value pairs from the section.
Section & section(std::string const &name)
Returns the section with the given name.
void build(IniFileSections const &ifs)
std::unordered_map< std::string, Section > map_
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.
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.
Holds a collection of configuration values.
Definition BasicConfig.h:26
std::string const & name() const
Returns the name of this section.
Definition BasicConfig.h:42
std::size_t size() const
std::string legacy() const
Get the legacy value for this section.
Definition BasicConfig.h:84
std::vector< std::string > lines_
Definition BasicConfig.h:30
friend std::ostream & operator<<(std::ostream &, Section const &section)
const_iterator begin() const
decltype(lookup_)::const_iterator const_iterator
Definition BasicConfig.h:34
const_iterator cend() const
bool had_trailing_comments() const
T value_or(std::string const &name, T const &other) const
Returns a value if present, else another value.
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition BasicConfig.h:51
void legacy(std::string value)
Set the legacy value for this section.
Definition BasicConfig.h:69
std::optional< T > get(std::string const &name) const
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
void append(std::string const &line)
Append a line to this section.
const_iterator cbegin() const
bool had_trailing_comments_
Definition BasicConfig.h:32
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition BasicConfig.h:60
std::string name_
Definition BasicConfig.h:28
std::unordered_map< std::string, std::string > lookup_
Definition BasicConfig.h:29
std::vector< std::string > values_
Definition BasicConfig.h:31
const_iterator end() const
bool empty() const
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:6
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(Section const &section, std::string const &name, T &v)
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.
T size(T... args)