Kea 1.5.0
data.h
Go to the documentation of this file.
1// Copyright (C) 2010-2018 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>
17
18namespace isc { namespace data {
19
20class Element;
21// todo: describe the rationale behind ElementPtr?
22typedef boost::shared_ptr<Element> ElementPtr;
23typedef boost::shared_ptr<const Element> ConstElementPtr;
24
30class TypeError : public isc::Exception {
31public:
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)
43class JSONError : public isc::Exception {
44public:
45 JSONError(const char* file, size_t line, const char* what) :
46 isc::Exception(file, line, what) {}
47};
48
66class Element {
67
68public:
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
125private:
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
134protected:
135
142 Element(int t, const Position& pos = ZERO_POSITION())
143 : type_(t), position_(pos) {
144 }
145
146
147public:
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
278 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
317 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
420 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
522 static ElementPtr fromWire(std::stringstream& in, int length);
523
530 static ElementPtr fromWire(const std::string& s);
532};
533
544class IntElement : public Element {
545 int64_t i;
546private:
547
548public:
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
560class DoubleElement : public Element {
561 double d;
562
563public:
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
575class BoolElement : public Element {
576 bool b;
577
578public:
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
590class NullElement : public Element {
591public:
593 : Element(null, pos) {};
594 void toJSON(std::ostream& ss) const;
595 bool equals(const Element& other) const;
596};
597
598class StringElement : public Element {
599 std::string s;
600
601public:
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
613class ListElement : public Element {
614 std::vector<ElementPtr> l;
615
616public:
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
646class MapElement : public Element {
647 std::map<std::string, ConstElementPtr> m;
648
649public:
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 return (contains(s) ? m.find(s)->second : ConstElementPtr());
669 }
670 using Element::set;
671 void set(const std::string& key, ConstElementPtr value);
672 using Element::remove;
673 void remove(const std::string& s) { m.erase(s); }
674 bool contains(const std::string& s) const {
675 return (m.find(s) != m.end());
676 }
677 void toJSON(std::ostream& ss) const;
678
679 // we should name the two finds better...
680 // find the element at id; raises TypeError if one of the
681 // elements at path except the one we're looking for is not a
682 // mapelement.
683 // returns an empty element if the item could not be found
684 ConstElementPtr find(const std::string& id) const;
685
686 // find the Element at 'id', and store the element pointer in t
687 // returns true if found, or false if not found (either because
688 // it doesn't exist or one of the elements in the path is not
689 // a MapElement)
690 bool find(const std::string& id, ConstElementPtr& t) const;
691
695 size_t size() const {
696 return (m.size());
697 }
698
699 bool equals(const Element& other) const;
700
701 bool empty() const { return (m.empty()); }
702};
703
707bool isNull(ConstElementPtr p);
708
717
724
737void merge(ElementPtr element, ConstElementPtr other);
738
749ElementPtr copy(ConstElementPtr from, int level = 100);
750
757
769void prettyPrint(ConstElementPtr element, std::ostream& out,
770 unsigned indent = 0, unsigned step = 2);
771
782std::string prettyPrint(ConstElementPtr element,
783 unsigned indent = 0, unsigned step = 2);
784
796std::ostream& operator<<(std::ostream& out, const Element::Position& pos);
797
813std::ostream& operator<<(std::ostream& out, const Element& e);
814
815bool operator==(const Element& a, const Element& b);
816bool operator!=(const Element& a, const Element& b);
817} }
818#endif // ISC_DATA_H
819
820// Local Variables:
821// mode: c++
822// End:
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
bool getValue(bool &t) const
Definition: data.h:583
bool setValue(const bool v)
Definition: data.h:585
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:798
BoolElement(const bool v, const Position &pos=ZERO_POSITION())
Definition: data.h:579
bool boolValue() const
Definition: data.h:581
bool equals(const Element &other) const
Definition: data.cc:974
bool setValue(const double v)
Definition: data.h:570
DoubleElement(double v, const Position &pos=ZERO_POSITION())
Definition: data.h:564
bool equals(const Element &other) const
Definition: data.cc:968
double doubleValue() const
Definition: data.h:566
bool getValue(double &t) const
Definition: data.h:568
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:793
The Element class represents a piece of data, used by the command channel and configuration parts.
Definition: data.h:66
const Position & getPosition() const
Returns position where the data element's value starts in a configuration string.
Definition: data.h:163
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:223
virtual bool equals(const Element &other) const =0
virtual bool getValue(int64_t &t) const
Definition: data.cc:70
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition: data.cc:605
virtual int64_t intValue() const
Definition: data.h:211
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
virtual std::string stringValue() const
Definition: data.h:217
std::string toWire() const
Returns the wireformat for the Element and all its child elements.
Definition: data.cc:58
static ElementPtr fromWire(std::stringstream &in, int length)
These function pparse the wireformat at the given stringstream (of the given length).
Definition: data.cc:927
virtual bool setValue(const long long int v)
Definition: data.cc:100
static ElementPtr fromJSONFile(const std::string &file_name, bool preproc=false)
Reads contents of specified file and interprets it as JSON.
Definition: data.cc:769
virtual bool empty() const
Return true if there are no elements in the list.
Definition: data.cc:160
virtual void remove(const int i)
Removes the element at the given position.
Definition: data.cc:150
virtual bool contains(const std::string &name) const
Checks if there is data at the given key.
Definition: data.cc:180
virtual ConstElementPtr find(const std::string &identifier) const
Recursively finds any data at the given identifier.
Definition: data.cc:185
virtual size_t size() const
Returns the number of elements in the list.
Definition: data.cc:155
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
virtual const std::map< std::string, ConstElementPtr > & mapValue() const
Definition: data.h:223
virtual void add(ElementPtr element)
Adds an ElementPtr to the list.
Definition: data.cc:145
virtual const std::vector< ElementPtr > & listValue() const
Definition: data.h:219
virtual ~Element()
Definition: data.h:153
bool setValue(const long int i)
Definition: data.h:257
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:750
virtual ConstElementPtr get(const int i) const
Returns the ElementPtr at the given index.
Definition: data.cc:130
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:268
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:629
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:263
virtual void toJSON(std::ostream &ss) const =0
Converts the Element to JSON format and appends it to the given stringstream.
virtual void set(const size_t i, ElementPtr element)
Sets the ElementPtr at the given index.
Definition: data.cc:140
virtual double doubleValue() const
Definition: data.h:213
bool setValue(const int i)
Definition: data.h:258
int getType() const
Definition: data.h:156
Element(int t, const Position &pos=ZERO_POSITION())
Constructor.
Definition: data.h:142
virtual bool boolValue() const
Definition: data.h:215
static void preprocess(std::istream &in, std::stringstream &out)
input text preprocessor
Definition: data.cc:1367
virtual ElementPtr getNonConst(const int i) const
returns element as non-const pointer
Definition: data.cc:135
Notes: IntElement type is changed to int64_t.
Definition: data.h:544
bool setValue(long long int v)
Definition: data.h:555
IntElement(int64_t v, const Position &pos=ZERO_POSITION())
Definition: data.h:549
bool equals(const Element &other) const
Definition: data.cc:962
int64_t intValue() const
Definition: data.h:551
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:788
bool getValue(int64_t &t) const
Definition: data.h:553
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
Definition: data.h:43
JSONError(const char *file, size_t line, const char *what)
Definition: data.h:45
bool empty() const
Return true if there are no elements in the list.
Definition: data.h:642
const std::vector< ElementPtr > & listValue() const
Definition: data.h:619
void remove(int i)
Removes the element at the given position.
Definition: data.h:639
bool getValue(std::vector< ElementPtr > &t) const
Definition: data.h:621
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:860
void add(ElementPtr e)
Adds an ElementPtr to the list.
Definition: data.h:637
ElementPtr getNonConst(int i) const
returns element as non-const pointer
Definition: data.h:632
void set(size_t i, ElementPtr e)
Sets the ElementPtr at the given index.
Definition: data.h:634
size_t size() const
Returns the number of elements in the list.
Definition: data.h:641
bool setValue(const std::vector< ElementPtr > &v)
Definition: data.h:626
bool equals(const Element &other) const
Definition: data.cc:991
ListElement(const Position &pos=ZERO_POSITION())
Definition: data.h:617
ConstElementPtr get(int i) const
Returns the ElementPtr at the given index.
Definition: data.h:631
bool empty() const
Return true if there are no elements in the list.
Definition: data.h:701
bool setValue(const std::map< std::string, ConstElementPtr > &v)
Definition: data.h:662
ConstElementPtr find(const std::string &id) const
Recursively finds any data at the given identifier.
Definition: data.cc:899
void remove(const std::string &s)
Remove the ElementPtr at the given key.
Definition: data.h:673
size_t size() const
Returns number of stored elements.
Definition: data.h:695
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:875
ConstElementPtr get(const std::string &s) const
Returns the ElementPtr at the given key.
Definition: data.h:667
bool getValue(std::map< std::string, ConstElementPtr > &t) const
Definition: data.h:657
bool contains(const std::string &s) const
Checks if there is data at the given key.
Definition: data.h:674
void set(const std::string &key, ConstElementPtr value)
Sets the ElementPtr at the given key.
Definition: data.cc:943
bool equals(const Element &other) const
Definition: data.cc:1009
MapElement(const Position &pos=ZERO_POSITION())
Definition: data.h:650
const std::map< std::string, ConstElementPtr > & mapValue() const
Definition: data.h:653
bool equals(const Element &other) const
Definition: data.cc:980
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:807
NullElement(const Position &pos=ZERO_POSITION())
Definition: data.h:592
std::string stringValue() const
Definition: data.h:604
bool setValue(const std::string &v)
Definition: data.h:608
bool getValue(std::string &t) const
Definition: data.h:606
void toJSON(std::ostream &ss) const
Converts the Element to JSON format and appends it to the given stringstream.
Definition: data.cc:812
StringElement(std::string v, const Position &pos=ZERO_POSITION())
Definition: data.h:602
bool equals(const Element &other) const
Definition: data.cc:985
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
Definition: data.h:30
TypeError(const char *file, size_t line, const char *what)
Definition: data.h:32
#define throwTypeError(error)
Add the position to a TypeError message should be used in place of isc_throw(TypeError,...
Definition: data.h:183
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1114
bool operator==(const Element &a, const Element &b)
Definition: data.cc:211
void removeIdentical(ElementPtr a, ConstElementPtr b)
Remove all values from the first ElementPtr that are equal in the second.
Definition: data.cc:1048
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
Definition: data.cc:1096
bool isEquivalent(ConstElementPtr a, ConstElementPtr b)
Compares the data with other using unordered lists.
Definition: data.cc:1251
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition: data.cc:1256
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition: data.cc:1043
std::ostream & operator<<(std::ostream &out, const Element::Position &pos)
Insert Element::Position as a string into stream.
Definition: data.cc:45
bool operator!=(const Element &a, const Element &b)
Definition: data.cc:215
boost::shared_ptr< Element > ElementPtr
Definition: data.h:22
Defines the logger used by the top-level component of kea-dhcp-ddns.
Represents the position of the data element within a configuration string.
Definition: data.h:88
Position(const std::string &file, const uint32_t line, const uint32_t pos)
Constructor.
Definition: data.h:102
uint32_t pos_
Position within the line.
Definition: data.h:91
std::string str() const
Returns the position in the textual format.
Definition: data.cc:38
Position()
Default constructor.
Definition: data.h:94
uint32_t line_
Line number.
Definition: data.h:90
std::string file_
File name.
Definition: data.h:89