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>(
88 "A legacy value must have exactly one line. Section: " + name_);
89 return lines_[0];
90 }
91
95 void
96 set(std::string const& key, std::string const& value);
97
103 void
105
107 void
108 append(std::string const& line)
109 {
111 }
112
114 bool
115 exists(std::string const& name) const;
116
117 template <class T = std::string>
119 get(std::string const& name) const
120 {
121 auto const iter = lookup_.find(name);
122 if (iter == lookup_.end())
123 return std::nullopt;
124 return boost::lexical_cast<T>(iter->second);
125 }
126
128 template <class T>
129 T
130 value_or(std::string const& name, T const& other) const
131 {
132 auto const v = get<T>(name);
133 return v.has_value() ? *v : other;
134 }
135
136 // indicates if trailing comments were seen
137 // during the appending of any lines/values
138 bool
140 {
142 }
143
144 friend std::ostream&
145 operator<<(std::ostream&, Section const& section);
146
147 // Returns `true` if there are no key/value pairs.
148 bool
149 empty() const
150 {
151 return lookup_.empty();
152 }
153
154 // Returns the number of key/value pairs.
156 size() const
157 {
158 return lookup_.size();
159 }
160
161 // For iteration of key/value pairs.
163 begin() const
164 {
165 return lookup_.cbegin();
166 }
167
168 // For iteration of key/value pairs.
170 cbegin() const
171 {
172 return lookup_.cbegin();
173 }
174
175 // For iteration of key/value pairs.
177 end() const
178 {
179 return lookup_.cend();
180 }
181
182 // For iteration of key/value pairs.
184 cend() const
185 {
186 return lookup_.cend();
187 }
188};
189
190//------------------------------------------------------------------------------
191
197{
198private:
200
201public:
203 bool
204 exists(std::string const& name) const;
205
210 Section&
211 section(std::string const& name);
212
213 Section const&
214 section(std::string const& name) const;
215
216 Section const&
217 operator[](std::string const& name) const
218 {
219 return section(name);
220 }
221
222 Section&
224 {
225 return section(name);
226 }
233 void
234 overwrite(std::string const& section, std::string const& key, std::string const& value);
235
238 void
240
250 void
251 legacy(std::string const& section, std::string value);
252
262 legacy(std::string const& sectionName) const;
263
264 friend std::ostream&
265 operator<<(std::ostream& ss, BasicConfig const& c);
266
267 // indicates if trailing comments were seen
268 // in any loaded Sections
269 bool
271 {
272 return std::any_of(
273 map_.cbegin(), map_.cend(), [](auto s) { return s.second.had_trailing_comments(); });
274 }
275
276protected:
277 void
278 build(IniFileSections const& ifs);
279};
280
281//------------------------------------------------------------------------------
282
288template <class T>
289bool
290set(T& target, std::string const& name, Section const& section)
291{
292 bool found_and_valid = false;
293 try
294 {
295 auto const val = section.get<T>(name);
296 if ((found_and_valid = val.has_value()))
297 target = *val;
298 }
299 catch (boost::bad_lexical_cast&)
300 {
301 }
302 return found_and_valid;
303}
304
310template <class T>
311bool
312set(T& target, T const& defaultValue, std::string const& name, Section const& section)
313{
314 bool const found_and_valid = set<T>(target, name, section);
315 if (!found_and_valid)
316 target = defaultValue;
317 return found_and_valid;
318}
319
324// NOTE This routine might be more clumsy than the previous two
325template <class T = std::string>
326T
327get(Section const& section, std::string const& name, T const& defaultValue = T{})
328{
329 try
330 {
331 return section.value_or<T>(name, defaultValue);
332 }
333 catch (boost::bad_lexical_cast&)
334 {
335 }
336 return defaultValue;
337}
338
339inline std::string
340get(Section const& section, std::string const& name, char const* defaultValue)
341{
342 try
343 {
344 auto const val = section.get(name);
345 if (val.has_value())
346 return *val;
347 }
348 catch (boost::bad_lexical_cast&)
349 {
350 }
351 return defaultValue;
352}
353
354template <class T>
355bool
356get_if_exists(Section const& section, std::string const& name, T& v)
357{
358 return set<T>(v, name, section);
359}
360
361template <>
362inline bool
363get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
364{
365 int intVal = 0;
366 auto stat = get_if_exists(section, name, intVal);
367 if (stat)
368 v = bool(intVal);
369 return stat;
370}
371
372} // 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)