Kea 2.5.9
stamped_value.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2024 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/stamped_value.h>
11#include <boost/lexical_cast.hpp>
12
13namespace isc {
14namespace data {
15
16StampedValue::StampedValue(const std::string& name)
17 : StampedElement(), name_(name), value_() {
18}
19
20StampedValue::StampedValue(const std::string& name, const ElementPtr& value)
21 : StampedElement(), name_(name), value_(value) {
22 validateConstruct();
23}
24
25StampedValue::StampedValue(const std::string& name, const std::string& value)
26 : StampedElement(), name_(name), value_(Element::create(value)) {
27 validateConstruct();
28}
29
31StampedValue::create(const std::string& name) {
32 return (StampedValuePtr(new StampedValue(name)));
33}
34
36StampedValue::create(const std::string& name, const ElementPtr& value) {
37 return (StampedValuePtr(new StampedValue(name, value)));
38}
39
41StampedValue::create(const std::string& name, const std::string& value) {
42 return (StampedValuePtr(new StampedValue(name, value)));
43}
44
46StampedValue::create(const std::string& name, const std::string& value,
47 Element::types parameter_type) {
48 StampedValuePtr stamped_value;
49
50 try {
51 switch (parameter_type) {
52 case Element::string:
53 stamped_value = StampedValue::create(name, value);
54 break;
55
57 stamped_value = StampedValue::create(name,
58 Element::create(boost::lexical_cast<int64_t>(value)));
59 break;
60
62 // We only allow "1" and "0" as input to this function.
63 if ((value != "0") && (value != "1")) {
64 isc_throw(BadValue, "StampedValue: invalid value " << value
65 << " specified as boolean. Expected \"0\" or \"1\"");
66 }
67 stamped_value = StampedValue::create(name,
68 Element::create((value == "0") ? false : true));
69 break;
70
71 case Element::real:
72 stamped_value = StampedValue::create(name,
73 Element::create(boost::lexical_cast<double>(value)));
74 break;
75
76 default:
77 // Invalid data type provided as argument.
78 isc_throw(TypeError, "StampedValue: unsupported type '"
79 << Element::typeToName(parameter_type)
80 << " of the parameter '" << name);
81 }
82
83 } catch (const boost::bad_lexical_cast& ex) {
84 // Failed to cast the value to a given type.
85 isc_throw(BadValue, "StampedValue: the value of the parameter '"
86 << Element::typeToName(parameter_type)
87 << "' can't be converted to "
88 << Element::typeToName(parameter_type)
89 << " type");
90 }
91
92 return (stamped_value);
93}
94
95int
97 if (!value_) {
98 isc_throw(InvalidOperation, "StampedValue: attempt to retrieve the "
99 "type of the null value for the '" << name_
100 << "' parameter");
101 }
102
103 return (value_->getType());
104}
105
106std::string
108 validateAccess(Element::string);
109
110 try {
111 switch (static_cast<Element::types>(value_->getType())) {
112 case Element::string:
113 return (value_->stringValue());
114 case Element::integer:
115 return (boost::lexical_cast<std::string>(value_->intValue()));
116 case Element::boolean:
117 return (value_->boolValue() ? "1" : "0");
118 case Element::real:
119 {
120 std::string repr =
121 boost::lexical_cast<std::string>(value_->doubleValue());
122 if (repr.find_first_of('.') == std::string::npos) {
123 repr += ".0";
124 }
125 return (repr);
126 }
127 default:
128 // Impossible condition.
129 isc_throw(TypeError, "StampedValue: invalid type of the '"
130 << name_ << "' parameter");
131 }
132
133 } catch (const boost::bad_lexical_cast& ex) {
134 isc_throw(BadValue, "StampedValue: unable to convert the value of "
135 "the parameter '" << name_ << "' to string");
136 }
137 // unreachable
138 return (value_->stringValue());
139}
140
141int64_t
143 validateAccess(Element::integer);
144 return (value_->intValue());
145}
146
147bool
149 validateAccess(Element::boolean);
150 return (value_->boolValue());
151}
152
153double
155 validateAccess(Element::real);
156 return (value_->doubleValue());
157}
158
159void
160StampedValue::validateConstruct() const {
161 if (!value_) {
162 isc_throw(BadValue, "StampedValue: provided value of the '"
163 << name_ << "' parameter is NULL");
164 }
165
166 auto type = value_->getType();
167 if ((type != Element::string) &&
168 (type != Element::integer) &&
169 (type != Element::boolean) &&
170 (type != Element::real) &&
171 (type != Element::map)) {
172 isc_throw(TypeError, "StampedValue: provided value of the '"
173 << name_ << "' parameter has invalid type: "
174 << Element::typeToName(type));
175 }
176
177 if (type == Element::map) {
178 size_t count = value_->mapValue().size();
179 if (count > 1) {
180 isc_throw(BadValue, "StampedValue: provided value of the '"
181 << name_ << "' parameter has more than one element in the map");
182 }
183 if (count == 1) {
184 type = value_->mapValue().begin()->second->getType();
185 if ((type != Element::string) &&
186 (type != Element::integer) &&
187 (type != Element::boolean) &&
188 (type != Element::real)) {
189 isc_throw(BadValue, "StampedValue: provided value of the '"
190 << name_ << "." << value_->mapValue().begin()->first
191 << "' parameter has invalid type: "
192 << Element::typeToName(type));
193 }
194 }
195 }
196}
197
198void
199StampedValue::validateAccess(Element::types type) const {
200 if (!value_) {
201 isc_throw(InvalidOperation, "StampedValue: attempt to get null value "
202 "of the '" << name_ << "' parameter");
203 }
204
205 if ((type != Element::string) && (type != value_->getType())) {
206 isc_throw(TypeError, "StampedValue: attempt to access a '"
207 << name_ << "' parameter as " << Element::typeToName(type)
208 << ", but this parameter has "
209 << Element::typeToName(value_->getType())
210 << " type");
211 }
212}
213
214} // end of namespace isc::data
215} // end of namespace isc
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.
The Element class represents a piece of data, used by the command channel and configuration parts.
Definition: data.h:72
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:249
types
The types that an Element can hold.
Definition: data.h:139
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition: data.cc:651
This class represents configuration element which is associated with database identifier,...
This class represents a named configuration parameter, e.g.
Definition: stamped_value.h:41
double getDoubleValue() const
Returns value as a real number.
bool getBoolValue() const
Returns value as a boolean.
StampedValue(const std::string &name)
Constructor creating a null value.
std::string getValue() const
Returns value as string.
int getType() const
Returns a type of the value.
int64_t getIntegerValue() const
Returns value as signed integer.
static StampedValuePtr create(const std::string &name)
Factory function creating a null value.
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
Definition: data.h:36
const Name & name_
Definition: dns/message.cc:696
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< StampedValue > StampedValuePtr
Pointer to the stamped value.
Definition: stamped_value.h:26
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
Defines the logger used by the top-level component of kea-lfc.