summaryrefslogtreecommitdiff
path: root/cpp/msgpack
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/msgpack')
-rw-r--r--cpp/msgpack/object.h88
-rw-r--r--cpp/msgpack/pack.h116
-rw-r--r--cpp/msgpack/sbuffer.h86
-rw-r--r--cpp/msgpack/unpack.h123
-rw-r--r--cpp/msgpack/vrefbuffer.h110
-rw-r--r--cpp/msgpack/zbuffer.h180
-rw-r--r--cpp/msgpack/zone.h131
7 files changed, 834 insertions, 0 deletions
diff --git a/cpp/msgpack/object.h b/cpp/msgpack/object.h
new file mode 100644
index 0000000..9a014be
--- /dev/null
+++ b/cpp/msgpack/object.h
@@ -0,0 +1,88 @@
+/*
+ * MessagePack for C dynamic typing 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_H__
+#define MSGPACK_OBJECT_H__
+
+#include "msgpack/zone.h"
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum {
+ MSGPACK_OBJECT_NIL = 0x01,
+ MSGPACK_OBJECT_BOOLEAN = 0x02,
+ MSGPACK_OBJECT_POSITIVE_INTEGER = 0x03,
+ MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x04,
+ MSGPACK_OBJECT_DOUBLE = 0x05,
+ MSGPACK_OBJECT_RAW = 0x06,
+ MSGPACK_OBJECT_ARRAY = 0x07,
+ MSGPACK_OBJECT_MAP = 0x08,
+} msgpack_object_type;
+
+
+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;
+ msgpack_object_array array;
+ msgpack_object_map map;
+ msgpack_object_raw raw;
+} msgpack_object_union;
+
+typedef struct msgpack_object {
+ msgpack_object_type type;
+ msgpack_object_union via;
+} msgpack_object;
+
+typedef struct msgpack_object_kv {
+ msgpack_object key;
+ msgpack_object val;
+} msgpack_object_kv;
+
+
+void msgpack_object_print(FILE* out, msgpack_object o);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/object.h */
+
diff --git a/cpp/msgpack/pack.h b/cpp/msgpack/pack.h
new file mode 100644
index 0000000..1525e0f
--- /dev/null
+++ b/cpp/msgpack/pack.h
@@ -0,0 +1,116 @@
+/*
+ * MessagePack for C packing 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_H__
+#define MSGPACK_PACK_H__
+
+#include "msgpack/pack_define.h"
+#include "msgpack/object.h"
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len);
+
+typedef struct msgpack_packer {
+ void* data;
+ msgpack_packer_write callback;
+} msgpack_packer;
+
+static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback);
+
+static msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback);
+static void msgpack_packer_free(msgpack_packer* pk);
+
+static int msgpack_pack_short(msgpack_packer* pk, short d);
+static int msgpack_pack_int(msgpack_packer* pk, int d);
+static int msgpack_pack_long(msgpack_packer* pk, long d);
+static int msgpack_pack_long_long(msgpack_packer* pk, long long d);
+static int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d);
+static int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d);
+static int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d);
+static int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d);
+
+static int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d);
+static int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d);
+static int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d);
+static int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d);
+static int msgpack_pack_int8(msgpack_packer* pk, int8_t d);
+static int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
+static int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
+static int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
+
+static int msgpack_pack_float(msgpack_packer* pk, float d);
+static int msgpack_pack_double(msgpack_packer* pk, double d);
+
+static int msgpack_pack_nil(msgpack_packer* pk);
+static int msgpack_pack_true(msgpack_packer* pk);
+static int msgpack_pack_false(msgpack_packer* pk);
+
+static int msgpack_pack_array(msgpack_packer* pk, unsigned int n);
+
+static int msgpack_pack_map(msgpack_packer* pk, unsigned int n);
+
+static int msgpack_pack_raw(msgpack_packer* pk, size_t l);
+static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l);
+
+int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
+
+
+
+#define msgpack_pack_inline_func(name) \
+ inline int msgpack_pack ## name
+
+#define msgpack_pack_inline_func_cint(name) \
+ inline int msgpack_pack ## name
+
+#define msgpack_pack_user msgpack_packer*
+
+#define msgpack_pack_append_buffer(user, buf, len) \
+ return (*(user)->callback)((user)->data, (const char*)buf, len)
+
+#include "msgpack/pack_template.h"
+
+inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
+{
+ pk->data = data;
+ pk->callback = callback;
+}
+
+inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback)
+{
+ msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer));
+ if(!pk) { return NULL; }
+ msgpack_packer_init(pk, data, callback);
+ return pk;
+}
+
+inline void msgpack_packer_free(msgpack_packer* pk)
+{
+ free(pk);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/pack.h */
+
diff --git a/cpp/msgpack/sbuffer.h b/cpp/msgpack/sbuffer.h
new file mode 100644
index 0000000..bc0a8fd
--- /dev/null
+++ b/cpp/msgpack/sbuffer.h
@@ -0,0 +1,86 @@
+/*
+ * 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_H__
+#define MSGPACK_SBUFFER_H__
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef MSGPACK_SBUFFER_INIT_SIZE
+#define MSGPACK_SBUFFER_INIT_SIZE 8192
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct msgpack_sbuffer {
+ size_t size;
+ char* data;
+ size_t alloc;
+} msgpack_sbuffer;
+
+static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
+{
+ memset(sbuf, 0, sizeof(msgpack_sbuffer));
+}
+
+static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
+{
+ free(sbuf->data);
+}
+
+static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len)
+{
+ msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
+
+ if(sbuf->alloc - sbuf->size < len) {
+ size_t nsize = (sbuf->alloc) ?
+ sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
+
+ while(nsize < sbuf->size + len) { nsize *= 2; }
+
+ void* tmp = realloc(sbuf->data, nsize);
+ if(!tmp) { return -1; }
+
+ sbuf->data = (char*)tmp;
+ sbuf->alloc = nsize;
+ }
+
+ memcpy(sbuf->data + sbuf->size, buf, len);
+ sbuf->size += len;
+ return 0;
+}
+
+static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
+{
+ char* tmp = sbuf->data;
+ sbuf->size = 0;
+ sbuf->data = NULL;
+ sbuf->alloc = 0;
+ return tmp;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/sbuffer.h */
+
diff --git a/cpp/msgpack/unpack.h b/cpp/msgpack/unpack.h
new file mode 100644
index 0000000..e17d0d8
--- /dev/null
+++ b/cpp/msgpack/unpack.h
@@ -0,0 +1,123 @@
+/*
+ * MessagePack for C unpacking 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_UNPACKER_H__
+#define MSGPACK_UNPACKER_H__
+
+#include "msgpack/zone.h"
+#include "msgpack/object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct msgpack_unpacker {
+ char* buffer;
+ size_t used;
+ size_t free;
+ size_t off;
+ size_t parsed;
+ msgpack_zone* z;
+ size_t initial_buffer_size;
+ void* ctx;
+} msgpack_unpacker;
+
+
+bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size);
+void msgpack_unpacker_destroy(msgpack_unpacker* mpac);
+
+msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size);
+void msgpack_unpacker_free(msgpack_unpacker* mpac);
+
+static inline bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size);
+static inline char* msgpack_unpacker_buffer(msgpack_unpacker* mpac);
+static inline size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac);
+static inline void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size);
+
+
+int msgpack_unpacker_execute(msgpack_unpacker* mpac);
+
+msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac);
+
+msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac);
+
+void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac);
+
+void msgpack_unpacker_reset(msgpack_unpacker* mpac);
+
+static inline size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac);
+
+
+
+typedef enum {
+ MSGPACK_UNPACK_SUCCESS = 2,
+ MSGPACK_UNPACK_EXTRA_BYTES = 1,
+ MSGPACK_UNPACK_CONTINUE = 0,
+ MSGPACK_UNPACK_PARSE_ERROR = -1,
+} msgpack_unpack_return;
+
+msgpack_unpack_return
+msgpack_unpack(const char* data, size_t len, size_t* off,
+ msgpack_zone* z, msgpack_object* result);
+
+
+static inline size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac);
+
+bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac);
+
+bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size);
+
+bool msgpack_unpacker_reserve_buffer(msgpack_unpacker* mpac, size_t size)
+{
+ if(mpac->free >= size) { return true; }
+ return msgpack_unpacker_expand_buffer(mpac, size);
+}
+
+char* msgpack_unpacker_buffer(msgpack_unpacker* mpac)
+{
+ return mpac->buffer + mpac->used;
+}
+
+size_t msgpack_unpacker_buffer_capacity(const msgpack_unpacker* mpac)
+{
+ return mpac->free;
+}
+
+void msgpack_unpacker_buffer_consumed(msgpack_unpacker* mpac, size_t size)
+{
+ mpac->used += size;
+ mpac->free -= size;
+}
+
+size_t msgpack_unpacker_message_size(const msgpack_unpacker* mpac)
+{
+ return mpac->parsed - mpac->off + mpac->used;
+}
+
+size_t msgpack_unpacker_parsed_size(const msgpack_unpacker* mpac)
+{
+ return mpac->parsed;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/unpack.h */
+
diff --git a/cpp/msgpack/vrefbuffer.h b/cpp/msgpack/vrefbuffer.h
new file mode 100644
index 0000000..38ead67
--- /dev/null
+++ b/cpp/msgpack/vrefbuffer.h
@@ -0,0 +1,110 @@
+/*
+ * 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_H__
+#define MSGPACK_VREFBUFFER_H__
+
+#include "msgpack/zone.h"
+
+#ifndef _WIN32
+#include <sys/uio.h>
+#else
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+
+#ifndef MSGPACK_VREFBUFFER_REF_SIZE
+#define MSGPACK_VREFBUFFER_REF_SIZE 32
+#endif
+
+#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
+#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct msgpack_vrefbuffer_chunk;
+typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk;
+
+typedef struct msgpack_vrefbuffer_inner_buffer {
+ size_t free;
+ char* ptr;
+ msgpack_vrefbuffer_chunk* head;
+} msgpack_vrefbuffer_inner_buffer;
+
+typedef struct msgpack_vrefbuffer {
+ struct iovec* tail;
+ struct iovec* end;
+ struct iovec* array;
+
+ size_t chunk_size;
+ size_t ref_size;
+
+ msgpack_vrefbuffer_inner_buffer inner_buffer;
+} msgpack_vrefbuffer;
+
+
+bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
+ size_t ref_size, size_t chunk_size);
+void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf);
+
+static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len);
+
+static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref);
+static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref);
+
+int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
+ const char* buf, unsigned int len);
+
+int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
+ const char* buf, unsigned int len);
+
+int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to);
+
+int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
+{
+ msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data;
+
+ if(len < vbuf->ref_size) {
+ return msgpack_vrefbuffer_append_copy(vbuf, buf, len);
+ } else {
+ return msgpack_vrefbuffer_append_ref(vbuf, buf, len);
+ }
+}
+
+const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref)
+{
+ return vref->array;
+}
+
+size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref)
+{
+ return vref->tail - vref->array;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/vrefbuffer.h */
+
diff --git a/cpp/msgpack/zbuffer.h b/cpp/msgpack/zbuffer.h
new file mode 100644
index 0000000..2a32206
--- /dev/null
+++ b/cpp/msgpack/zbuffer.h
@@ -0,0 +1,180 @@
+/*
+ * MessagePack for C deflate buffer implementation
+ *
+ * Copyright (C) 2010 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_ZBUFFER_H__
+#define MSGPACK_ZBUFFER_H__
+
+#include "msgpack/sysdep.h"
+#include <stdlib.h>
+#include <string.h>
+#include <zlib.h>
+
+#ifndef MSGPACK_ZBUFFER_INIT_SIZE
+#define MSGPACK_ZBUFFER_INIT_SIZE 8192
+#endif
+
+#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
+#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct msgpack_zbuffer {
+ z_stream stream;
+ char* data;
+ size_t init_size;
+} msgpack_zbuffer;
+
+
+static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
+ int level, size_t init_size);
+static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);
+
+static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf);
+
+static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf);
+static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf);
+
+static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf);
+static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf);
+static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf);
+
+
+static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len);
+
+static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);
+
+
+bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
+ int level, size_t init_size)
+{
+ memset(zbuf, 0, sizeof(msgpack_zbuffer));
+ zbuf->init_size = init_size;
+ if(deflateInit(&zbuf->stream, level) != Z_OK) {
+ free(zbuf->data);
+ return false;
+ }
+ return true;
+}
+
+void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
+{
+ deflateEnd(&zbuf->stream);
+ free(zbuf->data);
+}
+
+bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
+{
+ size_t used = (char*)zbuf->stream.next_out - zbuf->data;
+ size_t csize = used + zbuf->stream.avail_out;
+ size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2;
+
+ char* tmp = (char*)realloc(zbuf->data, nsize);
+ if(tmp == NULL) {
+ return false;
+ }
+
+ zbuf->data = tmp;
+ zbuf->stream.next_out = (Bytef*)(tmp + used);
+ zbuf->stream.avail_out = nsize - used;
+
+ return true;
+}
+
+int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len)
+{
+ msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data;
+
+ zbuf->stream.next_in = (Bytef*)buf;
+ zbuf->stream.avail_in = len;
+
+ do {
+ if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
+ if(!msgpack_zbuffer_expand(zbuf)) {
+ return -1;
+ }
+ }
+
+ if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) {
+ return -1;
+ }
+ } while(zbuf->stream.avail_in > 0);
+
+ return 0;
+}
+
+char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf)
+{
+ while(true) {
+ switch(deflate(&zbuf->stream, Z_FINISH)) {
+ case Z_STREAM_END:
+ return zbuf->data;
+ case Z_OK:
+ if(!msgpack_zbuffer_expand(zbuf)) {
+ return NULL;
+ }
+ break;
+ default:
+ return NULL;
+ }
+ }
+}
+
+const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf)
+{
+ return zbuf->data;
+}
+
+size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf)
+{
+ return (char*)zbuf->stream.next_out - zbuf->data;
+}
+
+void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf)
+{
+ zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data;
+ zbuf->stream.next_out = (Bytef*)zbuf->data;
+}
+
+bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf)
+{
+ if(deflateReset(&zbuf->stream) != Z_OK) {
+ return false;
+ }
+ msgpack_zbuffer_reset_buffer(zbuf);
+ return true;
+}
+
+char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
+{
+ char* tmp = zbuf->data;
+ zbuf->data = NULL;
+ zbuf->stream.next_out = NULL;
+ zbuf->stream.avail_out = 0;
+ return tmp;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/zbuffer.h */
+
diff --git a/cpp/msgpack/zone.h b/cpp/msgpack/zone.h
new file mode 100644
index 0000000..ce5be6d
--- /dev/null
+++ b/cpp/msgpack/zone.h
@@ -0,0 +1,131 @@
+/*
+ * MessagePack for C memory pool 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_ZONE_H__
+#define MSGPACK_ZONE_H__
+
+#include "msgpack/sysdep.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct msgpack_zone_finalizer {
+ void (*func)(void* data);
+ void* data;
+} msgpack_zone_finalizer;
+
+typedef struct msgpack_zone_finalizer_array {
+ msgpack_zone_finalizer* tail;
+ msgpack_zone_finalizer* end;
+ msgpack_zone_finalizer* array;
+} msgpack_zone_finalizer_array;
+
+struct msgpack_zone_chunk;
+typedef struct msgpack_zone_chunk msgpack_zone_chunk;
+
+typedef struct msgpack_zone_chunk_list {
+ size_t free;
+ char* ptr;
+ msgpack_zone_chunk* head;
+} msgpack_zone_chunk_list;
+
+typedef struct msgpack_zone {
+ msgpack_zone_chunk_list chunk_list;
+ msgpack_zone_finalizer_array finalizer_array;
+ size_t chunk_size;
+} msgpack_zone;
+
+#ifndef MSGPACK_ZONE_CHUNK_SIZE
+#define MSGPACK_ZONE_CHUNK_SIZE 8192
+#endif
+
+bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size);
+void msgpack_zone_destroy(msgpack_zone* zone);
+
+msgpack_zone* msgpack_zone_new(size_t chunk_size);
+void msgpack_zone_free(msgpack_zone* zone);
+
+static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size);
+static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size);
+
+static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
+ void (*func)(void* data), void* data);
+
+bool msgpack_zone_is_empty(msgpack_zone* zone);
+
+void msgpack_zone_clear(msgpack_zone* zone);
+
+
+
+#ifndef MSGPACK_ZONE_ALIGN
+#define MSGPACK_ZONE_ALIGN sizeof(int)
+#endif
+
+void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size);
+
+void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size)
+{
+ msgpack_zone_chunk_list* cl = &zone->chunk_list;
+
+ if(zone->chunk_list.free < size) {
+ return msgpack_zone_malloc_expand(zone, size);
+ }
+
+ char* ptr = cl->ptr;
+ cl->free -= size;
+ cl->ptr += size;
+
+ return ptr;
+}
+
+void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
+{
+ return msgpack_zone_malloc_no_align(zone,
+ ((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
+}
+
+
+bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
+ void (*func)(void* data), void* data);
+
+bool msgpack_zone_push_finalizer(msgpack_zone* zone,
+ void (*func)(void* data), void* data)
+{
+ msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
+ msgpack_zone_finalizer* fin = fa->tail;
+
+ if(fin == fa->end) {
+ return msgpack_zone_push_finalizer_expand(zone, func, data);
+ }
+
+ fin->func = func;
+ fin->data = data;
+
+ ++fa->tail;
+
+ return true;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* msgpack/zone.h */
+