[svn] commit: r1040 - in /trunk/src/lib/cc/cpp: data.cc data.h data_unittests.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Feb 28 20:00:49 UTC 2010
Author: jelte
Date: Sun Feb 28 20:00:49 2010
New Revision: 1040
Log:
equality functions for data::Element + tests
added a removeIdentical(mapelement, mapelement) for use in config update handlers
Modified:
trunk/src/lib/cc/cpp/data.cc
trunk/src/lib/cc/cpp/data.h
trunk/src/lib/cc/cpp/data_unittests.cc
Modified: trunk/src/lib/cc/cpp/data.cc
==============================================================================
--- trunk/src/lib/cc/cpp/data.cc (original)
+++ trunk/src/lib/cc/cpp/data.cc Sun Feb 28 20:00:49 2010
@@ -57,6 +57,11 @@
std::ostream& operator <<(std::ostream &out, const isc::data::ElementPtr& e) {
return out << e->str();
}
+
+bool operator==(const isc::data::ElementPtr a, const isc::data::ElementPtr b)
+{
+ return a->equals(b);
+};
//
// factory functions
@@ -912,8 +917,109 @@
}
bool
+IntElement::equals(ElementPtr other)
+{
+ return (other->getType() == Element::integer) &&
+ (i == other->intValue());
+}
+
+bool
+DoubleElement::equals(ElementPtr other)
+{
+ return (other->getType() == Element::real) &&
+ (d == other->doubleValue());
+}
+
+bool
+BoolElement::equals(ElementPtr other)
+{
+ return (other->getType() == Element::boolean) &&
+ (b == other->boolValue());
+}
+
+bool
+StringElement::equals(ElementPtr other)
+{
+ return (other->getType() == Element::string) &&
+ (s == other->stringValue());
+}
+
+bool
+ListElement::equals(ElementPtr other)
+{
+ if (other->getType() == Element::list) {
+ int s = size();
+ if (s != other->size()) {
+ return false;
+ }
+ for (int i = 0; i < s; i++) {
+ if (!get(i)->equals(other->get(i))) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool
+MapElement::equals(ElementPtr other)
+{
+ if (other->getType() == Element::map) {
+ std::map<std::string, ElementPtr> m = mapValue();
+ for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
+ it != m.end() ; ++it) {
+ if (other->contains((*it).first)) {
+ if (!get((*it).first)->equals(other->get((*it).first))) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ // quickly walk through the other map too, to see if there's
+ // anything in there that we don't have. We don't need to
+ // compare those elements; if one of them is missing we
+ // differ (and if it's not missing the loop above has checked
+ // it)
+ m = other->mapValue();
+ for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
+ it != m.end() ; ++it) {
+ if (!contains((*it).first)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool
isc::data::isNull(ElementPtr p)
{
return !p;
}
+void
+isc::data::removeIdentical(ElementPtr a, const ElementPtr b)
+{
+ if (a->getType() != Element::map || b->getType() != Element::map) {
+ dns_throw(TypeError, "Non-map Elements passed to removeIdentical");
+ }
+ std::cout<<"[XX] removeidentical from " << a << " and " << b << std::endl;
+
+ std::map<std::string, ElementPtr> m = a->mapValue();
+ for (std::map<std::string, ElementPtr>::iterator it = m.begin() ;
+ it != m.end() ; ++it) {
+ if (b->contains((*it).first)) {
+ if (a->get((*it).first)->equals(b->get((*it).first))) {
+ std::cout<<"[XX] remove " << (*it).first << std::endl;
+ a->remove((*it).first);
+ }
+ }
+ }
+ std::cout<<"[XX] a now " << a << std::endl;
+
+}
Modified: trunk/src/lib/cc/cpp/data.h
==============================================================================
--- trunk/src/lib/cc/cpp/data.h (original)
+++ trunk/src/lib/cc/cpp/data.h Sun Feb 28 20:00:49 2010
@@ -103,6 +103,10 @@
/// \return the type of this element
int getType() { return type; };
+
+ /// \returns true if the other ElementPtr has the same type and
+ /// value
+ virtual bool equals(ElementPtr other) = 0;
// pure virtuals, every derived class must implement these
@@ -332,6 +336,7 @@
bool setValue(const int v) { i = v; return true; };
std::string str();
void toWire(std::stringstream& ss, int omit_length = 1);
+ bool equals(ElementPtr other);
};
class DoubleElement : public Element {
@@ -346,6 +351,7 @@
bool setValue(const double v) { d = v; return true; };
std::string str();
void toWire(std::stringstream& ss, int omit_length = 1);
+ bool equals(ElementPtr other);
};
class BoolElement : public Element {
@@ -360,6 +366,7 @@
bool setValue(const bool v) { b = v; return true; };
std::string str();
void toWire(std::stringstream& ss, int omit_length = 1);
+ bool equals(ElementPtr other);
};
class StringElement : public Element {
@@ -374,6 +381,7 @@
bool setValue(const std::string& v) { s = v; return true; };
std::string str();
void toWire(std::stringstream& ss, int omit_length = 1);
+ bool equals(ElementPtr other);
};
class ListElement : public Element {
@@ -396,6 +404,7 @@
std::string str();
void toWire(std::stringstream& ss, int omit_length = 1);
size_t size() { return l.size(); }
+ bool equals(ElementPtr other);
};
class MapElement : public Element {
@@ -435,6 +444,8 @@
// it doesnt exist or one of the elements in the path is not
// a MapElement)
bool find(const std::string& id, ElementPtr& t);
+
+ bool equals(ElementPtr other);
};
/// Checks whether the given ElementPtr is a NULL pointer
@@ -442,6 +453,14 @@
/// \return true if it is NULL, false if not.
bool isNull(ElementPtr p);
+///
+/// \brief Remove all values from the first ElementPtr that are
+/// also present in the second. Both ElementPtrs MUST be MapElements
+/// The use for this function is to end up with a MapElement that
+/// only contains new and changed values (for ModuleCCSession and
+/// configuration update handlers)
+/// Raises a TypeError if a or b are not MapElements
+void removeIdentical(ElementPtr a, const ElementPtr b);
} }
@@ -462,6 +481,8 @@
/// parameter \c os after the insertion operation.
std::ostream& operator <<(std::ostream &out, const isc::data::ElementPtr& e);
+bool operator==(const isc::data::ElementPtr a, const isc::data::ElementPtr b);
+
#endif // _ISC_DATA_H
// Local Variables:
Modified: trunk/src/lib/cc/cpp/data_unittests.cc
==============================================================================
--- trunk/src/lib/cc/cpp/data_unittests.cc (original)
+++ trunk/src/lib/cc/cpp/data_unittests.cc Sun Feb 28 20:00:49 2010
@@ -276,3 +276,107 @@
EXPECT_EQ(ddef, ddef2);
}
+ElementPtr efs(const std::string& str) {
+ return Element::createFromString(str);
+}
+
+TEST(Element, equals) {
+ // why does EXPECT_EQ not work?
+ EXPECT_TRUE(efs("1") == efs("1"));
+ EXPECT_FALSE(efs("1") == efs("2"));
+ EXPECT_FALSE(efs("1") == efs("\"1\""));
+ EXPECT_FALSE(efs("1") == efs("[]"));
+ EXPECT_FALSE(efs("1") == efs("True"));
+ EXPECT_FALSE(efs("1") == efs("{}"));
+
+ EXPECT_TRUE(efs("1.1") == efs("1.1"));
+ EXPECT_FALSE(efs("1.0") == efs("1"));
+ EXPECT_FALSE(efs("1.1") == efs("\"1\""));
+ EXPECT_FALSE(efs("1.1") == efs("[]"));
+ EXPECT_FALSE(efs("1.1") == efs("True"));
+ EXPECT_FALSE(efs("1.1") == efs("{}"));
+
+ EXPECT_TRUE(efs("True") == efs("True"));
+ EXPECT_FALSE(efs("True") == efs("False"));
+ EXPECT_FALSE(efs("True") == efs("1"));
+ EXPECT_FALSE(efs("True") == efs("\"1\""));
+ EXPECT_FALSE(efs("True") == efs("[]"));
+ EXPECT_FALSE(efs("True") == efs("{}"));
+
+ EXPECT_TRUE(efs("\"foo\"") == efs("\"foo\""));
+ EXPECT_FALSE(efs("\"foo\"") == efs("\"bar\""));
+ EXPECT_FALSE(efs("\"foo\"") == efs("1"));
+ EXPECT_FALSE(efs("\"foo\"") == efs("\"1\""));
+ EXPECT_FALSE(efs("\"foo\"") == efs("True"));
+ EXPECT_FALSE(efs("\"foo\"") == efs("[]"));
+ EXPECT_FALSE(efs("\"foo\"") == efs("{}"));
+
+ EXPECT_TRUE(efs("[]") == efs("[]"));
+ EXPECT_TRUE(efs("[ 1, 2, 3 ]") == efs("[ 1, 2, 3 ]"));
+ EXPECT_TRUE(efs("[ \"a\", [ True, 1], 2.2 ]") == efs("[ \"a\", [ True, 1], 2.2 ]"));
+ EXPECT_FALSE(efs("[ \"a\", [ True, 1], 2.2 ]") == efs("[ \"a\", [ True, 2], 2.2 ]"));
+ EXPECT_FALSE(efs("[]") == efs("[1]"));
+ EXPECT_FALSE(efs("[]") == efs("1"));
+ EXPECT_FALSE(efs("[]") == efs("\"1\""));
+ EXPECT_FALSE(efs("[]") == efs("{}"));
+
+ EXPECT_TRUE(efs("{}") == efs("{}"));
+ EXPECT_TRUE(efs("{ \"foo\": \"bar\" }") == efs("{ \"foo\": \"bar\" }"));
+ EXPECT_TRUE(efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }") == efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"));
+ EXPECT_FALSE(efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }") == efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar2\" } }"));
+ EXPECT_FALSE(efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }") == efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\", 1 ], \"item3\": { \"foo\": \"bar\" } }"));
+ EXPECT_FALSE(efs("{ \"foo\": \"bar\" }") == efs("1"));
+ EXPECT_FALSE(efs("{ \"foo\": \"bar\" }") == efs("\"1\""));
+ EXPECT_FALSE(efs("{ \"foo\": \"bar\" }") == efs("[]"));
+ EXPECT_FALSE(efs("{ \"foo\": \"bar\" }") == efs("{}"));
+}
+
+TEST(Element, removeIdentical) {
+ ElementPtr a = Element::createFromString("{}");
+ ElementPtr b = Element::createFromString("{}");
+ ElementPtr c = Element::createFromString("{}");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+
+ a = Element::createFromString("{ \"a\": 1 }");
+ b = Element::createFromString("{ \"a\": 1 }");
+ c = Element::createFromString("{}");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+
+ a = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
+ b = Element::createFromString("{}");
+ 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("{}");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+
+ a = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 2 ] }");
+ b = Element::createFromString("{ \"a\": 1, \"b\": [ 1, 3 ] }");
+ c = Element::createFromString("{ \"b\": [ 1, 2 ] }");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+
+ a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
+ b = Element::createFromString("{}");
+ 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("{}");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+
+ a = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
+ b = Element::createFromString("{ \"a\": { \"b\": \"d\" } }");
+ c = Element::createFromString("{ \"a\": { \"b\": \"c\" } }");
+ removeIdentical(a, b);
+ EXPECT_TRUE(a == c);
+}
More information about the bind10-changes
mailing list