From 761b3980834e4644ce0ce57f6db13d1c93883380 Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 15 Feb 2009 18:39:30 +0900 Subject: [PATCH] rewrite msgpack::object::via --- c/object.c | 24 ++++++++--------- c/object.h | 32 +++++++++++++++++------ c/pack.h | 58 ++++++++++++++++++++++-------------------- c/zone.c | 2 +- cpp/object.cpp | 48 ++++++++++++++++------------------ cpp/object.hpp | 56 ++++++++++++++++++++++++++-------------- cpp/type/array.hpp | 6 ++--- cpp/type/map.hpp | 36 +++++++++++++------------- cpp/type/raw.hpp | 10 ++++---- cpp/type/tuple.hpp.erb | 4 +-- cpp/unpack.cpp | 22 ++++++++-------- 11 files changed, 165 insertions(+), 133 deletions(-) diff --git a/c/object.c b/c/object.c index 7a410640..63764383 100644 --- a/c/object.c +++ b/c/object.c @@ -98,42 +98,42 @@ static inline msgpack_object msgpack_unpack_array(unpack_user* u, unsigned int n { msgpack_object o; o.type = MSGPACK_OBJECT_ARRAY; - o.via.container.size = 0; - o.via.container.ptr = msgpack_zone_malloc(u->z, n*sizeof(msgpack_object)); - if(o.via.container.ptr == NULL) { u->failed = true; } + o.via.array.size = 0; + o.via.array.ptr = msgpack_zone_malloc(u->z, n*sizeof(msgpack_object)); + if(o.via.array.ptr == NULL) { u->failed = true; } return o; } static inline void msgpack_unpack_array_item(unpack_user* u, msgpack_object* c, msgpack_object o) { if(u->failed) { return; } - c->via.container.ptr[ c->via.container.size++ ] = o; + c->via.array.ptr[ c->via.array.size++ ] = o; } static inline msgpack_object msgpack_unpack_map(unpack_user* u, unsigned int n) { msgpack_object o; o.type = MSGPACK_OBJECT_MAP; - o.via.container.size = 0; - o.via.container.ptr = msgpack_zone_malloc(u->z, n*2*sizeof(msgpack_object)); - if(o.via.container.ptr == NULL) { u->failed = true; } + o.via.map.size = 0; + o.via.map.ptr = msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv)); + if(o.via.map.ptr == NULL) { u->failed = true; } return o; } static inline void msgpack_unpack_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v) { if(u->failed) { return; } - c->via.container.ptr[ c->via.container.size ] = k; - c->via.container.ptr[ c->via.container.size+1 ] = v; - ++c->via.container.size; + c->via.map.ptr[c->via.map.size].key = k; + c->via.map.ptr[c->via.map.size].val = v; + ++c->via.map.size; } static inline msgpack_object msgpack_unpack_raw(unpack_user* u, const char* b, const char* p, unsigned int l) { msgpack_object o; o.type = MSGPACK_OBJECT_RAW; - o.via.ref.ptr = p; - o.via.ref.size = l; + o.via.raw.ptr = p; + o.via.raw.size = l; u->referenced = true; return o; } diff --git a/c/object.h b/c/object.h index 1b60c572..b590ebe0 100644 --- a/c/object.h +++ b/c/object.h @@ -41,19 +41,31 @@ typedef enum { struct _msgpack_object; +struct _msgpack_object_kv; + +typedef struct { + uint32_t size; + struct _msgpack_object* ptr; +} msgpack_object_array; + +typedef struct { + uint32_t size; + struct _msgpack_object_kv* ptr; +} msgpack_object_map; + +typedef struct { + uint32_t size; + const char* ptr; +} msgpack_object_raw; + typedef union { bool boolean; uint64_t u64; int64_t i64; double dec; - struct { - struct _msgpack_object* ptr; - uint32_t size; - } container; - struct { - const char* ptr; - uint32_t size; - } ref; + msgpack_object_array array; + msgpack_object_map map; + msgpack_object_raw raw; } msgpack_object_union; typedef struct _msgpack_object { @@ -61,6 +73,10 @@ typedef struct _msgpack_object { msgpack_object_union via; } msgpack_object; +typedef struct _msgpack_object_kv { + msgpack_object key; + msgpack_object val; +} msgpack_object_kv; typedef enum { MSGPACK_OBJECT_PARSE_SUCCESS = 0, diff --git a/c/pack.h b/c/pack.h index 752cbc4f..a510effa 100644 --- a/c/pack.h +++ b/c/pack.h @@ -21,6 +21,7 @@ #include #include #include +#include "msgpack/pack_define.h" #ifdef __cplusplus extern "C" { @@ -34,42 +35,43 @@ typedef struct { msgpack_pack_write_t callback; } msgpack_pack_t; -void msgpack_pack_init(msgpack_pack_t* ctx, void* data, msgpack_pack_write_t callback); +static void msgpack_pack_init(msgpack_pack_t* ctx, void* data, msgpack_pack_write_t callback); -msgpack_pack_t* msgpack_pack_new(void* data, msgpack_pack_write_t callback); -void msgpack_pack_free(msgpack_pack_t* ctx); +static msgpack_pack_t* msgpack_pack_new(void* data, msgpack_pack_write_t callback); -int msgpack_pack_short(msgpack_pack_t* ctx, short d); -int msgpack_pack_int(msgpack_pack_t* ctx, int d); -int msgpack_pack_long(msgpack_pack_t* ctx, long d); -int msgpack_pack_long_long(msgpack_pack_t* ctx, long long d); -int msgpack_pack_unsigned_short(msgpack_pack_t* ctx, unsigned short d); -int msgpack_pack_unsigned_int(msgpack_pack_t* ctx, unsigned int d); -int msgpack_pack_unsigned_long(msgpack_pack_t* ctx, unsigned long d); -int msgpack_pack_unsigned_long_long(msgpack_pack_t* ctx, unsigned long long d); +static void msgpack_pack_free(msgpack_pack_t* ctx); -int msgpack_pack_uint8(msgpack_pack_t* ctx, uint8_t d); -int msgpack_pack_uint16(msgpack_pack_t* ctx, uint16_t d); -int msgpack_pack_uint32(msgpack_pack_t* ctx, uint32_t d); -int msgpack_pack_uint64(msgpack_pack_t* ctx, uint64_t d); -int msgpack_pack_int8(msgpack_pack_t* ctx, int8_t d); -int msgpack_pack_int16(msgpack_pack_t* ctx, int16_t d); -int msgpack_pack_int32(msgpack_pack_t* ctx, int32_t d); -int msgpack_pack_int64(msgpack_pack_t* ctx, int64_t d); +static int msgpack_pack_short(msgpack_pack_t* ctx, short d); +static int msgpack_pack_int(msgpack_pack_t* ctx, int d); +static int msgpack_pack_long(msgpack_pack_t* ctx, long d); +static int msgpack_pack_long_long(msgpack_pack_t* ctx, long long d); +static int msgpack_pack_unsigned_short(msgpack_pack_t* ctx, unsigned short d); +static int msgpack_pack_unsigned_int(msgpack_pack_t* ctx, unsigned int d); +static int msgpack_pack_unsigned_long(msgpack_pack_t* ctx, unsigned long d); +static int msgpack_pack_unsigned_long_long(msgpack_pack_t* ctx, unsigned long long d); -int msgpack_pack_float(msgpack_pack_t* ctx, float d); -int msgpack_pack_double(msgpack_pack_t* ctx, double d); +static int msgpack_pack_uint8(msgpack_pack_t* ctx, uint8_t d); +static int msgpack_pack_uint16(msgpack_pack_t* ctx, uint16_t d); +static int msgpack_pack_uint32(msgpack_pack_t* ctx, uint32_t d); +static int msgpack_pack_uint64(msgpack_pack_t* ctx, uint64_t d); +static int msgpack_pack_int8(msgpack_pack_t* ctx, int8_t d); +static int msgpack_pack_int16(msgpack_pack_t* ctx, int16_t d); +static int msgpack_pack_int32(msgpack_pack_t* ctx, int32_t d); +static int msgpack_pack_int64(msgpack_pack_t* ctx, int64_t d); -int msgpack_pack_nil(msgpack_pack_t* ctx); -int msgpack_pack_true(msgpack_pack_t* ctx); -int msgpack_pack_false(msgpack_pack_t* ctx); +static int msgpack_pack_float(msgpack_pack_t* ctx, float d); +static int msgpack_pack_double(msgpack_pack_t* ctx, double d); -int msgpack_pack_array(msgpack_pack_t* ctx, unsigned int n); +static int msgpack_pack_nil(msgpack_pack_t* ctx); +static int msgpack_pack_true(msgpack_pack_t* ctx); +static int msgpack_pack_false(msgpack_pack_t* ctx); -int msgpack_pack_map(msgpack_pack_t* ctx, unsigned int n); +static int msgpack_pack_array(msgpack_pack_t* ctx, unsigned int n); -int msgpack_pack_raw(msgpack_pack_t* ctx, size_t l); -int msgpack_pack_raw_body(msgpack_pack_t* ctx, const void* b, size_t l); +static int msgpack_pack_map(msgpack_pack_t* ctx, unsigned int n); + +static int msgpack_pack_raw(msgpack_pack_t* ctx, size_t l); +static int msgpack_pack_raw_body(msgpack_pack_t* ctx, const void* b, size_t l); diff --git a/c/zone.c b/c/zone.c index a41bb444..ccd702d1 100644 --- a/c/zone.c +++ b/c/zone.c @@ -41,7 +41,7 @@ void msgpack_zone_free(msgpack_zone* z) if(z->array) { size_t i; for(i=0; i <= z->ntail; ++i) { - free(z->array[i].ptr); + free(z->array[i].alloc); } } free(z); diff --git a/cpp/object.cpp b/cpp/object.cpp index d217c069..eb45f779 100644 --- a/cpp/object.cpp +++ b/cpp/object.cpp @@ -46,16 +46,16 @@ std::ostream& operator<< (std::ostream& s, const object o) break; case type::RAW: - (s << '"').write(o.via.ref.ptr, o.via.ref.size) << '"'; + (s << '"').write(o.via.raw.ptr, o.via.raw.size) << '"'; break; case type::ARRAY: s << "["; - if(o.via.container.size != 0) { - object* p(o.via.container.ptr); + if(o.via.array.size != 0) { + object* p(o.via.array.ptr); s << *p; ++p; - for(object* const pend(o.via.container.ptr + o.via.container.size); + for(object* const pend(o.via.array.ptr + o.via.array.size); p < pend; ++p) { s << ", " << *p; } @@ -66,17 +66,13 @@ std::ostream& operator<< (std::ostream& s, const object o) case type::MAP: s << "{"; - if(o.via.container.size != 0) { - object* p(o.via.container.ptr); - object* const pend(o.via.container.ptr + o.via.container.size*2); - s << *p; ++p; - s << "=>"; - s << *p; ++p; - while(p < pend) { - s << ", "; - s << *p; ++p; - s << "=>"; - s << *p; ++p; + if(o.via.map.size != 0) { + object_kv* p(o.via.map.ptr); + s << p->key << "=>" << p->val; + ++p; + for(object_kv* const pend(o.via.map.ptr + o.via.map.size); + p < pend; ++p) { + s << ", " << p->key << "=>" << p->val; } } s << "}"; @@ -109,14 +105,14 @@ bool operator==(const object x, const object y) return x.via.i64 == y.via.i64; case type::RAW: - return x.via.ref.size == y.via.ref.size && - memcmp(x.via.ref.ptr, y.via.ref.ptr, x.via.ref.size) == 0; + 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.container.size != y.via.container.size) { return false; } - for(object* px(x.via.container.ptr), - * const pxend(x.via.container.ptr + x.via.container.size), - * py(y.via.container.ptr); + 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; } } @@ -124,12 +120,12 @@ bool operator==(const object x, const object y) // FIXME loop optimiziation case type::MAP: - if(x.via.container.size != y.via.container.size) { return false; } - for(object* px(x.via.container.ptr), - * const pxend(x.via.container.ptr + x.via.container.size*2), - * py(y.via.container.ptr); + 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 != *py) { return false; } + if(px->key != py->key || px->val != py->val) { return false; } } return true; diff --git a/cpp/object.hpp b/cpp/object.hpp index c6f1e4af..08e715dc 100644 --- a/cpp/object.hpp +++ b/cpp/object.hpp @@ -45,20 +45,33 @@ namespace type { } +struct object; +struct object_kv; + +struct object_array { + uint32_t size; + object* ptr; +}; + +struct object_map { + uint32_t size; + object_kv* ptr; +}; + +struct object_raw { + uint32_t size; + const char* ptr; +}; + struct object { union union_type { bool boolean; uint64_t u64; int64_t i64; double dec; - struct { - object* ptr; - uint32_t size; - } container; - struct { - const char* ptr; - uint32_t size; - } ref; + object_array array; + object_map map; + object_raw raw; }; type::object_type type; @@ -79,6 +92,11 @@ public: implicit_type convert(); }; +struct object_kv { + object key; + object val; +}; + bool operator==(const object x, const object y); bool operator!=(const object x, const object y); @@ -258,14 +276,14 @@ packer& operator<< (packer& o, const object& v) return o; case type::RAW: - o.pack_raw(v.via.ref.size); - o.pack_raw_body(v.via.ref.ptr, v.via.ref.size); + o.pack_raw(v.via.raw.size); + o.pack_raw_body(v.via.raw.ptr, v.via.raw.size); return o; 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); + o.pack_array(v.via.array.size); + for(object* p(v.via.array.ptr), + * const pend(v.via.array.ptr + v.via.array.size); p < pend; ++p) { *p >> o; } @@ -273,12 +291,12 @@ packer& operator<< (packer& o, const object& 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; + o.pack_map(v.via.map.size); + for(object_kv* p(v.via.map.ptr), + * const pend(v.via.map.ptr + v.via.map.size); + p < pend; ++p) { + p->key >> o; + p->val >> o; } return o; // FIXME loop optimiziation diff --git a/cpp/type/array.hpp b/cpp/type/array.hpp index f9f8038f..b2a81efa 100644 --- a/cpp/type/array.hpp +++ b/cpp/type/array.hpp @@ -28,9 +28,9 @@ template inline std::vector operator>> (object o, std::vector& v) { if(o.type != type::ARRAY) { throw type_error(); } - v.resize(o.via.container.size); - object* p = o.via.container.ptr; - object* const pend = o.via.container.ptr + o.via.container.size; + v.resize(o.via.array.size); + object* p = o.via.array.ptr; + object* const pend = o.via.array.ptr + o.via.array.size; T* it = &v.front(); for(; p < pend; ++p, ++it) { p->convert(it); diff --git a/cpp/type/map.hpp b/cpp/type/map.hpp index 619c36e2..4585d660 100644 --- a/cpp/type/map.hpp +++ b/cpp/type/map.hpp @@ -46,13 +46,13 @@ template inline type::assoc_vector& operator>> (object o, type::assoc_vector& v) { if(o.type != type::MAP) { throw type_error(); } - v.resize(o.via.container.size); - object* p = o.via.container.ptr; - object* const pend = o.via.container.ptr + o.via.container.size; + v.resize(o.via.map.size); + object_kv* p = o.via.map.ptr; + object_kv* const pend = o.via.map.ptr + o.via.map.size; std::pair* it(&v.front()); - for(; p < pend; ++it) { - p->convert(&it->first); ++p; - p->convert(&it->second); ++p; + for(; p < pend; ++p, ++it) { + p->key.convert(&it->first); + p->val.convert(&it->second); } std::sort(v.begin(), v.end(), type::detail::pair_first_less()); return v; @@ -75,18 +75,18 @@ template inline std::map operator>> (object o, std::map& v) { if(o.type != type::MAP) { throw type_error(); } - object* p(o.via.container.ptr); - object* const pend(o.via.container.ptr + o.via.container.size*2); - while(p < pend) { + object_kv* p(o.via.map.ptr); + object_kv* const pend(o.via.map.ptr + o.via.map.size); + for(; p != pend; ++p) { K key; - p->convert(&key); ++p; + p->key.convert(&key); typename std::map::iterator it(v.find(key)); if(it != v.end()) { V val; - p->convert(&val); ++p; + p->val.convert(&val); it->insert( std::pair(key, val) ); } else { - p->convert(&it->second); ++p; + p->val.convert(&it->second); } } return v; @@ -109,12 +109,12 @@ template inline std::multimap operator>> (object o, std::multimap& v) { if(o.type != type::MAP) { throw type_error(); } - object* p = o.via.container.ptr; - object* const pend = o.via.container.ptr + o.via.container.size*2; - while(p < pend) { + object_kv* p(o.via.map.ptr); + object_kv* const pend(o.via.map.ptr + o.via.map.size); + for(; p != pend; ++p) { std::pair value; - p->convert(&value.first); ++p; - p->convert(&value.second); ++p; + p->key.convert(&value.first); + p->val.convert(&value.second); v.insert(value); } return v; @@ -123,7 +123,7 @@ inline std::multimap operator>> (object o, std::multimap& v) template inline packer& operator<< (packer& o, const std::multimap& v) { - o.pack_multimap(v.size()); + o.pack_map(v.size()); for(typename std::multimap::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); diff --git a/cpp/type/raw.hpp b/cpp/type/raw.hpp index e4f9dd3f..b102ee89 100644 --- a/cpp/type/raw.hpp +++ b/cpp/type/raw.hpp @@ -27,11 +27,11 @@ namespace msgpack { namespace type { struct raw_ref { - raw_ref() : ptr(NULL), size(0) {} - raw_ref(const char* p, uint32_t s) : ptr(p), size(s) {} + raw_ref() : size(0), ptr(NULL) {} + raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {} - const char* ptr; uint32_t size; + const char* ptr; std::string str() { return std::string(ptr, size); } @@ -64,8 +64,8 @@ struct raw_ref { inline type::raw_ref& operator>> (object o, type::raw_ref& v) { if(o.type != type::RAW) { throw type_error(); } - v.ptr = o.via.ref.ptr; - v.size = o.via.ref.size; + v.ptr = o.via.raw.ptr; + v.size = o.via.raw.size; return v; } diff --git a/cpp/type/tuple.hpp.erb b/cpp/type/tuple.hpp.erb index a66c57e2..a20f5d9c 100644 --- a/cpp/type/tuple.hpp.erb +++ b/cpp/type/tuple.hpp.erb @@ -136,9 +136,9 @@ type::tuple, A<%=j%><%}%>>& operator>> ( object o, type::tuple, A<%=j%><%}%>>& v) { if(o.type != type::ARRAY) { throw type_error(); } - if(o.via.container.size < <%=i+1%>) { throw type_error(); } + if(o.via.array.size < <%=i+1%>) { throw type_error(); } <%0.upto(i) {|j|%> - o.via.container.ptr[<%=j%>].convert>(&v.template get<<%=j%>>());<%}%> + o.via.array.ptr[<%=j%>].convert>(&v.template get<<%=j%>>());<%}%> return v; } <%}%> diff --git a/cpp/unpack.cpp b/cpp/unpack.cpp index 62088d60..0b9a476b 100644 --- a/cpp/unpack.cpp +++ b/cpp/unpack.cpp @@ -104,36 +104,36 @@ static inline object msgpack_unpack_array(unpack_user* u, unsigned int n) { object o; o.type = type::ARRAY; - o.via.container.size = 0; - o.via.container.ptr = (object*)u->z->malloc(n*sizeof(object)); + o.via.array.size = 0; + o.via.array.ptr = (object*)u->z->malloc(n*sizeof(object)); return o; } static inline void msgpack_unpack_array_item(unpack_user* u, object* c, object o) -{ c->via.container.ptr[ c->via.container.size++ ] = o; } +{ c->via.array.ptr[c->via.array.size++] = o; } static inline object msgpack_unpack_map(unpack_user* u, unsigned int n) { object o; o.type = type::MAP; - o.via.container.size = 0; - o.via.container.ptr = (object*)u->z->malloc(n*2*sizeof(object)); + o.via.map.size = 0; + o.via.map.ptr = (object_kv*)u->z->malloc(n*sizeof(object_kv)); return o; } static inline void msgpack_unpack_map_item(unpack_user* u, object* c, object k, object v) { - c->via.container.ptr[ c->via.container.size ] = k; - c->via.container.ptr[ c->via.container.size+1 ] = v; - ++c->via.container.size; + c->via.map.ptr[c->via.map.size].key = k; + c->via.map.ptr[c->via.map.size].val = v; + ++c->via.map.size; } static inline object msgpack_unpack_raw(unpack_user* u, const char* b, const char* p, unsigned int l) { object o; o.type = type::RAW; - o.via.ref.ptr = p; - o.via.ref.size = l; + o.via.raw.ptr = p; + o.via.raw.size = l; u->referenced = true; return o; } @@ -332,7 +332,7 @@ object unpacker::data() void unpacker::reset() { - if(!m_zone->empty()) { delete release_zone(); } + //if(!m_zone->empty()) { delete release_zone(); } as_ctx(m_ctx)->reset(); }