Kea  1.9.9-git
data.h
Go to the documentation of this file.
1 // Copyright (C) 2010-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef ISC_DATA_H
8 #define ISC_DATA_H 1
9 
10 #include <stdint.h>
11 #include <string>
12 #include <vector>
13 #include <map>
14 #include <boost/shared_ptr.hpp>
15 #include <stdexcept>
16 #include <exceptions/exceptions.h>
17 
18 namespace isc { namespace data {
19 
20 class Element;
21 // todo: describe the rationale behind ElementPtr?
22 typedef boost::shared_ptr<Element> ElementPtr;
23 typedef boost::shared_ptr<const Element> ConstElementPtr;
24 
30 class TypeError : public isc::Exception {
31 public:
32  TypeError(const char* file, size_t line, const char* what) :
33  isc::Exception(file, line, what) {}
34 };
35 
40 // i'd like to use Exception here but we need one that is derived from
41 // runtime_error (as this one is directly based on external data, and
42 // i want to add some values to any static data string that is provided)
43 class JSONError : public isc::Exception {
44 public:
45  JSONError(const char* file, size_t line, const char* what) :
46  isc::Exception(file, line, what) {}
47 };
48 
66 class Element {
67 
68 public:
88  struct Position {
89  std::string file_;
90  uint32_t line_;
91  uint32_t pos_;
92 
94  Position() : file_(""), line_(0), pos_(0) {
95  }
96 
102  Position(const std::string& file, const uint32_t line,
103  const uint32_t pos)
104  : file_(file), line_(line), pos_(pos) {
105  }
106 
110  std::string str() const;
111  };
112 
120  static const Position& ZERO_POSITION() {
121  static Position position("", 0, 0);
122  return (position);
123  }
124 
125 private:
126  // technically the type could be omitted; is it useful?
127  // should we remove it or replace it with a pure virtual
128  // function getType?
129  int type_;
130 
132  Position position_;
133 
134 protected:
135 
142  Element(int t, const Position& pos = ZERO_POSITION())
143  : type_(t), position_(pos) {
144  }
145 
146 
147 public:
148 
149  // any is a special type used in list specifications, specifying
150  // that the elements can be of any type
152  // base class; make dtor virtual
153  virtual ~Element() {};
154 
156  int getType() const { return (type_); }
157 
163  const Position& getPosition() const { return (position_); }
164 
172  std::string str() const;
173 
178  std::string toWire() const;
179  void toWire(std::ostream& out) const;
180 
183 #define throwTypeError(error) \
184  { \
185  std::string msg_ = error; \
186  if ((position_.file_ != "") || \
187  (position_.line_ != 0) || \
188  (position_.pos_ != 0)) { \
189  msg_ += " in (" + position_.str() + ")"; \
190  } \
191  isc_throw(TypeError, msg_); \
192  }
193 
195 
197  virtual bool equals(const Element& other) const = 0;
198 
201  virtual void toJSON(std::ostream& ss) const = 0;
202 
210 
211  virtual int64_t intValue() const
212  { throwTypeError("intValue() called on non-integer Element"); };
213  virtual double doubleValue() const
214  { throwTypeError("doubleValue() called on non-double Element"); };
215  virtual bool boolValue() const
216  { throwTypeError("boolValue() called on non-Bool Element"); };
217  virtual std::string stringValue() const
218  { throwTypeError("stringValue() called on non-string Element"); };
219  virtual const std::vector<ElementPtr>& listValue() const {
220  // replace with real exception or empty vector?
221  throwTypeError("listValue() called on non-list Element");
222  };
223  virtual const std::map<std::string, ConstElementPtr>& mapValue() const {
224  // replace with real exception or empty map?
225  throwTypeError("mapValue() called on non-map Element");
226  };
228 
237 
238  virtual bool getValue(int64_t& t) const;
239  virtual bool getValue(double& t) const;
240  virtual bool getValue(bool& t) const;
241  virtual bool getValue(std::string& t) const;
242  virtual bool getValue(std::vector<ElementPtr>& t) const;
243  virtual bool getValue(std::map<std::string, ConstElementPtr>& t) const;
245 
255 
256  virtual bool setValue(const long long int v);
257  bool setValue(const long int i) { return (setValue(static_cast<long long int>(i))); };
258  bool setValue(const int i) { return (setValue(static_cast<long long int>(i))); };
259  virtual bool setValue(const double v);
260  virtual bool setValue(const bool t);
261  virtual bool setValue(const std::string& v);
262  virtual bool setValue(const std::vector<ElementPtr>& v);
263  virtual bool setValue(const std::map<std::string, ConstElementPtr>& v);
265 
266 
267 
268  // Other functions for specific subtypes
269 
274 
275  virtual ConstElementPtr get(const int i) const;
279 
284  virtual ElementPtr getNonConst(const int i) const;
285 
290  virtual void set(const size_t i, ElementPtr element);
291 
294  virtual void add(ElementPtr element);
295 
299  virtual void remove(const int i);
300 
302  virtual size_t size() const;
303 
305  virtual bool empty() const;
307 
308 
313 
314  virtual ConstElementPtr get(const std::string& name) const;
318 
322  virtual void set(const std::string& name, ConstElementPtr element);
323 
326  virtual void remove(const std::string& name);
327 
331  virtual bool contains(const std::string& name) const;
332 
346  virtual ConstElementPtr find(const std::string& identifier) const;
347 
352  virtual bool find(const std::string& identifier, ConstElementPtr& t) const;
354 
355 
357 
358  // TODO: should we move all factory functions to a different class
359  // so as not to burden the Element base with too many functions?
360  // and/or perhaps even to a separate header?
361 
374 
375  static ElementPtr create(const Position& pos = ZERO_POSITION());
376  static ElementPtr create(const long long int i,
377  const Position& pos = ZERO_POSITION());
378  static ElementPtr create(const int i,
379  const Position& pos = ZERO_POSITION());
380  static ElementPtr create(const long int i,
381  const Position& pos = ZERO_POSITION());
382  static ElementPtr create(const double d,
383  const Position& pos = ZERO_POSITION());
384  static ElementPtr create(const bool b,
385  const Position& pos = ZERO_POSITION());
386  static ElementPtr create(const std::string& s,
387  const Position& pos = ZERO_POSITION());
388  // need both std:string and char *, since c++ will match
389  // bool before std::string when you pass it a char *
390  static ElementPtr create(const char *s,
391  const Position& pos = ZERO_POSITION());
392 
397  static ElementPtr createList(const Position& pos = ZERO_POSITION());
398 
403  static ElementPtr createMap(const Position& pos = ZERO_POSITION());
405 
406 
408 
412 
414  static ElementPtr fromJSON(const std::string& in, bool preproc = false);
421 
431  static ElementPtr fromJSON(std::istream& in, bool preproc = false);
432 
444  static ElementPtr fromJSON(std::istream& in, const std::string& file_name,
445  bool preproc = false);
446 
459  // make this one private?
461  static ElementPtr fromJSON(std::istream& in, const std::string& file,
462  int& line, int &pos);
463 
471  static ElementPtr fromJSONFile(const std::string& file_name,
472  bool preproc = false);
474 
476 
482  static std::string typeToName(Element::types type);
483 
489  static Element::types nameToType(const std::string& type_name);
490 
505  static void preprocess(std::istream& in, std::stringstream& out);
506 
508 
512 
514  static ElementPtr fromWire(std::stringstream& in, int length);
523 
530  static ElementPtr fromWire(const std::string& s);
532 };
533 
544 class IntElement : public Element {
545  int64_t i;
546 private:
547 
548 public:
549  IntElement(int64_t v, const Position& pos = ZERO_POSITION())
550  : Element(integer, pos), i(v) { }
551  int64_t intValue() const { return (i); }
552  using Element::getValue;
553  bool getValue(int64_t& t) const { t = i; return (true); }
554  using Element::setValue;
555  bool setValue(long long int v) { i = v; return (true); }
556  void toJSON(std::ostream& ss) const;
557  bool equals(const Element& other) const;
558 };
559 
560 class DoubleElement : public Element {
561  double d;
562 
563 public:
564  DoubleElement(double v, const Position& pos = ZERO_POSITION())
565  : Element(real, pos), d(v) {};
566  double doubleValue() const { return (d); }
567  using Element::getValue;
568  bool getValue(double& t) const { t = d; return (true); }
569  using Element::setValue;
570  bool setValue(const double v) { d = v; return (true); }
571  void toJSON(std::ostream& ss) const;
572  bool equals(const Element& other) const;
573 };
574 
575 class BoolElement : public Element {
576  bool b;
577 
578 public:
579  BoolElement(const bool v, const Position& pos = ZERO_POSITION())
580  : Element(boolean, pos), b(v) {};
581  bool boolValue() const { return (b); }
582  using Element::getValue;
583  bool getValue(bool& t) const { t = b; return (true); }
584  using Element::setValue;
585  bool setValue(const bool v) { b = v; return (true); }
586  void toJSON(std::ostream& ss) const;
587  bool equals(const Element& other) const;
588 };
589 
590 class NullElement : public Element {
591 public:
593  : Element(null, pos) {};
594  void toJSON(std::ostream& ss) const;
595  bool equals(const Element& other) const;
596 };
597 
598 class StringElement : public Element {
599  std::string s;
600 
601 public:
602  StringElement(std::string v, const Position& pos = ZERO_POSITION())
603  : Element(string, pos), s(v) {};
604  std::string stringValue() const { return (s); }
605  using Element::getValue;
606  bool getValue(std::string& t) const { t = s; return (true); }
607  using Element::setValue;
608  bool setValue(const std::string& v) { s = v; return (true); }
609  void toJSON(std::ostream& ss) const;
610  bool equals(const Element& other) const;
611 };
612 
613 class ListElement : public Element {
614  std::vector<ElementPtr> l;
615 
616 public:
618  : Element(list, pos) {}
619  const std::vector<ElementPtr>& listValue() const { return (l); }
620  using Element::getValue;
621  bool getValue(std::vector<ElementPtr>& t) const {
622  t = l;
623  return (true);
624  }
625  using Element::setValue;
626  bool setValue(const std::vector<ElementPtr>& v) {
627  l = v;
628  return (true);
629  }
630  using Element::get;
631  ConstElementPtr get(int i) const { return (l.at(i)); }
632  ElementPtr getNonConst(int i) const { return (l.at(i)); }
633  using Element::set;
634  void set(size_t i, ElementPtr e) {
635  l.at(i) = e;
636  }
637  void add(ElementPtr e) { l.push_back(e); };
638  using Element::remove;
639  void remove(int i) { l.erase(l.begin() + i); };
640  void toJSON(std::ostream& ss) const;
641  size_t size() const { return (l.size()); }
642  bool empty() const { return (l.empty()); }
643  bool equals(const Element& other) const;
644 };
645 
646 class MapElement : public Element {
647  std::map<std::string, ConstElementPtr> m;
648 
649 public:
650  MapElement(const Position& pos = ZERO_POSITION()) : Element(map, pos) {}
651  // @todo should we have direct iterators instead of exposing the std::map
652  // here?
653  const std::map<std::string, ConstElementPtr>& mapValue() const {
654  return (m);
655  }
656  using Element::getValue;
657  bool getValue(std::map<std::string, ConstElementPtr>& t) const {
658  t = m;
659  return (true);
660  }
661  using Element::setValue;
662  bool setValue(const std::map<std::string, ConstElementPtr>& v) {
663  m = v;
664  return (true);
665  }
666  using Element::get;
667  ConstElementPtr get(const std::string& s) const {
668  auto found = m.find(s);
669  return (found != m.end() ? found->second : ConstElementPtr());
670  }
671  using Element::set;
672  void set(const std::string& key, ConstElementPtr value);
673  using Element::remove;
674  void remove(const std::string& s) { m.erase(s); }
675  bool contains(const std::string& s) const {
676  return (m.find(s) != m.end());
677  }
678  void toJSON(std::ostream& ss) const;
679 
680  // we should name the two finds better...
681  // find the element at id; raises TypeError if one of the
682  // elements at path except the one we're looking for is not a
683  // mapelement.
684  // returns an empty element if the item could not be found
685  ConstElementPtr find(const std::string& id) const;
686 
687  // find the Element at 'id', and store the element pointer in t
688  // returns true if found, or false if not found (either because
689  // it doesn't exist or one of the elements in the path is not
690  // a MapElement)
691  bool find(const std::string& id, ConstElementPtr& t) const;
692 
696  size_t size() const {
697  return (m.size());
698  }
699 
700  bool equals(const Element& other) const;
701 
702  bool empty() const { return (m.empty()); }
703 };
704 
708 bool isNull(ConstElementPtr p);
709 
717 void removeIdentical(ElementPtr a, ConstElementPtr b);
718 
724 ConstElementPtr removeIdentical(ConstElementPtr a, ConstElementPtr b);
725 
738 void merge(ElementPtr element, ConstElementPtr other);
739 
750 ElementPtr copy(ConstElementPtr from, int level = 100);
751 
757 bool isEquivalent(ConstElementPtr a, ConstElementPtr b);
758 
770 void prettyPrint(ConstElementPtr element, std::ostream& out,
771  unsigned indent = 0, unsigned step = 2);
772 
783 std::string prettyPrint(ConstElementPtr element,
784  unsigned indent = 0, unsigned step = 2);
785 
797 std::ostream& operator<<(std::ostream& out, const Element::Position& pos);
798 
814 std::ostream& operator<<(std::ostream& out, const Element& e);
815 
816 bool operator==(const Element& a, const Element& b);
817 bool operator!=(const Element& a, const Element& b);
818 } }
819 #endif // ISC_DATA_H
820 
821 // Local Variables:
822 // mode: c++
823 // End:
virtual double doubleValue() const
Definition: data.h:213
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:806
virtual ~Element()
Definition: data.h:153
bool getValue(bool &t) const
Definition: data.h:583
static ElementPtr fromJSONFile(const std::string &file_name, bool preproc=false)
Reads contents of specified file and interprets it as JSON.
Definition: data.cc:759
bool contains(const std::string &s) const
Checks if there is data at the given key.
Definition: data.h:675
bool setValue(const int i)
Definition: data.h:258
uint32_t line_
Line number.
Definition: data.h:90
bool equals(const Element &other) const
Definition: data.cc:977
std::string toWire() const
Returns the wireformat for the Element and all its child elements.
Definition: data.cc:58
virtual void set(const size_t i, ElementPtr element)
Sets the ElementPtr at the given index.
Definition: data.cc:140
bool equals(const Element &other) const
Definition: data.cc:982
bool equals(const Element &other) const
Definition: data.cc:971
static const Position & ZERO_POSITION()
Returns Position object with line_ and pos_ set to 0, and with an empty file name.
Definition: data.h:120
const std::vector< ElementPtr > & listValue() const
Definition: data.h:619
std::string stringValue() const
Definition: data.h:604
bool setValue(const std::vector< ElementPtr > &v)
Definition: data.h:626
bool getValue(std::string &t) const
Definition: data.h:606
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
Definition: data.h:43
bool getValue(int64_t &t) const
Definition: data.h:553
std::string str() const
Returns the position in the textual format.
Definition: data.cc:38
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition: data.cc:1224
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition: data.cc:597
bool operator!=(const Element &a, const Element &b)
Definition: data.cc:214
bool equals(const Element &other) const
Definition: data.cc:1006
bool isEquivalent(ConstElementPtr a, ConstElementPtr b)
Compares the data with other using unordered lists.
Definition: data.cc:1219
double doubleValue() const
Definition: data.h:566
bool equals(const Element &other) const
Definition: data.cc:988
bool setValue(long long int v)
Definition: data.h:555
int getType() const
Definition: data.h:156
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:797
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
ListElement(const Position &pos=ZERO_POSITION())
Definition: data.h:617
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition: data.cc:740
virtual bool contains(const std::string &name) const
Checks if there is data at the given key.
Definition: data.cc:180
#define throwTypeError(error)
Add the position to a TypeError message should be used in place of isc_throw(TypeError, error)
Definition: data.h:183
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:776
void removeIdentical(ElementPtr a, ConstElementPtr b)
Remove all values from the first ElementPtr that are equal in the second.
Definition: data.cc:1033
StringElement(std::string v, const Position &pos=ZERO_POSITION())
Definition: data.h:602
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:781
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition: data.cc:1028
bool empty() const
Return true if there are no elements in the list.
Definition: data.h:702
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:267
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:262
virtual size_t size() const
Returns the number of elements in the list.
Definition: data.cc:155
virtual bool equals(const Element &other) const =0
Position()
Default constructor.
Definition: data.h:94
Position(const std::string &file, const uint32_t line, const uint32_t pos)
Constructor.
Definition: data.h:102
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:873
bool getValue(std::vector< ElementPtr > &t) const
Definition: data.h:621
bool operator==(const Element &a, const Element &b)
Definition: data.cc:210
virtual const std::map< std::string, ConstElementPtr > & mapValue() const
Definition: data.h:223
static ElementPtr fromWire(std::stringstream &in, int length)
These function pparse the wireformat at the given stringstream (of the given length).
Definition: data.cc:924
bool boolValue() const
Definition: data.h:581
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1097
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:811
std::ostream & operator<<(std::ostream &out, const Element::Position &pos)
Insert Element::Position as a string into stream.
Definition: data.cc:45
bool setValue(const bool v)
Definition: data.h:585
virtual bool boolValue() const
Definition: data.h:215
Notes: IntElement type is changed to int64_t.
Definition: data.h:544
virtual ConstElementPtr find(const std::string &identifier) const
Recursively finds any data at the given identifier.
Definition: data.cc:185
TypeError(const char *file, size_t line, const char *what)
Definition: data.h:32
bool equals(const Element &other) const
Definition: data.cc:959
const Position & getPosition() const
Returns position where the data element's value starts in a configuration string. ...
Definition: data.h:163
IntElement(int64_t v, const Position &pos=ZERO_POSITION())
Definition: data.h:549
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
size_t size() const
Returns the number of elements in the list.
Definition: data.h:641
std::string str() const
Returns a string representing the Element and all its child elements; note that this is different fro...
Definition: data.cc:51
NullElement(const Position &pos=ZERO_POSITION())
Definition: data.h:592
bool getValue(std::map< std::string, ConstElementPtr > &t) const
Definition: data.h:657
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
Definition: data.h:30
DoubleElement(double v, const Position &pos=ZERO_POSITION())
Definition: data.h:564
virtual void add(ElementPtr element)
Adds an ElementPtr to the list.
Definition: data.cc:145
bool equals(const Element &other) const
Definition: data.cc:965
MapElement(const Position &pos=ZERO_POSITION())
Definition: data.h:650
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
virtual ElementPtr getNonConst(const int i) const
returns element as non-const pointer
Definition: data.cc:135
virtual void toJSON(std::ostream &ss) const =0
Converts the Element to JSON format and appends it to the given stringstream.
virtual bool getValue(int64_t &t) const
Definition: data.cc:70
Represents the position of the data element within a configuration string.
Definition: data.h:88
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
static void preprocess(std::istream &in, std::stringstream &out)
input text preprocessor
Definition: data.cc:1315
uint32_t pos_
Position within the line.
Definition: data.h:91
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
Definition: data.cc:1079
bool setValue(const long int i)
Definition: data.h:257
static Element::types nameToType(const std::string &type_name)
Converts the string to the corresponding type Throws a TypeError if the name is unknown.
Definition: data.cc:621
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:859
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:222
const std::map< std::string, ConstElementPtr > & mapValue() const
Definition: data.h:653
virtual bool empty() const
Return true if there are no elements in the list.
Definition: data.cc:160
void set(const std::string &key, ConstElementPtr value)
Sets the ElementPtr at the given key.
Definition: data.cc:940
virtual ConstElementPtr get(const int i) const
Returns the ElementPtr at the given index.
Definition: data.cc:130
The Element class represents a piece of data, used by the command channel and configuration parts...
Definition: data.h:66
ElementPtr getNonConst(int i) const
returns element as non-const pointer
Definition: data.h:632
size_t size() const
Returns number of stored elements.
Definition: data.h:696
virtual int64_t intValue() const
Definition: data.h:211
void set(size_t i, ElementPtr e)
Sets the ElementPtr at the given index.
Definition: data.h:634
bool setValue(const std::map< std::string, ConstElementPtr > &v)
Definition: data.h:662
bool setValue(const std::string &v)
Definition: data.h:608
virtual bool setValue(const long long int v)
Definition: data.cc:100
bool setValue(const double v)
Definition: data.h:570
int64_t intValue() const
Definition: data.h:551
BoolElement(const bool v, const Position &pos=ZERO_POSITION())
Definition: data.h:579
virtual void remove(const int i)
Removes the element at the given position.
Definition: data.cc:150
std::string file_
File name.
Definition: data.h:89
virtual std::string stringValue() const
Definition: data.h:217
void add(ElementPtr e)
Adds an ElementPtr to the list.
Definition: data.h:637
virtual const std::vector< ElementPtr > & listValue() const
Definition: data.h:219
bool empty() const
Return true if there are no elements in the list.
Definition: data.h:642
JSONError(const char *file, size_t line, const char *what)
Definition: data.h:45
ConstElementPtr find(const std::string &id) const
Recursively finds any data at the given identifier.
Definition: data.cc:896
bool getValue(double &t) const
Definition: data.h:568
Element(int t, const Position &pos=ZERO_POSITION())
Constructor.
Definition: data.h:142