NSVD Reader  0.0.1
svd_reader.hpp
Go to the documentation of this file.
1 
5 /*
6  * These codes are licensed under CC0.
7  * http://creativecommons.org/publicdomain/zero/1.0/
8  */
9 #ifndef __NODAMUSHI_SVD_SVD_READER_HPP__
10 #define __NODAMUSHI_SVD_SVD_READER_HPP__
11 
13 # include "nodamushi/boxvec.hpp"
14 # include <cassert>
15 # include <type_traits>
16 # include <utility>
17 # include <stdexcept>
18 
19 # include <fstream>
20 
21 
22 namespace nodamushi{
23 namespace svd{
24 
25 
34 
36 
38 
40 
42 
46 struct svd_reader{};
47 
48 
52 struct file_read_exception:public std::invalid_argument
53 {
54  static bool check(const std::string& file_name,bool throw_exception)
55  {
56  using namespace std;
57  ifstream ifs(file_name);
58  if(!ifs.good()){
59  if(throw_exception){
60  string m = "File read error : "s + file_name;
62  }
63  return false;
64  }
65  return true;
66  }
67 
68  file_read_exception(const std::string& file,const std::string& message):
69  invalid_argument(message),
70  file_name(file){}
71  std::string file_name;
72 };
73 
77 struct xml_parse_exception:public std::runtime_error
78 {
79  static constexpr size_t UNKNOWN_FILE_LINE= ~(size_t)0;
81  const std::string& file,size_t file_line = UNKNOWN_FILE_LINE)
82  {
83  using namespace std;
84  string m = "XML parse error occured: "s + file;
85  return {file,m,file_line};
86  }
87  xml_parse_exception(const std::string& file,
88  const std::string& message,
89  size_t file_line):
90  runtime_error(message),
91  file_name(file),
92  line_number(file_line){}
93  std::string file_name;
94  size_t line_number;
95 };
96 
97 
98 
99 
101 {
102  template<typename T>
103  static std::pair<size_t,size_t> _trim(T& str)
104  {
105  size_t b = 0;
106  const size_t len = str.length();
107  size_t e = len;
108  while(b!=e){
109  char c = str[b];
110  if(c == ' ' || c == '\t' || c =='\r' || c == '\n')
111  b++;
112  else
113  break;
114  }
115  while(b!=e){
116  char c = str[e-1];
117  if(c == ' ' || c == '\t' || c =='\r' || c == '\n')
118  e--;
119  else
120  break;
121  }
122  return {b,e};
123  }
125  static void trim(std::string& str)
126  {
127  auto v = _trim(str);
128  size_t b = v.first,e=v.second;
129  if(e != str.length())
130  str.erase(e);
131  if(b)
132  str.erase(0,b);
133  }
134 
135 # if __cplusplus >= 201703
136  static void trim(std::string_view& str)
138  {
139  auto v = _trim(str);
140  size_t b = v.first,e=v.second,len = e-b;
141  std::string_view n(str.data()+b,len);
142  str = n;
143  }
144 
146  static std::string_view trimc(const std::string_view& str)
147  {
148  auto v = _trim(str);
149  size_t b = v.first,e=v.second,len = e-b;
150  return {str.data()+b,len};
151  }
153  static std::string_view trimc(const std::string& str)
154  {
155  auto v = _trim(str);
156  size_t b = v.first,e=v.second,len = e-b;
157  return {str.data()+b,len};
158  }
159 # else
160  static std::string trimc(const std::string& str)
162  {
163  auto v = _trim(str);
164  size_t b = v.first,e=v.second,len = e-b;
165  return std::string(str,b,len);
166  }
167 # endif
168 
169 };
170 
171 
177 template<typename CallBack>
179 {
180  stream_reader_element(const std::string& n,CallBack* f):
181  name(n),attribute(false),value(),
182  children{},closed(false),call_back(f),remove(false){}
183 
184  stream_reader_element(std::string&& n,CallBack* f):
185  name(std::move(n)),attribute(false),value(),
186  children{},closed(false),call_back(f),remove(false){}
187 
188  // ------------ svd_reader interface -----------------
189  bool is_attribute()const{return attribute;}
190  string_ref get_name()const{return name;}
192  if(!closed && call_back!=nullptr){
193  while(!closed)
194  (*call_back)(*this);
195  }
196  return value;
197  }
199  remove = true;
200  return children[0];
201  }
202  operator bool(){
203  if(remove){
204  if(children.size()!=0)
205  children.erase(children.begin());
206  remove = false;
207  }
208  if(call_back!=nullptr){
209  while(!closed && children.empty())
210  (*call_back)(*this);
211  }
212  return children.size()!=0;
213  }
214  //--------------------------------------------------
215 
219  void set_callback(CallBack* cb)
220  {
221  call_back=cb;
222  for(auto& c:children)
223  c.set_callback(cb);
224  }
225 
229  void close(){
230  if(!closed){
232  closed = true;
233  for(auto& c:children)
234  c.close();
235  }
236  }
237 
241  void set_value(const std::string& s){
242  value = s;
243  }
247  void add_value(const std::string& s){
248  value.append(s);
249  }
253  void add_value(const char* s,size_t size){
254  value.append(s,size);
255  }
259  void add_attribute(const std::string& name,const std::string& value)
260  {
261  children.emplace_back(name,value,true,call_back);
262  }
266  void add_attribute(std::string&& name,std::string&& value)
267  {
268  children.emplace_back(std::move(name),std::move(value),true,call_back);
269  }
270 
274  stream_reader_element& add_child(std::string&& name)
275  {
276  size_t s = children.size();
277  children.emplace_back(std::move(name),call_back);
278  return children[s];
279  }
283  stream_reader_element& add_child(const std::string& name)
284  {
285  size_t s = children.size();
286  children.emplace_back(name,call_back);
287  return children[s];
288  }
289 
294  {
295  if(closed)return nullptr;
296  if(children.empty())return this;
297  stream_reader_element& e = children[children.size()-1];
298  if(e.closed)return this;
300  return p == nullptr? &e:p;
301  }
302 
303  constexpr bool is_closed()const{return closed;}
304 
305 
306 
307 
308  stream_reader_element(const std::string& n,
309  const std::string& val,
310  bool attr,
311  CallBack* f):
312  name(n),attribute(attr),value(val),
313  children{},closed(attr),call_back(f),remove(false)
314  {
316  }
317 
319  std::string&& n,
320  std::string&& val,
321  bool attr,
322  CallBack* f):
323  name(std::move(n)),attribute(attr),value(std::move(val)),
324  children{},closed(attr),call_back(f),remove(false)
325  {
327  }
328  private:
329  // Don't copy and move
330  stream_reader_element(const stream_reader_element&)=delete;
331  stream_reader_element& operator=(const stream_reader_element&)=delete;
332  stream_reader_element(stream_reader_element&&d)=delete;
333  stream_reader_element& operator=(stream_reader_element&&)=delete;
334 
335  std::string name;
336  bool attribute;
337  std::string value;
339  bool closed;
340  CallBack* call_back;
341  bool remove;
342 };
343 
344 
355 template<typename SubClass>
357 {
359 
360  stream_reader_base(): children{},remove(false),_active_cache(nullptr)
361  {
362  static_assert(std::is_base_of<stream_reader_base<SubClass>,SubClass>::value,
363  "stream_reader_base is base of SubClass");
364  }
365  virtual ~stream_reader_base()=default;
366 
367  // move
369  children(std::move(d.children)),
370  remove(d.remove),_active_cache(nullptr)
371  {
372  for(auto & c:children) c.set_callback(this);
373  }
375  {
376  children = std::move(d.children);
377  remove = d.remove;
378  _active_cache=nullptr;
379  for(auto & c:children) c.set_callback(this);
380  }
381 
382  // Don't copy
383  stream_reader_base(const stream_reader_base&) = delete;
384  stream_reader_base& operator=(const stream_reader_base&)=delete;
385 
386 
387  // ------------ svd_reader interface -----------------
388  bool is_attribute()const{return false;}
389 # if __cplusplus >= 201703
390  std::string_view get_name()const{return std::string_view{};}
391  std::string_view get_value()const{return std::string_view{};}
392 # else
393  std::string get_name()const{return std::string{};}
394  std::string get_value()const{return std::string{};}
395 # endif
397  remove = true;
398  return children[0];
399  }
400  operator bool(){
401  if(remove){
402  if(!children.empty())
403  children.erase(children.begin());
404  remove = false;
405  }
406  SubClass* p = reinterpret_cast<SubClass*>(this);
407  while(children.empty() && !p->is_end()){
408  p->read();
409  }
410  return children.size() != 0;
411  }
412 
413  // call back
414  void operator()(el& e)
415  {
416  SubClass* p = reinterpret_cast<SubClass*>(this);
417  p->read();
418  }
419 
420 
421  //-----------------------------------------------------
422  el& add_child(std::string&& name)
423  {
424  size_t s = children.size();
425  children.emplace_back(name,this);
426  return children[s];
427  }
428 
429  el& add_child(const std::string& name)
430  {
431  size_t s = children.size();
432  children.emplace_back(name,this);
433  return children[s];
434  }
435 
437  {
438  if(_active_cache != nullptr && !_active_cache->is_closed()){
439  _active_cache = _active_cache ->get_active_open_element();
440  return _active_cache;
441  }
442  _active_cache = nullptr;
443  if(children.empty())return nullptr;
444  el& e = children[children.size()-1];
445  if(e.is_closed())return nullptr;
446  _active_cache = e.get_active_open_element();
447  return _active_cache;
448  }
449 
451  {
452  for(auto& c:children)c.close();
453  }
454 
455 
456  private:
457  ::nodamushi::boxvec<el> children;
458  bool remove;
459  el* _active_cache;
460 };
461 
462 
463 }}// end namespace nodamushi::svd
464 
465 #endif // __NODAMUSHI_SVD_SVD_READER_HPP__
boxvec. vector<pointer<X>>
stream_reader_element(std::string &&n, CallBack *f)
Definition: svd_reader.hpp:184
stream_reader_element & add_child(const std::string &name)
Definition: svd_reader.hpp:283
void add_attribute(std::string &&name, std::string &&value)
Definition: svd_reader.hpp:266
file_read_exception(const std::string &file, const std::string &message)
Definition: svd_reader.hpp:68
stream_reader_element(const std::string &n, const std::string &val, bool attr, CallBack *f)
Definition: svd_reader.hpp:308
static bool check(const std::string &file_name, bool throw_exception)
Definition: svd_reader.hpp:54
void add_value(const char *s, size_t size)
Definition: svd_reader.hpp:253
Definition: Access.hpp:143
stream_reader_element(std::string &&n, std::string &&val, bool attr, CallBack *f)
Definition: svd_reader.hpp:318
const std::string & string_ref
Definition: string_type.hpp:44
el & add_child(const std::string &name)
Definition: svd_reader.hpp:429
XML element class for stream type parser.
Definition: svd_reader.hpp:178
constexpr bool is_closed() const
Definition: svd_reader.hpp:303
svd_reader base class for stream type parser subclasses must be implements read method and is_end met...
Definition: svd_reader.hpp:356
stream_reader_base & operator=(stream_reader_base &&d)
Definition: svd_reader.hpp:374
void add_attribute(const std::string &name, const std::string &value)
Definition: svd_reader.hpp:259
stream_reader_element * get_active_open_element()
Definition: svd_reader.hpp:293
stream_reader_element & next_child()
Definition: svd_reader.hpp:198
stream_reader_base(stream_reader_base &&d)
Definition: svd_reader.hpp:368
void set_value(const std::string &s)
Definition: svd_reader.hpp:241
void add_value(const std::string &s)
Definition: svd_reader.hpp:247
This class reperesents SVD(xml) element / attribute.
Definition: value.hpp:53
el & add_child(std::string &&name)
Definition: svd_reader.hpp:422
stream_reader_element & add_child(std::string &&name)
Definition: svd_reader.hpp:274
vector<pointer<T>>.
Definition: boxvec.hpp:75
constexpr small library
static xml_parse_exception make(const std::string &file, size_t file_line=UNKNOWN_FILE_LINE)
Definition: svd_reader.hpp:80
xml_parse_exception(const std::string &file, const std::string &message, size_t file_line)
Definition: svd_reader.hpp:87
static std::pair< size_t, size_t > _trim(T &str)
Definition: svd_reader.hpp:103
static void trim(std::string &str)
remove white spaces
Definition: svd_reader.hpp:125
stream_reader_element(const std::string &n, CallBack *f)
Definition: svd_reader.hpp:180