Ariles
read.h
Go to the documentation of this file.
1 /**
2  @file
3  @author Alexander Sherikov
4 
5  @copyright 2017-2020 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 #pragma once
12 
13 #include <vector>
14 
15 #include "serialization.h"
16 
17 #ifndef ARILES_API_VERSION
18 # error "ARILES_API_VERSION is not defined, probably unhandled includion order, add explicit definition of ARILES_API_VERSION."
19 #endif
20 
21 #if 1 == ARILES_API_VERSION
22 # include "defaults.h"
23 # include "postprocess.h"
24 #endif
25 
26 
27 namespace ariles
28 {
29  namespace read
30  {
32  {
33  public:
35  {
36  SIZE_LIMIT_UNDEFINED = 0,
37  SIZE_LIMIT_NONE = 1,
38  SIZE_LIMIT_EQUAL = 2,
39  SIZE_LIMIT_RANGE = 3,
40  SIZE_LIMIT_MIN = 4
41  };
42 
43 
44  protected:
45  template <int t_size_limit_type>
46  std::size_t checkSize(
47  const std::size_t & /*size*/,
48  const std::size_t & /*min*/ = 0,
49  const std::size_t & /*max*/ = 0) const
50  {
51  ARILES_THROW("Internal logic error.");
52  }
53 
54  template <int t_size_limit_type>
56  {
57  static const int value =
58  SIZE_LIMIT_EQUAL == t_size_limit_type || SIZE_LIMIT_RANGE == t_size_limit_type ?
59  SIZE_LIMIT_MIN :
60  t_size_limit_type;
61  };
62 
63 
64  virtual std::size_t getMapSize(const bool expect_empty) = 0;
65  virtual std::size_t startMapImpl(const std::size_t size)
66  {
67  return (size);
68  }
69 
70  Visitor(){};
71  ~Visitor(){};
72 
73 
74  public:
75  /**
76  * @brief open configuration file
77  *
78  * @param[out] config_ifs
79  * @param[in] file_name
80  */
81  static void openFile(std::ifstream &config_ifs, const std::string &file_name)
82  {
83  config_ifs.open(file_name.c_str());
84  if (!config_ifs.good())
85  {
86  std::string file_name_default = file_name;
87  config_ifs.open(file_name_default.c_str());
88  }
89  ARILES_PERSISTENT_ASSERT(
90  true == config_ifs.good(),
91  std::string("Could not open configuration file: ") + file_name.c_str());
92  }
93 
94 
95  /**
96  * @brief Descend to the entry with the given name
97  *
98  * @param[in] child_name child node name
99  *
100  * @return true if successful.
101  */
102  virtual bool descend(const std::string &child_name)
103  {
105  ARILES_UNUSED_ARG(child_name)
106  return (true);
107  }
108 
109 
110  /**
111  * @brief Ascend from the current entry to its parent.
112  */
113  virtual void ascend() = 0;
114 
115 
116  template <int t_size_limit_type>
117  std::size_t startMap(const std::size_t &min = 0, const std::size_t &max = 0)
118  {
119  return (startMapImpl(
120  checkSize<RelaxedSizeLimitType<t_size_limit_type>::value>(getMapSize(0 == max), min, max)));
121  }
122 
123  virtual bool getMapEntryNames(std::vector<std::string> &)
124  {
125  return (false);
126  }
127 
128  virtual void endMap()
129  {
130  }
131 
132 
133  virtual std::size_t startArray() = 0;
134  virtual void shiftArray() = 0;
135  virtual void endArray() = 0;
136 
137  virtual bool startRoot(const std::string &name)
138  {
140  ARILES_TRACE_ENTRY(name);
141  if (false == name.empty())
142  {
143  return (descend(name));
144  }
145  return (true);
146  }
147 
148  virtual void endRoot(const std::string &name)
149  {
151  if (false == name.empty())
152  {
153  ascend();
154  }
155  }
156 
157 
158 #define ARILES_BASIC_TYPE(type) virtual void readElement(type &entry) = 0;
159 
161 
162 #undef ARILES_BASIC_TYPE
163 
164 
165  template <class t_Entry>
166  void start(t_Entry &entry, const std::string &name, const Parameters &parameters)
167  {
169  ARILES_TRACE_ENTRY(name);
170  ARILES_TRACE_TYPE(entry);
171 
172  Parameters param = parameters; // local modifiable copy
173 
174 #if 1 == ARILES_API_VERSION
175  ariles::apply<ariles::defaults::Visitor>(entry);
176 #endif
177  if (this->startRoot(name))
178  {
179  try
180  {
181  apply_read(*this, entry, param);
182  }
183  catch (const std::exception &e)
184  {
185  ARILES_THROW(std::string("Failed to parse entry <") + name + "> || " + e.what());
186  }
187 
188  this->endRoot(name);
189  }
190  else
191  {
192  ARILES_PERSISTENT_ASSERT(
193  true == param.isSet(Parameters::ALLOW_MISSING_ENTRIES),
194  std::string("Configuration file does not contain entry '") + name + "'.");
195  }
196  }
197 
198 
199  template <class t_Entry>
200  bool operator()(t_Entry &entry, const std::string &name, const Parameters &parameters)
201  {
203  ARILES_TRACE_ENTRY(name);
204  ARILES_TRACE_TYPE(entry);
205  Parameters param = parameters; // local modifiable copy
206 
207  if (this->descend(name))
208  {
209  param.unset(Parameters::DISABLE_ALLOW_MISSING_ENTRIES);
210 
211  try
212  {
213  apply_read(*this, entry, param);
214  }
215  catch (const std::exception &e)
216  {
217  ARILES_THROW(std::string("Failed to parse entry <") + name + "> || " + e.what());
218  }
219 
220  this->ascend();
221  return (true);
222  }
223  else
224  {
225  ARILES_PERSISTENT_ASSERT(
226  false == param.isSet(Parameters::DISABLE_ALLOW_MISSING_ENTRIES)
227  and true == param.isSet(Parameters::ALLOW_MISSING_ENTRIES),
228  std::string("Configuration file does not contain entry '") + name + "'.");
229  return (false);
230  }
231  }
232  };
233 
234 
235  template <>
236  inline std::size_t Visitor::checkSize<Visitor::SIZE_LIMIT_NONE>(
237  const std::size_t &size,
238  const std::size_t & /*min*/,
239  const std::size_t & /*max*/) const
240  {
241  return (size);
242  }
243 
244 
245  template <>
246  inline std::size_t Visitor::checkSize<Visitor::SIZE_LIMIT_EQUAL>(
247  const std::size_t &size,
248  const std::size_t &expected_size,
249  const std::size_t & /*max*/) const
250  {
251  ARILES_ASSERT(expected_size == size, "Actual number of entries is not the same as expected.");
252  return (size);
253  }
254 
255 
256  template <>
257  inline std::size_t Visitor::checkSize<Visitor::SIZE_LIMIT_RANGE>(
258  const std::size_t &size,
259  const std::size_t &min,
260  const std::size_t &max) const
261  {
262  ARILES_ASSERT(min <= size, "Actual number of entries is lower than expected.");
263  ARILES_ASSERT(max >= size, "Actual number of entries is larger than expected.");
264  return (size);
265  }
266 
267 
268  template <>
269  inline std::size_t Visitor::checkSize<Visitor::SIZE_LIMIT_MIN>(
270  const std::size_t &size,
271  const std::size_t &min,
272  const std::size_t & /*max*/) const
273  {
274  ARILES_ASSERT(min <= size, "Actual number of entries is lower than expected.");
275  return (size);
276  }
277 
278 
279  class ARILES_VISIBILITY_ATTRIBUTE Base : public entry::Base<read::Visitor>
280  {
281  };
282 
283 
284 #ifndef ARILES_METHODS_read
285 # define ARILES_METHODS_read ARILES_METHODS(read, ARILES_EMPTY_MACRO, ARILES_EMPTY_MACRO)
286 #endif
287  } // namespace read
288 
289 
291 } // namespace ariles
virtual void endRoot(const std::string &name)
Definition: read.h:148
#define ARILES_TRACE_FUNCTION
Definition: trace.h:118
std::size_t checkSize(const std::size_t &, const std::size_t &=0, const std::size_t &=0) const
Definition: read.h:46
virtual void endMap()
Definition: read.h:128
static void openFile(std::ifstream &config_ifs, const std::string &file_name)
open configuration file
Definition: read.h:81
std::size_t startMap(const std::size_t &min=0, const std::size_t &max=0)
Definition: read.h:117
virtual std::size_t startMapImpl(const std::size_t size)
Definition: read.h:65
ARILES_BASIC_TYPES_LIST void start(t_Entry &entry, const std::string &name, const Parameters &parameters)
Definition: read.h:166
virtual bool getMapEntryNames(std::vector< std::string > &)
Definition: read.h:123
#define ARILES_BASIC_TYPES_LIST
Definition: helpers.h:105
#define ARILES_TRACE_TYPE(entry)
Definition: trace.h:120
virtual bool descend(const std::string &child_name)
Descend to the entry with the given name.
Definition: read.h:102
read::Visitor Read
Definition: read.h:290
#define ARILES_VISIBILITY_ATTRIBUTE
Definition: helpers.h:69
void ARILES_VISIBILITY_ATTRIBUTE apply_read(t_Visitor &visitor, t_Entry &entry, const typename t_Visitor::Parameters &parameters, ARILES_IS_BASE_ENABLER(ariles::read::Base, t_Entry))
Definition: basic.h:22
#define ARILES_TRACE_ENTRY(entry_name)
Definition: trace.h:119
Definition: basic.h:17
bool operator()(t_Entry &entry, const std::string &name, const Parameters &parameters)
Definition: read.h:200
virtual bool startRoot(const std::string &name)
Definition: read.h:137