OnixS C++ ICE Binary Order Entry Handler 1.0.0
API Documentation
Loading...
Searching...
No Matches
ConfigurationParser.h
Go to the documentation of this file.
1/*
2 * Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3 *
4 * This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5 * and international copyright treaties.
6 *
7 * Access to and use of the software is governed by the terms of the applicable OnixS Software
8 * Services Agreement (the Agreement) and Customer end user license agreements granting
9 * a non-assignable, non-transferable and non-exclusive license to use the software
10 * for it's own data processing purposes under the terms defined in the Agreement.
11 *
12 * Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13 * of this source code or associated reference material to any other location for further reproduction
14 * or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15 *
16 * Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17 * the terms of the Agreement is a violation of copyright law.
18 */
19#pragma once
20
21#include <OnixS/ICE/BOE/ABI.h>
22
23#include <unordered_map>
24#include <functional>
25#include <string>
26#include <stdexcept>
27
29
30namespace System {
32namespace Utils {
33
35bool isEquals(const std::string& s1, const std::string& s2);
36
38bool parse(uint64_t& result, const std::string& value);
39
41bool parse(int64_t& result, const std::string& value);
42
44bool parse(double& result, const std::string& value);
45
47bool parse(bool& result, const std::string& value);
48
49template<typename> struct NumberName { static const char * name() noexcept;};
50
51#define ONIXS_TYPENAME(Type) template<> inline const char * NumberName<Type>::name() noexcept { return #Type; }
61#undef ONIXS_TYPENAME
62
63template<typename T>
64T parse(const std::string& value)
65{
66 static_assert(std::is_arithmetic<T>::value, "");
67
68 using Wide = typename std::conditional<std::is_floating_point<T>::value, double, typename std::conditional<std::is_signed<T>::value, int64_t, uint64_t>::type>::type;
69
70 Wide v{};
71
72 if(!parse(v, value) || static_cast<Wide>(static_cast<T>(v)) != v)
73 throw std::invalid_argument("Cannot parse " + std::string(NumberName<T>::name()) + " value: '" + value + "'");
74
75 return static_cast<T>(v);
76}
77
78template<typename T>
79T fromString(const std::string& value)
80{
81 return parse<T>(value);
82}
83
84template<> inline std::string fromString<std::string>(const std::string& value)
85{
86 return value;
87}
88
89template<> inline bool fromString<bool>(const std::string& value)
90{
91 bool v{};
92
93 if(!parse(v, value))
94 throw std::invalid_argument("Cannot parse bool value: '" + value + "'");
95
96 return v;
97}
98
99} // Utils
100
101using KeyValueMap = std::unordered_map<std::string, std::string>;
102
105KeyValueMap parseConfigFile(const std::string& fileName, const std::string& rootNode);
106
108void throwCannotApplyConfigurationValue(const std::string& key, const std::string& value);
109
110template<typename C> using Setter = std::function<void(C&, const std::string&)>;
111template<typename C> using Registry = std::unordered_map<std::string, Setter<C>>;
112
113template<typename C, typename Arg>
114Setter<C> makeSetter(C& (C::*mf)(Arg))
115{
116 using Type = typename std::decay<Arg>::type ;
117 return [mf](C& obj, const std::string& text)
118 {
119 (obj.*mf)(Utils::fromString<Type>(text));
120 };
121}
122
124template<typename C>
125void loadFromFile(const std::string& fileName, C& obj, const Registry<C>& reg, const std::string& rootNode, bool ignoreUnknown = true)
126{
127 const auto map = parseConfigFile(fileName, rootNode);
128
129 for (const auto& pair : map)
130 {
131 const auto& key = pair.first;
132 const auto& value = pair.second;
133
134 const auto it = reg.find(key);
135
136 if(it != reg.end())
137 {
138 try
139 {
140 it->second(obj, value);
141 }
142 catch(...)
143 {
145 }
146 }
147 else if (!ignoreUnknown)
148 throw std::invalid_argument("Unknown configuration property '" + key + "'");
149 }
150}
151
152}}
153
#define ONIXS_ICEBOE_NAMESPACE_BEGIN
Definition ABI.h:94
#define ONIXS_ICEBOE_NAMESPACE_END
Definition ABI.h:98
#define ONIXS_ICEBOE_EXPORTED
Definition Compiler.h:153
#define ONIXS_TYPENAME(Type)
@ C
Vendor-provided platform billed by executing broker.
Definition Fields.h:180
bool parse(uint64_t &result, const std::string &value)
bool isEquals(const std::string &s1, const std::string &s2)
KeyValueMap parseConfigFile(const std::string &fileName, const std::string &rootNode)
Parses the given file to the key-value pair map.
std::unordered_map< std::string, Setter< C > > Registry
void throwCannotApplyConfigurationValue(const std::string &key, const std::string &value)
void loadFromFile(const std::string &fileName, C &obj, const Registry< C > &reg, const std::string &rootNode, bool ignoreUnknown=true)
Loads configuration from the given file.
std::function< void(C &, const std::string &)> Setter
std::unordered_map< std::string, std::string > KeyValueMap