Ariles
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 
12 #include "common.h"
13 
14 
15 namespace ariles
16 {
17  namespace ns_rapidjson
18  {
19  namespace impl
20  {
21  class ARILES_VISIBILITY_ATTRIBUTE Reader : public ariles::ns_rapidjson::ImplBase<const ::rapidjson::Value>
22  {
23  public:
24  void initialize(std::istream &input_stream)
25  {
26  ariles::ns_rapidjson::IStreamWrapper isw(input_stream);
27  document_.ParseStream(isw);
28  ARILES_ASSERT(false == document_.HasParseError(), "Parsing failed");
29  }
30  };
31  } // namespace impl
32  } // namespace ns_rapidjson
33 } // namespace ariles
34 
35 
36 
37 namespace ariles
38 {
39  namespace ns_rapidjson
40  {
41  Reader::Reader(const std::string &file_name, const Flags &flags) : Base(flags)
42  {
43  std::ifstream config_ifs;
44  read::Visitor::openFile(config_ifs, file_name);
45  impl_ = ImplPtr(new Impl());
46  impl_->initialize(config_ifs);
47  }
48 
49 
50  Reader::Reader(std::istream &input_stream, const Flags &flags) : Base(flags)
51  {
52  impl_ = ImplPtr(new Impl());
53  impl_->initialize(input_stream);
54  }
55 
56 
57  void Reader::constructFromString(const char *input_string)
58  {
59  impl_ = ImplPtr(new Impl());
60  impl_->document_.Parse(input_string);
61  }
62 
63 
64  std::size_t Reader::getMapSize(const bool /*expect_empty*/)
65  {
66  return (impl_->getRawNode().MemberCount());
67  }
68 
69 
70 
71  bool Reader::descend(const std::string &child_name)
72  {
73  const ::rapidjson::Value::ConstMemberIterator child = impl_->getRawNode().FindMember(child_name.c_str());
74 
75  if (impl_->getRawNode().MemberEnd() == child)
76  {
77  return (false);
78  }
79  else
80  {
81  impl_->node_stack_.push_back(impl::Reader::NodeWrapper(&(child->value)));
82  return (true);
83  }
84  }
85 
86 
88  {
89  impl_->node_stack_.pop_back();
90  }
91 
92 
93  bool Reader::getMapEntryNames(std::vector<std::string> &child_names)
94  {
95  const ::rapidjson::Value &selected_node = impl_->getRawNode();
96 
97  if (false == selected_node.IsObject())
98  {
99  return (false);
100  }
101  else
102  {
103  child_names.resize(selected_node.MemberCount());
104 
105  std::size_t i = 0;
106  for (::rapidjson::Value::ConstMemberIterator it = selected_node.MemberBegin();
107  it != selected_node.MemberEnd();
108  ++it, ++i)
109  {
110  child_names[i] = it->name.GetString();
111  }
112  return (true);
113  }
114  }
115 
116 
117  std::size_t Reader::startArray()
118  {
119  std::size_t size = impl_->getRawNode().Size();
120  impl_->node_stack_.push_back(impl::Reader::NodeWrapper(0, size));
121 
122  return (size);
123  }
124 
125 
127  {
128  ARILES_ASSERT(true == impl_->node_stack_.back().isArray(), "Internal error: expected array.");
129  ARILES_ASSERT(
130  impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_,
131  "Internal error: array has more elements than expected.");
132  ++impl_->node_stack_.back().index_;
133  }
134 
135 
137  {
138  impl_->node_stack_.pop_back();
139  }
140 
141 
142  void Reader::readElement(std::string &element)
143  {
144  element = impl_->getRawNode().GetString();
145  }
146 
147 
148  void Reader::readElement(bool &element)
149  {
150  element = impl_->getRawNode().GetBool();
151  }
152 
153 
154  void Reader::readElement(float &element)
155  {
156  float tmp_value;
157  if (true == impl_->getRawNode().IsString())
158  {
159  tmp_value = boost::lexical_cast<float>(impl_->getRawNode().GetString());
160  if (true == ariles::isNaN(tmp_value))
161  {
162  element = std::numeric_limits<float>::signaling_NaN();
163  return;
164  }
165  if (true == ariles::isInfinity(tmp_value))
166  {
167  element = static_cast<float>(tmp_value);
168  return;
169  }
170  }
171  else
172  {
173  tmp_value = impl_->getRawNode().GetDouble(); // old API compatibility
174  // tmp_value = impl_->getRawNode().GetFloat();
175  }
176  ARILES_ASSERT(
177  tmp_value <= std::numeric_limits<float>::max() && tmp_value >= -std::numeric_limits<float>::max(),
178  "Value is out of range.");
179  element = static_cast<float>(tmp_value);
180  }
181 
182 
183  void Reader::readElement(double &element)
184  {
185  double tmp_value;
186  if (true == impl_->getRawNode().IsString())
187  {
188  tmp_value = boost::lexical_cast<double>(impl_->getRawNode().GetString());
189  if (true == ariles::isNaN(tmp_value))
190  {
191  element = std::numeric_limits<double>::signaling_NaN();
192  return;
193  }
194  if (true == ariles::isInfinity(tmp_value))
195  {
196  element = static_cast<double>(tmp_value);
197  return;
198  }
199  }
200  else
201  {
202  tmp_value = impl_->getRawNode().GetDouble();
203  }
204  ARILES_ASSERT(
205  tmp_value <= std::numeric_limits<double>::max() && tmp_value >= -std::numeric_limits<double>::max(),
206  "Value is out of range.");
207  element = static_cast<double>(tmp_value);
208  }
209 
210 
211 #define ARILES_BASIC_TYPE(type) \
212  void Reader::readElement(type &element) \
213  { \
214  int64_t tmp_value = impl_->getRawNode().GetInt64(); \
215  ARILES_ASSERT( \
216  tmp_value <= std::numeric_limits<type>::max() && tmp_value >= std::numeric_limits<type>::min(), \
217  "Value is out of range."); \
218  element = static_cast<type>(tmp_value); \
219  }
220 
222 
223 #undef ARILES_BASIC_TYPE
224 
225 
226 #define ARILES_BASIC_TYPE(type) \
227  void Reader::readElement(type &element) \
228  { \
229  uint64_t tmp_value = impl_->getRawNode().GetUint64(); \
230  ARILES_ASSERT(tmp_value <= std::numeric_limits<type>::max(), "Value is too large."); \
231  element = static_cast<type>(tmp_value); \
232  }
233 
235 
236 #undef ARILES_BASIC_TYPE
237  } // namespace ns_rapidjson
238 } // namespace ariles
t_Implementation Impl
Definition: rapidjson.h:61
bool descend(const std::string &child_name)
Definition: reader.cpp:71
void constructFromString(const char *)
Definition: reader.cpp:57
#define ARILES_BASIC_UNSIGNED_INTEGER_TYPES_LIST
Definition: helpers.h:86
std::size_t getMapSize(const bool)
Definition: reader.cpp:64
void initialize(std::istream &input_stream)
Definition: reader.cpp:24
static void openFile(std::ifstream &config_ifs, const std::string &file_name)
open configuration file
Definition: read.h:81
ARILES_SHARED_PTR< t_Implementation > ImplPtr
Definition: rapidjson.h:62
#define ARILES_BASIC_SIGNED_INTEGER_TYPES_LIST
Definition: helpers.h:80
Reader(const Flags &flags=Flags::DEFAULT)
Definition: reader.h:32
ARILES_MACRO_SUBSTITUTE(ARILES_BASIC_SIGNED_INTEGER_TYPES_LIST) ARILES_MACRO_SUBSTITUTE(ARILES_BASIC_UNSIGNED_INTEGER_TYPES_LIST) ARILES_MACRO_SUBSTITUTE(ARILES_BASIC_REAL_TYPES_LIST) void Reader
Definition: reader.cpp:172
bool getMapEntryNames(std::vector< std::string > &child_names)
Definition: reader.cpp:93
Wrapper of std::basic_istream into RapidJSON's Stream concept.
#define ARILES_VISIBILITY_ATTRIBUTE
Definition: helpers.h:69
Definition: basic.h:17
std::size_t startArray()
Definition: reader.cpp:117