simple_parser.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright (C) 2016 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. #include <cc/simple_parser.h>
  7. #include <boost/foreach.hpp>
  8. #include <boost/lexical_cast.hpp>
  9. #include <cc/data.h>
  10. #include <string>
  11. using namespace std;
  12. namespace isc {
  13. namespace data {
  14. std::string
  15. SimpleParser::getString(isc::data::ConstElementPtr scope, const std::string& name) {
  16. ConstElementPtr x = scope->get(name);
  17. if (!x) {
  18. isc_throw(BadValue, "String parameter " << name << " not found"
  19. << "(" << scope->getPosition() << ")");
  20. }
  21. if (x->getType() != Element::string) {
  22. isc_throw(BadValue, "Element " << name << " found, but is not a string"
  23. << "(" << x->getPosition() << ")");
  24. }
  25. return (x->stringValue());
  26. }
  27. int64_t
  28. SimpleParser::getInteger(isc::data::ConstElementPtr scope, const std::string& name) {
  29. ConstElementPtr x = scope->get(name);
  30. if (!x) {
  31. isc_throw(BadValue, "Integer parameter " << name << " not found "
  32. << "(" << scope->getPosition() << ")");
  33. }
  34. if (x->getType() != Element::integer) {
  35. isc_throw(BadValue, "Element " << name << " found, but is not an integer"
  36. << "(" << x->getPosition() << ")");
  37. }
  38. return (x->intValue());
  39. }
  40. bool
  41. SimpleParser::getBoolean(isc::data::ConstElementPtr scope, const std::string& name) {
  42. ConstElementPtr x = scope->get(name);
  43. if (!x) {
  44. isc_throw(BadValue, "Boolean element " << name << " not found "
  45. << "(" << scope->getPosition() << ")");
  46. }
  47. if (x->getType() != Element::boolean) {
  48. isc_throw(BadValue, "Element " << name << " found, but is not a boolean"
  49. << "(" << x->getPosition() << ")");
  50. }
  51. return (x->boolValue());
  52. }
  53. const data::Element::Position&
  54. SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) {
  55. if (!parent) {
  56. return (data::Element::ZERO_POSITION());
  57. }
  58. ConstElementPtr elem = parent->get(name);
  59. if (!elem) {
  60. return (data::Element::ZERO_POSITION());
  61. }
  62. return (elem->getPosition());
  63. }
  64. size_t SimpleParser::setDefaults(isc::data::ElementPtr scope,
  65. const SimpleDefaults& default_values) {
  66. size_t cnt = 0;
  67. // This is the position representing a default value. As the values
  68. // we're inserting here are not present in whatever the config file
  69. // came from, we need to make sure it's clearly labeled as default.
  70. const Element::Position pos("<default-value>", 0, 0);
  71. // Let's go over all parameters we have defaults for.
  72. BOOST_FOREACH(SimpleDefault def_value, default_values) {
  73. // Try if such a parameter is there. If it is, let's
  74. // skip it, because user knows best *cough*.
  75. ConstElementPtr x = scope->get(string(def_value.name_));
  76. if (x) {
  77. // There is such a value already, skip it.
  78. continue;
  79. }
  80. // There isn't such a value defined, let's create the default
  81. // value...
  82. switch (def_value.type_) {
  83. case Element::string: {
  84. x.reset(new StringElement(def_value.value_, pos));
  85. break;
  86. }
  87. case Element::integer: {
  88. int int_value = boost::lexical_cast<int>(def_value.value_);
  89. x.reset(new IntElement(int_value, pos));
  90. break;
  91. }
  92. case Element::boolean: {
  93. bool bool_value;
  94. if (def_value.value_ == string("true")) {
  95. bool_value = true;
  96. } else if (def_value.value_ == string("false")) {
  97. bool_value = false;
  98. } else {
  99. isc_throw(BadValue, "Internal error. Boolean value specified as "
  100. << def_value.value_ << ", expected true or false");
  101. }
  102. x.reset(new BoolElement(bool_value, pos));
  103. break;
  104. }
  105. case Element::real: {
  106. double dbl_value = boost::lexical_cast<double>(def_value.value_);
  107. x.reset(new DoubleElement(dbl_value, pos));
  108. break;
  109. }
  110. default:
  111. // No default values for null, list or map
  112. isc_throw(BadValue, "Internal error. Incorrect default value type.");
  113. }
  114. // ... and insert it into the provided Element tree.
  115. scope->set(def_value.name_, x);
  116. ++cnt;
  117. }
  118. return (cnt);
  119. }
  120. size_t
  121. SimpleParser::setListDefaults(isc::data::ConstElementPtr list,
  122. const SimpleDefaults& default_values) {
  123. size_t cnt = 0;
  124. BOOST_FOREACH(ElementPtr entry, list->listValue()) {
  125. cnt += setDefaults(entry, default_values);
  126. }
  127. return (cnt);
  128. }
  129. size_t
  130. SimpleParser::deriveParams(isc::data::ConstElementPtr parent,
  131. isc::data::ElementPtr child,
  132. const ParamsList& params) {
  133. if ( (parent->getType() != Element::map) ||
  134. (child->getType() != Element::map)) {
  135. return (0);
  136. }
  137. size_t cnt = 0;
  138. BOOST_FOREACH(string param, params) {
  139. ConstElementPtr x = parent->get(param);
  140. if (!x) {
  141. // Parent doesn't define this parameter, so there's
  142. // nothing to derive from
  143. continue;
  144. }
  145. if (child->get(param)) {
  146. // Child defines this parameter already. There's
  147. // nothing to do here.
  148. continue;
  149. }
  150. // Copy the parameters to the child scope.
  151. child->set(param, x);
  152. cnt++;
  153. }
  154. return (cnt);
  155. }
  156. }; // end of isc::dhcp namespace
  157. }; // end of isc namespace