[svn] commit: r2296 - in /branches/trac172/src/lib/cc: data.cc data.h data_unittests.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Jun 27 19:37:00 UTC 2010
Author: jelte
Date: Sun Jun 27 19:37:00 2010
New Revision: 2296
Log:
addressed review comments 2 of 3 (or 4)
Modified:
branches/trac172/src/lib/cc/data.cc
branches/trac172/src/lib/cc/data.h
branches/trac172/src/lib/cc/data_unittests.cc
Modified: branches/trac172/src/lib/cc/data.cc
==============================================================================
--- branches/trac172/src/lib/cc/data.cc (original)
+++ branches/trac172/src/lib/cc/data.cc Sun Jun 27 19:37:00 2010
@@ -29,6 +29,8 @@
#include <cmath>
using namespace std;
+
+#define MAX_LABEL_LENGTH 255
namespace isc {
namespace data {
@@ -347,6 +349,11 @@
inline int
count_chars_i(int i) {
int result = 1;
+ if (i < 0) {
+ i = -i;
+ // account for the '-' symbol
+ result += 1;
+ }
while (i > 10) {
++result;
i = i / 10;
@@ -359,7 +366,7 @@
// value is larger than an int can handle)
ElementPtr
from_stringstream_number(std::istream &in, int &pos) {
- int i, d_i;
+ int i = 0;
double d = 0.0;
bool is_double = false;
@@ -369,6 +376,7 @@
isc_throw(JSONError, "Bad integer or overflow");
}
if (in.peek() == '.') {
+ int d_i = 0;
is_double = true;
in.get();
pos++;
@@ -376,7 +384,14 @@
if (in.fail()) {
isc_throw(JSONError, "Bad real or overflow");
}
- d = i + (double)d_i / 10;
+ 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') {
@@ -481,11 +496,6 @@
} else {
while (c != EOF && c != '}') {
std::string key = str_from_stringstream(in, file, line, pos);
- if (key.length() > 255) {
- // Map tag has one-byte length field in wire format, so the
- // length cannot exceed 255.
- throwJSONError("Map tag is too long", file, line, pos);
- }
skip_to(in, file, line, pos, ":", " \t\n");
// skip the :
@@ -502,6 +512,54 @@
}
return map;
}
+}
+
+std::string
+Element::typeToName(Element::types type)
+{
+ switch(type) {
+ case Element::integer:
+ return std::string("integer");
+ case Element::real:
+ return std::string("real");
+ case Element::boolean:
+ return std::string("boolean");
+ case Element::string:
+ return std::string("string");
+ case Element::list:
+ return std::string("list");
+ case Element::map:
+ return std::string("map");
+ case Element::null:
+ return std::string("null");
+ case Element::any:
+ return std::string("any");
+ default:
+ return std::string("unknown");
+ }
+}
+
+Element::types
+Element::nameToType(const std::string& type_name) {
+ if (type_name == "integer") {
+ return Element::integer;
+ } else if (type_name == "real") {
+ return Element::real;
+ } else if (type_name == "boolean") {
+ return Element::boolean;
+ } else if (type_name == "string") {
+ return Element::string;
+ } else if (type_name == "list") {
+ return Element::list;
+ } else if (type_name == "map") {
+ return Element::map;
+ } else if (type_name == "null") {
+ return Element::null;
+ } else if (type_name == "any") {
+ return Element::any;
+ } else {
+ isc_throw(TypeError, type_name + " is not a valid type name");
+ }
}
ElementPtr
@@ -538,7 +596,12 @@
case '8':
case '9':
case '0':
+ case '-':
in.putback(c);
+ element = from_stringstream_number(in, pos);
+ el_read = true;
+ break;
+ case '+':
element = from_stringstream_number(in, pos);
el_read = true;
break;
@@ -551,6 +614,7 @@
el_read = true;
break;
case 'n':
+ case 'N':
in.putback(c);
element = from_stringstream_null(in, file, line, pos);
el_read = true;
@@ -606,7 +670,7 @@
void
BoolElement::toJSON(std::ostream& ss)
{
- if (b) {
+ if (boolValue()) {
ss << "true";
} else {
ss << "false";
@@ -714,11 +778,7 @@
void
MapElement::set(const std::string& key, ElementPtr value) {
- if (key.length() <= 255) {
- m[key] = value;
- } else {
- isc_throw(TypeError, "Map key too long");
- }
+ m[key] = value;
}
bool
Modified: branches/trac172/src/lib/cc/data.h
==============================================================================
--- branches/trac172/src/lib/cc/data.h (original)
+++ branches/trac172/src/lib/cc/data.h Sun Jun 27 19:37:00 2010
@@ -315,6 +315,22 @@
// make this one private?
static ElementPtr fromJSON(std::istream& in, const std::string& file, int& line, int &pos) throw(JSONError);
//@}
+
+ /// \name Type name conversion functions
+
+ /// Returns the name of the given type as a string
+ ///
+ /// \param type The type to return the name of
+ /// \return The name of the type, or "unknown" if the type
+ /// is not known.
+ static std::string typeToName(Element::types type);
+
+ /// Converts the string to the corresponding type
+ /// Throws a TypeError if the name is unknown.
+ ///
+ /// \param type_name The name to get the type of
+ /// \return the corresponding type value
+ static Element::types nameToType(const std::string& type_name);
/// \name Wire format factory functions
Modified: branches/trac172/src/lib/cc/data_unittests.cc
==============================================================================
--- branches/trac172/src/lib/cc/data_unittests.cc (original)
+++ branches/trac172/src/lib/cc/data_unittests.cc Sun Jun 27 19:37:00 2010
@@ -47,6 +47,28 @@
}
+TEST(Element, TypeNameConversion) {
+ EXPECT_EQ(Element::integer, Element::nameToType("integer"));
+ EXPECT_EQ(Element::real, Element::nameToType("real"));
+ EXPECT_EQ(Element::boolean, Element::nameToType("boolean"));
+ EXPECT_EQ(Element::string, Element::nameToType("string"));
+ EXPECT_EQ(Element::list, Element::nameToType("list"));
+ EXPECT_EQ(Element::map, Element::nameToType("map"));
+ EXPECT_EQ(Element::null, Element::nameToType("null"));
+ EXPECT_EQ(Element::any, Element::nameToType("any"));
+ EXPECT_THROW(Element::nameToType("somethingunknown"), TypeError);
+
+ EXPECT_EQ("integer", Element::typeToName(Element::integer));
+ EXPECT_EQ("real", Element::typeToName(Element::real));
+ EXPECT_EQ("boolean", Element::typeToName(Element::boolean));
+ EXPECT_EQ("string", Element::typeToName(Element::string));
+ EXPECT_EQ("list", Element::typeToName(Element::list));
+ EXPECT_EQ("map", Element::typeToName(Element::map));
+ EXPECT_EQ("null", Element::typeToName(Element::null));
+ EXPECT_EQ("any", Element::typeToName(Element::any));
+ EXPECT_EQ("unknown", Element::typeToName((Element::types)123));
+}
+
TEST(Element, from_and_to_json) {
// this test checks whether the str() method returns the same
// string that was used for creation
@@ -62,7 +84,13 @@
sv.push_back("[ 1, 2, 3, 4 ]");
sv.push_back("{ \"name\": \"foo\", \"value\": 47806 }");
sv.push_back("[ { \"a\": 1, \"b\": \"c\" }, { \"a\": 2, \"b\": \"d\" } ]");
-
+ sv.push_back("8.23");
+ sv.push_back("123.456");
+ sv.push_back("null");
+ sv.push_back("-1");
+ sv.push_back("-1.234");
+ sv.push_back("-123.456");
+
BOOST_FOREACH(std::string s, sv) {
// test << operator, which uses Element::str()
std::ostringstream stream;
@@ -101,8 +129,12 @@
// some json specific format tests, here the str() output is
// different from the string input
+ EXPECT_EQ("100", Element::fromJSON("+100")->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("1.2", Element::fromJSON("1.2")->str());
EXPECT_EQ("1", Element::fromJSON("1.0")->str());
EXPECT_EQ("120", Element::fromJSON("1.2e2")->str());
@@ -111,6 +143,12 @@
EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
+ EXPECT_EQ("null", Element::fromJSON("Null")->str());
+ EXPECT_EQ("null", Element::fromJSON("NULL")->str());
+ EXPECT_EQ("false", Element::fromJSON("False")->str());
+ EXPECT_EQ("false", Element::fromJSON("FALSE")->str());
+ EXPECT_EQ("true", Element::fromJSON("True")->str());
+ EXPECT_EQ("true", Element::fromJSON("TRUE")->str());
// number overflows
EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
@@ -326,13 +364,11 @@
el->set(long_maptag, Element::create("bar"));
EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
- // A one-byte longer tag should trigger an exception.
+ // A one-byte longer tag should still be allowed
long_maptag.push_back('f');
- EXPECT_THROW(Element::fromJSON("{ \"" + long_maptag +
- "\": \"bar\"}"),
- JSONError);
-
- EXPECT_THROW(el->set(long_maptag, Element::create("bar")), TypeError);
+ el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
+ el->set(long_maptag, Element::create("bar"));
+ EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
}
More information about the bind10-changes
mailing list