Ariles
reader.cpp
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2014-2017 INRIA. Licensed under the Apache License, Version 2.0.
6  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
7 
8  @copyright 2017-2018 Alexander Sherikov, Licensed under the Apache License, Version 2.0.
9  (see @ref LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
10 
11  @brief
12 */
13 
14 #include <sstream>
15 #include <msgpack.hpp>
16 
18 
19 namespace ariles
20 {
21  namespace ns_msgpack
22  {
24  }
25 } // namespace ariles
26 
27 
28 namespace ariles
29 {
30  namespace ns_msgpack
31  {
32  namespace impl
33  {
35  {
36  public:
37  std::string buffer_;
38 
39  std::vector<ARILES_SHARED_PTR< ::msgpack::object_handle> > handles_;
40 
41  /// Stack of nodes.
42  std::vector<NodeWrapper> node_stack_;
43 
44  std::size_t nameless_counter_;
45 
46 
47  public:
48  /**
49  * @brief open configuration file
50  *
51  * @param[in] input_stream
52  */
53  void initialize(std::istream &input_stream)
54  {
56  std::stringstream str_stream;
57  str_stream << input_stream.rdbuf();
58  buffer_ = str_stream.str();
59 
60 
61  handles_.clear();
62  try
63  {
64  std::size_t buffer_offset = 0;
65 
66  while (buffer_offset != buffer_.size())
67  {
68  handles_.push_back(
69  ARILES_SHARED_PTR< ::msgpack::object_handle>(new ::msgpack::object_handle));
70 
71  unpack(*handles_[handles_.size() - 1], buffer_.data(), buffer_.size(), buffer_offset);
72  }
73  }
74  catch (const std::exception &e)
75  {
76  ARILES_THROW(std::string("Failed to parse the configuration file: ") + e.what());
77  }
78 
79  nameless_counter_ = 0;
80  }
81 
82 
83  /**
84  * @brief Get current node
85  *
86  * @return pointer to the current node
87  */
88  const ::msgpack::object &getRawNode(const std::size_t depth)
89  {
91  if (node_stack_[depth].isArray())
92  {
93  return (getRawNode(depth - 1).via.array.ptr[node_stack_[depth].index_]);
94  }
95  else
96  {
97  return (*node_stack_[depth].node_);
98  }
99  }
100 
101 
102  const ::msgpack::object &getRawNode()
103  {
105  return (getRawNode(node_stack_.size() - 1));
106  }
107  };
108  } // namespace impl
109  } // namespace ns_msgpack
110 } // namespace ariles
111 
112 
113 namespace ariles
114 {
115  namespace ns_msgpack
116  {
117  Reader::Reader(const std::string &file_name)
118  {
119  std::ifstream config_ifs;
120  read::Visitor::openFile(config_ifs, file_name);
121  impl_ = ImplPtr(new Impl());
122  impl_->initialize(config_ifs);
123  }
124 
125 
126  Reader::Reader(std::istream &input_stream)
127  {
128  impl_ = ImplPtr(new Impl());
129  impl_->initialize(input_stream);
130  }
131 
132 
133  std::size_t Reader::getMapSize(const bool /*expect_empty*/)
134  {
136  return (impl_->getRawNode().via.map.size);
137  }
138 
139 
140 
141  bool Reader::descend(const std::string &child_name)
142  {
144  ARILES_TRACE_ENTRY(child_name);
145  if (impl_->node_stack_.size() == 0)
146  {
147  for (std::size_t i = 0; i < impl_->handles_.size(); ++i)
148  {
149  if (::msgpack::type::MAP == impl_->handles_[i]->get().type)
150  {
151  if (child_name == impl_->handles_[i]->get().via.map.ptr[0].key.as<std::string>())
152  {
153  if (::msgpack::type::MAP == impl_->handles_[i]->get().via.map.ptr[0].val.type)
154  {
155  impl_->node_stack_.push_back(
156  NodeWrapper(&(impl_->handles_[i]->get().via.map.ptr[0].val)));
157  return (true);
158  }
159  }
160  }
161  }
162  }
163  else
164  {
165  if (::msgpack::type::MAP == impl_->getRawNode().type)
166  {
167  for (std::size_t i = 0; i < impl_->getRawNode().via.map.size; ++i)
168  {
169  if (child_name == impl_->getRawNode().via.map.ptr[i].key.as<std::string>())
170  {
171  impl_->node_stack_.push_back(NodeWrapper(&(impl_->getRawNode().via.map.ptr[i].val)));
172  return (true);
173  }
174  }
175  }
176  }
177 
178  return (false);
179  }
180 
181 
183  {
185  impl_->node_stack_.pop_back();
186  }
187 
188 
189  std::size_t Reader::startArray()
190  {
192  std::size_t size = impl_->getRawNode().via.array.size;
193  impl_->node_stack_.push_back(NodeWrapper(0, size));
194 
195  return (size);
196  }
197 
198 
200  {
202  impl_->node_stack_.pop_back();
203  }
204 
205 
207  {
209  ARILES_ASSERT(true == impl_->node_stack_.back().isArray(), "Internal error: expected array.");
210  ARILES_ASSERT(
211  impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_,
212  "Internal error: array has more elements than expected.");
213  ++impl_->node_stack_.back().index_;
214  }
215 
216 
217  bool Reader::startRoot(const std::string &name)
218  {
220  if (true == name.empty())
221  {
222  ARILES_ASSERT(
223  0 == impl_->nameless_counter_,
224  "Multiple nameless root entries are not supported, specify root names explicitly.");
225  ++impl_->nameless_counter_;
226  return (descend("ariles"));
227  }
228  else
229  {
230  return (descend(name));
231  }
232  }
233 
234  void Reader::endRoot(const std::string & /*name*/)
235  {
237  ascend();
238  }
239 
240 
241 #define ARILES_BASIC_TYPE(type) \
242  void Reader::readElement(type &element) \
243  { \
244  ARILES_TRACE_FUNCTION; \
245  impl_->getRawNode() >> element; \
246  }
247 
249 
250 #undef ARILES_BASIC_TYPE
251  } // namespace ns_msgpack
252 } // namespace ariles
bool descend(const std::string &child_name)
Descend to the entry with the given name.
Definition: reader.cpp:141
#define ARILES_TRACE_FUNCTION
Definition: trace.h:118
bool startRoot(const std::string &name)
Definition: reader.cpp:217
std::size_t getMapSize(const bool)
Definition: reader.cpp:133
static void openFile(std::ifstream &config_ifs, const std::string &file_name)
open configuration file
Definition: read.h:81
std::vector< ARILES_SHARED_PTR< ::msgpack::object_handle > > handles_
Definition: reader.cpp:39
void ascend()
Ascend from the current entry to its parent.
Definition: reader.cpp:182
#define ARILES_BASIC_TYPES_LIST
Definition: helpers.h:105
void initialize(std::istream &input_stream)
open configuration file
Definition: reader.cpp:53
std::vector< NodeWrapper > node_stack_
Stack of nodes.
Definition: reader.cpp:42
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
void endRoot(const std::string &name)
Definition: reader.cpp:234
const ::msgpack::object & getRawNode()
Definition: reader.cpp:102
ariles::Node< const ::msgpack::object * > NodeWrapper
Definition: reader.cpp:23
#define ARILES_VISIBILITY_ATTRIBUTE
Definition: helpers.h:69
#define ARILES_TRACE_ENTRY(entry_name)
Definition: trace.h:119
Definition: basic.h:17
const ::msgpack::object & getRawNode(const std::size_t depth)
Get current node.
Definition: reader.cpp:88
Reader(const std::string &file_name)
Constructor.
Definition: reader.cpp:117
std::size_t startArray()
Definition: reader.cpp:189