rippled
Loading...
Searching...
No Matches
BasicConfig.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_BASICS_BASICCONFIG_H_INCLUDED
21#define RIPPLE_BASICS_BASICCONFIG_H_INCLUDED
22
23#include <xrpl/basics/contract.h>
24
25#include <boost/beast/core/string.hpp>
26#include <boost/lexical_cast.hpp>
27
28#include <algorithm>
29#include <optional>
30#include <ostream>
31#include <string>
32#include <unordered_map>
33#include <vector>
34
35namespace ripple {
36
39
40//------------------------------------------------------------------------------
41
46{
47private:
53
55
56public:
58 explicit Section(std::string const& name = "");
59
61 std::string const&
62 name() const
63 {
64 return name_;
65 }
66
71 lines() const
72 {
73 return lines_;
74 }
75
80 values() const
81 {
82 return values_;
83 }
84
88 void
90 {
91 if (lines_.empty())
92 lines_.emplace_back(std::move(value));
93 else
94 lines_[0] = std::move(value);
95 }
96
104 legacy() const
105 {
106 if (lines_.empty())
107 return "";
108 if (lines_.size() > 1)
109 Throw<std::runtime_error>(
110 "A legacy value must have exactly one line. Section: " + name_);
111 return lines_[0];
112 }
113
117 void
118 set(std::string const& key, std::string const& value);
119
125 void
127
129 void
130 append(std::string const& line)
131 {
133 }
134
136 bool
137 exists(std::string const& name) const;
138
139 template <class T = std::string>
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
150 template <class T>
151 T
152 value_or(std::string const& name, T const& other) const
153 {
154 auto const v = get<T>(name);
155 return v.has_value() ? *v : other;
156 }
157
158 // indicates if trailing comments were seen
159 // during the appending of any lines/values
160 bool
162 {
164 }
165
166 friend std::ostream&
167 operator<<(std::ostream&, Section const& section);
168
169 // Returns `true` if there are no key/value pairs.
170 bool
171 empty() const
172 {
173 return lookup_.empty();
174 }
175
176 // Returns the number of key/value pairs.
178 size() const
179 {
180 return lookup_.size();
181 }
182
183 // For iteration of key/value pairs.
185 begin() const
186 {
187 return lookup_.cbegin();
188 }
189
190 // For iteration of key/value pairs.
192 cbegin() const
193 {
194 return lookup_.cbegin();
195 }
196
197 // For iteration of key/value pairs.
199 end() const
200 {
201 return lookup_.cend();
202 }
203
204 // For iteration of key/value pairs.
206 cend() const
207 {
208 return lookup_.cend();
209 }
210};
211
212//------------------------------------------------------------------------------
213
219{
220private:
222
223public:
225 bool
226 exists(std::string const& name) const;
227
232 Section&
233 section(std::string const& name);
234
235 Section const&
236 section(std::string const& name) const;
237
238 Section const&
239 operator[](std::string const& name) const
240 {
241 return section(name);
242 }
243
244 Section&
246 {
247 return section(name);
248 }
255 void
256 overwrite(
257 std::string const& section,
258 std::string const& key,
259 std::string const& value);
260
263 void
265
275 void
276 legacy(std::string const& section, std::string value);
277
287 legacy(std::string const& sectionName) const;
288
289 friend std::ostream&
290 operator<<(std::ostream& ss, BasicConfig const& c);
291
292 // indicates if trailing comments were seen
293 // in any loaded Sections
294 bool
296 {
297 return std::any_of(map_.cbegin(), map_.cend(), [](auto s) {
298 return s.second.had_trailing_comments();
299 });
300 }
301
302protected:
303 void
304 build(IniFileSections const& ifs);
305};
306
307//------------------------------------------------------------------------------
308
314template <class T>
315bool
316set(T& target, std::string const& name, Section const& section)
317{
318 bool found_and_valid = false;
319 try
320 {
321 auto const val = section.get<T>(name);
322 if ((found_and_valid = val.has_value()))
323 target = *val;
324 }
325 catch (boost::bad_lexical_cast&)
326 {
327 }
328 return found_and_valid;
329}
330
336template <class T>
337bool
338set(T& target,
339 T const& defaultValue,
340 std::string const& name,
341 Section const& section)
342{
343 bool found_and_valid = set<T>(target, name, section);
344 if (!found_and_valid)
345 target = defaultValue;
346 return found_and_valid;
347}
348
353// NOTE This routine might be more clumsy than the previous two
354template <class T = std::string>
355T
356get(Section const& section,
357 std::string const& name,
358 T const& defaultValue = T{})
359{
360 try
361 {
362 return section.value_or<T>(name, defaultValue);
363 }
364 catch (boost::bad_lexical_cast&)
365 {
366 }
367 return defaultValue;
368}
369
370inline std::string
371get(Section const& section, std::string const& name, const char* defaultValue)
372{
373 try
374 {
375 auto const val = section.get(name);
376 if (val.has_value())
377 return *val;
378 }
379 catch (boost::bad_lexical_cast&)
380 {
381 }
382 return defaultValue;
383}
384
385template <class T>
386bool
387get_if_exists(Section const& section, std::string const& name, T& v)
388{
389 return set<T>(v, name, section);
390}
391
392template <>
393inline bool
394get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
395{
396 int intVal = 0;
397 auto stat = get_if_exists(section, name, intVal);
398 if (stat)
399 v = bool(intVal);
400 return stat;
401}
402
403} // namespace ripple
404
405#endif
T any_of(T... args)
T cbegin(T... args)
Holds unparsed configuration information.
Definition: BasicConfig.h:219
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
Definition: BasicConfig.h:295
Section const & operator[](std::string const &name) const
Definition: BasicConfig.h:239
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_
Definition: BasicConfig.h:221
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)
Definition: BasicConfig.h:245
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:46
std::string const & name() const
Returns the name of this section.
Definition: BasicConfig.h:62
std::size_t size() const
Definition: BasicConfig.h:178
std::string legacy() const
Get the legacy value for this section.
Definition: BasicConfig.h:104
std::vector< std::string > lines_
Definition: BasicConfig.h:50
friend std::ostream & operator<<(std::ostream &, Section const &section)
const_iterator begin() const
Definition: BasicConfig.h:185
decltype(lookup_)::const_iterator const_iterator
Definition: BasicConfig.h:54
const_iterator cend() const
Definition: BasicConfig.h:206
bool had_trailing_comments() const
Definition: BasicConfig.h:161
T value_or(std::string const &name, T const &other) const
Returns a value if present, else another value.
Definition: BasicConfig.h:152
std::vector< std::string > const & lines() const
Returns all the lines in the section.
Definition: BasicConfig.h:71
void legacy(std::string value)
Set the legacy value for this section.
Definition: BasicConfig.h:89
std::optional< T > get(std::string const &name) const
Definition: BasicConfig.h:141
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.
Definition: BasicConfig.h:130
const_iterator cbegin() const
Definition: BasicConfig.h:192
bool had_trailing_comments_
Definition: BasicConfig.h:52
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
Definition: BasicConfig.cpp:38
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:80
std::string name_
Definition: BasicConfig.h:48
std::unordered_map< std::string, std::string > lookup_
Definition: BasicConfig.h:49
std::vector< std::string > values_
Definition: BasicConfig.h:51
const_iterator end() const
Definition: BasicConfig.h:199
bool empty() const
Definition: BasicConfig.h:171
T emplace_back(T... args)
T empty(T... args)
T end(T... args)
T find(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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,...
Definition: BasicConfig.h:316
bool get_if_exists(Section const &section, std::string const &name, T &v)
Definition: BasicConfig.h:387
bool get_if_exists< bool >(Section const &section, std::string const &name, bool &v)
Definition: BasicConfig.h:394
T get(Section const &section, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
Definition: BasicConfig.h:356
T size(T... args)