diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/Makefile.am | 1 | ||||
-rw-r--r-- | cpp/object.hpp | 22 | ||||
-rw-r--r-- | cpp/type/map.hpp | 10 | ||||
-rw-r--r-- | cpp/vrefbuffer.hpp | 85 | ||||
-rw-r--r-- | cpp/zone.hpp.erb | 10 |
5 files changed, 112 insertions, 16 deletions
diff --git a/cpp/Makefile.am b/cpp/Makefile.am index 76770f4..b9126f8 100644 --- a/cpp/Makefile.am +++ b/cpp/Makefile.am @@ -6,6 +6,7 @@ libmsgpack_la_SOURCES = \ nobase_include_HEADERS = \ msgpack.hpp \ msgpack/sbuffer.hpp \ + msgpack/vrefbuffer.hpp \ msgpack/pack.hpp \ msgpack/unpack.hpp \ msgpack/object.hpp \ diff --git a/cpp/object.hpp b/cpp/object.hpp index 09ddb89..07917c2 100644 --- a/cpp/object.hpp +++ b/cpp/object.hpp @@ -80,13 +80,13 @@ struct object { type::object_type type; union_type via; - bool is_nil() { return type == type::NIL; } + bool is_nil() const { return type == type::NIL; } template <typename T> - T as(); + T as() const; template <typename T> - void convert(T* v); + void convert(T* v) const; object(); object(msgpack_object obj); @@ -96,7 +96,7 @@ private: struct implicit_type; public: - implicit_type convert(); + implicit_type convert() const; }; struct object_kv { @@ -201,23 +201,23 @@ inline object::operator msgpack_object() } -inline object::implicit_type object::convert() +inline object::implicit_type object::convert() const { return implicit_type(*this); } template <typename T> -inline T object::as() +inline void object::convert(T* v) const { - T v; - convert(&v); - return v; + *this >> *v; } template <typename T> -inline void object::convert(T* v) +inline T object::as() const { - *this >> *v; + T v; + convert(&v); + return v; } diff --git a/cpp/type/map.hpp b/cpp/type/map.hpp index c136d53..552de57 100644 --- a/cpp/type/map.hpp +++ b/cpp/type/map.hpp @@ -80,13 +80,13 @@ inline std::map<K, V> operator>> (object o, std::map<K, V>& v) for(; p != pend; ++p) { K key; p->key.convert(&key); - typename std::map<K,V>::iterator it(v.find(key)); - if(it != v.end()) { + typename std::map<K,V>::iterator it(v.lower_bound(key)); + if(it != v.end() && !(key < it->first)) { + p->val.convert(&it->second); + } else { V val; p->val.convert(&val); - it->insert( std::pair<K,V>(key, val) ); - } else { - p->val.convert(&it->second); + v.insert(it, std::pair<K,V>(key, val)); } } return v; diff --git a/cpp/vrefbuffer.hpp b/cpp/vrefbuffer.hpp new file mode 100644 index 0000000..549d77f --- /dev/null +++ b/cpp/vrefbuffer.hpp @@ -0,0 +1,85 @@ +// +// MessagePack for C++ zero-copy buffer implementation +// +// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef MSGPACK_VREFBUFFER_HPP__ +#define MSGPACK_VREFBUFFER_HPP__ + +#include "msgpack/vrefbuffer.h" +#include <stdexcept> + +namespace msgpack { + + +class vrefbuffer : public msgpack_vrefbuffer { +public: + vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE, + size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE) + { + msgpack_vrefbuffer_init(this, ref_size, chunk_size); + } + + ~vrefbuffer() + { + msgpack_vrefbuffer_destroy(this); + } + +public: + void write(const char* buf, unsigned int len) + { + if(len < base::ref_size) { + append_copy(buf, len); + } else { + append_ref(buf, len); + } + } + + void append_ref(const char* buf, size_t len) + { + if(msgpack_vrefbuffer_append_ref(this, buf, len) < 0) { + throw std::bad_alloc(); + } + } + + void append_copy(const char* buf, size_t len) + { + if(msgpack_vrefbuffer_append_copy(this, buf, len) < 0) { + throw std::bad_alloc(); + } + } + + const struct iovec* vector() const + { + return msgpack_vrefbuffer_vec(this); + } + + size_t vector_size() const + { + return msgpack_vrefbuffer_veclen(this); + } + +private: + typedef msgpack_vrefbuffer base; + +private: + vrefbuffer(const vrefbuffer&); +}; + + +} // namespace msgpack + +#endif /* msgpack/vrefbuffer.hpp */ + diff --git a/cpp/zone.hpp.erb b/cpp/zone.hpp.erb index 9e85080..8fd14a6 100644 --- a/cpp/zone.hpp.erb +++ b/cpp/zone.hpp.erb @@ -34,6 +34,7 @@ public: public: void* malloc(size_t size); + void* malloc_no_align(size_t size); void push_finalizer(void (*func)(void*), void* data); @@ -77,6 +78,15 @@ inline void* zone::malloc(size_t size) return ptr; } +inline void* zone::malloc_no_align(size_t size) +{ + void* ptr = msgpack_zone_malloc_no_align(this, size); + if(!ptr) { + throw std::bad_alloc(); + } + return ptr; +} + inline void zone::push_finalizer(void (*func)(void*), void* data) { if(!msgpack_zone_push_finalizer(this, func, data)) { |