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 ariles2
20 {
21  namespace ns_msgpack
22  {
24  }
25 } // namespace ariles2
26 
27 
28 namespace ariles2
29 {
30  namespace ns_msgpack
31  {
32  namespace impl
33  {
35  {
36  public:
37  std::string buffer_;
38 
39  std::vector<ARILES2_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  {
55  ARILES2_TRACE_FUNCTION;
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  ARILES2_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  ARILES2_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  {
90  ARILES2_TRACE_FUNCTION;
91  if (node_stack_[depth].isArray())
92  {
93  return (getRawNode(depth - 1).via.array.ptr[node_stack_[depth].index_]);
94  }
95  return (*node_stack_[depth].node_);
96  }
97 
98 
99  const ::msgpack::object &getRawNode()
100  {
101  ARILES2_TRACE_FUNCTION;
102  return (getRawNode(node_stack_.size() - 1));
103  }
104  };
105  } // namespace impl
106  } // namespace ns_msgpack
107 } // namespace ariles2
108 
109 
110 namespace ariles2
111 {
112  namespace ns_msgpack
113  {
114  Reader::Reader(const std::string &file_name)
115  {
116  std::ifstream config_ifs;
117  read::Visitor::openFile(config_ifs, file_name);
118  impl_ = ImplPtr(new Impl());
119  impl_->initialize(config_ifs);
120  }
121 
122 
123  Reader::Reader(std::istream &input_stream)
124  {
125  impl_ = ImplPtr(new Impl());
126  impl_->initialize(input_stream);
127  }
128 
129 
130  void Reader::startMap(const SizeLimitEnforcementType limit_type, const std::size_t min, const std::size_t max)
131  {
132  ARILES2_TRACE_FUNCTION;
133  checkSize(limit_type, impl_->getRawNode().via.map.size, min, max);
134  }
135 
136 
137 
138  bool Reader::startMapEntry(const std::string &child_name)
139  {
140  ARILES2_TRACE_FUNCTION;
141  ARILES2_TRACE_VALUE(child_name);
142  if (impl_->node_stack_.empty())
143  {
144  for (std::size_t i = 0; i < impl_->handles_.size(); ++i)
145  {
146  if (::msgpack::type::MAP == impl_->handles_[i]->get().type)
147  {
148  if (child_name == impl_->handles_[i]->get().via.map.ptr[0].key.as<std::string>())
149  {
150  if (::msgpack::type::MAP == impl_->handles_[i]->get().via.map.ptr[0].val.type)
151  {
152  impl_->node_stack_.push_back(
153  NodeWrapper(&(impl_->handles_[i]->get().via.map.ptr[0].val)));
154  return (true);
155  }
156  }
157  }
158  }
159  }
160  else
161  {
162  if (::msgpack::type::MAP == impl_->getRawNode().type)
163  {
164  for (std::size_t i = 0; i < impl_->getRawNode().via.map.size; ++i)
165  {
166  if (child_name == impl_->getRawNode().via.map.ptr[i].key.as<std::string>())
167  {
168  impl_->node_stack_.push_back(NodeWrapper(&(impl_->getRawNode().via.map.ptr[i].val)));
169  return (true);
170  }
171  }
172  }
173  }
174 
175  return (false);
176  }
177 
178 
180  {
181  ARILES2_TRACE_FUNCTION;
182  impl_->node_stack_.pop_back();
183  }
184 
185 
186  std::size_t Reader::startArray()
187  {
188  ARILES2_TRACE_FUNCTION;
189  const std::size_t size = impl_->getRawNode().via.array.size;
190  impl_->node_stack_.push_back(NodeWrapper(0, size));
191 
192  return (size);
193  }
194 
195 
197  {
198  ARILES2_TRACE_FUNCTION;
199  impl_->node_stack_.pop_back();
200  }
201 
202 
204  {
205  ARILES2_ASSERT(
206  impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_,
207  "Internal error: namevalue.has more elements than expected.");
208  }
209 
210 
212  {
213  ARILES2_TRACE_FUNCTION;
214  ARILES2_ASSERT(true == impl_->node_stack_.back().isArray(), "Internal error: expected array.");
215  ++impl_->node_stack_.back().index_;
216  }
217 
218 
219  bool Reader::startRoot(const std::string &name)
220  {
221  ARILES2_TRACE_FUNCTION;
222  if (true == name.empty())
223  {
224  ARILES2_ASSERT(
225  0 == impl_->nameless_counter_,
226  "Multiple nameless root entries are not supported, specify root names explicitly.");
227  ++impl_->nameless_counter_;
228  return (startMapEntry("ariles"));
229  }
230  return (startMapEntry(name));
231  }
232 
233  void Reader::endRoot(const std::string & /*name*/)
234  {
235  ARILES2_TRACE_FUNCTION;
236  endMapEntry();
237  }
238 
239 
240 #define ARILES2_BASIC_TYPE(type) \
241  void Reader::readElement(type &element) \
242  { \
243  ARILES2_TRACE_FUNCTION; \
244  impl_->getRawNode() >> element; \
245  }
246 
248 
249 #undef ARILES2_BASIC_TYPE
250  } // namespace ns_msgpack
251 } // namespace ariles2
ariles2
Definition: basic.h:16
ariles2::ns_msgpack::Reader::endMapEntry
void endMapEntry()
endMapEntry from the current entry to its parent.
Definition: reader.cpp:179
ariles2::read::Visitor::checkSize
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:62
ARILES2_BASIC_TYPES_LIST
#define ARILES2_BASIC_TYPES_LIST
Definition: helpers.h:131
ariles2::ns_msgpack::Reader::startRoot
bool startRoot(const std::string &name)
Definition: reader.cpp:219
ariles2::ns_rosparam::ARILES2_MACRO_SUBSTITUTE
ARILES2_MACRO_SUBSTITUTE(ARILES2_BASIC_SIGNED_INTEGER_TYPES_LIST) ARILES2_MACRO_SUBSTITUTE(ARILES2_BASIC_UNSIGNED_INTEGER_TYPES_LIST) ARILES2_MACRO_SUBSTITUTE(ARILES2_BASIC_REAL_TYPES_LIST) void Reader
Definition: reader.cpp:188
ariles2::ns_msgpack::Reader::startArrayElement
void startArrayElement()
Definition: reader.cpp:203
ariles2::ns_msgpack::Reader::startMapEntry
bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition: reader.cpp:138
ariles2::ns_msgpack::impl::Reader::getRawNode
const ::msgpack::object & getRawNode(const std::size_t depth)
Get current node.
Definition: reader.cpp:88
ariles2::read::Visitor::SizeLimitEnforcementType
SizeLimitEnforcementType
Definition: read.h:47
ariles2::ns_msgpack::Reader::startMap
void startMap(const SizeLimitEnforcementType limit_type=SIZE_LIMIT_NONE, const std::size_t min=0, const std::size_t max=0)
Definition: reader.cpp:130
msgpack.h
ariles2::ns_msgpack::impl::Reader::getRawNode
const ::msgpack::object & getRawNode()
Definition: reader.cpp:99
ariles2::ns_msgpack::Reader::endArray
void endArray()
Definition: reader.cpp:196
ariles2::read::Visitor::openFile
static void openFile(std::ifstream &config_ifs, const std::string &file_name)
open configuration file
Definition: read.h:95
ariles2::serialization::PIMPLVisitor< read::Visitor, impl::Reader >::Impl
impl::Reader Impl
Definition: serialization.h:124
ariles2::ns_msgpack::Reader::endArrayElement
void endArrayElement()
Definition: reader.cpp:211
ARILES2_VISIBILITY_ATTRIBUTE
#define ARILES2_VISIBILITY_ATTRIBUTE
Definition: helpers.h:138
ariles2::ns_msgpack::impl::Reader::nameless_counter_
std::size_t nameless_counter_
Definition: reader.cpp:44
ariles2::ns_msgpack::Reader::startArray
std::size_t startArray()
Definition: reader.cpp:186
ariles2::ns_msgpack::impl::Reader::handles_
std::vector< ARILES2_SHARED_PTR< ::msgpack::object_handle > > handles_
Definition: reader.cpp:39
ariles2::serialization::PIMPLVisitor< read::Visitor, impl::Reader >::impl_
ImplPtr impl_
Definition: serialization.h:128
ariles2::ns_msgpack::impl::Reader::buffer_
std::string buffer_
Definition: reader.cpp:37
ariles2::ns_msgpack::Reader::Reader
Reader(const std::string &file_name)
Constructor.
Definition: reader.cpp:114
ariles2::ns_msgpack::impl::Reader::initialize
void initialize(std::istream &input_stream)
open configuration file
Definition: reader.cpp:53
ariles2::ns_msgpack::NodeWrapper
serialization::Node< const ::msgpack::object * > NodeWrapper
Definition: reader.cpp:23
ariles2::ns_msgpack::Reader::endRoot
void endRoot(const std::string &name)
Definition: reader.cpp:233
ariles2::ns_msgpack::impl::Reader::node_stack_
std::vector< NodeWrapper > node_stack_
Stack of nodes.
Definition: reader.cpp:42
ariles2::serialization::Node
Definition: serialization.h:49
ariles2::serialization::PIMPLVisitor< read::Visitor, impl::Reader >::ImplPtr
ARILES2_SHARED_PTR< impl::Reader > ImplPtr
Definition: serialization.h:125
ariles2::ns_msgpack::impl::Reader
Definition: reader.cpp:34