Kea  1.5.0
lib/cc/simple_parser.cc
Go to the documentation of this file.
1 // Copyright (C) 2016-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 #include <config.h>
8 
9 #include <cc/simple_parser.h>
10 #include <asiolink/io_address.h>
11 #include <boost/foreach.hpp>
12 #include <boost/lexical_cast.hpp>
13 #include <cc/data.h>
14 #include <string>
15 
16 using namespace std;
17 using namespace isc::asiolink;
19 
20 namespace isc {
21 namespace data {
22 
23 std::string
24 SimpleParser::getString(isc::data::ConstElementPtr scope, const std::string& name) {
25  ConstElementPtr x = scope->get(name);
26  if (!x) {
28  "missing parameter '" << name << "' ("
29  << scope->getPosition() << ")");
30  }
31  if (x->getType() != Element::string) {
33  "invalid type specified for parameter '" << name
34  << "' (" << x->getPosition() << ")");
35  }
36 
37  return (x->stringValue());
38 }
39 
40 int64_t
41 SimpleParser::getInteger(isc::data::ConstElementPtr scope, const std::string& name) {
42  ConstElementPtr x = scope->get(name);
43  if (!x) {
45  "missing parameter '" << name << "' ("
46  << scope->getPosition() << ")");
47  }
48  if (x->getType() != Element::integer) {
50  "invalid type specified for parameter '" << name
51  << "' (" << x->getPosition() << ")");
52  }
53 
54  return (x->intValue());
55 }
56 
57 bool
58 SimpleParser::getBoolean(isc::data::ConstElementPtr scope, const std::string& name) {
59  ConstElementPtr x = scope->get(name);
60  if (!x) {
62  "missing parameter '" << name << "' ("
63  << scope->getPosition() << ")");
64  }
65  if (x->getType() != Element::boolean) {
67  "invalid type specified for parameter '" << name
68  << "' (" << x->getPosition() << ")");
69  }
70 
71  return (x->boolValue());
72 }
73 
75 SimpleParser::getAddress(const ConstElementPtr& scope,
76  const std::string& name) {
77  std::string str = getString(scope, name);
78  try {
79  return (IOAddress(str));
80  } catch (const std::exception& e) {
81  isc_throw(DhcpConfigError, "Failed to convert '" << str
82  << "' to address: " << e.what() << "("
83  << getPosition(name, scope) << ")");
84  }
85 }
86 
88 SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) {
89  if (!parent) {
90  return (data::Element::ZERO_POSITION());
91  }
92  ConstElementPtr elem = parent->get(name);
93  if (!elem) {
94  return (parent->getPosition());
95  }
96  return (elem->getPosition());
97 }
98 
99 size_t SimpleParser::setDefaults(isc::data::ElementPtr scope,
100  const SimpleDefaults& default_values) {
101  size_t cnt = 0;
102 
103  // This is the position representing a default value. As the values
104  // we're inserting here are not present in whatever the config file
105  // came from, we need to make sure it's clearly labeled as default.
106  const Element::Position pos("<default-value>", 0, 0);
107 
108  // Let's go over all parameters we have defaults for.
109  BOOST_FOREACH(SimpleDefault def_value, default_values) {
110 
111  // Try if such a parameter is there. If it is, let's
112  // skip it, because user knows best *cough*.
113  ConstElementPtr x = scope->get(string(def_value.name_));
114  if (x) {
115  // There is such a value already, skip it.
116  continue;
117  }
118 
119  // There isn't such a value defined, let's create the default
120  // value...
121  switch (def_value.type_) {
122  case Element::string: {
123  x.reset(new StringElement(def_value.value_, pos));
124  break;
125  }
126  case Element::integer: {
127  try {
128  int int_value = boost::lexical_cast<int>(def_value.value_);
129  x.reset(new IntElement(int_value, pos));
130  }
131  catch (const std::exception& ex) {
132  isc_throw(BadValue, "Internal error. Integer value expected for: "
133  << def_value.name_ << ", value is: "
134  << def_value.value_ );
135  }
136 
137  break;
138  }
139  case Element::boolean: {
140  bool bool_value;
141  if (def_value.value_ == string("true")) {
142  bool_value = true;
143  } else if (def_value.value_ == string("false")) {
144  bool_value = false;
145  } else {
147  "Internal error. Boolean value specified as "
148  << def_value.value_ << ", expected true or false");
149  }
150  x.reset(new BoolElement(bool_value, pos));
151  break;
152  }
153  case Element::real: {
154  double dbl_value = boost::lexical_cast<double>(def_value.value_);
155  x.reset(new DoubleElement(dbl_value, pos));
156  break;
157  }
158  default:
159  // No default values for null, list or map
161  "Internal error. Incorrect default value type.");
162  }
163 
164  // ... and insert it into the provided Element tree.
165  scope->set(def_value.name_, x);
166  ++cnt;
167  }
168 
169  return (cnt);
170 }
171 
172 size_t
173 SimpleParser::setListDefaults(isc::data::ConstElementPtr list,
174  const SimpleDefaults& default_values) {
175  size_t cnt = 0;
176  BOOST_FOREACH(ElementPtr entry, list->listValue()) {
177  cnt += setDefaults(entry, default_values);
178  }
179  return (cnt);
180 }
181 
182 size_t
183 SimpleParser::deriveParams(isc::data::ConstElementPtr parent,
184  isc::data::ElementPtr child,
185  const ParamsList& params) {
186  if ( (parent->getType() != Element::map) ||
187  (child->getType() != Element::map)) {
188  return (0);
189  }
190 
191  size_t cnt = 0;
192  BOOST_FOREACH(string param, params) {
193  ConstElementPtr x = parent->get(param);
194  if (!x) {
195  // Parent doesn't define this parameter, so there's
196  // nothing to derive from
197  continue;
198  }
199 
200  if (child->get(param)) {
201  // Child defines this parameter already. There's
202  // nothing to do here.
203  continue;
204  }
205 
206  // Copy the parameters to the child scope.
207  child->set(param, x);
208  cnt++;
209  }
210 
211  return (cnt);
212 }
213 
214 }; // end of isc::dhcp namespace
215 }; // end of isc namespace
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet)
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
const isc::data::Element::types type_
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
To be removed. Please use ConfigError instead.
Notes: IntElement type is changed to int64_t.
Definition: data.h:544
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
This array defines a single entry of default values.
Represents the position of the data element within a configuration string.
Definition: data.h:88
Defines the logger used by the top-level component of kea-dhcp-ddns.
std::vector< std::string > ParamsList
This defines a list of all parameters that are derived (or inherited) between contexts.