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
16using namespace std;
17using namespace isc::asiolink;
19
20namespace isc {
21namespace data {
22
23std::string
24SimpleParser::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
40int64_t
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
57bool
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
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
88SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) {
89 if (!parent) {
91 }
92 ConstElementPtr elem = parent->get(name);
93 if (!elem) {
94 return (parent->getPosition());
95 }
96 return (elem->getPosition());
97}
98
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
172size_t
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
182size_t
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
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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
Notes: IntElement type is changed to int64_t.
Definition: data.h:544
static size_t setListDefaults(isc::data::ConstElementPtr list, const SimpleDefaults &default_values)
Sets the default values for all entries in a list.
static const data::Element::Position & getPosition(const std::string &name, const data::ConstElementPtr parent)
Utility method that returns position of an element.
static isc::asiolink::IOAddress getAddress(const ConstElementPtr &scope, const std::string &name)
Returns a IOAddress parameter from a scope.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
static size_t deriveParams(isc::data::ConstElementPtr parent, isc::data::ElementPtr child, const ParamsList &params)
Derives (inherits) parameters from parent scope to a child.
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults &default_values)
Sets the default values.
To be removed. Please use ConfigError instead.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::vector< std::string > ParamsList
This defines a list of all parameters that are derived (or inherited) between contexts.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
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: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
This array defines a single entry of default values.
const isc::data::Element::types type_