Commit ab6751e3 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

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