Ariles
Loading...
Searching...
No Matches
read.h
Go to the documentation of this file.
1/**
2 @file
3 @author Alexander Sherikov
4
5 @copyright 2017-2020 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
6 (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7
8 @brief
9*/
10
11#pragma once
12
13#include <vector>
14
15#include "serialization.h"
16#include "count.h"
17
18/**
19@defgroup read Read
20@ingroup serialization
21
22@brief Base for deserialization.
23*/
24
25namespace ariles2
26{
27 /// @ingroup read
28 namespace read
29 {
31
32
33 class Visitor : public serialization::Base<Visitor, Parameters>
34 {
35 public:
44
45
46 protected:
48 const SizeLimitEnforcementType limit_type,
49 const std::size_t size = 0,
50 const std::size_t min = 0,
51 const std::size_t max = 0) const
52 {
53 switch (limit_type)
54 {
55 case SIZE_LIMIT_NONE:
56 return;
58 CPPUT_ASSERT(size == min, "Actual number of entries is not the same as expected.");
59 return;
61 CPPUT_ASSERT(min <= size, "Actual number of entries is lower than expected.");
62 CPPUT_ASSERT(max >= size, "Actual number of entries is larger than expected.");
63 return;
64 case SIZE_LIMIT_MIN:
65 CPPUT_ASSERT(min <= size, "Actual number of entries is lower than expected.");
66 return;
67 default:
68 CPPUT_THROW("Internal logic error.");
69 }
70 }
71
72
73 virtual bool startRoot(const std::string &name)
74 {
77
78 if (not name.empty())
79 {
80 return (startMapEntry(name));
81 }
82 return (true);
83 }
84
85 virtual void endRoot(const std::string &name)
86 {
88 if (not name.empty())
89 {
91 }
92 }
93
94
95 virtual bool startRoot(const std::vector<std::string> &subtree)
96 {
98
99 bool result = false;
100 if (0 == subtree.size())
101 {
102 result = this->startRoot("");
103 }
104 else
105 {
106 result = this->startRoot(subtree[0]);
107 for (std::size_t i = 1; i < subtree.size() and result; ++i)
108 {
109 this->startMap(SIZE_LIMIT_MIN, 1);
110 result &= (this->startMapEntry(subtree[i]));
111 }
112 }
113
114 return (result);
115 }
116
117 virtual void endRoot(const std::vector<std::string> &subtree)
118 {
120 for (std::size_t i = 1; i < subtree.size(); ++i)
121 {
122 this->endMapEntry();
123 this->endMap();
124 }
125 if (0 == subtree.size())
126 {
127 endRoot("");
128 }
129 else
130 {
131 endRoot(subtree[0]);
132 }
133 }
134
135
136 const std::string &convertSubtreeToString(const std::string &subtree) const
137 {
138 return (subtree);
139 }
140
141 std::string convertSubtreeToString(const std::vector<std::string> &subtree) const
142 {
143 std::string result;
144 for (std::size_t i = 0; i < subtree.size(); ++i)
145 {
146 if (i > 0)
147 {
148 result += "/";
149 }
150 result += subtree[i];
151 }
152 return (result);
153 }
154
155
156 public:
157 template <class t_Entry>
158 void startMap(t_Entry &entry, const Parameters &parameters)
159 {
160 startMap(
161 parameters.allow_missing_entries_ ? SIZE_LIMIT_NONE : SIZE_LIMIT_MIN,
162 ariles2::apply<ariles2::Count>(entry));
163 }
164
165 virtual void startMap(
166 const SizeLimitEnforcementType /*limit_type*/ = SIZE_LIMIT_NONE,
167 const std::size_t /*min*/ = 0,
168 const std::size_t /*max*/ = 0)
169 {
170 }
171
172 /**
173 * @brief startMapEntry to the entry with the given name
174 *
175 * @param[in] child_name child node name
176 *
177 * @return true if successful.
178 */
179 virtual bool startMapEntry(const std::string &child_name)
180 {
182 CPPUT_UNUSED_ARG(child_name)
183 return (true);
184 }
185
186 /**
187 * @brief endMapEntry from the current entry to its parent.
188 */
189 virtual void endMapEntry() = 0;
190
191 virtual void endMap()
192 {
193 }
194
195
196 virtual bool startIteratedMap(
197 const SizeLimitEnforcementType /*limit_type*/ = SIZE_LIMIT_NONE,
198 const std::size_t /*min*/ = 0,
199 const std::size_t /*max*/ = 0)
200 {
201 return (false);
202 }
203 virtual bool startIteratedMapElement(std::string & /*entry_name*/)
204 {
205 CPPUT_THROW("startIteratedMapElement() is not supported.");
206 }
208 {
209 }
210 virtual void endIteratedMap()
211 {
212 }
213
214
215 bool startPointer(const Parameters &param)
216 {
218
219 bool is_null = true;
220
221 this->startMap(SIZE_LIMIT_RANGE, 1, 2);
222
223 if (this->startMapEntry("is_null"))
224 {
225 this->readElement(is_null);
226 this->endMapEntry();
227 }
228 else
229 {
231 param.allow_missing_entries_, "Pointer entry does not include 'is_null' subentry.");
232 }
233
234 if (not is_null)
235 {
236 CPPUT_ASSERT(this->startMapEntry("value"), "Missing value in a pointer entry.");
237 }
238
239 return (is_null);
240 }
241 void endPointer(const bool is_null)
242 {
243 if (not is_null)
244 {
245 this->endMapEntry();
246 }
247 this->endMap();
248 }
249
250
251 virtual std::size_t startArray() = 0;
252 virtual void startArrayElement(){};
253 virtual void endArrayElement() = 0;
254 virtual void endArray() = 0;
255
256 virtual std::size_t startVector()
257 {
258 return (startArray());
259 }
260 virtual void startVectorElement()
261 {
263 }
264 virtual void endVectorElement()
265 {
267 }
268 virtual void endVector()
269 {
270 endArray();
271 }
272
273
274 virtual void startMatrix(std::size_t &cols, std::size_t &rows, const bool dynamic, const Parameters &param)
275 {
276 if (param.flat_matrices_)
277 {
278 if (dynamic or param.explicit_matrix_size_)
279 {
280 this->startMap(SIZE_LIMIT_EQUAL, 3);
281
282 CPPUT_ASSERT(this->startMapEntry("cols"), "Missing 'cols' in a matrix entry.");
283 this->readElement(cols);
284 this->endMapEntry();
285
286 CPPUT_ASSERT(this->startMapEntry("rows"), "Missing 'rows' in a matrix entry.");
287 this->readElement(rows);
288 this->endMapEntry();
289
290 CPPUT_ASSERT(this->startMapEntry("data"), "Missing 'data' in a matrix entry.");
291
292 // cppcheck-suppress unreadVariable
293 const std::size_t vec_len = this->startVector();
294 CPPUT_ASSERT(cols * rows == vec_len, "Inconsistent matrix size.");
295 }
296 else
297 {
298 this->startVector();
299 }
300 }
301 else
302 {
303 rows = this->startArray();
304 if (rows > 0)
305 {
306 this->startArrayElement();
307 cols = this->startVector();
308 }
309 }
310 }
311 virtual void startMatrixRow(const std::size_t row_index, const std::size_t cols, const Parameters &param)
312 {
313 if (not param.flat_matrices_ and 0 != row_index)
314 {
315 this->startArrayElement();
316 // cppcheck-suppress unreadVariable
317 const std::size_t vec_len = this->startVector();
318 CPPUT_ASSERT(cols == vec_len, "Inconsistent matrix row length.");
319 }
320 }
321 virtual void startMatrixElement()
322 {
323 this->startVectorElement();
324 }
325 virtual void endMatrixElement()
326 {
327 this->endVectorElement();
328 }
329 virtual void endMatrixRow(const Parameters &param)
330 {
331 if (not param.flat_matrices_)
332 {
333 this->endVector();
334 this->endArrayElement();
335 }
336 }
337 virtual void endMatrix(const bool dynamic, const Parameters &param)
338 {
339 if (param.flat_matrices_)
340 {
341 this->endVector();
342
343 if (dynamic)
344 {
345 this->endMapEntry();
346 this->endMap();
347 }
348 }
349 else
350 {
351 this->endArray();
352 }
353 }
354
355
356 template <class t_Scalar>
357 void readElement(std::complex<t_Scalar> &entry)
358 {
359 CPPUT_PERSISTENT_ASSERT(2 == this->startArray(), "Wrong number of elements in a complex number");
360 t_Scalar value;
361 this->startArrayElement();
362 this->readElement(value);
363 entry.real(value);
364 this->endArrayElement();
365 this->startArrayElement();
366 this->readElement(value);
367 entry.imag(value);
368 this->endArrayElement();
369 this->endArray();
370 }
371 virtual void readElement(std::complex<float> &entry)
372 {
373 readElement<float>(entry);
374 }
375 virtual void readElement(std::complex<double> &entry)
376 {
377 readElement<double>(entry);
378 }
379
380
381#define ARILES2_BASIC_TYPE(type) virtual void readElement(type &entry) = 0;
382
384
385#undef ARILES2_BASIC_TYPE
386
387
388 template <class t_Entry, class t_Subtree>
389 void visit(t_Entry &entry, const t_Subtree &subtree, const Parameters &param)
390 {
392 CPPUT_TRACE_TYPE(entry);
393
394
395 if (this->startRoot(subtree))
396 {
397 try
398 {
399 apply_read(*this, entry, param);
400 }
401 catch (const std::exception &e)
402 {
403 CPPUT_THROW("Failed to parse entry <", convertSubtreeToString(subtree), "> || ", e.what());
404 }
405
406 this->endRoot(subtree);
407 }
408 else
409 {
411 param.allow_missing_entries_,
412 "Configuration file does not contain entry '",
413 convertSubtreeToString(subtree),
414 "'.");
415 }
416 }
417
418
419 template <class t_Entry>
421 t_Entry &entry,
422 const std::string &name,
423 const Parameters &param,
424 const bool override_missing_entries_locally = false)
425 {
427 CPPUT_TRACE_VALUE(name);
428 CPPUT_TRACE_TYPE(entry);
429
430 if (this->startMapEntry(name))
431 {
432 try
433 {
434 apply_read(*this, entry, param);
435 }
436 catch (const std::exception &e)
437 {
438 CPPUT_THROW("Failed to parse entry <", name, "> || ", e.what());
439 }
440
441 this->endMapEntry();
442 return (true);
443 }
444 else
445 {
447 not override_missing_entries_locally and param.allow_missing_entries_,
448 "Configuration file does not contain entry '",
449 name,
450 "'.");
451 return (false);
452 }
453 }
454
455 template <typename t_Element>
456 void visitArrayElement(t_Element &element, const Parameters &param)
457 {
459 CPPUT_TRACE_TYPE(element);
460
461 this->startArrayElement();
462 apply_read(*this, element, param);
463 this->endArrayElement();
464 }
465
466 template <typename t_Element>
467 void visitVectorElement(t_Element &element, const Parameters & /*param*/)
468 {
470 CPPUT_TRACE_TYPE(element);
471
472 this->startVectorElement();
473 this->readElement(element);
474 this->endVectorElement();
475 }
476
477 template <typename t_Element>
478 void visitMatrixElement(t_Element &element, const Parameters & /*param*/)
479 {
481
482 this->startMatrixElement();
483 this->readElement(element);
484 this->endMatrixElement();
485 }
486 };
487
488
490 {
491 protected:
492 std::ifstream config_ifs_;
493
494 std::istream *input_stream_;
495
496 protected:
498
499 explicit FileVisitorImplementation(const std::string &file_name)
500 {
501 openFile(file_name);
503 }
504
505 explicit FileVisitorImplementation(std::istream &input_stream)
506 {
507 input_stream_ = &input_stream;
508 }
509
510
511 /**
512 * @brief open configuration file
513 *
514 * @param[in] file_name
515 */
516 void openFile(const std::string &file_name)
517 {
518 config_ifs_.open(file_name.c_str());
519 if (!config_ifs_.good())
520 {
521 std::string file_name_default = file_name;
522 config_ifs_.open(file_name_default.c_str());
523 }
524 CPPUT_PERSISTENT_ASSERT(config_ifs_.good(), "Could not open configuration file: ", file_name.c_str());
525 }
526 };
527
528
530
531
532#define ARILES2_NAMED_ENTRY_read(v, entry, name) visitor.visitMapEntry(entry, #name, parameters);
533#define ARILES2_PARENT_read(v, entry)
534#define ARILES2_VISIT_read \
535 template <class t_Visitor> /* cppcheck-suppress duplInheritedMember */ \
536 void arilesVisit( \
537 t_Visitor &visitor, \
538 const typename t_Visitor::Parameters &parameters, \
539 ARILES2_IS_BASE_ENABLER(ariles2::read::Visitor, t_Visitor)) \
540 { \
541 CPPUT_TRACE_FUNCTION; \
542 CPPUT_UNUSED_ARG(visitor); \
543 CPPUT_UNUSED_ARG(parameters); \
544 arilesVisitParents(visitor, parameters); \
545 ARILES2_ENTRIES(read) \
546 }
547
548#define ARILES2_METHODS_read ARILES2_METHODS(read, ARILES2_EMPTY_MACRO, ARILES2_EMPTY_MACRO)
549#define ARILES2_BASE_METHODS_read ARILES2_BASE_METHODS(read)
550 } // namespace read
551
552
553 /// @ingroup read
555} // namespace ariles2
FileVisitorImplementation(const std::string &file_name)
Definition read.h:499
void openFile(const std::string &file_name)
open configuration file
Definition read.h:516
FileVisitorImplementation(std::istream &input_stream)
Definition read.h:505
const std::string & convertSubtreeToString(const std::string &subtree) const
Definition read.h:136
virtual void startMatrixRow(const std::size_t row_index, const std::size_t cols, const Parameters &param)
Definition read.h:311
virtual bool startRoot(const std::vector< std::string > &subtree)
Definition read.h:95
void visitVectorElement(t_Element &element, const Parameters &)
Definition read.h:467
virtual void endIteratedMapElement()
Definition read.h:207
virtual void endVector()
Definition read.h:268
void checkSize(const SizeLimitEnforcementType limit_type, const std::size_t size=0, const std::size_t min=0, const std::size_t max=0) const
Definition read.h:47
virtual void endMatrix(const bool dynamic, const Parameters &param)
Definition read.h:337
virtual void endRoot(const std::string &name)
Definition read.h:85
std::string convertSubtreeToString(const std::vector< std::string > &subtree) const
Definition read.h:141
virtual bool startRoot(const std::string &name)
Definition read.h:73
virtual void startVectorElement()
Definition read.h:260
ARILES2_BASIC_TYPES_LIST void visit(t_Entry &entry, const t_Subtree &subtree, const Parameters &param)
Definition read.h:389
bool startPointer(const Parameters &param)
Definition read.h:215
virtual void endArrayElement()=0
virtual void startArrayElement()
Definition read.h:252
void visitMatrixElement(t_Element &element, const Parameters &)
Definition read.h:478
virtual void endArray()=0
virtual void endMatrixRow(const Parameters &param)
Definition read.h:329
virtual void endIteratedMap()
Definition read.h:210
void visitArrayElement(t_Element &element, const Parameters &param)
Definition read.h:456
bool visitMapEntry(t_Entry &entry, const std::string &name, const Parameters &param, const bool override_missing_entries_locally=false)
Definition read.h:420
virtual void readElement(std::complex< float > &entry)
Definition read.h:371
virtual void endMatrixElement()
Definition read.h:325
virtual void endMapEntry()=0
endMapEntry from the current entry to its parent.
void readElement(std::complex< t_Scalar > &entry)
Definition read.h:357
virtual void endRoot(const std::vector< std::string > &subtree)
Definition read.h:117
virtual std::size_t startVector()
Definition read.h:256
virtual bool startIteratedMap(const SizeLimitEnforcementType=SIZE_LIMIT_NONE, const std::size_t=0, const std::size_t=0)
Definition read.h:196
virtual bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition read.h:179
virtual void endMap()
Definition read.h:191
virtual void endVectorElement()
Definition read.h:264
virtual std::size_t startArray()=0
void startMap(t_Entry &entry, const Parameters &parameters)
Definition read.h:158
void endPointer(const bool is_null)
Definition read.h:241
virtual void startMatrixElement()
Definition read.h:321
virtual bool startIteratedMapElement(std::string &)
Definition read.h:203
virtual void startMap(const SizeLimitEnforcementType=SIZE_LIMIT_NONE, const std::size_t=0, const std::size_t=0)
Definition read.h:165
virtual void startMatrix(std::size_t &cols, std::size_t &rows, const bool dynamic, const Parameters &param)
Definition read.h:274
virtual void readElement(std::complex< double > &entry)
Definition read.h:375
#define CPPUT_PERSISTENT_ASSERT(condition,...)
Definition exception.h:23
#define CPPUT_THROW(...)
Definition exception.h:19
#define CPPUT_ASSERT(condition,...)
Definition exception.h:32
#define ARILES2_BASIC_TYPES_LIST
Definition helpers.h:72
#define CPPUT_UNUSED_ARG(parameter)
Definition misc.h:19
void apply_read(t_Visitor &visitor, t_Entry &entry, const typename t_Visitor::Parameters &parameters, ARILES2_IS_BASE_ENABLER(ariles2::read::Base, t_Entry))
Definition basic.h:21
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126
#define CPPUT_TRACE_TYPE(type)
Definition trace.h:128
#define CPPUT_TRACE_VALUE(value)
Definition trace.h:127