Commit fb3488a5 authored by Jelte Jansen's avatar Jelte Jansen

updated doxy of merge()

made number parser use strol/d
added 'support' for numbers of the form '.1'
IntElement now contains long int instead of int



git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac172@2345 e5f2f494-b856-4b98-b285-d166d9295462
parent 93ef8788
...@@ -63,7 +63,7 @@ Element::toWire(std::ostream& ss) ...@@ -63,7 +63,7 @@ Element::toWire(std::ostream& ss)
// installed files we define the methods here. // installed files we define the methods here.
// //
bool bool
Element::getValue(int& t UNUSED_PARAM) { Element::getValue(long int& t UNUSED_PARAM) {
return false; return false;
} }
...@@ -93,7 +93,7 @@ Element::getValue(std::map<std::string, ElementPtr>& t UNUSED_PARAM) { ...@@ -93,7 +93,7 @@ Element::getValue(std::map<std::string, ElementPtr>& t UNUSED_PARAM) {
} }
bool bool
Element::setValue(const int v UNUSED_PARAM) { Element::setValue(const long int v UNUSED_PARAM) {
return false; return false;
} }
...@@ -209,7 +209,7 @@ Element::create() { ...@@ -209,7 +209,7 @@ Element::create() {
} }
ElementPtr ElementPtr
Element::create(const int i) { Element::create(const long int i) {
return ElementPtr(new IntElement(i)); return ElementPtr(new IntElement(i));
} }
...@@ -344,19 +344,15 @@ word_from_stringstream(std::istream &in, int& pos) { ...@@ -344,19 +344,15 @@ word_from_stringstream(std::istream &in, int& pos) {
return ss.str(); return ss.str();
} }
inline int static std::string
count_chars_i(int i) { number_from_stringstream(std::istream &in, int& pos) {
int result = 1; std::stringstream ss;
if (i < 0) { while (isdigit(in.peek()) || in.peek() == '+' || in.peek() == '-' ||
i = -i; in.peek() == '.' || in.peek() == 'e' || in.peek() == 'E') {
// account for the '-' symbol ss << (char) in.get();
result += 1;
}
while (i > 10) {
++result;
i = i / 10;
} }
return result; pos += ss.str().size();
return ss.str();
} }
// Should we change from IntElement and DoubleElement to NumberElement // Should we change from IntElement and DoubleElement to NumberElement
...@@ -364,61 +360,30 @@ count_chars_i(int i) { ...@@ -364,61 +360,30 @@ count_chars_i(int i) {
// value is larger than an int can handle) // value is larger than an int can handle)
ElementPtr ElementPtr
from_stringstream_number(std::istream &in, int &pos) { from_stringstream_number(std::istream &in, int &pos) {
int i = 0; long int i = 0;
double d = 0.0; double d = 0.0;
bool is_double = false; bool is_double = false;
char *endptr;
in >> i; std::string number = number_from_stringstream(in, pos);
pos += count_chars_i(i);
if (in.fail()) { i = strtol(number.c_str(), &endptr, 10);
isc_throw(JSONError, "Bad integer or overflow"); if (*endptr != '\0') {
} d = strtod(number.c_str(), &endptr);
if (in.peek() == '.') {
int d_i = 0;
is_double = true; is_double = true;
in.get(); if (*endptr != '\0') {
pos++; isc_throw(JSONError, std::string("Bad number: ") + number);
in >> d_i;
if (in.fail()) {
isc_throw(JSONError, "Bad real or overflow");
}
d = (double)d_i / 10;
while (d > 1.0) {
d = d / 10;
}
if (i < 0) {
d = - d;
}
d += i;
pos += count_chars_i(d_i);
}
if (in.peek() == 'e' || in.peek() == 'E') {
int e;
double p;
in.get();
pos++;
in >> e;
if (in.fail()) {
isc_throw(JSONError, "Bad exponent or overflow");
}
pos += count_chars_i(e);
p = pow(10, e);
if (p == HUGE_VAL) {
isc_throw(JSONError, "Bad exponent or overflow");
}
if (is_double) {
d = d * p;
} else { } else {
if (p > 1.0) { if (d == HUGE_VAL) {
i = i * p; isc_throw(JSONError, std::string("Number overflow: ") + number);
} else {
// negative exponent, so type becomes a double
is_double = true;
d = i * p;
} }
} }
} else {
if (i == LONG_MAX || i == LONG_MIN) {
isc_throw(JSONError, std::string("Number overflow: ") + number);
}
} }
if (is_double) { if (is_double) {
return Element::create(d); return Element::create(d);
} else { } else {
...@@ -595,11 +560,9 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos ...@@ -595,11 +560,9 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line, int& pos
case '9': case '9':
case '0': case '0':
case '-': case '-':
in.putback(c);
element = from_stringstream_number(in, pos);
el_read = true;
break;
case '+': case '+':
case '.':
in.putback(c);
element = from_stringstream_number(in, pos); element = from_stringstream_number(in, pos);
el_read = true; el_read = true;
break; break;
......
...@@ -126,7 +126,7 @@ public: ...@@ -126,7 +126,7 @@ public:
/// If you want an exception-safe getter method, use /// If you want an exception-safe getter method, use
/// getValue() below /// getValue() below
//@{ //@{
virtual int intValue() { isc_throw(TypeError, "intValue() called on non-integer Element"); }; virtual long int intValue() { isc_throw(TypeError, "intValue() called on non-integer Element"); };
virtual double doubleValue() { isc_throw(TypeError, "doubleValue() called on non-double Element"); }; virtual double doubleValue() { isc_throw(TypeError, "doubleValue() called on non-double Element"); };
virtual bool boolValue() { isc_throw(TypeError, "boolValue() called on non-Bool Element"); }; virtual bool boolValue() { isc_throw(TypeError, "boolValue() called on non-Bool Element"); };
virtual std::string stringValue() { isc_throw(TypeError, "stringValue() called on non-string Element"); }; virtual std::string stringValue() { isc_throw(TypeError, "stringValue() called on non-string Element"); };
...@@ -143,7 +143,7 @@ public: ...@@ -143,7 +143,7 @@ public:
/// data to the given reference and returning true /// data to the given reference and returning true
/// ///
//@{ //@{
virtual bool getValue(int& t); virtual bool getValue(long int& t);
virtual bool getValue(double& t); virtual bool getValue(double& t);
virtual bool getValue(bool& t); virtual bool getValue(bool& t);
virtual bool getValue(std::string& t); virtual bool getValue(std::string& t);
...@@ -159,7 +159,7 @@ public: ...@@ -159,7 +159,7 @@ public:
/// is of the correct type /// is of the correct type
/// ///
//@{ //@{
virtual bool setValue(const int v); virtual bool setValue(const long int v);
virtual bool setValue(const double v); virtual bool setValue(const double v);
virtual bool setValue(const bool t); virtual bool setValue(const bool t);
virtual bool setValue(const std::string& v); virtual bool setValue(const std::string& v);
...@@ -264,7 +264,8 @@ public: ...@@ -264,7 +264,8 @@ public:
/// represents an empty value, and is created with Element::create()) /// represents an empty value, and is created with Element::create())
//@{ //@{
static ElementPtr create(); static ElementPtr create();
static ElementPtr create(const int i); static ElementPtr create(const long int i);
static ElementPtr create(const int i) { return create(static_cast<long int>(i)); };
static ElementPtr create(const double d); static ElementPtr create(const double d);
static ElementPtr create(const bool b); static ElementPtr create(const bool b);
static ElementPtr create(const std::string& s); static ElementPtr create(const std::string& s);
...@@ -360,15 +361,15 @@ public: ...@@ -360,15 +361,15 @@ public:
}; };
class IntElement : public Element { class IntElement : public Element {
int i; long int i;
public: public:
IntElement(int v) : Element(integer), i(v) { }; IntElement(long int v) : Element(integer), i(v) { };
int intValue() { return i; } long int intValue() { return i; }
using Element::getValue; using Element::getValue;
bool getValue(int& t) { t = i; return true; }; bool getValue(long int& t) { t = i; return true; };
using Element::setValue; using Element::setValue;
bool setValue(const int v) { i = v; return true; }; bool setValue(const long int v) { i = v; return true; };
void toJSON(std::ostream& ss); void toJSON(std::ostream& ss);
bool equals(ElementPtr other); bool equals(ElementPtr other);
}; };
...@@ -499,8 +500,12 @@ void removeIdentical(ElementPtr a, const ElementPtr b); ...@@ -499,8 +500,12 @@ void removeIdentical(ElementPtr a, const ElementPtr b);
/// MapElements. /// MapElements.
/// Every string,value pair in other is copied into element /// Every string,value pair in other is copied into element
/// (the ElementPtr of value is copied, this is not a new object) /// (the ElementPtr of value is copied, this is not a new object)
/// Unless the value is an empty ElementPtr, in which case the /// Unless the value is a NullElement, in which case the
/// whole key is removed from element. /// key is removed from element, rather than setting the value to
/// the given NullElement.
/// This way, we can remove values from for instance maps with
/// configuration data (which would then result in reverting back
/// to the default).
/// Raises a TypeError if either ElementPtr is not a MapElement /// Raises a TypeError if either ElementPtr is not a MapElement
void merge(ElementPtr element, const ElementPtr other); void merge(ElementPtr element, const ElementPtr other);
......
...@@ -135,6 +135,7 @@ TEST(Element, from_and_to_json) { ...@@ -135,6 +135,7 @@ TEST(Element, from_and_to_json) {
EXPECT_EQ("100", Element::fromJSON("+1e2")->str()); EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
EXPECT_EQ("-100", Element::fromJSON("-1e2")->str()); EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str()); EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str()); EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str());
EXPECT_EQ("1.2", Element::fromJSON("1.2")->str()); EXPECT_EQ("1.2", Element::fromJSON("1.2")->str());
EXPECT_EQ("1", Element::fromJSON("1.0")->str()); EXPECT_EQ("1", Element::fromJSON("1.0")->str());
...@@ -153,7 +154,6 @@ TEST(Element, from_and_to_json) { ...@@ -153,7 +154,6 @@ TEST(Element, from_and_to_json) {
// number overflows // number overflows
EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError); EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
EXPECT_THROW(Element::fromJSON("1.12345678901234567890")->str(), JSONError);
EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError); EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError); EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError); EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);
...@@ -164,7 +164,7 @@ TEST(Element, create_and_value_throws) { ...@@ -164,7 +164,7 @@ TEST(Element, create_and_value_throws) {
// this test checks whether elements throw exceptions if the // this test checks whether elements throw exceptions if the
// incorrect type is requested // incorrect type is requested
ElementPtr el; ElementPtr el;
int i; long int i;
double d; double d;
bool b; bool b;
std::string s("asdf"); std::string s("asdf");
......
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
virtual void readData(void* data, size_t datalen) = 0; virtual void readData(void* data, size_t datalen) = 0;
virtual void startRead(boost::function<void()> user_handler) = 0; virtual void startRead(boost::function<void()> user_handler) = 0;
int sequence_; // the next sequence number to use long int sequence_; // the next sequence number to use
std::string lname_; std::string lname_;
ElementPtr queue_; ElementPtr queue_;
}; };
...@@ -458,7 +458,7 @@ Session::group_sendmsg(ElementPtr msg, std::string group, ...@@ -458,7 +458,7 @@ Session::group_sendmsg(ElementPtr msg, std::string group,
std::string instance, std::string to) std::string instance, std::string to)
{ {
ElementPtr env = Element::createMap(); ElementPtr env = Element::createMap();
int nseq = ++impl_->sequence_; long int nseq = ++impl_->sequence_;
env->set("type", Element::create("send")); env->set("type", Element::create("send"));
env->set("from", Element::create(impl_->lname_)); env->set("from", Element::create(impl_->lname_));
...@@ -482,7 +482,7 @@ Session::group_recvmsg(ElementPtr& envelope, ElementPtr& msg, ...@@ -482,7 +482,7 @@ Session::group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
int int
Session::reply(ElementPtr& envelope, ElementPtr& newmsg) { Session::reply(ElementPtr& envelope, ElementPtr& newmsg) {
ElementPtr env = Element::createMap(); ElementPtr env = Element::createMap();
int nseq = ++impl_->sequence_; long int nseq = ++impl_->sequence_;
env->set("type", Element::create("send")); env->set("type", Element::create("send"));
env->set("from", Element::create(impl_->lname_)); env->set("from", Element::create(impl_->lname_));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment