diff --git a/cpp/Makefile.am b/cpp/Makefile.am index f1a1d6cb..fa8d6cf9 100644 --- a/cpp/Makefile.am +++ b/cpp/Makefile.am @@ -66,7 +66,7 @@ check_PROGRAMS = \ msgpack_test msgpackc_test_SOURCES = msgpackc_test.cpp -msgpackc_test_LDADD = libmsgpackc.la -lgtest_main +msgpackc_test_LDADD = libmsgpack.la -lgtest_main msgpack_test_SOURCES = msgpack_test.cpp msgpack_test_LDADD = libmsgpack.la -lgtest_main diff --git a/cpp/msgpack/object.h b/cpp/msgpack/object.h index 9a014be7..bbfac196 100644 --- a/cpp/msgpack/object.h +++ b/cpp/msgpack/object.h @@ -79,6 +79,8 @@ typedef struct msgpack_object_kv { void msgpack_object_print(FILE* out, msgpack_object o); +bool msgpack_object_equal(const msgpack_object x, const msgpack_object y); + #ifdef __cplusplus } diff --git a/cpp/msgpack/object.hpp b/cpp/msgpack/object.hpp index a72913a1..13628184 100644 --- a/cpp/msgpack/object.hpp +++ b/cpp/msgpack/object.hpp @@ -101,7 +101,7 @@ struct object { template object& operator=(const T& v); - operator msgpack_object(); + operator msgpack_object() const; struct with_zone; @@ -226,6 +226,11 @@ void operator<< (object::with_zone& o, const T& v) } +inline bool operator==(const object x, const object y) +{ + return msgpack_object_equal(x, y); +} + template inline bool operator==(const object x, const T& y) try { @@ -310,7 +315,7 @@ inline void operator<< (object& o, msgpack_object v) ::memcpy(&o, &v, sizeof(v)); } -inline object::operator msgpack_object() +inline object::operator msgpack_object() const { // FIXME beter way? msgpack_object obj; diff --git a/cpp/object.cpp b/cpp/object.cpp index 626d1861..dfe32bbc 100644 --- a/cpp/object.cpp +++ b/cpp/object.cpp @@ -16,7 +16,6 @@ // limitations under the License. // #include "msgpack/object.hpp" -#include namespace msgpack { @@ -61,7 +60,6 @@ std::ostream& operator<< (std::ostream& s, const object o) } s << "]"; break; - // FIXME loop optimiziation case type::MAP: s << "{"; @@ -76,7 +74,6 @@ std::ostream& operator<< (std::ostream& s, const object o) } s << "}"; break; - // FIXME loop optimiziation default: // FIXME @@ -86,56 +83,5 @@ std::ostream& operator<< (std::ostream& s, const object o) } -bool operator==(const object x, const object y) -{ - if(x.type != y.type) { return false; } - - switch(x.type) { - case type::NIL: - return true; - - case type::BOOLEAN: - return x.via.boolean == y.via.boolean; - - case type::POSITIVE_INTEGER: - return x.via.u64 == y.via.u64; - - case type::NEGATIVE_INTEGER: - return x.via.i64 == y.via.i64; - - case type::DOUBLE: - return x.via.dec == y.via.dec; - - case type::RAW: - return x.via.raw.size == y.via.raw.size && - memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0; - - case type::ARRAY: - if(x.via.array.size != y.via.array.size) { return false; } - for(object* px(x.via.array.ptr), - * const pxend(x.via.array.ptr + x.via.array.size), - * py(y.via.array.ptr); - px < pxend; ++px, ++py) { - if(*px != *py) { return false; } - } - return true; - // FIXME loop optimiziation - - case type::MAP: - if(x.via.map.size != y.via.map.size) { return false; } - for(object_kv* px(x.via.map.ptr), - * const pxend(x.via.map.ptr + x.via.map.size), - * py(y.via.map.ptr); - px < pxend; ++px, ++py) { - if(px->key != py->key || px->val != py->val) { return false; } - } - return true; - - default: - return false; - } -} - - } // namespace msgpack diff --git a/cpp/object.c b/cpp/objectc.c similarity index 71% rename from cpp/object.c rename to cpp/objectc.c index a22ce214..d4f1c8aa 100644 --- a/cpp/object.c +++ b/cpp/objectc.c @@ -18,6 +18,7 @@ #include "msgpack/object.h" #include "msgpack/pack.h" #include +#include #ifndef _MSC_VER #include @@ -141,7 +142,6 @@ void msgpack_object_print(FILE* out, msgpack_object o) } fprintf(out, "]"); break; - // FIXME loop optimiziation case MSGPACK_OBJECT_MAP: fprintf(out, "{"); @@ -161,7 +161,6 @@ void msgpack_object_print(FILE* out, msgpack_object o) } fprintf(out, "}"); break; - // FIXME loop optimiziation default: // FIXME @@ -169,3 +168,70 @@ void msgpack_object_print(FILE* out, msgpack_object o) } } +bool msgpack_object_equal(const msgpack_object x, const msgpack_object y) +{ + if(x.type != y.type) { return false; } + + switch(x.type) { + case MSGPACK_OBJECT_NIL: + return true; + + case MSGPACK_OBJECT_BOOLEAN: + return x.via.boolean == y.via.boolean; + + case MSGPACK_OBJECT_POSITIVE_INTEGER: + return x.via.u64 == y.via.u64; + + case MSGPACK_OBJECT_NEGATIVE_INTEGER: + return x.via.i64 == y.via.i64; + + case MSGPACK_OBJECT_DOUBLE: + return x.via.dec == y.via.dec; + + case MSGPACK_OBJECT_RAW: + return x.via.raw.size == y.via.raw.size && + memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0; + + case MSGPACK_OBJECT_ARRAY: + if(x.via.array.size != y.via.array.size) { + return false; + } else if(x.via.array.size == 0) { + return true; + } else { + msgpack_object* px = x.via.array.ptr; + msgpack_object* const pxend = x.via.array.ptr + x.via.array.size; + msgpack_object* py = y.via.array.ptr; + do { + if(!msgpack_object_equal(*px, *py)) { + return false; + } + ++px; + ++py; + } while(px < pxend); + return true; + } + + case MSGPACK_OBJECT_MAP: + if(x.via.map.size != y.via.map.size) { + return false; + } else if(x.via.map.size == 0) { + return true; + } else { + msgpack_object_kv* px = x.via.map.ptr; + msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size; + msgpack_object_kv* py = y.via.map.ptr; + do { + if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) { + return false; + } + ++px; + ++py; + } while(px < pxend); + return true; + } + + default: + return false; + } +} +