diff --git a/cpp/object.cpp b/cpp/object.cpp index 276732cb..45cfb5f0 100644 --- a/cpp/object.cpp +++ b/cpp/object.cpp @@ -81,7 +81,7 @@ std::ostream& operator<< (std::ostream& s, const object o) default: // FIXME - s << "#<UNKNOWN " << (uint16_t)o.type << ">" << std::endl; + s << "#<UNKNOWN " << (uint16_t)o.type << ">"; } return s; } @@ -113,7 +113,7 @@ bool operator==(const object x, const object y) for(object* px(x.via.container.ptr), * const pxend(x.via.container.ptr + x.via.container.size), * py(y.via.container.ptr); - px != pxend; ++px, ++py) { + px < pxend; ++px, ++py) { if(*px != *py) { return false; } } return true; @@ -124,7 +124,7 @@ bool operator==(const object x, const object y) for(object* px(x.via.container.ptr), * const pxend(x.via.container.ptr + x.via.container.size*2), * py(y.via.container.ptr); - px != pxend; ++px, ++py) { + px < pxend; ++px, ++py) { if(*px != *py) { return false; } } return true; @@ -135,10 +135,5 @@ bool operator==(const object x, const object y) } -// FIXME -//template <typename Stream> -//const object& operator>> (const object& v, packer<Stream>& o); - - } // namespace msgpack diff --git a/cpp/object.hpp b/cpp/object.hpp index 7007b908..a5e86829 100644 --- a/cpp/object.hpp +++ b/cpp/object.hpp @@ -22,6 +22,7 @@ #include <stdint.h> #include <stdexcept> #include <typeinfo> +#include <limits> #include <ostream> namespace msgpack { @@ -46,7 +47,9 @@ struct object { uint32_t size; } ref; } via; - // FIXME template <typename T> operator T() { T v; convert(*this, v); return v; }; + + template <typename T> + operator T() { T v; convert(v, *this); return v; }; }; std::ostream& operator<< (std::ostream& s, const object o); @@ -55,6 +58,9 @@ bool operator==(const object x, const object y); inline bool operator!=(const object x, const object y) { return !(x == y); } +inline object& operator<< (object& v, object o) + { v = o; return v; } + template <typename Stream> const object& operator>> (const object& v, packer<Stream>& o); @@ -73,7 +79,7 @@ namespace type { template <typename T> inline T& operator<< (T& v, object o) { - v = o; + v.msgpack_unpack(o); return v; } @@ -87,7 +93,7 @@ namespace type { template <typename Stream, typename T> inline const T& operator>> (const T& v, packer<Stream>& o) { - detail::pack_copy(v.pack(), o); + detail::pack_copy(v.msgpack_pack(), o); return v; } @@ -118,6 +124,86 @@ inline void pack(T& v, Stream& s) } + +template <typename Stream> +const object& operator>> (const object& v, packer<Stream>& o) +{ + switch(v.type) { + case type::NIL: + o.pack_nil(); + return v; + + case type::BOOLEAN: + if(v.via.boolean) { + o.pack_true(); + } else { + o.pack_false(); + } + return v; + + case type::POSITIVE_INTEGER: + if(v.via.u64 <= (uint64_t)std::numeric_limits<uint16_t>::max()) { + if(v.via.u64 <= (uint16_t)std::numeric_limits<uint8_t>::max()) { + o.pack_uint8(v.via.u64); + } else { + o.pack_uint16(v.via.u64); + } + } else { + if(v.via.u64 <= (uint64_t)std::numeric_limits<uint32_t>::max()) { + o.pack_uint32(v.via.u64); + } else { + o.pack_uint64(v.via.u64); + } + } + return v; + + case type::NEGATIVE_INTEGER: + if(v.via.i64 >= (int64_t)std::numeric_limits<int16_t>::min()) { + if(v.via.i64 >= (int64_t)std::numeric_limits<int8_t>::min()) { + o.pack_int8(v.via.i64); + } else { + o.pack_int16(v.via.i64); + } + } else { + if(v.via.i64 >= (int64_t)std::numeric_limits<int32_t>::min()) { + o.pack_int64(v.via.i64); + } else { + o.pack_int64(v.via.i64); + } + } + return v; + + case type::RAW: + o.pack_raw(v.via.ref.ptr, v.via.ref.size); + return v; + + case type::ARRAY: + o.pack_array(v.via.container.size); + for(object* p(v.via.container.ptr), + * const pend(v.via.container.ptr + v.via.container.size); + p < pend; ++p) { + *p >> o; + } + return v; + // FIXME loop optimiziation + + case type::MAP: + o.pack_map(v.via.container.size); + for(object* p(v.via.container.ptr), + * const pend(v.via.container.ptr + v.via.container.size*2); + p < pend; ) { + *p >> o; ++p; + *p >> o; ++p; + } + return v; + // FIXME loop optimiziation + + default: + throw type_error(); + } +} + + } // namespace msgpack #include "msgpack/type.hpp"