Ariles
Loading...
Searching...
No Matches
reader.cpp
Go to the documentation of this file.
1/**
2 @file
3 @author Alexander Sherikov
4
5 @copyright 2018-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#include <boost/math/special_functions.hpp>
13#include "common.h"
14
15
16namespace ariles2
17{
18 namespace ns_rapidjson
19 {
20 namespace impl
21 {
22 class Reader : public ariles2::ns_rapidjson::ImplBase<const ::rapidjson::Value>,
24 {
25 public:
26 std::vector<::rapidjson::Value::ConstMemberIterator> iterator_stack_;
27
28 public:
29 Reader() = default;
30
31 template <class... t_Args>
32 explicit Reader(t_Args &&...args) : FileVisitorImplementation(std::forward<t_Args>(args)...)
33 {
34 initialize();
35 }
36
37
39 {
41 document_.ParseStream(isw);
42 CPPUT_ASSERT(not document_.HasParseError(), "Parsing failed");
43 }
44 };
45 } // namespace impl
46 } // namespace ns_rapidjson
47} // namespace ariles2
48
49
50
51namespace ariles2
52{
53 namespace ns_rapidjson
54 {
55 Reader::Reader(const std::string &file_name)
56 {
57 makeImplPtr(file_name);
58 }
59
60
61 Reader::Reader(std::istream &input_stream)
62 {
63 makeImplPtr(input_stream);
64 }
65
66
67 void Reader::constructFromString(const char *input_string)
68 {
70 impl_->document_.Parse(input_string);
71 }
72
73
74 void Reader::startMap(const SizeLimitEnforcementType limit_type, const std::size_t min, const std::size_t max)
75 {
77 checkSize(limit_type, impl_->getRawNode().MemberCount(), min, max);
78 }
79
80 bool Reader::startMapEntry(const std::string &child_name)
81 {
82 const ::rapidjson::Value::ConstMemberIterator child = impl_->getRawNode().FindMember(child_name.c_str());
83
84 if (impl_->getRawNode().MemberEnd() == child)
85 {
86 return (false);
87 }
88 impl_->emplace(&(child->value));
89 return (true);
90 }
91
93 {
94 impl_->pop();
95 }
96
97
99 const SizeLimitEnforcementType limit_type,
100 const std::size_t min,
101 const std::size_t max)
102 {
104 checkSize(limit_type, impl_->getRawNode().MemberCount(), min, max);
105
106
107 const ::rapidjson::Value &selected_node = impl_->getRawNode();
108
109 if (selected_node.IsObject())
110 {
111 impl_->iterator_stack_.push_back(selected_node.MemberBegin());
112 return (true);
113 }
114 return (false);
115 }
116
117 bool Reader::startIteratedMapElement(std::string &entry_name)
118 {
119 if (impl_->iterator_stack_.back() != impl_->getRawNode().MemberEnd())
120 {
121 impl_->emplace(&(impl_->iterator_stack_.back()->value));
122 entry_name = impl_->iterator_stack_.back()->name.GetString();
123 return (true);
124 }
125 return (false);
126 }
127
129 {
130 ++impl_->iterator_stack_.back();
131 impl_->pop();
132 }
133
135 {
137 impl_->iterator_stack_.back() == impl_->getRawNode().MemberEnd(),
138 "End of iterated map has not been reached.");
139 impl_->iterator_stack_.pop_back();
140 }
141
142
143 std::size_t Reader::startArray()
144 {
145 CPPUT_ASSERT(impl_->getRawNode().IsArray(), "Internal error: expected array.");
146
147 std::size_t size = impl_->getRawNode().Size();
148 impl_->emplace(0, size);
149
150 return (size);
151 }
152
153
155 {
157 impl_->back().index_ < impl_->back().size_,
158 "Internal error: array has more elements than expected.");
159 }
160
161
163 {
164 impl_->shiftArray();
165 }
166
167
169 {
170 impl_->pop();
171 }
172
173
174 void Reader::readElement(std::string &element)
175 {
176 element = impl_->getRawNode().GetString();
177 }
178
179
180 void Reader::readElement(bool &element)
181 {
182 element = impl_->getRawNode().GetBool();
183 }
184
185
186 void Reader::readElement(float &element)
187 {
188 float tmp_value = 0.0;
189 if (impl_->getRawNode().IsString())
190 {
191 tmp_value = boost::lexical_cast<float>(impl_->getRawNode().GetString());
192 if (boost::math::isnan(tmp_value))
193 {
194 element = std::numeric_limits<float>::signaling_NaN();
195 return;
196 }
197 if (boost::math::isinf(tmp_value))
198 {
199 element = static_cast<float>(tmp_value);
200 return;
201 }
202 }
203 else
204 {
205 tmp_value = static_cast<float>(impl_->getRawNode().GetDouble()); // old API compatibility
206 // tmp_value = impl_->getRawNode().GetFloat();
207 }
209 tmp_value <= std::numeric_limits<float>::max() && tmp_value >= -std::numeric_limits<float>::max(),
210 "Value is out of range.");
211 element = static_cast<float>(tmp_value);
212 }
213
214
215 void Reader::readElement(double &element)
216 {
217 double tmp_value = 0.0;
218 if (impl_->getRawNode().IsString())
219 {
220 tmp_value = boost::lexical_cast<double>(impl_->getRawNode().GetString());
221 if (boost::math::isnan(tmp_value))
222 {
223 element = std::numeric_limits<double>::signaling_NaN();
224 return;
225 }
226 if (boost::math::isinf(tmp_value))
227 {
228 element = static_cast<double>(tmp_value);
229 return;
230 }
231 }
232 else
233 {
234 tmp_value = impl_->getRawNode().GetDouble();
235 }
237 tmp_value <= std::numeric_limits<double>::max() && tmp_value >= -std::numeric_limits<double>::max(),
238 "Value is out of range.");
239 element = static_cast<double>(tmp_value);
240 }
241
242
243#define ARILES2_BASIC_TYPE(type) \
244 void Reader::readElement(type &element) \
245 { \
246 int64_t tmp_value = impl_->getRawNode().GetInt64(); \
247 CPPUT_ASSERT( \
248 tmp_value <= std::numeric_limits<type>::max() && tmp_value >= std::numeric_limits<type>::min(), \
249 "Value is out of range."); \
250 element = static_cast<type>(tmp_value); \
251 }
252
254
255#undef ARILES2_BASIC_TYPE
256
257
258#define ARILES2_BASIC_TYPE(type) \
259 void Reader::readElement(type &element) \
260 { \
261 uint64_t tmp_value = impl_->getRawNode().GetUint64(); \
262 CPPUT_ASSERT(tmp_value <= std::numeric_limits<type>::max(), "Value is too large."); \
263 element = static_cast<type>(tmp_value); \
264 }
265
267
268#undef ARILES2_BASIC_TYPE
269 } // namespace ns_rapidjson
270} // namespace ariles2
Wrapper of std::basic_istream into RapidJSON's Stream concept.
::rapidjson::Document document_
instance of the parser
Definition common.h:40
bool startIteratedMapElement(std::string &entry_name)
Definition reader.cpp:117
void endMapEntry()
endMapEntry from the current entry to its parent.
Definition reader.cpp:92
bool startIteratedMap(const SizeLimitEnforcementType=SIZE_LIMIT_NONE, const std::size_t=0, const std::size_t=0)
Definition reader.cpp:98
void startMap(const SizeLimitEnforcementType limit_type=SIZE_LIMIT_NONE, const std::size_t min=0, const std::size_t max=0)
Definition reader.cpp:74
bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition reader.cpp:80
void constructFromString(const char *)
Definition reader.cpp:67
std::vector<::rapidjson::Value::ConstMemberIterator > iterator_stack_
Definition reader.cpp:26
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
void readElement(std::complex< t_Scalar > &entry)
Definition read.h:357
#define CPPUT_ASSERT(condition,...)
Definition exception.h:32
#define ARILES2_BASIC_UNSIGNED_INTEGER_TYPES_LIST
Definition helpers.h:50
#define ARILES2_BASIC_SIGNED_INTEGER_TYPES_LIST
Definition helpers.h:37
#define CPPUT_MACRO_SUBSTITUTE(macro)
Definition misc.h:21
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126