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