Commit ab6751e3 authored by Jelte Jansen's avatar Jelte Jansen

empty constructors for lists and maps, and corresponding 'factory' functions...

empty constructors for lists and maps, and corresponding 'factory' functions Element::createList() and Element::createMap()


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac172@2112 e5f2f494-b856-4b98-b285-d166d9295462
parent e8e56447
......@@ -274,7 +274,7 @@ AuthSrvImpl::setDbFile(const isc::data::ElementPtr config) {
string item("database_file");
ElementPtr value = cs_->getValue(is_default, item);
db_file_ = value->stringValue();
final = Element::createFromString("{}");
final = Element::createMap();
final->set(item, value);
} else {
return (answer);
......
......@@ -250,19 +250,13 @@ Element::create(const bool b) {
}
ElementPtr
Element::create(const std::vector<ElementPtr>& v) {
return ElementPtr(new ListElement(v));
Element::createList() {
return ElementPtr(new ListElement());
}
ElementPtr
Element::create(const std::map<std::string, ElementPtr>& m) {
for (std::map<std::string, ElementPtr>::const_iterator it = m.begin();
it != m.end(); ++it) {
if ((*it).first.length() > 255) {
isc_throw(TypeError, "Map tag is too long");
}
}
return ElementPtr(new MapElement(m));
Element::createMap() {
return ElementPtr(new MapElement());
}
......@@ -477,27 +471,27 @@ ElementPtr
from_stringstream_list(std::istream &in, const std::string& file, int& line, int& pos)
{
char c = 0;
std::vector<ElementPtr> v;
ElementPtr list = Element::createList();
ElementPtr cur_list_element;
skip_chars(in, " \t\n", line, pos);
while (c != EOF && c != ']') {
if (in.peek() != ']') {
cur_list_element = Element::createFromString(in, file, line, pos);
v.push_back(cur_list_element);
list->add(cur_list_element);
skip_to(in, file, line, pos, ",]", " \t\n");
}
c = in.get();
pos++;
}
return Element::create(v);
return list;
}
ElementPtr
from_stringstream_map(std::istream &in, const std::string& file, int& line,
int& pos)
{
std::map<std::string, ElementPtr> m;
ElementPtr map = Element::createMap();
skip_chars(in, " \t\n", line, pos);
char c = in.peek();
if (c == '}') {
......@@ -505,10 +499,8 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
c = in.get();
} else {
while (c != EOF && c != '}') {
std::pair<std::string, ElementPtr> p;
p.first = str_from_stringstream(in, file, line, pos);
if (p.first.length() > 255) {
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.
throwParseError("Map tag is too long", file, line, pos);
......@@ -518,14 +510,16 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
// skip the :
in.get();
pos++;
p.second = Element::createFromString(in, file, line, pos);
m.insert(p);
ElementPtr value = Element::createFromString(in, file, line, pos);
map->set(key, value);
skip_to(in, file, line, pos, ",}", " \t\n");
c = in.get();
pos++;
}
}
return Element::create(m);
return map;
}
}
......@@ -737,6 +731,15 @@ Element::fromWire(std::stringstream& in, int length) {
return createFromString(in, "<wire>", line, pos);
}
void
MapElement::set(const std::string& key, ElementPtr value) {
if (key.length() <= 255) {
m[key] = value;
} else {
isc_throw(TypeError, "Map key too long");
}
}
bool
MapElement::find(const std::string& id, ElementPtr& t) {
try {
......
......@@ -272,9 +272,12 @@ public:
static ElementPtr create(const std::string& s);
// need both std:string and char *, since c++ will match
// bool before std::string when you pass it a char *
static ElementPtr create(const char *s) { return create(std::string(s)); };
static ElementPtr create(const std::vector<ElementPtr>& v);
static ElementPtr create(const std::map<std::string, ElementPtr>& m);
static ElementPtr create(const char *s) { return create(std::string(s)); };
/// \brief Creates an empty ListElement type ElementPtr.
static ElementPtr createList();
/// \brief Creates an empty MapElement type ElementPtr.
static ElementPtr createMap();
//@}
/// \name Compound factory functions
......@@ -404,7 +407,7 @@ class ListElement : public Element {
std::vector<ElementPtr> l;
public:
ListElement(std::vector<ElementPtr> v) : Element(list), l(v) {};
ListElement() : Element(list), l(std::vector<ElementPtr>()) {};
const std::vector<ElementPtr>& listValue() { return l; }
using Element::getValue;
bool getValue(std::vector<ElementPtr>& t) { t = l; return true; };
......@@ -426,7 +429,8 @@ class MapElement : public Element {
std::map<std::string, ElementPtr> m;
public:
MapElement(const std::map<std::string, ElementPtr>& v) : Element(map), m(v) {};
MapElement() : Element(map), m(std::map<std::string, ElementPtr>()) {};
// TODO: should we have direct iterators instead of exposing the std::map here?
const std::map<std::string, ElementPtr>& mapValue() { return m; }
using Element::getValue;
bool getValue(std::map<std::string, ElementPtr>& t) { t = m; return true; };
......@@ -435,7 +439,7 @@ public:
using Element::get;
ElementPtr get(const std::string& s) { if (contains(s)) { return m[s]; } else { return ElementPtr();} };
using Element::set;
void set(const std::string& s, ElementPtr p) { m[s] = p; };
void set(const std::string& key, ElementPtr value);
using Element::remove;
void remove(const std::string& s) { m.erase(s); }
bool contains(const std::string& s) { return m.find(s) != m.end(); }
......
......@@ -40,11 +40,9 @@ TEST(Element, type) {
EXPECT_EQ(bool_el.getType(), Element::boolean);
StringElement str_el = StringElement("foo");
EXPECT_EQ(str_el.getType(), Element::string);
std::vector<ElementPtr> v;
ListElement list_el = ListElement(v);
ListElement list_el = ListElement();
EXPECT_EQ(list_el.getType(), Element::list);
std::map<std::string, ElementPtr> m;
MapElement map_el = MapElement(m);
MapElement map_el = MapElement();
EXPECT_EQ(map_el.getType(), Element::map);
}
......@@ -139,16 +137,14 @@ TEST(Element, create_and_value_throws) {
EXPECT_THROW(el->listValue(), TypeError);
EXPECT_THROW(el->mapValue(), TypeError);
std::vector<ElementPtr> v;
el = Element::create(v);
el = Element::createList();
EXPECT_THROW(el->intValue(), TypeError);
EXPECT_THROW(el->doubleValue(), TypeError);
EXPECT_THROW(el->boolValue(), TypeError);
EXPECT_THROW(el->stringValue(), TypeError);
EXPECT_THROW(el->mapValue(), TypeError);
std::map<std::string, ElementPtr> m;
el = Element::create(m);
el = Element::createMap();
EXPECT_THROW(el->intValue(), TypeError);
EXPECT_THROW(el->doubleValue(), TypeError);
EXPECT_THROW(el->boolValue(), TypeError);
......@@ -222,14 +218,13 @@ TEST(Element, MapElement) {
"9123456789abcdefa123456789abcdefb123456789abcdef"
"c123456789abcdefd123456789abcdefe123456789abcdef"
"f123456789abcde");
std::map<std::string, ElementPtr> long_maptag_map;
EXPECT_EQ(255, long_maptag.length()); // check prerequisite
el = Element::createFromString("{ \"" + long_maptag + "\": \"bar\"}");
EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
long_maptag_map[long_maptag] = Element::create("bar");
el = Element::create(long_maptag_map);
el = Element::createMap();
el->set(long_maptag, Element::create("bar"));
EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
// A one-byte longer tag should trigger an exception.
......@@ -238,8 +233,7 @@ TEST(Element, MapElement) {
"\": \"bar\"}"),
ParseError);
long_maptag_map[long_maptag] = Element::create("bar");
EXPECT_THROW(Element::create(long_maptag_map), TypeError);
EXPECT_THROW(el->set(long_maptag, Element::create("bar")), TypeError);
}
......@@ -314,27 +308,27 @@ TEST(Element, equals) {
}
TEST(Element, removeIdentical) {
ElementPtr a = Element::createFromString("{}");
ElementPtr b = Element::createFromString("{}");
ElementPtr c = Element::createFromString("{}");
ElementPtr a = Element::createMap();
ElementPtr b = Element::createMap();
ElementPtr c = Element::createMap();
removeIdentical(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": 1 }");
b = Element::createFromString("{ \"a\": 1 }");
c = Element::createFromString("{}");
c = Element::createMap();
removeIdentical(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
b = Element::createFromString("{}");
b = Element::createMap();
c = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
removeIdentical(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
b = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
c = Element::createFromString("{}");
c = Element::createMap();
removeIdentical(a, b);
EXPECT_TRUE(a == c);
......@@ -345,14 +339,14 @@ TEST(Element, removeIdentical) {
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
b = Element::createFromString("{}");
b = Element::createMap();
c = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
removeIdentical(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
b = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
c = Element::createFromString("{}");
c = Element::createMap();
removeIdentical(a, b);
EXPECT_TRUE(a == c);
......@@ -365,17 +359,17 @@ TEST(Element, removeIdentical) {
TEST(Element, merge)
{
ElementPtr a = Element::createFromString("{}");
ElementPtr b = Element::createFromString("{}");
ElementPtr c = Element::createFromString("{}");
ElementPtr a = Element::createMap();
ElementPtr b = Element::createMap();
ElementPtr c = Element::createMap();
merge(a, b);
EXPECT_TRUE(a == c);
a = Element::createFromString("1");
b = Element::createFromString("{}");
b = Element::createMap();
EXPECT_THROW(merge(a, b), TypeError);
a = Element::createFromString("{}");
a = Element::createMap();
b = Element::createFromString("{ \"a\": 1 }");
c = Element::createFromString("{ \"a\": 1 }");
merge(a, b);
......
......@@ -56,7 +56,7 @@ namespace cc {
class SessionImpl {
public:
SessionImpl() : sequence_(-1) { queue_ = Element::createFromString("[]"); }
SessionImpl() : sequence_(-1) { queue_ = Element::createList(); }
virtual ~SessionImpl() {}
virtual void establish(const char& socket_file) = 0;
virtual int getSocket() = 0;
......@@ -422,7 +422,7 @@ Session::recvmsg(ElementPtr& env, ElementPtr& msg,
msg = l_msg;
return true;
} else {
ElementPtr q_el = Element::createFromString("[]");
ElementPtr q_el = Element::createList();
q_el->add(l_env);
q_el->add(l_msg);
impl_->queue_->add(q_el);
......@@ -433,7 +433,7 @@ Session::recvmsg(ElementPtr& env, ElementPtr& msg,
void
Session::subscribe(std::string group, std::string instance) {
ElementPtr env = Element::create(std::map<std::string, ElementPtr>());
ElementPtr env = Element::createMap();
env->set("type", Element::create("subscribe"));
env->set("group", Element::create(group));
......@@ -444,7 +444,7 @@ Session::subscribe(std::string group, std::string instance) {
void
Session::unsubscribe(std::string group, std::string instance) {
ElementPtr env = Element::create(std::map<std::string, ElementPtr>());
ElementPtr env = Element::createMap();
env->set("type", Element::create("unsubscribe"));
env->set("group", Element::create(group));
......@@ -457,7 +457,7 @@ int
Session::group_sendmsg(ElementPtr msg, std::string group,
std::string instance, std::string to)
{
ElementPtr env = Element::create(std::map<std::string, ElementPtr>());
ElementPtr env = Element::createMap();
int nseq = ++impl_->sequence_;
env->set("type", Element::create("send"));
......@@ -481,7 +481,7 @@ Session::group_recvmsg(ElementPtr& envelope, ElementPtr& msg,
int
Session::reply(ElementPtr& envelope, ElementPtr& newmsg) {
ElementPtr env = Element::create(std::map<std::string, ElementPtr>());
ElementPtr env = Element::createMap();
int nseq = ++impl_->sequence_;
env->set("type", Element::create("send"));
......
......@@ -125,8 +125,8 @@ createCommand(const std::string& command)
ElementPtr
createCommand(const std::string& command, ElementPtr arg)
{
ElementPtr cmd = Element::createFromString("{}");
ElementPtr cmd_parts = Element::createFromString("[]");
ElementPtr cmd = Element::createMap();
ElementPtr cmd_parts = Element::createList();
cmd_parts->add(Element::create(command));
if (arg) {
cmd_parts->add(arg);
......@@ -274,7 +274,7 @@ ElementPtr
ModuleCCSession::handleConfigUpdate(ElementPtr new_config)
{
ElementPtr answer;
ElementPtr errors = Element::createFromString("[]");
ElementPtr errors = Element::createList();
if (!config_handler_) {
answer = createAnswer(1, module_name_ + " does not have a config handler");
} else if (!module_specification_.validate_config(new_config, false, errors)) {
......
......@@ -158,7 +158,7 @@ ConfigData::getValue(bool& is_default, const std::string& identifier)
ElementPtr
ConfigData::getItemList(const std::string& identifier, bool recurse)
{
ElementPtr result = Element::createFromString("[]");
ElementPtr result = Element::createList();
ElementPtr spec_part = getModuleSpec().getConfigSpec();
if (identifier != "" && identifier != "/") {
spec_part = find_spec_part(spec_part, identifier);
......@@ -172,7 +172,7 @@ ConfigData::getItemList(const std::string& identifier, bool recurse)
ElementPtr
ConfigData::getFullConfig()
{
ElementPtr result = Element::createFromString("{}");
ElementPtr result = Element::createMap();
ElementPtr items = getItemList("", true);
BOOST_FOREACH(ElementPtr item, items->listValue()) {
result->set(item->stringValue(), getValue(item->stringValue()));
......
......@@ -39,12 +39,12 @@ class ConfigData {
public:
/// Constructs a ConfigData option with no specification and an
/// empty configuration.
ConfigData() { _config = Element::createFromString("{}"); };
ConfigData() { _config = Element::createMap(); };
/// Constructs a ConfigData option with the given specification
/// and an empty configuration.
/// \param module_spec A ModuleSpec for the relevant module
ConfigData(const ModuleSpec& module_spec) : _module_spec(module_spec) { _config = Element::createFromString("{}"); }
ConfigData(const ModuleSpec& module_spec) : _module_spec(module_spec) { _config = Element::createMap(); }
virtual ~ConfigData() {};
......
......@@ -92,12 +92,12 @@ getFirstMessage(std::string& group, std::string& to)
void
addMessage(ElementPtr msg, const std::string& group, const std::string& to)
{
ElementPtr m_el = Element::createFromString("[]");
ElementPtr m_el = Element::createList();
m_el->add(Element::create(group));
m_el->add(Element::create(to));
m_el->add(msg);
if (!msg_queue) {
msg_queue = Element::createFromString("[]");
msg_queue = Element::createList();
}
msg_queue->add(m_el);
}
......@@ -108,8 +108,8 @@ haveSubscription(const std::string& group, const std::string& instance)
if (!subscriptions) {
return false;
}
ElementPtr s1 = Element::createFromString("[]");
ElementPtr s2 = Element::createFromString("[]");
ElementPtr s1 = Element::createList();
ElementPtr s2 = Element::createList();
s1->add(Element::create(group));
s1->add(Element::create(instance));
s2->add(Element::create(group));
......@@ -206,7 +206,7 @@ Session::recvmsg(ElementPtr& env, ElementPtr& msg, bool nonblock UNUSED_PARAM, i
BOOST_FOREACH(ElementPtr c_m, msg_queue->listValue()) {
ElementPtr to_remove = ElementPtr();
if (haveSubscription(c_m->get(0), c_m->get(1))) {
env = Element::createFromString("{}");
env = Element::createMap();
env->set("group", c_m->get(0));
env->set("to", c_m->get(1));
msg = c_m->get(2);
......@@ -226,11 +226,11 @@ Session::recvmsg(ElementPtr& env, ElementPtr& msg, bool nonblock UNUSED_PARAM, i
void
Session::subscribe(std::string group, std::string instance) {
//cout << "[XX] client subscribes to " << group << " . " << instance << endl;
ElementPtr s_el = Element::createFromString("[]");
ElementPtr s_el = Element::createList();
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
if (!subscriptions) {
subscriptions = Element::createFromString("[]");
subscriptions = Element::createList();
}
subscriptions->add(s_el);
}
......@@ -238,7 +238,7 @@ Session::subscribe(std::string group, std::string instance) {
void
Session::unsubscribe(std::string group, std::string instance) {
//cout << "[XX] client unsubscribes from " << group << " . " << instance << endl;
ElementPtr s_el = Element::createFromString("[]");
ElementPtr s_el = Element::createList();
s_el->add(Element::create(group));
s_el->add(Element::create(instance));
if (!subscriptions) {
......
......@@ -169,7 +169,7 @@ TEST(ModuleSpec, DataValidation) {
EXPECT_TRUE(data_test(dd, "data22_7.data"));
EXPECT_FALSE(data_test(dd, "data22_8.data"));
ElementPtr errors = Element::createFromString("[]");
ElementPtr errors = Element::createList();
EXPECT_FALSE(data_test_with_errors(dd, "data22_8.data", errors));
EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
}
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