Ariles
Loading...
Searching...
No Matches
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
19namespace ariles2
20{
21 namespace ns_msgpack
22 {
24 }
25} // namespace ariles2
26
27
28namespace ariles2
29{
30 namespace ns_msgpack
31 {
32 namespace impl
33 {
35 {
36 public:
37 std::string buffer_;
38
39 std::vector<std::shared_ptr<::msgpack::object_handle>> handles_;
40
41 std::size_t nameless_counter_;
42
43
44 public:
45 template <class... t_Args>
46 explicit Reader(t_Args &&...args) : FileVisitorImplementation(std::forward<t_Args>(args)...)
47 {
48 initialize();
49 }
50
51
52 /**
53 * @brief open configuration file
54 */
56 {
58 std::stringstream str_stream;
59 str_stream << input_stream_->rdbuf();
60 buffer_ = str_stream.str();
61
62
63 handles_.clear();
64 try
65 {
66 std::size_t buffer_offset = 0;
67
68 while (buffer_offset != buffer_.size())
69 {
70 handles_.push_back(std::make_shared<::msgpack::object_handle>());
71
72 unpack(*handles_.back(), buffer_.data(), buffer_.size(), buffer_offset);
73 }
74 }
75 catch (const std::exception &e)
76 {
77 CPPUT_THROW("Failed to parse the configuration file: ", e.what());
78 }
79
81 }
82
83
84 /**
85 * @brief Get current node
86 *
87 * @return pointer to the current node
88 */
89 const ::msgpack::object &getRawNode(const std::size_t depth)
90 {
92 if (node_stack_[depth].isArray())
93 {
94 return (getRawNode(depth - 1).via.array.ptr[node_stack_[depth].index_]);
95 }
96 return (*node_stack_[depth].node_);
97 }
98
99
100 const ::msgpack::object &getRawNode()
101 {
103 return (getRawNode(node_stack_.size() - 1));
104 }
105 };
106 } // namespace impl
107 } // namespace ns_msgpack
108} // namespace ariles2
109
110
111namespace ariles2
112{
113 namespace ns_msgpack
114 {
115 Reader::Reader(const std::string &file_name)
116 {
117 makeImplPtr(file_name);
118 }
119
120
121 Reader::Reader(std::istream &input_stream)
122 {
123 makeImplPtr(input_stream);
124 }
125
126
127 void Reader::startMap(const SizeLimitEnforcementType limit_type, const std::size_t min, const std::size_t max)
128 {
130 checkSize(limit_type, impl_->getRawNode().via.map.size, min, max);
131 }
132
133
134
135 bool Reader::startMapEntry(const std::string &child_name)
136 {
138 CPPUT_TRACE_VALUE(child_name);
139 if (impl_->empty())
140 {
141 for (std::size_t i = 0; i < impl_->handles_.size(); ++i)
142 {
143 if (::msgpack::type::MAP == impl_->handles_[i]->get().type)
144 {
145 if (child_name == impl_->handles_[i]->get().via.map.ptr[0].key.as<std::string>())
146 {
147 if (::msgpack::type::MAP == impl_->handles_[i]->get().via.map.ptr[0].val.type)
148 {
149 impl_->emplace(&(impl_->handles_[i]->get().via.map.ptr[0].val));
150 return (true);
151 }
152 }
153 }
154 }
155 }
156 else
157 {
158 if (::msgpack::type::MAP == impl_->getRawNode().type)
159 {
160 for (std::size_t i = 0; i < impl_->getRawNode().via.map.size; ++i)
161 {
162 if (child_name == impl_->getRawNode().via.map.ptr[i].key.as<std::string>())
163 {
164 impl_->emplace(&(impl_->getRawNode().via.map.ptr[i].val));
165 return (true);
166 }
167 }
168 }
169 }
170
171 return (false);
172 }
173
174
176 {
178 impl_->pop();
179 }
180
181
182 std::size_t Reader::startArray()
183 {
185 const std::size_t size = impl_->getRawNode().via.array.size;
186 impl_->emplace(0, size);
187
188 return (size);
189 }
190
191
193 {
195 impl_->pop();
196 }
197
198
200 {
202 impl_->back().index_ < impl_->back().size_,
203 "Internal error: array has more elements than expected.");
204 }
205
206
208 {
210 impl_->shiftArray();
211 }
212
213
214 bool Reader::startRoot(const std::string &name)
215 {
217 if (name.empty())
218 {
220 0 == impl_->nameless_counter_,
221 "Multiple nameless root entries are not supported, specify root names explicitly.");
222 ++impl_->nameless_counter_;
223 return (startMapEntry("ariles"));
224 }
225 return (startMapEntry(name));
226 }
227
228 void Reader::endRoot(const std::string & /*name*/)
229 {
231 endMapEntry();
232 }
233
234
235#define ARILES2_BASIC_TYPE(type) \
236 void Reader::readElement(type &element) \
237 { \
238 CPPUT_TRACE_FUNCTION; \
239 impl_->getRawNode() >> element; \
240 }
241
243
244#undef ARILES2_BASIC_TYPE
245 } // namespace ns_msgpack
246} // namespace ariles2
void endMapEntry()
endMapEntry from the current entry to its parent.
Definition reader.cpp:175
bool startRoot(const std::string &name)
Definition reader.cpp:214
bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition reader.cpp:135
void startMap(const SizeLimitEnforcementType limit_type=SIZE_LIMIT_NONE, const std::size_t min=0, const std::size_t max=0)
Definition reader.cpp:127
void endRoot(const std::string &name)
Definition reader.cpp:228
Reader(const std::string &file_name)
Constructor.
Definition reader.cpp:115
const ::msgpack::object & getRawNode(const std::size_t depth)
Get current node.
Definition reader.cpp:89
const ::msgpack::object & getRawNode()
Definition reader.cpp:100
void initialize()
open configuration file
Definition reader.cpp:55
std::vector< std::shared_ptr<::msgpack::object_handle > > handles_
Definition reader.cpp:39
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
#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_MACRO_SUBSTITUTE(macro)
Definition misc.h:21
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126
#define CPPUT_TRACE_VALUE(value)
Definition trace.h:127