26#include <boost/lexical_cast.hpp>
35const char*
const WHITESPACE =
" \b\f\n\r\t";
45 std::ostringstream ss;
62 if (type_ ==
list || type_ ==
map) {
64 for (
size_t i = 0; i < s; ++i) {
69 }
else if (type_ ==
map) {
80 child = boost::const_pointer_cast<Element>(
get(key));
84 if (child->getType() !=
list && child->getType() !=
map) {
90 child->removeEmptyContainersRecursively(level - 1);
105 std::stringstream ss;
112 std::stringstream ss;
254throwJSONError(
const std::string& error,
const std::string& file,
int line,
256 std::stringstream ss;
257 ss << error <<
" in " + file +
":" << line <<
":" << pos;
264 return (out << e.
str());
315 return (
create(
static_cast<long long int>(i), pos));
320 return (
create(
static_cast<long long int>(i), pos));
325 return (
create(
static_cast<long long int>(i), pos));
345 return (
create(std::string(s), pos));
364charIn(
const int c,
const char* chars) {
365 const size_t chars_len = std::strlen(chars);
366 for (
size_t i = 0; i < chars_len; ++i) {
375skipChars(std::istream& in,
const char* chars,
int& line,
int& pos) {
377 while (charIn(c, chars) && c != EOF) {
395skipTo(std::istream& in,
const std::string& file,
int& line,
int& pos,
396 const char* chars,
const char* may_skip=
"") {
404 if (charIn(c, may_skip)) {
407 }
else if (charIn(c, chars)) {
408 while (charIn(in.peek(), may_skip)) {
409 if (in.peek() ==
'\n') {
419 throwJSONError(std::string(
"'") + std::string(1, c) +
"' read, one of \"" + chars +
"\" expected", file, line, pos);
422 throwJSONError(std::string(
"EOF read, one of \"") + chars +
"\" expected", file, line, pos);
429strFromStringstream(std::istream& in,
const std::string& file,
430 const int line,
int& pos) {
431 std::stringstream ss;
438 throwJSONError(
"String expected", file, line, pos);
441 while (c != EOF && c !=
'"') {
476 throwJSONError(
"Unsupported unicode escape", file, line, pos);
483 throwJSONError(
"Unsupported unicode escape", file, line, pos - 2);
489 if ((d >=
'0') && (d <=
'9')) {
491 }
else if ((d >=
'A') && (d <=
'F')) {
492 c = (d -
'A' + 10) << 4;
493 }
else if ((d >=
'a') && (d <=
'f')) {
494 c = (d -
'a' + 10) << 4;
496 throwJSONError(
"Not hexadecimal in unicode escape", file, line, pos - 3);
502 if ((d >=
'0') && (d <=
'9')) {
504 }
else if ((d >=
'A') && (d <=
'F')) {
506 }
else if ((d >=
'a') && (d <=
'f')) {
509 throwJSONError(
"Not hexadecimal in unicode escape", file, line, pos - 4);
513 throwJSONError(
"Bad escape", file, line, pos);
524 throwJSONError(
"Unterminated string", file, line, pos);
530wordFromStringstream(std::istream& in,
int& pos) {
531 std::stringstream ss;
532 while (isalpha(in.peek())) {
533 ss << (char) in.get();
535 pos += ss.str().size();
540numberFromStringstream(std::istream& in,
int& pos) {
541 std::stringstream ss;
542 while (isdigit(in.peek()) || in.peek() ==
'+' || in.peek() ==
'-' ||
543 in.peek() ==
'.' || in.peek() ==
'e' || in.peek() ==
'E') {
544 ss << (char) in.get();
546 pos += ss.str().size();
560fromStringstreamNumber(std::istream& in,
const std::string& file,
561 const int line,
int& pos) {
564 const uint32_t start_pos = pos;
566 const std::string number = numberFromStringstream(in, pos);
569 if (((number.size() > 1) && (number[0] ==
'0') && isdigit(number[1])) ||
570 ((number.size() > 2) && (number[0] ==
'-') &&
571 (number[1] ==
'0') && isdigit(number[2]))) {
572 throwJSONError(
"Illegal leading zeros in '" + number +
"'",
573 file, line, start_pos);
576 if (number.find_first_of(
".eE") < number.size()) {
579 Element::Position(file, line, start_pos)));
580 }
catch (
const boost::bad_lexical_cast& exception) {
581 throwJSONError(
"Number overflow while trying to cast '" + number +
582 "' to double: " + exception.what(),
583 file, line, start_pos);
590 Element::Position(file, line, start_pos)));
591 }
catch (
const boost::bad_lexical_cast& exception64) {
595 Element::Position(file, line, start_pos)));
596 }
catch (overflow_error
const& exception128) {
597 throwJSONError(
"Number overflow while trying to cast '" + number +
598 "' to int64 and subsequently to int128: " +
599 exception64.what() +
", " + exception128.what(),
600 file, line, start_pos);
607fromStringstreamBool(std::istream& in,
const std::string& file,
608 const int line,
int& pos) {
611 const uint32_t start_pos = pos;
613 const std::string word = wordFromStringstream(in, pos);
615 if (word ==
"true") {
618 }
else if (word ==
"false") {
622 throwJSONError(std::string(
"Bad boolean value: ") + word, file,
629fromStringstreamNull(std::istream& in,
const std::string& file,
630 const int line,
int& pos) {
633 const uint32_t start_pos = pos;
635 const std::string word = wordFromStringstream(in, pos);
636 if (word ==
"null") {
639 throwJSONError(std::string(
"Bad null value: ") + word, file,
646fromStringstreamString(std::istream& in,
const std::string& file,
int& line,
650 const uint32_t start_pos = pos;
652 const std::string string_value = strFromStringstream(in, file, line, pos);
658fromStringstreamList(std::istream& in,
const std::string& file,
int& line,
659 int& pos,
unsigned level) {
661 isc_throw(JSONError,
"fromJSON elements nested too deeply");
667 skipChars(in, WHITESPACE, line, pos);
668 while (c != EOF && c !=
']') {
669 if (in.peek() !=
']') {
672 list->add(cur_list_element);
673 c = skipTo(in, file, line, pos,
",]", WHITESPACE);
683fromStringstreamMap(std::istream& in,
const std::string& file,
int& line,
684 int& pos,
unsigned level) {
686 isc_throw(JSONError,
"fromJSON elements nested too deeply");
689 skipChars(in, WHITESPACE, line, pos);
692 throwJSONError(std::string(
"Unterminated map, <string> or } expected"), file, line, pos);
693 }
else if (c ==
'}') {
697 while (c != EOF && c !=
'}') {
698 std::string key = strFromStringstream(in, file, line, pos);
700 skipTo(in, file, line, pos,
":", WHITESPACE);
705 map->set(key, value);
707 c = skipTo(in, file, line, pos,
",}", WHITESPACE);
718 return (std::string(
"integer"));
720 return (std::string(
"bigint"));
722 return (std::string(
"real"));
724 return (std::string(
"boolean"));
726 return (std::string(
"string"));
728 return (std::string(
"list"));
730 return (std::string(
"map"));
732 return (std::string(
"null"));
734 return (std::string(
"any"));
736 return (std::string(
"unknown"));
742 if (type_name ==
"integer") {
744 }
else if (type_name ==
"bigint") {
746 }
else if (type_name ==
"real") {
748 }
else if (type_name ==
"boolean") {
750 }
else if (type_name ==
"string") {
752 }
else if (type_name ==
"list") {
754 }
else if (type_name ==
"map") {
756 }
else if (type_name ==
"named_set") {
758 }
else if (type_name ==
"null") {
760 }
else if (type_name ==
"any") {
770 int line = 1, pos = 1;
771 stringstream filtered;
783 int line = 1, pos = 1;
784 stringstream filtered;
788 return (
fromJSON(preproc ? filtered : in, file_name, line, pos));
793 int& pos,
unsigned level) {
799 bool el_read =
false;
800 skipChars(in, WHITESPACE, line, pos);
801 while (c != EOF && !el_read) {
819 element = fromStringstreamNumber(in, file, line, pos);
826 element = fromStringstreamBool(in, file, line, pos);
832 element = fromStringstreamNull(in, file, line, pos);
838 element = fromStringstreamString(in, file, line, pos);
842 element = fromStringstreamList(in, file, line, pos, level);
846 element = fromStringstreamMap(in, file, line, pos, level);
852 throwJSONError(std::string(
"error: unexpected character ") + std::string(1, c), file, line, pos);
865 std::stringstream ss;
868 int line = 1, pos = 1;
869 stringstream filtered;
874 skipChars(ss, WHITESPACE, line, pos);
876 if (ss.peek() != EOF) {
877 throwJSONError(
"Extra data",
"<string>", line, pos);
887 std::ifstream infile(file_name.c_str(), std::ios::in | std::ios::binary);
888 if (!infile.is_open()) {
889 const char* error = strerror(errno);
894 return (
fromJSON(infile, file_name, preproc));
917 ostringstream val_ss;
920 if (val_ss.str().find_first_of(
".eE") == string::npos) {
943 for (
size_t i = 0; i <
str.size(); ++i) {
944 const signed char c =
str[i];
971 if (c < 0x20 || c == 0x7f) {
972 std::ostringstream esc;
977 << (
static_cast<unsigned>(c) & 0xff);
991 "arguments include cycles");
995 const std::vector<ElementPtr>& v =
listValue();
997 for (
auto const& it : v) {
1003 it->toJSON(ss, level - 1);
1012 "arguments include cycles");
1017 for (
auto const& it : m) {
1023 ss <<
"\"" << it.first <<
"\": ";
1025 it.second->toJSON(ss, level - 1);
1039 const size_t sep =
id.find(
'/');
1040 if (sep == std::string::npos) {
1046 if (sep + 1 !=
id.
size()) {
1047 return (ce->find(
id.substr(sep + 1)));
1059 std::stringstream ss;
1061 int line = 0, pos = 0;
1062 return (
fromJSON(ss,
"<wire>", line, pos));
1077 int line = 0, pos = 0;
1078 return (
fromJSON(in,
"<wire>", line, pos));
1149 "arguments include cycles");
1152 const size_t s =
size();
1153 if (s != other.
size()) {
1156 for (
size_t i = 0; i < s; ++i) {
1173 int const t(l.at(0)->getType());
1176 if (index.empty()) {
1187 }
else if (t ==
list) {
1192 if (!index.empty()) {
1200 std::sort(l.begin(), l.end(), comparator);
1207 "arguments include cycles");
1213 for (
auto const& kv :
mapValue()) {
1214 auto key = kv.first;
1247 for (
auto const& kv : b->mapValue()) {
1248 auto key = kv.first;
1249 if (a->contains(key)) {
1250 if (a->get(key)->equals(*b->get(key))) {
1269 for (
auto const& kv : a->mapValue()) {
1270 auto key = kv.first;
1271 if (!b->contains(key) ||
1272 !a->get(key)->equals(*b->get(key))) {
1273 result->set(key, kv.second);
1287 for (
auto const& kv : other->mapValue()) {
1288 auto key = kv.first;
1289 auto value = kv.second;
1291 element->set(key, value);
1292 }
else if (element->contains(key)) {
1293 element->remove(key);
1304 "arguments include cycles");
1306 if (element->getType() != other->getType()) {
1314 for (
auto const& right : other->listValue()) {
1317 auto f = hierarchy[idx].find(key);
1318 if (f != hierarchy[idx].end()) {
1320 ElementPtr mutable_right = boost::const_pointer_cast<Element>(right);
1321 for (
auto const& left : element->listValue()) {
1322 ElementPtr mutable_left = boost::const_pointer_cast<Element>(left);
1325 if (f->second.match_(mutable_left, mutable_right)) {
1328 key, idx, level - 1);
1332 new_elements->add(right);
1335 new_elements->add(right);
1339 for (
auto const& right : new_elements->listValue()) {
1340 element->add(right);
1346 for (
auto const& kv : other->mapValue()) {
1347 auto current_key = kv.first;
1348 auto value = boost::const_pointer_cast<Element>(kv.second);
1350 if (element->contains(current_key) &&
1353 ElementPtr mutable_element = boost::const_pointer_cast<Element>(element->get(current_key));
1355 current_key, idx + 1, level - 1);
1357 element->set(current_key, value);
1372 "arguments include cycles");
1374 if (element->getType() != other->getType()) {
1379 for (
auto const& value : other->listValue()) {
1380 ElementPtr mutable_right = boost::const_pointer_cast<Element>(value);
1381 for (uint32_t iter = 0; iter < element->listValue().
size();) {
1382 bool removed =
false;
1385 auto f = hierarchy[idx].find(key);
1386 if (f != hierarchy[idx].end()) {
1387 ElementPtr mutable_left = boost::const_pointer_cast<Element>(element->listValue().at(iter));
1390 if (f->second.match_(mutable_left, mutable_right)) {
1394 if (f->second.no_data_(mutable_right)) {
1395 element->remove(iter);
1399 hierarchy, key, idx, level - 1);
1400 if (mutable_left->empty()) {
1401 element->remove(iter);
1406 }
else if (element->listValue().at(iter)->equals(*value)) {
1407 element->remove(iter);
1422 for (
auto const& kv : other->mapValue()) {
1423 auto current_key = kv.first;
1424 auto value = boost::const_pointer_cast<Element>(kv.second);
1426 if (element->contains(current_key)) {
1427 ElementPtr mutable_element = boost::const_pointer_cast<Element>(element->get(current_key));
1431 current_key, idx + 1, level - 1);
1432 if (mutable_element->empty()) {
1433 element->remove(current_key);
1438 auto f = hierarchy[idx].find(key);
1439 if (f != hierarchy[idx].end()) {
1442 if (f->second.is_key_(current_key)) {
1444 new_elements->set(current_key, mutable_element);
1447 element->remove(current_key);
1453 if (element->size()) {
1454 for (
auto const& kv : new_elements->mapValue()) {
1455 element->set(kv.first, kv.second);
1464extend(
const std::string& container,
const std::string& extension,
1466 std::string key,
size_t idx,
bool alter,
unsigned level) {
1470 "arguments include cycles");
1472 if (element->getType() != other->getType()) {
1477 for (
auto const& right : other->listValue()) {
1480 auto f = hierarchy[idx].find(key);
1481 if (f != hierarchy[idx].end()) {
1482 ElementPtr mutable_right = boost::const_pointer_cast<Element>(right);
1483 for (
auto const& left : element->listValue()) {
1484 ElementPtr mutable_left = boost::const_pointer_cast<Element>(left);
1485 if (container == key) {
1488 if (f->second.match_(mutable_left, mutable_right)) {
1489 extend(container, extension, mutable_left, mutable_right,
1490 hierarchy, key, idx, alter, level - 1);
1499 for (
auto const& kv : other->mapValue()) {
1500 auto current_key = kv.first;
1501 auto value = boost::const_pointer_cast<Element>(kv.second);
1503 if (element->contains(current_key) &&
1506 ElementPtr mutable_element = boost::const_pointer_cast<Element>(element->get(current_key));
1507 if (container == key) {
1510 extend(container, extension, mutable_element, value,
1511 hierarchy, current_key, idx + 1, alter, level - 1);
1512 }
else if (alter && current_key == extension) {
1513 element->set(current_key, value);
1527 auto pos = from->getPosition();
1528 int from_type = from->getType();
1541 for (
auto const& elem : from->listValue()) {
1545 result->add(
copy(elem, level - 1));
1551 for (
auto const& kv : from->mapValue()) {
1552 auto key = kv.first;
1553 auto value = kv.second;
1555 result->set(key, value);
1557 result->set(key,
copy(value, level - 1));
1574 "arguments include cycles");
1577 isc_throw(BadValue,
"isEquivalent got a null pointer");
1580 if (a->getType() != b->getType()) {
1586 return (b->empty());
1589 if (a->size() != b->size()) {
1594 const size_t s = a->size();
1595 std::list<ConstElementPtr> l;
1596 for (
size_t i = 0; i < s; ++i) {
1597 l.push_back(b->get(i));
1601 for (
size_t i = 0; i < s; ++i) {
1605 for (
auto it = l.begin(); it != l.end(); ++it) {
1607 if (isEquivalent0(item, *it, level - 1)) {
1621 isc_throw(Unexpected,
"isEquivalent internal error");
1626 if (a->size() != b->size()) {
1630 for (
auto const& kv : a->mapValue()) {
1633 if (!item || !isEquivalent0(kv.second, item, level - 1)) {
1639 return (a->equals(*b));
1647 return (isEquivalent0(a, b, 100));
1654 unsigned indent,
unsigned step,
unsigned level) {
1657 "arguments include cycles");
1660 isc_throw(BadValue,
"prettyPrint got a null pointer");
1664 if (element->empty()) {
1670 if (!element->get(0)) {
1671 isc_throw(BadValue,
"prettyPrint got a null pointer");
1673 int first_type = element->get(0)->getType();
1674 bool complex =
false;
1678 std::string separator = complex ?
",\n" :
", ";
1681 out <<
"[" << (complex ?
"\n" :
" ");
1684 auto const& l = element->listValue();
1686 for (
auto const& it : l) {
1695 out << std::string(indent + step,
' ');
1698 prettyPrint0(it, out, indent + step, step, level - 1);
1703 out <<
"\n" << std::string(indent,
' ');
1710 if (element->size() == 0) {
1719 auto const& m = element->mapValue();
1721 for (
auto const& it : m) {
1729 out << std::string(indent + step,
' ');
1731 out <<
"\"" << it.first <<
"\": ";
1733 prettyPrint0(it.second, out, indent + step, step, level - 1);
1737 out <<
"\n" << std::string(indent,
' ') <<
"}";
1740 element->toJSON(out);
1748 unsigned indent,
unsigned step) {
1754 std::stringstream ss;
1763 while (std::getline(in, line)) {
1766 if (!line.empty() && line[0] ==
'#') {
1781typedef std::set<ConstElementPtr> Arc;
1790 auto type = element->getType();
1796 if (element->empty()) {
1800 if (arc.count(element) > 0) {
1804 arc.insert(element);
1806 for (
auto const& it : element->listValue()) {
1807 if (IsCircular0(it, arc)) {
1814 for (
auto const& it : element->mapValue()) {
1815 if (IsCircular0(it.second, arc)) {
1826 return (IsCircular0(element, Arc()));
1831 if (max_depth == 0U) {
1839 for (
auto const& i : element->listValue()) {
1841 if (sub == max_depth - 1) {
1844 if (sub + 1 > ret) {
1849 for (
auto const& i : element->mapValue()) {
1851 if (sub == max_depth - 1) {
1854 if (sub + 1 > ret) {
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const override
Converts the Element to JSON format and appends it to the given stringstream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const override
Checks whether the other Element is equal.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
The Element class represents a piece of data, used by the command channel and configuration parts.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
virtual bool getValue(int64_t &t) const
Get the integer value.
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
virtual int64_t intValue() const
Return the integer value.
static constexpr unsigned MAX_NESTING_LEVEL
Maximum nesting level of Element objects.
std::string str() const
Returns a string representing the Element and all its child elements.
virtual std::string stringValue() const
Return the string value.
std::string toWire() const
Returns the wireformat for the Element and all its child elements.
types
The types that an Element can hold.
virtual void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const =0
Converts the Element to JSON format and appends it to the given output stream.
static ElementPtr fromWire(std::stringstream &in, int length)
These function parse the wireformat at the given stringstream (of the given length).
virtual bool setValue(const long long int v)
Set the integer value.
static ElementPtr fromJSONFile(const std::string &file_name, bool preproc=false)
Reads contents of specified file and interprets it as JSON.
virtual bool empty() const
Return true if there are no elements in the list.
virtual void remove(const int i)
Removes the element at the given position.
virtual bool contains(const std::string &name) const
Checks if there is data at the given key.
virtual ConstElementPtr find(const std::string &identifier) const
Recursively finds any data at the given identifier.
virtual size_t size() const
Returns the number of elements in the list.
Element(types t, const Position &pos=ZERO_POSITION())
Constructor.
virtual const std::map< std::string, ConstElementPtr > & mapValue() const
Return the map value.
virtual void add(ElementPtr element)
Adds an ElementPtr to the list.
virtual const std::vector< ElementPtr > & listValue() const
Return the list value.
virtual bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const =0
Test equality.
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
virtual ConstElementPtr get(const int i) const
Returns the ElementPtr at the given index.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static Element::types nameToType(const std::string &type_name)
Converts the string to the corresponding type Throws a TypeError if the name is unknown.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
virtual void set(const size_t i, ElementPtr element)
Sets the ElementPtr at the given index.
virtual double doubleValue() const
Return the double value.
virtual isc::util::int128_t bigIntValue() const
Return the big integer value.
virtual bool boolValue() const
Return the boolean value.
static void preprocess(std::istream &in, std::stringstream &out)
input text preprocessor.
virtual ElementPtr getNonConst(const int i) const
returns element as non-const pointer.
void removeEmptyContainersRecursively(unsigned level=MAX_NESTING_LEVEL)
Remove all empty maps and lists from this Element and its descendants.
Notes: IntElement type is changed to int64_t.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
void sort(std::string const &index=std::string())
Sorts the elements inside the list.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
ConstElementPtr find(const std::string &id) const override
Recursively finds any data at the given identifier.
void set(const std::string &key, ConstElementPtr value) override
Sets the ElementPtr at the given key.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const override
Test equality.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const override
Converts the Element to JSON format and appends it to the given output stream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
bool equals(const Element &other, unsigned level=MAX_NESTING_LEVEL) const
Test equality.
void toJSON(std::ostream &ss, unsigned level=MAX_NESTING_LEVEL) const
Converts the Element to JSON format and appends it to the given output stream.
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
#define throwTypeError(error)
Add the position to a TypeError message should be used in place of isc_throw(TypeError,...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
bool operator==(const Element &a, const Element &b)
Test equality.
void extend(const std::string &container, const std::string &extension, ElementPtr &element, ElementPtr &other, HierarchyDescriptor &hierarchy, std::string key, size_t idx, bool alter, unsigned level)
Extends data by adding the specified 'extension' elements from 'other' inside the 'container' element...
void removeIdentical(ElementPtr a, ConstElementPtr b)
Remove all values from the first ElementPtr that are equal in the second.
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element. (on the first level).
bool isEquivalent(ConstElementPtr a, ConstElementPtr b)
Compares the data with other using unordered lists.
bool operator<(Element const &a, Element const &b)
Test less than.
bool IsCircular(ConstElementPtr element)
Check if the data is circular.
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
ElementPtr copy(ConstElementPtr from, unsigned level)
Copy the data up to a nesting level.
boost::shared_ptr< const Element > ConstElementPtr
void mergeDiffAdd(ElementPtr &element, ElementPtr &other, HierarchyDescriptor &hierarchy, std::string key, size_t idx, unsigned level)
Merges the diff data by adding the missing elements from 'other' to 'element' (recursively).
unsigned getNestDepth(ConstElementPtr element, unsigned max_depth)
Compute the nesting depth.
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a null pointer.
std::ostream & operator<<(std::ostream &out, const Element::Position &pos)
Insert Element::Position as a string into stream.
void mergeDiffDel(ElementPtr &element, ElementPtr &other, HierarchyDescriptor &hierarchy, std::string key, size_t idx, unsigned level)
Merges the diff data by removing the data present in 'other' from 'element' (recursively).
bool operator!=(const Element &a, const Element &b)
Test inequality.
boost::shared_ptr< Element > ElementPtr
std::vector< FunctionMap > HierarchyDescriptor
Hierarchy descriptor of the containers in a specific Element hierarchy tree.
boost::multiprecision::checked_int128_t int128_t
Defines the logger used by the top-level component of kea-lfc.
Represents the position of the data element within a configuration string.
uint32_t pos_
Position within the line.
std::string str() const
Returns the position in the textual format.
uint32_t line_
Line number.
std::string file_
File name.