return (false);
}
+bool
+Element::setValue(isc::util::int128_t const&) {
+ return (false);
+}
+
bool
Element::setValue(const double) {
return (false);
return (ElementPtr(new IntElement(static_cast<int64_t>(i), pos)));
}
+ElementPtr
+Element::create(const isc::util::int128_t& i, const Position& pos) {
+ return (ElementPtr(new BigIntElement(i, pos)));
+}
+
ElementPtr
Element::create(const int i, const Position& pos) {
return (create(static_cast<long long int>(i), pos));
switch (type) {
case Element::integer:
return (std::string("integer"));
+ case Element::bigint:
+ return (std::string("bigint"));
case Element::real:
return (std::string("real"));
case Element::boolean:
Element::nameToType(const std::string& type_name) {
if (type_name == "integer") {
return (Element::integer);
+ } else if (type_name == "bigint") {
+ return (Element::bigint);
} else if (type_name == "real") {
return (Element::real);
} else if (type_name == "boolean") {
ss << intValue();
}
+void
+BigIntElement::toJSON(std::ostream& ss) const {
+ ss << bigIntValue();
+}
+
void
DoubleElement::toJSON(std::ostream& ss) const {
// The default output for doubles nicely drops off trailing
bool
IntElement::equals(const Element& other) const {
- return (other.getType() == Element::integer) &&
- (i == other.intValue());
+ // Let's not be very picky with constraining the integer types to be the
+ // same. Equality is sometimes checked from high-up in the Element hierarcy.
+ // That is a context which, most of the time, does not have information on
+ // the type of integers stored on Elements lower in the hierarchy. So it
+ // would be difficult to differentiate between the integer types.
+ return (other.getType() == Element::integer && i == other.intValue()) ||
+ (other.getType() == Element::bigint && i == other.bigIntValue());
+}
+
+bool
+BigIntElement::equals(const Element& other) const {
+ // Let's not be very picky with constraining the integer types to be the
+ // same. Equality is sometimes checked from high-up in the Element hierarcy.
+ // That is a context which, most of the time, does not have information on
+ // the type of integers stored on Elements lower in the hierarchy. So it
+ // would be difficult to differentiate between the integer types.
+ return (other.getType() == Element::bigint && i_ == other.bigIntValue()) ||
+ (other.getType() == Element::integer && i_ == other.intValue());
}
bool
#ifndef ISC_DATA_H
#define ISC_DATA_H 1
+#include <util/bigints.h>
+
#include <iostream>
#include <map>
#include <stdexcept>
return (position);
}
- // any is a special type used in list specifications, specifying
- // that the elements can be of any type
- enum types { integer, real, boolean, null, string, list, map, any };
+ /// @brief The types that an Element can hold
+ ///
+ /// Some of these types need to match their associated integer from the
+ /// parameter_data_type database table, so let the enums be explicitly
+ /// mapped to integers, to reduce the chance of messing up.
+ ///
+ /// any is a special type used in list specifications, specifying that the
+ /// elements can be of any type.
+ enum types {
+ integer = 0,
+ real = 1,
+ boolean = 2,
+ null = 3,
+ string = 4,
+ bigint = 5,
+ list = 6,
+ map = 7,
+ any = 8,
+ };
private:
// technically the type could be omitted; is it useful?
//@{
virtual int64_t intValue() const
{ throwTypeError("intValue() called on non-integer Element"); };
+ virtual isc::util::int128_t bigIntValue() const {
+ throwTypeError("bigIntValue() called on non-big-integer Element");
+ }
virtual double doubleValue() const
{ throwTypeError("doubleValue() called on non-double Element"); };
virtual bool boolValue() const
/// long long int, long int and int.
//@{
virtual bool setValue(const long long int v);
+ virtual bool setValue(const isc::util::int128_t& v);
bool setValue(const long int i) { return (setValue(static_cast<long long int>(i))); };
bool setValue(const int i) { return (setValue(static_cast<long long int>(i))); };
virtual bool setValue(const double v);
static ElementPtr create(const Position& pos = ZERO_POSITION());
static ElementPtr create(const long long int i,
const Position& pos = ZERO_POSITION());
+ static ElementPtr create(const isc::util::int128_t& i,
+ const Position& pos = ZERO_POSITION());
static ElementPtr create(const int i,
const Position& pos = ZERO_POSITION());
static ElementPtr create(const long int i,
bool equals(const Element& other) const;
};
+/// @brief Wrapper over int128_t
+class BigIntElement : public Element {
+ using int128_t = isc::util::int128_t;
+ using Element::getValue;
+ using Element::setValue;
+
+public:
+ /// @brief Constructor
+ BigIntElement(const int128_t& v, const Position& pos = ZERO_POSITION())
+ : Element(bigint, pos), i_(v) {
+ }
+
+ /// @brief Retrieve the underlying big integer value.
+ ///
+ /// @return the underlying value
+ int128_t bigIntValue() const override {
+ return (i_);
+ }
+
+ /// @brief Sets the underlying big integer value.
+ ///
+ /// @return true for no reason
+ bool setValue(const int128_t& v) override {
+ i_ = v;
+ return (true);
+ }
+
+ /// @brief Converts the Element to JSON format and appends it to the given
+ /// stringstream.
+ void toJSON(std::ostream& ss) const override;
+
+ /// @brief Checks whether the other Element has the same type and value.
+ bool equals(const Element& other) const override;
+
+private:
+ /// @brief the underlying stored value
+ int128_t i_;
+};
+
class DoubleElement : public Element {
double d;
-// Copyright (C) 2009-2022 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2023 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
TEST(Element, TypeNameConversion) {
EXPECT_EQ(Element::integer, Element::nameToType("integer"));
+ EXPECT_EQ(Element::bigint, Element::nameToType("bigint"));
EXPECT_EQ(Element::real, Element::nameToType("real"));
EXPECT_EQ(Element::boolean, Element::nameToType("boolean"));
EXPECT_EQ(Element::string, Element::nameToType("string"));
EXPECT_THROW(Element::nameToType("somethingunknown"), TypeError);
EXPECT_EQ("integer", Element::typeToName(Element::integer));
+ EXPECT_EQ("bigint", Element::typeToName(Element::bigint));
EXPECT_EQ("real", Element::typeToName(Element::real));
EXPECT_EQ("boolean", Element::typeToName(Element::boolean));
EXPECT_EQ("string", Element::typeToName(Element::string));