Robot Raconteur Companion C++ Library
Loading...
Searching...
No Matches
yaml_number_parser.h
1#include <RobotRaconteur/DataTypes.h>
2#include "yaml-cpp/yaml.h"
3
4#pragma once
5
6namespace RobotRaconteur
7{
8namespace Companion
9{
10namespace InfoParser
11{
12namespace yaml
13{
14
15template <typename T>
16T parse_number(const YAML::Node& node, const std::string& key, bool optional)
17{
18 if (node[key])
19 {
20 return node[key].as<T>();
21 }
22 else
23 {
24 if (optional)
25 {
26 return (T)0;
27 }
28 else
29 {
30 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
31 }
32 }
33}
34
35template <typename T>
36RobotRaconteur::RRArrayPtr<T> parse_numeric_array(const YAML::Node& node, const std::string& key, bool optional,
37 bool varlength = true, size_t len = 0)
38{
39 if (node[key])
40 {
41 auto vec = node[key].as<std::vector<T> >();
42 if (len != 0)
43 {
44 if (!varlength)
45 {
46 if (vec.size() != len)
47 {
48 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
49 }
50 }
51 if (vec.size() >= len)
52 {
53 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
54 }
55 }
56 return RobotRaconteur::VectorToRRArray<T>(vec);
57 }
58 else
59 {
60 if (optional)
61 {
62 if (varlength)
63 {
64 return RobotRaconteur::AllocateRRArray<T>(0);
65 }
66 else
67 {
68 return RobotRaconteur::AllocateRRArray<T>(len);
69 }
70 }
71 else
72 {
73 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
74 }
75 }
76}
77
78template <typename T, int N>
79boost::array<T, N> parse_numeric_array_na(const YAML::Node& node, const std::string& key)
80{
81 if (node[key])
82 {
83 auto arr = node[key].as<std::vector<T> >();
84 if (arr.size() != N)
85 {
86 throw RobotRaconteur::InvalidArgumentException("Invalid array length");
87 }
88 boost::array<T, N> ret{};
89 std::copy(arr.begin(), arr.end(), ret.begin());
90 return ret;
91 }
92 else
93 {
94 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
95 }
96}
97
98static RobotRaconteur::rr_bool parse_bool(const YAML::Node& node, const std::string& key, bool optional)
99{
100 if (node[key])
101 {
102 bool val = node[key].as<bool>();
103 RobotRaconteur::rr_bool ret;
104 ret.value = (val) ? 1 : 0;
105 return ret;
106 }
107 else
108 {
109 if (optional)
110 {
111 RobotRaconteur::rr_bool ret;
112 ret.value = false;
113 return ret;
114 }
115 else
116 {
117 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
118 }
119 }
120}
121
122static std::string parse_string(const YAML::Node& node, const std::string& key, bool optional)
123{
124 if (node[key])
125 {
126 return node[key].as<std::string>();
127 }
128 else
129 {
130 if (optional)
131 {
132 return "";
133 }
134 else
135 {
136 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
137 }
138 }
139}
140
141static RobotRaconteur::RRListPtr<RRArray<char> > parse_string_list(const YAML::Node& node, const std::string& key,
142 bool optional)
143{
144 if (node[key])
145 {
146 return RobotRaconteur::stringVectorToRRList(node[key].as<std::vector<std::string> >());
147 }
148 else
149 {
150 if (optional)
151 {
152 return RobotRaconteur::RRListPtr<RRArray<char> >();
153 }
154 else
155 {
156 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
157 }
158 }
159}
160
161template <typename T>
162RobotRaconteur::RRListPtr<RobotRaconteur::RRArray<T> > parse_numeric_array_list(const YAML::Node& node,
163 const std::string& key, bool optional,
164 bool varlength = true, size_t len = 0)
165{
166 if (node[key])
167 {
168 if (!node[key].IsSequence())
169 {
170 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
171 }
172
173 auto ret = RobotRaconteur::AllocateEmptyRRList<RRArray<double> >();
174 for (auto e : node[key])
175 {
176
177 auto vec = e.as<std::vector<T> >();
178 if (len != 0)
179 {
180 if (!varlength)
181 {
182 if (vec.size() != len)
183 {
184 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
185 }
186 }
187 if (vec.size() >= len)
188 {
189 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
190 }
191 }
192 ret->push_back(RobotRaconteur::VectorToRRArray<T>(vec));
193 }
194 return ret;
195 }
196 else
197 {
198 if (optional)
199 {
200 return RobotRaconteur::AllocateEmptyRRList<RRArray<T> >();
201 }
202 else
203 {
204 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
205 }
206 }
207}
208
209template <typename T>
210RobotRaconteur::RRMapPtr<std::string, RobotRaconteur::RRArray<T> > parse_numeric_array_map_string(
211 const YAML::Node& node, const std::string& key, bool optional, bool varlength = true, size_t len = 0)
212{
213 if (node[key])
214 {
215 if (!node[key].IsMap())
216 {
217 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
218 }
219
220 auto ret = RobotRaconteur::AllocateEmptyRRMap<std::string, RRArray<double> >();
221 for (auto e : node[key])
222 {
223
224 auto vec = e.second.as<std::vector<T> >();
225 if (len != 0)
226 {
227 if (!varlength)
228 {
229 if (vec.size() != len)
230 {
231 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
232 }
233 }
234 if (vec.size() >= len)
235 {
236 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
237 }
238 }
239 ret->insert(std::make_pair(e.first.as<std::string>(), RobotRaconteur::VectorToRRArray<T>(vec)));
240 }
241 return ret;
242 }
243 else
244 {
245 if (optional)
246 {
247 return RobotRaconteur::AllocateEmptyRRMap<std::string, RobotRaconteur::RRArray<T> >();
248 }
249 else
250 {
251 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
252 }
253 }
254}
255
256template <typename T>
257RobotRaconteur::RRMultiDimArrayPtr<T> parse_numeric_multidimarray(const YAML::Node& node, const std::string& key,
258 bool optional, uint32_t m, uint32_t n)
259{
260 if (node[key])
261 {
262 auto vec = node[key].as<std::vector<T> >();
263 if (vec.size() != m * n)
264 {
265 throw RobotRaconteur::InvalidArgumentException("Bad conversion");
266 }
267 std::vector<uint32_t> dims = {m, n};
268 auto ret = RobotRaconteur::AllocateEmptyRRMultiDimArray<T>(dims);
269 std::copy(vec.begin(), vec.end(), ret->Array->begin());
270
271 return ret;
272 }
273 else
274 {
275 if (optional)
276 {
277 std::vector<uint32_t> dims = {m, n};
278 return RobotRaconteur::AllocateEmptyRRMultiDimArray<T>(dims);
279 }
280 else
281 {
282 throw RobotRaconteur::InvalidArgumentException("Key not found: " + key);
283 }
284 }
285}
286
287} // namespace yaml
288} // namespace InfoParser
289} // namespace Companion
290} // namespace RobotRaconteur