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 xrpl {
16
18
19//------------------------------------------------------------------------------
20
25{
26private:
32
34
35public:
37 explicit Section(std::string const& name = "");
38
40 std::string const&
41 name() const
42 {
43 return name_;
44 }
45
50 lines() const
51 {
52 return lines_;
53 }
54
59 values() const
60 {
61 return values_;
62 }
63
67 void
69 {
70 if (lines_.empty())
71 lines_.emplace_back(std::move(value));
72 else
73 lines_[0] = std::move(value);
74 }
75
83 legacy() const
84 {
85 if (lines_.empty())
86 return "";
87 if (lines_.size() > 1)
88 Throw<std::runtime_error>("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(map_.cbegin(), map_.cend(), [](auto s) { return s.second.had_trailing_comments(); });
273 }
274
275protected:
276 void
277 build(IniFileSections const& ifs);
278};
279
280//------------------------------------------------------------------------------
281
287template <class T>
288bool
289set(T& target, std::string const& name, Section const& section)
290{
291 bool found_and_valid = false;
292 try
293 {
294 auto const val = section.get<T>(name);
295 if ((found_and_valid = val.has_value()))
296 target = *val;
297 }
298 catch (boost::bad_lexical_cast&)
299 {
300 }
301 return found_and_valid;
302}
303
309template <class T>
310bool
311set(T& target, T const& defaultValue, std::string const& name, Section const& section)
312{
313 bool found_and_valid = set<T>(target, name, section);
314 if (!found_and_valid)
315 target = defaultValue;
316 return found_and_valid;
317}
318
323// NOTE This routine might be more clumsy than the previous two
324template <class T = std::string>
325T
326get(Section const& section, std::string const& name, T const& defaultValue = T{})
327{
328 try
329 {
330 return section.value_or<T>(name, defaultValue);
331 }
332 catch (boost::bad_lexical_cast&)
333 {
334 }
335 return defaultValue;
336}
337
338inline std::string
339get(Section const& section, std::string const& name, char const* defaultValue)
340{
341 try
342 {
343 auto const val = section.get(name);
344 if (val.has_value())
345 return *val;
346 }
347 catch (boost::bad_lexical_cast&)
348 {
349 }
350 return defaultValue;
351}
352
353template <class T>
354bool
355get_if_exists(Section const& section, std::string const& name, T& v)
356{
357 return set<T>(v, name, section);
358}
359
360template <>
361inline bool
362get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
363{
364 int intVal = 0;
365 auto stat = get_if_exists(section, name, intVal);
366 if (stat)
367 v = bool(intVal);
368 return stat;
369}
370
371} // namespace xrpl
372
373#endif
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:25
const_iterator end() const
std::optional< T > get(std::string const &name) const
decltype(lookup_)::const_iterator const_iterator
Definition BasicConfig.h:33
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:28
bool had_trailing_comments() const
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition BasicConfig.h:59
std::string const & name() const
Returns the name of this section.
Definition BasicConfig.h:41
std::vector< std::string > values_
Definition BasicConfig.h:30
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition BasicConfig.h:50
std::string name_
Definition BasicConfig.h:27
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:83
void legacy(std::string value)
Set the legacy value for this section.
Definition BasicConfig.h:68
bool had_trailing_comments_
Definition BasicConfig.h:31
std::vector< std::string > lines_
Definition BasicConfig.h:29
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: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< 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)