summaryrefslogtreecommitdiff
path: root/cpp/msgpack
diff options
context:
space:
mode:
authorfrsyuki <frsyuki@users.sourceforge.jp>2010-02-06 20:09:41 +0900
committerfrsyuki <frsyuki@users.sourceforge.jp>2010-02-06 20:09:41 +0900
commitcd10fbc1fe39308045f0b7bf9cce5f8153f25f1d (patch)
tree44e4a1e075deebc3339cdd44e1f550a3ea914e88 /cpp/msgpack
parentca0b085d156260b6d916139495a6d306a1e7f886 (diff)
downloadmsgpack-python-cd10fbc1fe39308045f0b7bf9cce5f8153f25f1d.tar.gz
removed symbolic links
Diffstat (limited to 'cpp/msgpack')
l---------cpp/msgpack1
-rw-r--r--cpp/msgpack/object.hpp329
-rw-r--r--cpp/msgpack/pack.hpp252
-rw-r--r--cpp/msgpack/sbuffer.hpp103
-rw-r--r--cpp/msgpack/type.hpp15
-rw-r--r--cpp/msgpack/type/bool.hpp46
-rw-r--r--cpp/msgpack/type/define.hpp.erb98
-rw-r--r--cpp/msgpack/type/deque.hpp56
-rw-r--r--cpp/msgpack/type/float.hpp63
-rw-r--r--cpp/msgpack/type/int.hpp147
-rw-r--r--cpp/msgpack/type/list.hpp56
-rw-r--r--cpp/msgpack/type/map.hpp139
-rw-r--r--cpp/msgpack/type/nil.hpp49
-rw-r--r--cpp/msgpack/type/pair.hpp50
-rw-r--r--cpp/msgpack/type/raw.hpp84
-rw-r--r--cpp/msgpack/type/set.hpp80
-rw-r--r--cpp/msgpack/type/string.hpp46
-rw-r--r--cpp/msgpack/type/tr1/unordered_map.hpp85
-rw-r--r--cpp/msgpack/type/tr1/unordered_set.hpp80
-rw-r--r--cpp/msgpack/type/tuple.hpp.erb171
-rw-r--r--cpp/msgpack/type/vector.hpp60
-rw-r--r--cpp/msgpack/unpack.hpp301
-rw-r--r--cpp/msgpack/vrefbuffer.hpp92
-rw-r--r--cpp/msgpack/zone.hpp.erb149
24 files changed, 2551 insertions, 1 deletions
diff --git a/cpp/msgpack b/cpp/msgpack
deleted file mode 120000
index 945c9b4..0000000
--- a/cpp/msgpack
+++ /dev/null
@@ -1 +0,0 @@
-. \ No newline at end of file
diff --git a/cpp/msgpack/object.hpp b/cpp/msgpack/object.hpp
new file mode 100644
index 0000000..ed2e290
--- /dev/null
+++ b/cpp/msgpack/object.hpp
@@ -0,0 +1,329 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_OBJECT_HPP__
+#define MSGPACK_OBJECT_HPP__
+
+#include "msgpack/object.h"
+#include "msgpack/pack.hpp"
+#include <string.h>
+#include <stdexcept>
+#include <typeinfo>
+#include <limits>
+#include <ostream>
+
+namespace msgpack {
+
+
+class type_error : public std::bad_cast { };
+
+
+namespace type {
+ enum object_type {
+ NIL = 0x01,
+ BOOLEAN = 0x02,
+ POSITIVE_INTEGER = 0x03,
+ NEGATIVE_INTEGER = 0x04,
+ DOUBLE = 0x05,
+ RAW = 0x06,
+ ARRAY = 0x07,
+ MAP = 0x08,
+ };
+}
+
+
+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;
+ object_array array;
+ object_map map;
+ object_raw raw;
+ object_raw ref; // obsolete
+ };
+
+ type::object_type type;
+ union_type via;
+
+ bool is_nil() const { return type == type::NIL; }
+
+ template <typename T>
+ T as() const;
+
+ template <typename T>
+ void convert(T* v) const;
+
+ object();
+ object(msgpack_object obj);
+ operator msgpack_object();
+
+private:
+ struct implicit_type;
+
+public:
+ implicit_type convert() const;
+};
+
+struct object_kv {
+ object key;
+ object val;
+};
+
+bool operator==(const object x, const object y);
+bool operator!=(const object x, const object y);
+
+std::ostream& operator<< (std::ostream& s, const object o);
+
+
+template <typename Stream, typename T>
+packer<Stream>& operator<< (packer<Stream>& o, const T& v);
+
+template <typename T>
+T& operator>> (object o, T& v);
+
+
+struct object::implicit_type {
+ implicit_type(object o) : obj(o) { }
+ ~implicit_type() { }
+
+ template <typename T>
+ operator T() { return obj.as<T>(); }
+
+private:
+ object obj;
+};
+
+
+// obsolete
+template <typename Type>
+class define : public Type {
+public:
+ typedef Type msgpack_type;
+ typedef define<Type> define_type;
+
+ define() {}
+ define(const msgpack_type& v) : msgpack_type(v) {}
+
+ template <typename Packer>
+ void msgpack_pack(Packer& o) const
+ {
+ o << static_cast<const msgpack_type&>(*this);
+ }
+
+ void msgpack_unpack(object o)
+ {
+ o >> static_cast<msgpack_type&>(*this);
+ }
+};
+
+
+template <typename Stream>
+template <typename T>
+inline packer<Stream>& packer<Stream>::pack(const T& v)
+{
+ *this << v;
+ return *this;
+}
+
+inline object& operator>> (object o, object& v)
+{
+ v = o;
+ return v;
+}
+
+template <typename T>
+inline T& operator>> (object o, T& v)
+{
+ v.msgpack_unpack(o.convert());
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
+{
+ v.msgpack_pack(o);
+ return o;
+}
+
+
+inline bool operator!=(const object x, const object y)
+{ return !(x == y); }
+
+
+inline object::object() { }
+
+inline object::object(msgpack_object obj)
+{
+ // FIXME beter way?
+ ::memcpy(this, &obj, sizeof(obj));
+}
+
+inline object::operator msgpack_object()
+{
+ // FIXME beter way?
+ msgpack_object obj;
+ ::memcpy(&obj, this, sizeof(obj));
+ return obj;
+}
+
+
+inline object::implicit_type object::convert() const
+{
+ return implicit_type(*this);
+}
+
+template <typename T>
+inline void object::convert(T* v) const
+{
+ *this >> *v;
+}
+
+template <typename T>
+inline T object::as() const
+{
+ T v;
+ convert(&v);
+ return v;
+}
+
+
+// obsolete
+template <typename T>
+inline void convert(T& v, object o)
+{
+ o.convert(&v);
+}
+
+// obsolete
+template <typename Stream, typename T>
+inline void pack(packer<Stream>& o, const T& v)
+{
+ o.pack(v);
+}
+
+// obsolete
+template <typename Stream, typename T>
+inline void pack_copy(packer<Stream>& o, T v)
+{
+ pack(o, v);
+}
+
+
+template <typename Stream>
+packer<Stream>& operator<< (packer<Stream>& o, const object& v)
+{
+ switch(v.type) {
+ case type::NIL:
+ o.pack_nil();
+ return o;
+
+ case type::BOOLEAN:
+ if(v.via.boolean) {
+ o.pack_true();
+ } else {
+ o.pack_false();
+ }
+ return o;
+
+ 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 o;
+
+ 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 o;
+
+ case type::RAW:
+ 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.array.size);
+ for(object* p(v.via.array.ptr),
+ * const pend(v.via.array.ptr + v.via.array.size);
+ p < pend; ++p) {
+ o << *p;
+ }
+ return o;
+
+ case type::MAP:
+ 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) {
+ o << p->key;
+ o << p->val;
+ }
+ return o;
+
+ default:
+ throw type_error();
+ }
+}
+
+
+} // namespace msgpack
+
+#include "msgpack/type.hpp"
+
+#endif /* msgpack/object.hpp */
+
diff --git a/cpp/msgpack/pack.hpp b/cpp/msgpack/pack.hpp
new file mode 100644
index 0000000..9c291c1
--- /dev/null
+++ b/cpp/msgpack/pack.hpp
@@ -0,0 +1,252 @@
+//
+// MessagePack for C++ serializing routine
+//
+// 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_PACK_HPP__
+#define MSGPACK_PACK_HPP__
+
+#include "msgpack/pack_define.h"
+#include <stdexcept>
+#include <limits.h>
+
+namespace msgpack {
+
+
+template <typename Stream>
+class packer {
+public:
+ packer(Stream& s);
+ ~packer();
+
+public:
+ template <typename T>
+ packer<Stream>& pack(const T& v);
+
+ packer<Stream>& pack_uint8(uint8_t d);
+ packer<Stream>& pack_uint16(uint16_t d);
+ packer<Stream>& pack_uint32(uint32_t d);
+ packer<Stream>& pack_uint64(uint64_t d);
+ packer<Stream>& pack_int8(uint8_t d);
+ packer<Stream>& pack_int16(uint16_t d);
+ packer<Stream>& pack_int32(uint32_t d);
+ packer<Stream>& pack_int64(uint64_t d);
+
+ packer<Stream>& pack_short(int d);
+ packer<Stream>& pack_int(int d);
+ packer<Stream>& pack_long(long d);
+ packer<Stream>& pack_long_long(long long d);
+ packer<Stream>& pack_unsigned_short(unsigned short d);
+ packer<Stream>& pack_unsigned_int(unsigned int d);
+ packer<Stream>& pack_unsigned_long(unsigned long d);
+ packer<Stream>& pack_unsigned_long_long(unsigned long long d);
+
+ packer<Stream>& pack_float(float d);
+ packer<Stream>& pack_double(double d);
+
+ packer<Stream>& pack_nil();
+ packer<Stream>& pack_true();
+ packer<Stream>& pack_false();
+
+ packer<Stream>& pack_array(unsigned int n);
+
+ packer<Stream>& pack_map(unsigned int n);
+
+ packer<Stream>& pack_raw(size_t l);
+ packer<Stream>& pack_raw_body(const char* b, size_t l);
+
+private:
+ static void _pack_uint8(Stream& x, uint8_t d);
+ static void _pack_uint16(Stream& x, uint16_t d);
+ static void _pack_uint32(Stream& x, uint32_t d);
+ static void _pack_uint64(Stream& x, uint64_t d);
+ static void _pack_int8(Stream& x, int8_t d);
+ static void _pack_int16(Stream& x, int16_t d);
+ static void _pack_int32(Stream& x, int32_t d);
+ static void _pack_int64(Stream& x, int64_t d);
+
+ static void _pack_short(Stream& x, short d);
+ static void _pack_int(Stream& x, int d);
+ static void _pack_long(Stream& x, long d);
+ static void _pack_long_long(Stream& x, long long d);
+ static void _pack_unsigned_short(Stream& x, unsigned short d);
+ static void _pack_unsigned_int(Stream& x, unsigned int d);
+ static void _pack_unsigned_long(Stream& x, unsigned long d);
+ static void _pack_unsigned_long_long(Stream& x, unsigned long long d);
+
+ static void _pack_float(Stream& x, float d);
+ static void _pack_double(Stream& x, double d);
+
+ static void _pack_nil(Stream& x);
+ static void _pack_true(Stream& x);
+ static void _pack_false(Stream& x);
+
+ static void _pack_array(Stream& x, unsigned int n);
+
+ static void _pack_map(Stream& x, unsigned int n);
+
+ static void _pack_raw(Stream& x, size_t l);
+ static void _pack_raw_body(Stream& x, const void* b, size_t l);
+
+ static void append_buffer(Stream& x, const unsigned char* buf, unsigned int len)
+ { x.write((const char*)buf, len); }
+
+private:
+ Stream& m_stream;
+
+private:
+ packer();
+};
+
+
+template <typename Stream, typename T>
+inline void pack(Stream& s, const T& v)
+{
+ packer<Stream>(s).pack(v);
+}
+
+
+#define msgpack_pack_inline_func(name) \
+ template <typename Stream> \
+ inline void packer<Stream>::_pack ## name
+
+#define msgpack_pack_inline_func_cint(name) \
+ template <typename Stream> \
+ inline void packer<Stream>::_pack ## name
+
+#define msgpack_pack_user Stream&
+
+#define msgpack_pack_append_buffer append_buffer
+
+#include "msgpack/pack_template.h"
+
+
+template <typename Stream>
+packer<Stream>::packer(Stream& s) : m_stream(s) { }
+
+template <typename Stream>
+packer<Stream>::~packer() { }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)
+{ _pack_uint8(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_uint16(uint16_t d)
+{ _pack_uint16(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_uint32(uint32_t d)
+{ _pack_uint32(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_uint64(uint64_t d)
+{ _pack_uint64(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_int8(uint8_t d)
+{ _pack_int8(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_int16(uint16_t d)
+{ _pack_int16(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_int32(uint32_t d)
+{ _pack_int32(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_int64(uint64_t d)
+{ _pack_int64(m_stream, d); return *this;}
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_short(int d)
+{ _pack_short(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_int(int d)
+{ _pack_int(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_long(long d)
+{ _pack_long(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_long_long(long long d)
+{ _pack_long_long(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_unsigned_short(unsigned short d)
+{ _pack_unsigned_short(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_unsigned_int(unsigned int d)
+{ _pack_unsigned_int(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_unsigned_long(unsigned long d)
+{ _pack_unsigned_long(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_unsigned_long_long(unsigned long long d)
+{ _pack_unsigned_long_long(m_stream, d); return *this; }
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_float(float d)
+{ _pack_float(m_stream, d); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_double(double d)
+{ _pack_double(m_stream, d); return *this; }
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_nil()
+{ _pack_nil(m_stream); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_true()
+{ _pack_true(m_stream); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_false()
+{ _pack_false(m_stream); return *this; }
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_array(unsigned int n)
+{ _pack_array(m_stream, n); return *this; }
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_map(unsigned int n)
+{ _pack_map(m_stream, n); return *this; }
+
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_raw(size_t l)
+{ _pack_raw(m_stream, l); return *this; }
+
+template <typename Stream>
+inline packer<Stream>& packer<Stream>::pack_raw_body(const char* b, size_t l)
+{ _pack_raw_body(m_stream, b, l); return *this; }
+
+
+} // namespace msgpack
+
+#endif /* msgpack/pack.hpp */
+
diff --git a/cpp/msgpack/sbuffer.hpp b/cpp/msgpack/sbuffer.hpp
new file mode 100644
index 0000000..ca06884e
--- /dev/null
+++ b/cpp/msgpack/sbuffer.hpp
@@ -0,0 +1,103 @@
+//
+// MessagePack for C++ simple 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_SBUFFER_HPP__
+#define MSGPACK_SBUFFER_HPP__
+
+#include "msgpack/sbuffer.h"
+#include <stdexcept>
+
+namespace msgpack {
+
+
+class sbuffer : public msgpack_sbuffer {
+public:
+ sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE)
+ {
+ base::data = (char*)::malloc(initsz);
+ if(!base::data) {
+ throw std::bad_alloc();
+ }
+
+ base::size = 0;
+ base::alloc = initsz;
+ }
+
+ ~sbuffer()
+ {
+ ::free(base::data);
+ }
+
+public:
+ void write(const char* buf, unsigned int len)
+ {
+ if(base::alloc - base::size < len) {
+ expand_buffer(len);
+ }
+ memcpy(base::data + base::size, buf, len);
+ base::size += len;
+ }
+
+ char* data()
+ {
+ return base::data;
+ }
+
+ const char* data() const
+ {
+ return base::data;
+ }
+
+ size_t size() const
+ {
+ return base::size;
+ }
+
+ char* release()
+ {
+ return msgpack_sbuffer_release(this);
+ }
+
+private:
+ void expand_buffer(size_t len)
+ {
+ size_t nsize = (base::alloc) ?
+ base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
+
+ while(nsize < base::size + len) { nsize *= 2; }
+
+ void* tmp = realloc(base::data, nsize);
+ if(!tmp) {
+ throw std::bad_alloc();
+ }
+
+ base::data = (char*)tmp;
+ base::alloc = nsize;
+ }
+
+private:
+ typedef msgpack_sbuffer base;
+
+private:
+ sbuffer(const sbuffer&);
+};
+
+
+} // namespace msgpack
+
+#endif /* msgpack/sbuffer.hpp */
+
diff --git a/cpp/msgpack/type.hpp b/cpp/msgpack/type.hpp
new file mode 100644
index 0000000..fafa674
--- /dev/null
+++ b/cpp/msgpack/type.hpp
@@ -0,0 +1,15 @@
+#include "msgpack/type/bool.hpp"
+#include "msgpack/type/float.hpp"
+#include "msgpack/type/int.hpp"
+#include "msgpack/type/list.hpp"
+#include "msgpack/type/deque.hpp"
+#include "msgpack/type/map.hpp"
+#include "msgpack/type/nil.hpp"
+#include "msgpack/type/pair.hpp"
+#include "msgpack/type/raw.hpp"
+#include "msgpack/type/set.hpp"
+#include "msgpack/type/string.hpp"
+#include "msgpack/type/vector.hpp"
+#include "msgpack/type/tuple.hpp"
+#include "msgpack/type/define.hpp"
+
diff --git a/cpp/msgpack/type/bool.hpp b/cpp/msgpack/type/bool.hpp
new file mode 100644
index 0000000..b945d85
--- /dev/null
+++ b/cpp/msgpack/type/bool.hpp
@@ -0,0 +1,46 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_BOOL_HPP__
+#define MSGPACK_TYPE_BOOL_HPP__
+
+#include "msgpack/object.hpp"
+#include <vector>
+
+namespace msgpack {
+
+
+inline bool& operator>> (object o, bool& v)
+{
+ if(o.type != type::BOOLEAN) { throw type_error(); }
+ v = o.via.boolean;
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v)
+{
+ if(v) { o.pack_true(); }
+ else { o.pack_false(); }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/bool.hpp */
+
diff --git a/cpp/msgpack/type/define.hpp.erb b/cpp/msgpack/type/define.hpp.erb
new file mode 100644
index 0000000..2eac4f4
--- /dev/null
+++ b/cpp/msgpack/type/define.hpp.erb
@@ -0,0 +1,98 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_DEFINE_HPP__
+#define MSGPACK_TYPE_DEFINE_HPP__
+
+#define MSGPACK_DEFINE(...) \
+ template <typename Packer> \
+ void msgpack_pack(Packer& pk) const \
+ { \
+ msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
+ } \
+ void msgpack_unpack(msgpack::object o) \
+ { \
+ msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
+ }
+
+namespace msgpack {
+namespace type {
+
+
+<% GENERATION_LIMIT = 31 %>
+template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
+struct define;
+
+
+template <>
+struct define<> {
+ typedef define<> value_type;
+ typedef tuple<> tuple_type;
+ template <typename Packer>
+ void msgpack_pack(Packer& pk) const
+ {
+ pk.pack_array(1);
+ }
+ void msgpack_unpack(msgpack::object o)
+ {
+ if(o.type != type::ARRAY) { throw type_error(); }
+ }
+};
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
+ typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
+ typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type;
+ define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) :
+ a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
+ template <typename Packer>
+ void msgpack_pack(Packer& pk) const
+ {
+ pk.pack_array(<%=i+1%>);
+ <%0.upto(i) {|j|%>
+ pk.pack(a<%=j%>);<%}%>
+ }
+ void msgpack_unpack(msgpack::object o)
+ {
+ if(o.type != type::ARRAY) { throw type_error(); }
+ const size_t size = o.via.array.size;
+ <%0.upto(i) {|j|%>
+ if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%>
+ }
+ <%0.upto(i) {|j|%>
+ A<%=j%>& a<%=j%>;<%}%>
+};
+<%}%>
+
+inline define<> make_define()
+{
+ return define<>();
+}
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>)
+{
+ return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
+}
+<%}%>
+
+} // namespace type
+} // namespace msgpack
+
+
+#endif /* msgpack/type/define.hpp */
+
diff --git a/cpp/msgpack/type/deque.hpp b/cpp/msgpack/type/deque.hpp
new file mode 100644
index 0000000..d34d243
--- /dev/null
+++ b/cpp/msgpack/type/deque.hpp
@@ -0,0 +1,56 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_DEQUE_HPP__
+#define MSGPACK_TYPE_DEQUE_HPP__
+
+#include "msgpack/object.hpp"
+#include <deque>
+
+namespace msgpack {
+
+
+template <typename T>
+inline std::deque<T>& operator>> (object o, std::deque<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ v.resize(o.via.array.size);
+ object* p = o.via.array.ptr;
+ object* const pend = o.via.array.ptr + o.via.array.size;
+ typename std::deque<T>::iterator it = v.begin();
+ for(; p < pend; ++p, ++it) {
+ p->convert(&*it);
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::deque<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/deque.hpp */
+
diff --git a/cpp/msgpack/type/float.hpp b/cpp/msgpack/type/float.hpp
new file mode 100644
index 0000000..390e340
--- /dev/null
+++ b/cpp/msgpack/type/float.hpp
@@ -0,0 +1,63 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_FLOAT_HPP__
+#define MSGPACK_TYPE_FLOAT_HPP__
+
+#include "msgpack/object.hpp"
+#include <vector>
+
+namespace msgpack {
+
+
+// FIXME check overflow, underflow
+
+
+inline float& operator>> (object o, float& v)
+{
+ if(o.type != type::DOUBLE) { throw type_error(); }
+ v = o.via.dec;
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const float& v)
+{
+ o.pack_float(v);
+ return o;
+}
+
+
+inline double& operator>> (object o, double& v)
+{
+ if(o.type != type::DOUBLE) { throw type_error(); }
+ v = o.via.dec;
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
+{
+ o.pack_double(v);
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/float.hpp */
+
diff --git a/cpp/msgpack/type/int.hpp b/cpp/msgpack/type/int.hpp
new file mode 100644
index 0000000..03500f7
--- /dev/null
+++ b/cpp/msgpack/type/int.hpp
@@ -0,0 +1,147 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_INT_HPP__
+#define MSGPACK_TYPE_INT_HPP__
+
+#include "msgpack/object.hpp"
+#include <limits>
+
+namespace msgpack {
+
+
+namespace type {
+namespace detail {
+ template <typename T, bool Signed>
+ struct convert_integer_sign;
+
+ template <typename T>
+ struct convert_integer_sign<T, true> {
+ static inline T convert(object o) {
+ if(o.type == type::POSITIVE_INTEGER) {
+ if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
+ { throw type_error(); }
+ return o.via.u64;
+ } else if(o.type == type::NEGATIVE_INTEGER) {
+ if(o.via.i64 < (int64_t)std::numeric_limits<T>::min())
+ { throw type_error(); }
+ return o.via.i64;
+ }
+ throw type_error();
+ }
+ };
+
+ template <typename T>
+ struct convert_integer_sign<T, false> {
+ static inline T convert(object o) {
+ if(o.type == type::POSITIVE_INTEGER) {
+ if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
+ { throw type_error(); }
+ return o.via.u64;
+ }
+ throw type_error();
+ }
+ };
+
+ template <typename T>
+ static inline T convert_integer(object o)
+ {
+ return detail::convert_integer_sign<T, std::numeric_limits<T>::is_signed>::convert(o);
+ }
+
+} // namespace detail
+} // namespace type
+
+
+inline signed char& operator>> (object o, signed char& v)
+ { v = type::detail::convert_integer<signed char>(o); return v; }
+
+inline signed short& operator>> (object o, signed short& v)
+ { v = type::detail::convert_integer<signed short>(o); return v; }
+
+inline signed int& operator>> (object o, signed int& v)
+ { v = type::detail::convert_integer<signed int>(o); return v; }
+
+inline signed long& operator>> (object o, signed long& v)
+ { v = type::detail::convert_integer<signed long>(o); return v; }
+
+inline signed long long& operator>> (object o, signed long long& v)
+ { v = type::detail::convert_integer<signed long long>(o); return v; }
+
+
+inline unsigned char& operator>> (object o, unsigned char& v)
+ { v = type::detail::convert_integer<unsigned char>(o); return v; }
+
+inline unsigned short& operator>> (object o, unsigned short& v)
+ { v = type::detail::convert_integer<unsigned short>(o); return v; }
+
+inline unsigned int& operator>> (object o, unsigned int& v)
+ { v = type::detail::convert_integer<unsigned int>(o); return v; }
+
+inline unsigned long& operator>> (object o, unsigned long& v)
+ { v = type::detail::convert_integer<unsigned long>(o); return v; }
+
+inline unsigned long long& operator>> (object o, unsigned long long& v)
+ { v = type::detail::convert_integer<unsigned long long>(o); return v; }
+
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const signed char& v)
+ { o.pack_int8(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const signed short& v)
+ { o.pack_short(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const signed int& v)
+ { o.pack_int(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const signed long& v)
+ { o.pack_long(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const signed long long& v)
+ { o.pack_long_long(v); return o; }
+
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned char& v)
+ { o.pack_uint8(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned short& v)
+ { o.pack_unsigned_short(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned int& v)
+ { o.pack_unsigned_int(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long& v)
+ { o.pack_unsigned_long(v); return o; }
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& v)
+ { o.pack_unsigned_long_long(v); return o; }
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/int.hpp */
+
diff --git a/cpp/msgpack/type/list.hpp b/cpp/msgpack/type/list.hpp
new file mode 100644
index 0000000..6ecc02f
--- /dev/null
+++ b/cpp/msgpack/type/list.hpp
@@ -0,0 +1,56 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_LIST_HPP__
+#define MSGPACK_TYPE_LIST_HPP__
+
+#include "msgpack/object.hpp"
+#include <list>
+
+namespace msgpack {
+
+
+template <typename T>
+inline std::list<T>& operator>> (object o, std::list<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ v.resize(o.via.array.size);
+ object* p = o.via.array.ptr;
+ object* const pend = o.via.array.ptr + o.via.array.size;
+ typename std::list<T>::iterator it = v.begin();
+ for(; p < pend; ++p, ++it) {
+ p->convert(&*it);
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/list.hpp */
+
diff --git a/cpp/msgpack/type/map.hpp b/cpp/msgpack/type/map.hpp
new file mode 100644
index 0000000..552de57
--- /dev/null
+++ b/cpp/msgpack/type/map.hpp
@@ -0,0 +1,139 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_MAP_HPP__
+#define MSGPACK_TYPE_MAP_HPP__
+
+#include "msgpack/object.hpp"
+#include <map>
+#include <vector>
+#include <algorithm>
+
+namespace msgpack {
+
+
+namespace type {
+
+template <typename K, typename V>
+class assoc_vector : public std::vector< std::pair<K, V> > {};
+
+namespace detail {
+ template <typename K, typename V>
+ struct pair_first_less {
+ bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
+ { return x.first < y.first; }
+ };
+}
+
+} //namespace type
+
+
+template <typename K, typename V>
+inline type::assoc_vector<K,V>& operator>> (object o, type::assoc_vector<K,V>& v)
+{
+ if(o.type != type::MAP) { throw type_error(); }
+ 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<K, V>* it(&v.front());
+ 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<K,V>());
+ return v;
+}
+
+template <typename Stream, typename K, typename V>
+inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v)
+{
+ o.pack_map(v.size());
+ for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(it->first);
+ o.pack(it->second);
+ }
+ return o;
+}
+
+
+template <typename K, typename V>
+inline std::map<K, V> operator>> (object o, std::map<K, V>& v)
+{
+ if(o.type != type::MAP) { throw type_error(); }
+ 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->key.convert(&key);
+ 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);
+ v.insert(it, std::pair<K,V>(key, val));
+ }
+ }
+ return v;
+}
+
+template <typename Stream, typename K, typename V>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v)
+{
+ o.pack_map(v.size());
+ for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(it->first);
+ o.pack(it->second);
+ }
+ return o;
+}
+
+
+template <typename K, typename V>
+inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v)
+{
+ if(o.type != type::MAP) { throw type_error(); }
+ 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<K, V> value;
+ p->key.convert(&value.first);
+ p->val.convert(&value.second);
+ v.insert(value);
+ }
+ return v;
+}
+
+template <typename Stream, typename K, typename V>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v)
+{
+ o.pack_map(v.size());
+ for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(it->first);
+ o.pack(it->second);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/map.hpp */
+
diff --git a/cpp/msgpack/type/nil.hpp b/cpp/msgpack/type/nil.hpp
new file mode 100644
index 0000000..93e66ff
--- /dev/null
+++ b/cpp/msgpack/type/nil.hpp
@@ -0,0 +1,49 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_NIL_HPP__
+#define MSGPACK_TYPE_NIL_HPP__
+
+#include "msgpack/object.hpp"
+
+namespace msgpack {
+
+namespace type {
+
+struct nil { };
+
+} // namespace type
+
+
+inline type::nil& operator>> (object o, type::nil& v)
+{
+ if(o.type != type::NIL) { throw type_error(); }
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v)
+{
+ o.pack_nil();
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/nil.hpp */
+
diff --git a/cpp/msgpack/type/pair.hpp b/cpp/msgpack/type/pair.hpp
new file mode 100644
index 0000000..ba72c1f
--- /dev/null
+++ b/cpp/msgpack/type/pair.hpp
@@ -0,0 +1,50 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_PAIR_HPP__
+#define MSGPACK_TYPE_PAIR_HPP__
+
+#include "msgpack/object.hpp"
+#include <utility>
+
+namespace msgpack {
+
+
+template <typename T1, typename T2>
+inline std::pair<T1, T2>& operator>> (object o, std::pair<T1, T2>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ if(o.via.array.size != 2) { throw type_error(); }
+ o.via.array.ptr[0].convert(&v.first);
+ o.via.array.ptr[1].convert(&v.second);
+ return v;
+}
+
+template <typename Stream, typename T1, typename T2>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::pair<T1, T2>& v)
+{
+ o.pack_array(2);
+ o.pack(v.first);
+ o.pack(v.second);
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/pair.hpp */
+
diff --git a/cpp/msgpack/type/raw.hpp b/cpp/msgpack/type/raw.hpp
new file mode 100644
index 0000000..8c68aba
--- /dev/null
+++ b/cpp/msgpack/type/raw.hpp
@@ -0,0 +1,84 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_RAW_HPP__
+#define MSGPACK_TYPE_RAW_HPP__
+
+#include "msgpack/object.hpp"
+#include <string.h>
+#include <string>
+
+namespace msgpack {
+
+namespace type {
+
+struct raw_ref {
+ raw_ref() : size(0), ptr(NULL) {}
+ raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {}
+
+ uint32_t size;
+ const char* ptr;
+
+ std::string str() { return std::string(ptr, size); }
+
+ bool operator== (const raw_ref& x)
+ {
+ return size == x.size && memcmp(ptr, x.ptr, size) == 0;
+ }
+
+ bool operator!= (const raw_ref& x)
+ {
+ return !(*this != x);
+ }
+
+ bool operator< (const raw_ref& x)
+ {
+ if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; }
+ else { return size < x.size; }
+ }
+
+ bool operator> (const raw_ref& x)
+ {
+ if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; }
+ else { return size > x.size; }
+ }
+};
+
+} // namespace type
+
+
+inline type::raw_ref& operator>> (object o, type::raw_ref& v)
+{
+ if(o.type != type::RAW) { throw type_error(); }
+ v.ptr = o.via.raw.ptr;
+ v.size = o.via.raw.size;
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v)
+{
+ o.pack_raw(v.size);
+ o.pack_raw_body(v.ptr, v.size);
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/raw.hpp */
+
diff --git a/cpp/msgpack/type/set.hpp b/cpp/msgpack/type/set.hpp
new file mode 100644
index 0000000..f2c5bfb
--- /dev/null
+++ b/cpp/msgpack/type/set.hpp
@@ -0,0 +1,80 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_SET_HPP__
+#define MSGPACK_TYPE_SET_HPP__
+
+#include "msgpack/object.hpp"
+#include <set>
+
+namespace msgpack {
+
+
+template <typename T>
+inline std::set<T>& operator>> (object o, std::set<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ object* p = o.via.array.ptr + o.via.array.size;
+ object* const pbegin = o.via.array.ptr;
+ while(p > pbegin) {
+ --p;
+ v.insert(p->as<T>());
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+template <typename T>
+inline std::multiset<T>& operator>> (object o, std::multiset<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ object* p = o.via.array.ptr + o.via.array.size;
+ object* const pbegin = o.via.array.ptr;
+ while(p > pbegin) {
+ --p;
+ v.insert(p->as<T>());
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/set.hpp */
+
diff --git a/cpp/msgpack/type/string.hpp b/cpp/msgpack/type/string.hpp
new file mode 100644
index 0000000..a085d53
--- /dev/null
+++ b/cpp/msgpack/type/string.hpp
@@ -0,0 +1,46 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_STRING_HPP__
+#define MSGPACK_TYPE_STRING_HPP__
+
+#include "msgpack/object.hpp"
+#include <string>
+
+namespace msgpack {
+
+
+inline std::string& operator>> (object o, std::string& v)
+{
+ if(o.type != type::RAW) { throw type_error(); }
+ v.assign(o.via.raw.ptr, o.via.raw.size);
+ return v;
+}
+
+template <typename Stream>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v)
+{
+ o.pack_raw(v.size());
+ o.pack_raw_body(v.data(), v.size());
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/string.hpp */
+
diff --git a/cpp/msgpack/type/tr1/unordered_map.hpp b/cpp/msgpack/type/tr1/unordered_map.hpp
new file mode 100644
index 0000000..1996cfd
--- /dev/null
+++ b/cpp/msgpack/type/tr1/unordered_map.hpp
@@ -0,0 +1,85 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_TR1_UNORDERED_MAP_HPP__
+#define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__
+
+#include "msgpack/object.hpp"
+#include <tr1/unordered_map>
+
+namespace msgpack {
+
+
+template <typename K, typename V>
+inline std::tr1::unordered_map<K, V> operator>> (object o, std::tr1::unordered_map<K, V>& v)
+{
+ if(o.type != type::MAP) { throw type_error(); }
+ 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->key.convert(&key);
+ p->val.convert(&v[key]);
+ }
+ return v;
+}
+
+template <typename Stream, typename K, typename V>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_map<K,V>& v)
+{
+ o.pack_map(v.size());
+ for(typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(it->first);
+ o.pack(it->second);
+ }
+ return o;
+}
+
+
+template <typename K, typename V>
+inline std::tr1::unordered_multimap<K, V> operator>> (object o, std::tr1::unordered_multimap<K, V>& v)
+{
+ if(o.type != type::MAP) { throw type_error(); }
+ 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<K, V> value;
+ p->key.convert(&value.first);
+ p->val.convert(&value.second);
+ v.insert(value);
+ }
+ return v;
+}
+
+template <typename Stream, typename K, typename V>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multimap<K,V>& v)
+{
+ o.pack_map(v.size());
+ for(typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(it->first);
+ o.pack(it->second);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/map.hpp */
+
diff --git a/cpp/msgpack/type/tr1/unordered_set.hpp b/cpp/msgpack/type/tr1/unordered_set.hpp
new file mode 100644
index 0000000..eb127b5
--- /dev/null
+++ b/cpp/msgpack/type/tr1/unordered_set.hpp
@@ -0,0 +1,80 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_TR1_UNORDERED_SET_HPP__
+#define MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__
+
+#include "msgpack/object.hpp"
+#include <tr1/unordered_set>
+
+namespace msgpack {
+
+
+template <typename T>
+inline std::tr1::unordered_set<T>& operator>> (object o, std::tr1::unordered_set<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ object* p = o.via.array.ptr + o.via.array.size;
+ object* const pbegin = o.via.array.ptr;
+ while(p > pbegin) {
+ --p;
+ v.insert(p->as<T>());
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_set<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::tr1::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+template <typename T>
+inline std::tr1::unordered_multiset<T>& operator>> (object o, std::tr1::unordered_multiset<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ object* p = o.via.array.ptr + o.via.array.size;
+ object* const pbegin = o.via.array.ptr;
+ while(p > pbegin) {
+ --p;
+ v.insert(p->as<T>());
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multiset<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/set.hpp */
+
diff --git a/cpp/msgpack/type/tuple.hpp.erb b/cpp/msgpack/type/tuple.hpp.erb
new file mode 100644
index 0000000..2930ae0
--- /dev/null
+++ b/cpp/msgpack/type/tuple.hpp.erb
@@ -0,0 +1,171 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_TUPLE_HPP__
+#define MSGPACK_TYPE_TUPLE_HPP__
+
+#include "msgpack/object.hpp"
+
+namespace msgpack {
+
+namespace type {
+
+// FIXME operator==
+// FIXME operator!=
+<% GENERATION_LIMIT = 31 %>
+
+template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
+struct tuple;
+
+template <typename Tuple, int N>
+struct tuple_element;
+
+template <typename Tuple, int N>
+struct const_tuple_element;
+
+template <typename T>
+struct tuple_type {
+ typedef T type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef const T& transparent_reference;
+};
+
+template <typename T>
+struct tuple_type<T&> {
+ typedef T type;
+ typedef T& value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T& transparent_reference;
+};
+
+template <typename T>
+struct tuple_type<const T&> {
+ typedef T type;
+ typedef T& value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef const T& transparent_reference;
+};
+
+<%0.upto(GENERATION_LIMIT) {|i|%>
+<%0.upto(i) {|j|%>
+template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
+struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
+ tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : _x(x.a<%=j%>) {}
+ typename tuple_type<A<%=j%>>::reference get() { return _x; }
+ typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
+private:
+ typename tuple_type<A<%=j%>>::reference _x;
+};
+<%}%>
+<%}%>
+
+<%0.upto(GENERATION_LIMIT) {|i|%>
+<%0.upto(i) {|j|%>
+template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
+struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
+ const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : _x(x.a<%=j%>) {}
+ typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
+private:
+ typename tuple_type<A<%=j%>>::const_reference _x;
+};
+<%}%>
+<%}%>
+
+template <>
+struct tuple<> {
+ tuple() {}
+ tuple(object o) { o.convert(this); }
+ typedef tuple<> value_type;
+};
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
+ typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
+ tuple() {}
+ tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) :
+ a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
+ tuple(object o) { o.convert(this); }
+ template <int N> typename tuple_element<value_type, N>::reference get()
+ { return tuple_element<value_type, N>(*this).get(); }
+ template <int N> typename const_tuple_element<value_type, N>::const_reference get() const
+ { return const_tuple_element<value_type, N>(*this).get(); }
+ <%0.upto(i) {|j|%>
+ A<%=j%> a<%=j%>;<%}%>
+};
+<%}%>
+
+inline tuple<> make_tuple()
+{
+ return tuple<>();
+}
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>)
+{
+ return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
+}
+<%}%>
+
+} // namespace type
+
+
+inline type::tuple<>& operator>> (
+ object o,
+ type::tuple<>& v) {
+ if(o.type != type::ARRAY) { throw type_error(); }
+ return v;
+}
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> (
+ object o,
+ type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
+ if(o.type != type::ARRAY) { throw type_error(); }
+ if(o.via.array.size < <%=i+1%>) { throw type_error(); }
+ <%0.upto(i) {|j|%>
+ o.via.array.ptr[<%=j%>].convert<A<%=j%>>(&v.template get<<%=j%>>());<%}%>
+ return v;
+}
+<%}%>
+
+template <typename Stream>
+const packer<Stream>& operator<< (
+ packer<Stream>& o,
+ const type::tuple<>& v) {
+ o.pack_array(0);
+ return o;
+}
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+const packer<Stream>& operator<< (
+ packer<Stream>& o,
+ const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
+ o.pack_array(<%=i+1%>);
+ <%0.upto(i) {|j|%>
+ o.pack(v.template get<<%=j%>>());<%}%>
+ return o;
+}
+<%}%>
+
+} // namespace msgpack
+
+#endif /* msgpack/type/tuple.hpp */
+
diff --git a/cpp/msgpack/type/vector.hpp b/cpp/msgpack/type/vector.hpp
new file mode 100644
index 0000000..385d070
--- /dev/null
+++ b/cpp/msgpack/type/vector.hpp
@@ -0,0 +1,60 @@
+//
+// MessagePack for C++ static resolution routine
+//
+// 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_TYPE_VECTOR_HPP__
+#define MSGPACK_TYPE_VECTOR_HPP__
+
+#include "msgpack/object.hpp"
+#include <vector>
+
+namespace msgpack {
+
+
+template <typename T>
+inline std::vector<T>& operator>> (object o, std::vector<T>& v)
+{
+ if(o.type != type::ARRAY) { throw type_error(); }
+ v.resize(o.via.array.size);
+ if(o.via.array.size > 0) {
+ object* p = o.via.array.ptr;
+ object* const pend = o.via.array.ptr + o.via.array.size;
+ T* it = &v[0];
+ do {
+ p->convert(it);
+ ++p;
+ ++it;
+ } while(p < pend);
+ }
+ return v;
+}
+
+template <typename Stream, typename T>
+inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v)
+{
+ o.pack_array(v.size());
+ for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
+ it != it_end; ++it) {
+ o.pack(*it);
+ }
+ return o;
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/type/vector.hpp */
+
diff --git a/cpp/msgpack/unpack.hpp b/cpp/msgpack/unpack.hpp
new file mode 100644
index 0000000..324111a
--- /dev/null
+++ b/cpp/msgpack/unpack.hpp
@@ -0,0 +1,301 @@
+//
+// MessagePack for C++ deserializing routine
+//
+// 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_UNPACK_HPP__
+#define MSGPACK_UNPACK_HPP__
+
+#include "msgpack/unpack.h"
+#include "msgpack/object.hpp"
+#include "msgpack/zone.hpp"
+#include <memory>
+#include <stdexcept>
+
+#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
+#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE (32*1024)
+#endif
+
+namespace msgpack {
+
+
+struct unpack_error : public std::runtime_error {
+ unpack_error(const std::string& msg) :
+ std::runtime_error(msg) { }
+};
+
+
+class unpacker : public msgpack_unpacker {
+public:
+ unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE);
+ ~unpacker();
+
+public:
+ /*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
+ void reserve_buffer(size_t size);
+
+ /*! 2. read data to the buffer() up to buffer_capacity() bytes */
+ char* buffer();
+ size_t buffer_capacity() const;
+
+ /*! 3. specify the number of bytes actually copied */
+ void buffer_consumed(size_t size);
+
+ /*! 4. repeat execute() until it retunrs false */
+ bool execute();
+
+ /*! 5.1. if execute() returns true, take out the parsed object */
+ object data();
+
+ /*! 5.2. the object is valid until the zone is deleted */
+ // Note that once release_zone() from unpacker, you must delete it
+ // otherwise the memrory will leak.
+ zone* release_zone();
+
+ /*! 5.2. this method is equivalence to `delete release_zone()` */
+ void reset_zone();
+
+ /*! 5.3. after release_zone(), re-initialize unpacker */
+ void reset();
+
+ /*! 6. check if the size of message doesn't exceed assumption. */
+ size_t message_size() const;
+
+
+ // Basic usage of the unpacker is as following:
+ //
+ // msgpack::unpacker pac;
+ //
+ // while( /* readable */ ) {
+ //
+ // // 1.
+ // pac.reserve(1024);
+ //
+ // // 2.
+ // ssize_t bytes =
+ // read(the_source, pac.buffer(), pac.buffer_capacity());
+ //
+ // // error handling ...
+ //
+ // // 3.
+ // pac.buffer_consumed(bytes);
+ //
+ // // 4.
+ // while(pac.execute()) {
+ // // 5.1
+ // object o = pac.data();
+ //
+ // // 5.2
+ // std::auto_ptr<msgpack::zone> olife( pac.release_zone() );
+ //
+ // // boost::shared_ptr is also usable:
+ // // boost::shared_ptr<msgpack::zone> olife( pac.release_zone() );
+ //
+ // // 5.3
+ // pac.reset();
+ //
+ // // do some with the object with the old zone.
+ // do_something(o, olife);
+ // }
+ // }
+ //
+
+public:
+ // These functions are usable when non-MessagePack message follows after
+ // MessagePack message.
+ size_t parsed_size() const;
+
+ /*! get address of the buffer that is not parsed */
+ char* nonparsed_buffer();
+ size_t nonparsed_size() const;
+
+ /*! skip specified size of non-parsed buffer, leaving the buffer */
+ // Note that the `size' argument must be smaller than nonparsed_size()
+ void skip_nonparsed_buffer(size_t size);
+
+ /*! remove unparsed buffer from unpacker */
+ // Note that reset() leaves non-parsed buffer.
+ void remove_nonparsed_buffer();
+
+private:
+ typedef msgpack_unpacker base;
+
+private:
+ unpacker(const unpacker&);
+};
+
+
+typedef enum {
+ UNPACK_SUCCESS = 2,
+ UNPACK_EXTRA_BYTES = 1,
+ UNPACK_CONTINUE = 0,
+ UNPACK_PARSE_ERROR = -1,
+} unpack_return;
+
+static unpack_return unpack(const char* data, size_t len, size_t* off,
+ zone* z, object* result);
+
+
+// obsolete
+static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);
+
+
+inline unpacker::unpacker(size_t initial_buffer_size)
+{
+ if(!msgpack_unpacker_init(this, initial_buffer_size)) {
+ throw std::bad_alloc();
+ }
+}
+
+inline unpacker::~unpacker()
+{
+ msgpack_unpacker_destroy(this);
+}
+
+
+inline void unpacker::reserve_buffer(size_t size)
+{
+ if(!msgpack_unpacker_reserve_buffer(this, size)) {
+ throw std::bad_alloc();
+ }
+}
+
+inline char* unpacker::buffer()
+{
+ return msgpack_unpacker_buffer(this);
+}
+
+inline size_t unpacker::buffer_capacity() const
+{
+ return msgpack_unpacker_buffer_capacity(this);
+}
+
+inline void unpacker::buffer_consumed(size_t size)
+{
+ return msgpack_unpacker_buffer_consumed(this, size);
+}
+
+
+inline bool unpacker::execute()
+{
+ int ret = msgpack_unpacker_execute(this);
+ if(ret < 0) {
+ throw unpack_error("parse error");
+ } else if(ret == 0) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+inline object unpacker::data()
+{
+ return msgpack_unpacker_data(this);
+}
+
+inline zone* unpacker::release_zone()
+{
+ if(!msgpack_unpacker_flush_zone(this)) {
+ throw std::bad_alloc();
+ }
+
+ zone* r = new zone();
+
+ msgpack_zone old = *base::z;
+ *base::z = *r;
+ *static_cast<msgpack_zone*>(r) = old;
+
+ return r;
+}
+
+inline void unpacker::reset_zone()
+{
+ msgpack_unpacker_reset_zone(this);
+}
+
+inline void unpacker::reset()
+{
+ msgpack_unpacker_reset(this);
+}
+
+inline size_t unpacker::message_size() const
+{
+ return msgpack_unpacker_message_size(this);
+}
+
+
+inline size_t unpacker::parsed_size() const
+{
+ return msgpack_unpacker_parsed_size(this);
+}
+
+inline char* unpacker::nonparsed_buffer()
+{
+ return base::buffer + base::off;
+}
+
+inline size_t unpacker::nonparsed_size() const
+{
+ return base::used - base::off;
+}
+
+inline void unpacker::skip_nonparsed_buffer(size_t size)
+{
+ base::off += size;
+}
+
+inline void unpacker::remove_nonparsed_buffer()
+{
+ base::used = base::off;
+}
+
+
+inline unpack_return unpack(const char* data, size_t len, size_t* off,
+ zone* z, object* result)
+{
+ return (unpack_return)msgpack_unpack(data, len, off,
+ z, reinterpret_cast<msgpack_object*>(result));
+}
+
+// obsolete
+inline object unpack(const char* data, size_t len, zone& z, size_t* off)
+{
+ object result;
+
+ switch( msgpack::unpack(data, len, off, &z, &result) ) {
+ case UNPACK_SUCCESS:
+ return result;
+
+ case UNPACK_EXTRA_BYTES:
+ if(off) {
+ return result;
+ } else {
+ throw unpack_error("extra bytes");
+ }
+
+ case UNPACK_CONTINUE:
+ throw unpack_error("insufficient bytes");
+
+ case UNPACK_PARSE_ERROR:
+ default:
+ throw unpack_error("parse error");
+ }
+}
+
+
+} // namespace msgpack
+
+#endif /* msgpack/unpack.hpp */
+
diff --git a/cpp/msgpack/vrefbuffer.hpp b/cpp/msgpack/vrefbuffer.hpp
new file mode 100644
index 0000000..c8eca7b
--- /dev/null
+++ b/cpp/msgpack/vrefbuffer.hpp
@@ -0,0 +1,92 @@
+//
+// 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);
+ }
+
+ void migrate(vrefbuffer* to)
+ {
+ if(msgpack_vrefbuffer_migrate(this, to) < 0) {
+ throw std::bad_alloc();
+ }
+ }
+
+private:
+ typedef msgpack_vrefbuffer base;
+
+private:
+ vrefbuffer(const vrefbuffer&);
+};
+
+
+} // namespace msgpack
+
+#endif /* msgpack/vrefbuffer.hpp */
+
diff --git a/cpp/msgpack/zone.hpp.erb b/cpp/msgpack/zone.hpp.erb
new file mode 100644
index 0000000..48988ab
--- /dev/null
+++ b/cpp/msgpack/zone.hpp.erb
@@ -0,0 +1,149 @@
+//
+// MessagePack for C++ memory pool
+//
+// 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_ZONE_HPP__
+#define MSGPACK_ZONE_HPP__
+
+#include "msgpack/object.hpp"
+#include "msgpack/zone.h"
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+<% GENERATION_LIMIT = 15 %>
+namespace msgpack {
+
+
+class zone : public msgpack_zone {
+public:
+ zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
+ ~zone();
+
+public:
+ void* malloc(size_t size);
+ void* malloc_no_align(size_t size);
+
+ void push_finalizer(void (*func)(void*), void* data);
+
+ template <typename T>
+ void push_finalizer(std::auto_ptr<T> obj);
+
+ void clear();
+
+ <%0.upto(GENERATION_LIMIT) {|i|%>
+ template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+ T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
+ <%}%>
+
+private:
+ void undo_malloc(size_t size);
+
+ template <typename T>
+ static void object_destructor(void* obj);
+
+ typedef msgpack_zone base;
+
+private:
+ zone(const zone&);
+};
+
+
+
+inline zone::zone(size_t chunk_size)
+{
+ msgpack_zone_init(this, chunk_size);
+}
+
+inline zone::~zone()
+{
+ msgpack_zone_destroy(this);
+}
+
+inline void* zone::malloc(size_t size)
+{
+ void* ptr = msgpack_zone_malloc(this, size);
+ if(!ptr) {
+ throw std::bad_alloc();
+ }
+ 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)) {
+ throw std::bad_alloc();
+ }
+}
+
+template <typename T>
+inline void zone::push_finalizer(std::auto_ptr<T> obj)
+{
+ if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, obj.get())) {
+ throw std::bad_alloc();
+ }
+ obj.release();
+}
+
+inline void zone::clear()
+{
+ msgpack_zone_clear(this);
+}
+
+template <typename T>
+void zone::object_destructor(void* obj)
+{
+ reinterpret_cast<T*>(obj)->~T();
+}
+
+inline void zone::undo_malloc(size_t size)
+{
+ base::chunk_list.ptr -= size;
+ base::chunk_list.free += size;
+}
+
+<%0.upto(GENERATION_LIMIT) {|i|%>
+template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
+T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
+{
+ void* x = malloc(sizeof(T));
+ if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, x)) {
+ undo_malloc(sizeof(T));
+ throw std::bad_alloc();
+ }
+ try {
+ return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
+ } catch (...) {
+ --base::finalizer_array.tail;
+ undo_malloc(sizeof(T));
+ throw;
+ }
+}
+<%}%>
+
+} // namespace msgpack
+
+#endif /* msgpack/zone.hpp */
+