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 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
12#include "common.h"
13
14namespace ariles2
15{
16 namespace ns_pugixml
17 {
18 namespace impl
19 {
20 class Reader : public serialization::NodeStackBase<NodeWrapper>
21 {
22 public:
23 pugi::xml_document document_;
24
25
26 public:
27 /**
28 * @brief Get current node
29 *
30 * @return pointer to the current node
31 */
32 pugi::xml_node &getRawNode()
33 {
34 return (back().node_);
35 }
36 };
37 } // namespace impl
38 } // namespace ns_pugixml
39} // namespace ariles2
40
41
42namespace ariles2
43{
44 namespace ns_pugixml
45 {
46 Reader::Reader(const std::string &file_name)
47 {
48 impl_ = std::make_shared<impl::Reader>();
49
50 const pugi::xml_parse_result result = impl_->document_.load_file(file_name.c_str(), pugi::parse_minimal);
51 CPPUT_ASSERT(result, std::string("Parsing of '") + file_name + "' failed: " + result.description());
52 impl_->node_stack_.emplace_back(impl_->document_);
53 }
54
55
56 Reader::Reader(std::istream &input_stream)
57 {
58 impl_ = std::make_shared<impl::Reader>();
59
60 const pugi::xml_parse_result result = impl_->document_.load(input_stream, pugi::parse_minimal);
61 CPPUT_ASSERT(result, std::string("Parsing failed: ") + result.description());
62 impl_->node_stack_.emplace_back(impl_->document_);
63 }
64
65
66 bool Reader::startMapEntry(const std::string &child_name)
67 {
68 const pugi::xml_node child = impl_->getRawNode().child(child_name.c_str());
69
70 if (nullptr != child)
71 {
72 impl_->emplace(child);
73 return (true);
74 }
75
76 const pugi::xml_attribute attribute = impl_->getRawNode().attribute(child_name.c_str());
77 if (nullptr != attribute)
78 {
79 const pugi::xml_node new_child = impl_->getRawNode().append_child(child_name.c_str());
80 new_child.text() = attribute.value();
81 impl_->emplace(new_child);
82 return (true);
83 }
84
85 return (false);
86 }
87
88
90 {
91 impl_->pop();
92 }
93
94
96 const SizeLimitEnforcementType /*limit_type*/,
97 const std::size_t /*min*/,
98 const std::size_t /*max*/)
99 {
100 const pugi::xml_node child = impl_->getRawNode().first_child();
101 if (nullptr != child)
102 {
103 impl_->emplace(child, NodeWrapper::Type::ITERATED_MAP);
104 return (true);
105 }
106 return (false);
107 }
108
109 bool Reader::startIteratedMapElement(std::string &entry_name)
110 {
111 if (nullptr != impl_->getRawNode())
112 {
113 entry_name = impl_->getRawNode().name();
114 return (true);
115 }
116 return (false);
117 }
118
120 {
121 const pugi::xml_node node = impl_->getRawNode();
122 if (nullptr != node)
123 {
124 impl_->getRawNode() = node.next_sibling();
125 }
126 }
127
129 {
130 CPPUT_ASSERT(!impl_->getRawNode(), "End of iterated map has not been reached.");
131 impl_->pop();
132 }
133
134
135 std::size_t Reader::startArray()
136 {
137 std::size_t size = 0;
138 const pugi::xml_node node = impl_->getRawNode();
139 for (pugi::xml_node child = node.child("item"); nullptr != child;
140 child = child.next_sibling("item"), ++size)
141 {
142 }
143
144 if (size > 0)
145 {
146 impl_->emplace(node.child("item"), 0, size);
147 }
148 else
149 {
150 // if there are no 'item' childs try to iterate
151 // over childs with the same name in the parent
152 // node
153 for (pugi::xml_node child = impl_->getRawNode(); nullptr != child;
154 child = child.next_sibling(child.name()), ++size)
155 {
156 }
157 impl_->emplace(impl_->getRawNode(), 0, size);
158 }
159
160 return (size);
161 }
162
163
165 {
167 impl_->back().index_ < impl_->back().size_,
168 "Internal error: array has more elements than expected.");
169 }
170
171
173 {
174 CPPUT_ASSERT(impl_->back().isArray(), "Internal error: expected array.");
175 impl_->back().node_ = impl_->getRawNode().next_sibling(impl_->getRawNode().name());
176 ++impl_->back().index_;
177 }
178
179
181 {
182 impl_->pop();
183 }
184
185
186 bool Reader::startRoot(const std::string &name)
187 {
189 if (name.empty())
190 {
191 return (startMapEntry("ariles"));
192 }
193 return (startMapEntry(name));
194 }
195
196 void Reader::endRoot(const std::string & /*name*/)
197 {
199 endMapEntry();
200 }
201
202
203 void Reader::readElement(std::string &element)
204 {
205 element = impl_->getRawNode().text().as_string();
206 }
207
208
209#define ARILES2_BASIC_TYPE(type) \
210 void Reader::readElement(type &element) \
211 { \
212 CPPUT_ASSERT(not impl_->getRawNode().text().empty(), "Empty integer elements are not allowed."); \
213 element = boost::lexical_cast<type>(impl_->getRawNode().text().as_string()); \
214 }
215
217
218#undef ARILES2_BASIC_TYPE
219 } // namespace ns_pugixml
220} // namespace ariles2
void endRoot(const std::string &name)
Definition reader.cpp:196
bool startIteratedMap(const SizeLimitEnforcementType=SIZE_LIMIT_NONE, const std::size_t=0, const std::size_t=0)
Definition reader.cpp:95
bool startRoot(const std::string &name)
Definition reader.cpp:186
Reader(const std::string &file_name)
Constructor.
Definition reader.cpp:46
bool startMapEntry(const std::string &child_name)
startMapEntry to the entry with the given name
Definition reader.cpp:66
bool startIteratedMapElement(std::string &entry_name)
Definition reader.cpp:109
void endMapEntry()
endMapEntry from the current entry to its parent.
Definition reader.cpp:89
pugi::xml_document document_
Definition reader.cpp:23
pugi::xml_node & getRawNode()
Get current node.
Definition reader.cpp:32
void readElement(std::complex< t_Scalar > &entry)
Definition read.h:357
#define CPPUT_ASSERT(condition,...)
Definition exception.h:32
#define ARILES2_BASIC_NUMERIC_TYPES_LIST
Definition helpers.h:63
#define CPPUT_MACRO_SUBSTITUTE(macro)
Definition misc.h:21
#define CPPUT_TRACE_FUNCTION
Definition trace.h:126