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 ariles
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 ariles
42 
43 
44 namespace ariles
45 {
46  namespace ns_pugixml
47  {
48  Reader::Reader(const std::string &file_name)
49  {
50  impl_ = ImplPtr(new Impl());
51 
52  pugi::xml_parse_result result = impl_->document_.load_file(file_name.c_str(), pugi::parse_minimal);
53  ARILES_ASSERT(
54  true == result, std::string("Parsing of '") + file_name + "' failed: " + result.description());
55  impl_->node_stack_.push_back(impl_->document_);
56  }
57 
58 
59  Reader::Reader(std::istream &input_stream)
60  {
61  impl_ = ImplPtr(new Impl());
62 
63  pugi::xml_parse_result result = impl_->document_.load(input_stream, pugi::parse_minimal);
64  ARILES_ASSERT(true == result, std::string("Parsing failed: ") + result.description());
65  impl_->node_stack_.push_back(impl_->document_);
66  }
67 
68 
69  std::size_t Reader::getMapSize(const bool /*expect_empty*/)
70  {
71  std::size_t size = 0;
72  for (pugi::xml_node_iterator it = impl_->getRawNode().begin(); it != impl_->getRawNode().end();
73  ++it, ++size)
74  ;
75  for (pugi::xml_attribute attribute = impl_->getRawNode().first_attribute(); attribute;
76  attribute = attribute.next_attribute(), ++size)
77  ;
78  return (size);
79  }
80 
81 
82  bool Reader::descend(const std::string &child_name)
83  {
84  const pugi::xml_node child = impl_->getRawNode().child(child_name.c_str());
85 
86  if (child)
87  {
88  impl_->node_stack_.push_back(child);
89  return (true);
90  }
91  else
92  {
93  const pugi::xml_attribute attribute = impl_->getRawNode().attribute(child_name.c_str());
94  if (attribute)
95  {
96  pugi::xml_node new_child = impl_->getRawNode().append_child(child_name.c_str());
97  new_child.text() = attribute.value();
98  impl_->node_stack_.push_back(new_child);
99  return (true);
100  }
101  else
102  {
103  return (false);
104  }
105  }
106  }
107 
108 
110  {
111  impl_->node_stack_.pop_back();
112  }
113 
114 
115  bool Reader::getMapEntryNames(std::vector<std::string> &child_names)
116  {
117  const pugi::xml_node node = impl_->getRawNode();
118  child_names.clear();
119  for (pugi::xml_node_iterator it = node.begin(); it != node.end(); ++it)
120  {
121  child_names.push_back(it->name());
122  }
123  return (true);
124  }
125 
126 
127  std::size_t Reader::startArray()
128  {
129  std::size_t size = 0;
130  const pugi::xml_node node = impl_->getRawNode();
131  for (pugi::xml_node child = node.child("item"); child; child = child.next_sibling("item"), ++size)
132  ;
133 
134  if (size > 0)
135  {
136  impl_->node_stack_.push_back(NodeWrapper(node.child("item"), 0, size));
137  }
138  else
139  {
140  // if there are no 'item' childs try to iterate
141  // over childs with the same name in the parent
142  // node
143  for (pugi::xml_node child = impl_->getRawNode(); child;
144  child = child.next_sibling(child.name()), ++size)
145  ;
146  impl_->node_stack_.push_back(NodeWrapper(impl_->getRawNode(), 0, size));
147  }
148 
149  return (size);
150  }
151 
152 
154  {
155  ARILES_ASSERT(true == impl_->node_stack_.back().isArray(), "Internal error: expected array.");
156  ARILES_ASSERT(
157  impl_->node_stack_.back().index_ < impl_->node_stack_.back().size_,
158  "Internal error: array has more elements than expected.");
159  impl_->node_stack_.back().node_ = impl_->getRawNode().next_sibling(impl_->getRawNode().name());
160  ++impl_->node_stack_.back().index_;
161  }
162 
163 
165  {
166  impl_->node_stack_.pop_back();
167  }
168 
169 
170  bool Reader::startRoot(const std::string &name)
171  {
173  if (true == name.empty())
174  {
175  return (descend("ariles"));
176  }
177  else
178  {
179  return (descend(name));
180  }
181  }
182 
183  void Reader::endRoot(const std::string & /*name*/)
184  {
186  ascend();
187  }
188 
189 
190  void Reader::readElement(std::string &element)
191  {
192  element = impl_->getRawNode().text().as_string();
193  }
194 
195 
196 #define ARILES_BASIC_TYPE(type) \
197  void Reader::readElement(type &element) \
198  { \
199  ARILES_ASSERT(false == impl_->getRawNode().text().empty(), "Empty integer elements are not allowed."); \
200  element = boost::lexical_cast<type>(impl_->getRawNode().text().as_string()); \
201  }
202 
204 
205 #undef ARILES_BASIC_TYPE
206  } // namespace ns_pugixml
207 } // namespace ariles
#define ARILES_TRACE_FUNCTION
Definition: trace.h:118
pugi::xml_node & getRawNode()
Get current node.
Definition: reader.cpp:34
void endRoot(const std::string &name)
Definition: reader.cpp:183
std::size_t getMapSize(const bool)
Definition: reader.cpp:69
bool descend(const std::string &child_name)
Descend to the entry with the given name.
Definition: reader.cpp:82
std::size_t startArray()
Definition: reader.cpp:127
Reader(const std::string &file_name)
Constructor.
Definition: reader.cpp:48
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
bool getMapEntryNames(std::vector< std::string > &child_names)
Definition: reader.cpp:115
ariles::Node< pugi::xml_node > NodeWrapper
Definition: common.h:22
pugi::xml_document document_
Definition: reader.cpp:23
bool startRoot(const std::string &name)
Definition: reader.cpp:170
void ascend()
Ascend from the current entry to its parent.
Definition: reader.cpp:109
#define ARILES_BASIC_NUMERIC_TYPES_LIST
Definition: helpers.h:100
#define ARILES_VISIBILITY_ATTRIBUTE
Definition: helpers.h:69
std::vector< NodeWrapper > node_stack_
Definition: reader.cpp:25
Definition: basic.h:17