summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorfrsyuki <frsyuki@users.sourceforge.jp>2010-04-18 00:08:03 +0900
committerfrsyuki <frsyuki@users.sourceforge.jp>2010-04-18 00:08:03 +0900
commitab8e0c9e31585b24f1d4cbfb1e73b0ce249e408a (patch)
tree042100bffb170e6bec88cc497345bd4074e2f067 /cpp
parentc3f43fb0cf14f596a9ebb1c30b0417b3a8ba9958 (diff)
downloadmsgpack-python-ab8e0c9e31585b24f1d4cbfb1e73b0ce249e408a.tar.gz
c,cpp: reforms source tree
Diffstat (limited to 'cpp')
-rw-r--r--cpp/AUTHORS1
-rw-r--r--cpp/COPYING14
-rw-r--r--cpp/ChangeLog0
-rw-r--r--cpp/LICENSE202
-rw-r--r--cpp/Makefile.am56
-rw-r--r--cpp/NOTICE4
-rw-r--r--cpp/bench.cpp188
-rw-r--r--cpp/bench.mk9
-rwxr-xr-xcpp/bootstrap126
-rw-r--r--cpp/configure.in43
-rw-r--r--cpp/msgpack.h23
-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
-rw-r--r--cpp/msgpack_test.cpp (renamed from cpp/test.cpp)0
-rw-r--r--cpp/msgpack_vc8.postbuild.bat49
-rw-r--r--cpp/msgpack_vc8.sln20
-rw-r--r--cpp/msgpack_vc8.vcproj283
-rw-r--r--cpp/msgpackc_test.cpp424
-rw-r--r--cpp/object.c171
-rwxr-xr-xcpp/preprocess (renamed from cpp/preprocess.sh)4
-rw-r--r--cpp/unpack.c407
-rw-r--r--cpp/vrefbuffer.c201
-rw-r--r--cpp/zone.c220
28 files changed, 3076 insertions, 203 deletions
diff --git a/cpp/AUTHORS b/cpp/AUTHORS
new file mode 100644
index 0000000..ababacb
--- /dev/null
+++ b/cpp/AUTHORS
@@ -0,0 +1 @@
+FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>
diff --git a/cpp/COPYING b/cpp/COPYING
new file mode 100644
index 0000000..4388e8f
--- /dev/null
+++ b/cpp/COPYING
@@ -0,0 +1,14 @@
+Copyright (C) 2008-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.
+
diff --git a/cpp/ChangeLog b/cpp/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cpp/ChangeLog
diff --git a/cpp/LICENSE b/cpp/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/cpp/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index c1b4981..aba7e28 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -1,9 +1,38 @@
-lib_LTLIBRARIES = libmsgpack.la
+lib_LTLIBRARIES = libmsgpackc.la libmsgpack.la
+
+libmsgpackc_la_SOURCES = \
+ unpack.c \
+ object.c \
+ vrefbuffer.c \
+ zone.c
+
+# -version-info CURRENT:REVISION:AGE
+libmsgpackc_la_LDFLAGS = -version-info 2:0:0
+
libmsgpack_la_SOURCES = \
object.cpp
+libmsgpack_la_LIBADD = -lmsgpackc
+
+# -version-info CURRENT:REVISION:AGE
+libmsgpack_la_LDFLAGS = -version-info 2:0:0
+
+
nobase_include_HEADERS = \
+ msgpack/pack_define.h \
+ msgpack/pack_template.h \
+ msgpack/unpack_define.h \
+ msgpack/unpack_template.h \
+ msgpack/sysdep.h \
+ msgpack.h \
+ msgpack/sbuffer.h \
+ msgpack/vrefbuffer.h \
+ msgpack/zbuffer.h \
+ msgpack/pack.h \
+ msgpack/unpack.h \
+ msgpack/object.h \
+ msgpack/zone.h \
msgpack.hpp \
msgpack/sbuffer.hpp \
msgpack/vrefbuffer.hpp \
@@ -30,16 +59,31 @@ nobase_include_HEADERS = \
msgpack/type/tr1/unordered_map.hpp \
msgpack/type/tr1/unordered_set.hpp
-libmsgpack_la_LIBADD = -L../c -lmsgpackc
-# -version-info CURRENT:REVISION:AGE
-libmsgpack_la_LDFLAGS = -version-info 2:0:0
+# work around for duplicated object file name
+libmsgpackc_la_CFLAGS = $(AM_CFLAGS)
+libmsgpackc_la_CXXFLAGS = $(AM_CXXFLAGS)
+libmsgpack_la_CFLAGS = $(AM_CFLAGS)
+libmsgpack_la_CXXFLAGS = $(AM_CXXFLAGS)
+
+
+EXTRA_DIST = \
+ msgpack_vc8.vcproj \
+ msgpack_vc8.sln \
+ msgpack_vc8.postbuild.bat
+
check_PROGRAMS = \
- msgpack_test
+ msgpackc_test \
+ msgpack_test
-msgpack_test_SOURCES = test.cpp
+msgpackc_test_SOURCES = msgpackc_test.cpp
+msgpackc_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c
+msgpackc_test_LDADD = libmsgpackc.la -lgtest_main
+
+msgpack_test_SOURCES = msgpack_test.cpp
msgpack_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c -I$(top_srcdir)/cpp
msgpack_test_LDADD = libmsgpack.la -lgtest_main
TESTS = $(check_PROGRAMS)
+
diff --git a/cpp/NOTICE b/cpp/NOTICE
new file mode 100644
index 0000000..e706f2a
--- /dev/null
+++ b/cpp/NOTICE
@@ -0,0 +1,4 @@
+MessagePack is developed by FURUHASHI Sadayuki, licensed under Apache License,
+Version 2.0. The original software and related information is available at
+http://msgpack.sourceforge.jp/.
+
diff --git a/cpp/bench.cpp b/cpp/bench.cpp
deleted file mode 100644
index aa303fa..0000000
--- a/cpp/bench.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <msgpack/unpack.hpp>
-#include <msgpack/pack.hpp>
-#include <string.h>
-#include <sys/time.h>
-#include <iostream>
-#include <stdexcept>
-#include <string>
-
-static const unsigned int TASK_INT_NUM = 1<<24;
-static const unsigned int TASK_STR_LEN = 1<<15;
-//static const unsigned int TASK_INT_NUM = 1<<22;
-//static const unsigned int TASK_STR_LEN = 1<<13;
-static const char* TASK_STR_PTR;
-
-
-class simple_timer {
-public:
- void reset() { gettimeofday(&m_timeval, NULL); }
- void show_stat(size_t bufsz)
- {
- struct timeval endtime;
- gettimeofday(&endtime, NULL);
- double sec = (endtime.tv_sec - m_timeval.tv_sec)
- + (double)(endtime.tv_usec - m_timeval.tv_usec) / 1000 / 1000;
- std::cout << sec << " sec" << std::endl;
- std::cout << (double(bufsz)/1024/1024) << " MB" << std::endl;
- std::cout << (bufsz/sec/1000/1000*8) << " Mbps" << std::endl;
- }
-private:
- timeval m_timeval;
-};
-
-
-class simple_buffer {
-public:
- static const size_t DEFAULT_INITIAL_SIZE = 32*1024;//512*1024*1024*2;
-
- simple_buffer(size_t initial_size = DEFAULT_INITIAL_SIZE) :
- m_storage((char*)malloc(initial_size)),
- m_allocated(initial_size),
- m_used(0)
- {
- if(!m_storage) { throw std::bad_alloc(); }
- }
-
- ~simple_buffer()
- {
- free(m_storage);
- }
-
-public:
- inline void write(const char* buf, size_t len)
- {
- if(m_allocated - m_used < len) {
- expand_buffer(len);
- }
- memcpy(m_storage + m_used, buf, len);
- m_used += len;
- }
-
- void clear()
- {
- m_used = 0;
- }
-
-private:
- void expand_buffer(size_t req)
- {
- size_t nsize = m_allocated * 2;
- size_t at_least = m_used + req;
- while(nsize < at_least) { nsize *= 2; }
- char* tmp = (char*)realloc(m_storage, nsize);
- if(!tmp) { throw std::bad_alloc(); }
- m_storage = tmp;
- m_allocated = nsize;
- }
-
-public:
- size_t size() const { return m_used; }
- const char* data() const { return m_storage; }
-
-private:
- char* m_storage;
- size_t m_allocated;
- size_t m_used;
-};
-
-
-void bench_msgpack_int()
-{
- simple_buffer buf;
- simple_timer timer;
-
- std::cout << "----" << std::endl;
- std::cout << "pack integer" << std::endl;
-
- timer.reset();
- {
- msgpack::packer<simple_buffer> pk(buf);
- pk.pack_array(TASK_INT_NUM);
- for(unsigned int i=0; i < TASK_INT_NUM; ++i) {
- pk.pack_unsigned_int(i);
- }
- }
- timer.show_stat(buf.size());
-
-
- std::cout << "----" << std::endl;
- std::cout << "unpack integer" << std::endl;
-
- msgpack::zone z;
- msgpack::object obj;
-
- timer.reset();
- {
- obj = msgpack::unpack(buf.data(), buf.size(), z);
- }
- timer.show_stat(buf.size());
-
- /*
- std::cout << "----" << std::endl;
- std::cout << "dynamic pack integer" << std::endl;
-
- buf.clear();
-
- timer.reset();
- msgpack::pack(buf, obj);
- timer.show_stat(buf.size());
- */
-}
-
-void bench_msgpack_str()
-{
- simple_buffer buf;
- simple_timer timer;
-
- std::cout << "----" << std::endl;
- std::cout << "pack string" << std::endl;
-
- timer.reset();
- {
- msgpack::packer<simple_buffer> pk(buf);
- pk.pack_array(TASK_STR_LEN);
- for(unsigned int i=0; i < TASK_STR_LEN; ++i) {
- pk.pack_raw(i);
- pk.pack_raw_body(TASK_STR_PTR, i);
- }
- }
- timer.show_stat(buf.size());
-
-
- std::cout << "----" << std::endl;
- std::cout << "unpack string" << std::endl;
-
- msgpack::zone z;
- msgpack::object obj;
-
- timer.reset();
- {
- obj = msgpack::unpack(buf.data(), buf.size(), z);
- }
- timer.show_stat(buf.size());
-
-
- /*
- std::cout << "----" << std::endl;
- std::cout << "dynamic pack string" << std::endl;
-
- buf.clear();
-
- timer.reset();
- msgpack::pack(buf, obj);
- timer.show_stat(buf.size());
- */
-}
-
-int main(void)
-{
- char* str = (char*)malloc(TASK_STR_LEN);
- memset(str, 'a', TASK_STR_LEN);
- TASK_STR_PTR = str;
-
- bench_msgpack_int();
- bench_msgpack_str();
-
- return 0;
-}
-
diff --git a/cpp/bench.mk b/cpp/bench.mk
deleted file mode 100644
index 8da2b7f..0000000
--- a/cpp/bench.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-
-CXXFLAGS += -Wall -g -I. -I.. -O4
-LDFLAGS +=
-
-all: bench
-
-bench: bench.o unpack.o zone.o object.o pack.hpp unpack.hpp zone.hpp object.hpp
- $(CXX) bench.o unpack.o zone.o object.o $(CXXFLAGS) $(LDFLAGS) -o $@
-
diff --git a/cpp/bootstrap b/cpp/bootstrap
new file mode 100755
index 0000000..4a04e0a
--- /dev/null
+++ b/cpp/bootstrap
@@ -0,0 +1,126 @@
+#!/bin/sh
+# vim:ts=4:sw=4
+# Calls autotools to build configure script and Makefile.in.
+# Generated automatically using bootstrapper 0.2.1
+# http://bootstrapper.sourceforge.net/
+#
+# Copyright (C) 2002 Anthony Ventimiglia
+#
+# This bootstrap script is free software; you can redistribute
+# it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+#
+# Calls proper programs to create configure script and Makefile.in files.
+# if run with the --clean option, bootstrap removes files it generates. To
+# clean all autogenerated files (eg: for cvs imports) first run
+# make distclean, then bootstrap --clean
+# see bootstrapper(1) for more infor
+
+
+if test x"$1" = x"--help"; then
+ echo "$0: automatic bootstrapping utility for GNU Autotools"
+ echo " cleans up old autogenerated files and runs autoconf,"
+ echo " automake and aclocal on local directory"
+ echo
+ echo " --clean clean up auto-generated files without"
+ echo " creating new scripts"
+ echo
+ exit 0
+fi
+
+
+mkdir -p ac
+test -f AUTHORS || touch AUTHORS
+test -f COPYING || touch COPYING
+test -f ChangeLog || touch ChangeLog
+test -f NEWS || touch NEWS
+test -f README || touch README
+
+if ! ./preprocess; then
+ exit 1
+fi
+
+
+
+ACLOCAL="aclocal"
+ACLOCAL_FILES="aclocal.m4"
+ALWAYS_CLEAN="config.status config.log config.cache libtool"
+AUTOCONF="autoconf"
+AUTOCONF_FILES="configure"
+AUTOHEADER="autoheader"
+AUTOHEADER_FILES=""
+AUTOMAKE="automake --add-missing --copy"
+AUTOMAKE_FILES="config.sub stamp-h.in ltmain.sh missing mkinstalldirs install-sh config.guess"
+CONFIG_AUX_DIR="."
+CONFIG_FILES="stamp-h ltconfig"
+CONFIG_HEADER=""
+if [ x`uname` = x"Darwin" ]; then
+ LIBTOOLIZE="glibtoolize --force --copy"
+else
+ LIBTOOLIZE="libtoolize --force --copy"
+fi
+LIBTOOLIZE_FILES="config.sub ltmain.sh config.guess"
+RM="rm"
+SUBDIRS="[]"
+
+
+# These are files created by configure, so we'll always clean them
+for i in $ALWAYS_CLEAN; do
+ test -f $i && \
+ $RM $i
+done
+
+if test x"$1" = x"--clean"; then
+ #
+ #Clean Files left by previous bootstrap run
+ #
+ if test -n "$CONFIG_AUX_DIR";
+ then CONFIG_AUX_DIR="$CONFIG_AUX_DIR/"
+ fi
+ # Clean Libtoolize generated files
+ for cf in $LIBTOOLIZE_FILES; do
+ cf="$CONFIG_AUX_DIR$cf"
+ test -f $cf && \
+ $RM $cf
+ done
+ #aclocal.m4 created by aclocal
+ test -f $ACLOCAL_FILES && $RM $ACLOCAL_FILES
+ #Clean Autoheader Generated files
+ for cf in $AUTOHEADER_FILES; do
+ cf=$CONFIG_AUX_DIR$cf
+ test -f $cf && \
+ $RM $cf
+ done
+ # remove config header (Usaually config.h)
+ test -n "$CONFIG_HEADER" && test -f $CONFIG_HEADER && $RM $CONFIG_HEADER
+ #Clean Automake generated files
+ for cf in $AUTOMAKE_FILES; do
+ cf=$CONFIG_AUX_DIR$cf
+ test -f $cf && \
+ $RM $cf
+ done
+ for i in $SUBDIRS; do
+ test -f $i/Makefile.in && \
+ $RM $i/Makefile.in
+ done
+ #Autoconf generated files
+ for cf in $AUTOCONF_FILES; do
+ test -f $cf && \
+ $RM $cf
+ done
+ for cf in $CONFIG_FILES; do
+ cf="$CONFIG_AUX_DIR$cf"
+ test -f $cf && \
+ $RM $cf
+ done
+else
+ $LIBTOOLIZE
+ $ACLOCAL
+ $AUTOHEADER
+ $AUTOMAKE
+ $AUTOCONF
+fi
+
+
diff --git a/cpp/configure.in b/cpp/configure.in
new file mode 100644
index 0000000..a4cb4d8
--- /dev/null
+++ b/cpp/configure.in
@@ -0,0 +1,43 @@
+AC_INIT(object.cpp)
+AC_CONFIG_AUX_DIR(ac)
+AM_INIT_AUTOMAKE(msgpack, 0.4.3)
+AC_CONFIG_HEADER(config.h)
+
+AC_SUBST(CFLAGS)
+CFLAGS="-O4 -Wall $CFLAGS"
+
+AC_SUBST(CXXFLAGS)
+CXXFLAGS="-O4 -Wall $CXXFLAGS"
+
+AC_PROG_CC
+AC_PROG_CXX
+
+AC_PROG_LIBTOOL
+AM_PROG_AS
+AM_PROG_CC_C_O
+
+AC_LANG_PUSH([C++])
+AC_CHECK_HEADERS(tr1/unordered_map)
+AC_CHECK_HEADERS(tr1/unordered_set)
+AC_LANG_POP([C++])
+
+AC_CACHE_CHECK([for __sync_* atomic operations], msgpack_cv_atomic_ops, [
+ AC_TRY_LINK([
+ int atomic_sub(int i) { return __sync_sub_and_fetch(&i, 1); }
+ int atomic_add(int i) { return __sync_add_and_fetch(&i, 1); }
+ ], [], msgpack_cv_atomic_ops="yes")
+ ])
+if test "$msgpack_cv_atomic_ops" != "yes"; then
+ AC_MSG_ERROR([__sync_* atomic operations are not supported.
+
+Note that gcc < 4.1 is not supported.
+
+If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
+add CFLAGS="--march=i686" and CXXFLAGS="-march=i668" options to ./configure as follows:
+
+ $ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
+])
+fi
+
+AC_OUTPUT([Makefile])
+
diff --git a/cpp/msgpack.h b/cpp/msgpack.h
new file mode 100644
index 0000000..21729f4
--- /dev/null
+++ b/cpp/msgpack.h
@@ -0,0 +1,23 @@
+/*
+ * MessagePack for C
+ *
+ * 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.
+ */
+#include "msgpack/object.h"
+#include "msgpack/zone.h"
+#include "msgpack/pack.h"
+#include "msgpack/unpack.h"
+#include "msgpack/sbuffer.h"
+#include "msgpack/vrefbuffer.h"
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 */
+
diff --git a/cpp/test.cpp b/cpp/msgpack_test.cpp
index 113914a..113914a 100644
--- a/cpp/test.cpp
+++ b/cpp/msgpack_test.cpp
diff --git a/cpp/msgpack_vc8.postbuild.bat b/cpp/msgpack_vc8.postbuild.bat
new file mode 100644
index 0000000..1bdfabe
--- /dev/null
+++ b/cpp/msgpack_vc8.postbuild.bat
@@ -0,0 +1,49 @@
+IF NOT EXIST include MKDIR include
+IF NOT EXIST include\msgpack MKDIR include\msgpack
+IF NOT EXIST include\msgpack\type MKDIR include\msgpack\type
+IF NOT EXIST include\msgpack\type\tr1 MKDIR include\msgpack\type\tr1
+IF EXIST bootstrap (
+ copy ..\msgpack\pack_define.h include\msgpack\
+ copy ..\msgpack\pack_template.h include\msgpack\
+ copy ..\msgpack\unpack_define.h include\msgpack\
+ copy ..\msgpack\unpack_template.h include\msgpack\
+ copy ..\msgpack\sysdep.h include\msgpack\
+) ELSE (
+ copy msgpack\pack_define.h include\msgpack\
+ copy msgpack\pack_template.h include\msgpack\
+ copy msgpack\unpack_define.h include\msgpack\
+ copy msgpack\unpack_template.h include\msgpack\
+ copy msgpack\sysdep.h include\msgpack\
+)
+copy msgpack.h include\
+copy msgpack\sbuffer.h include\msgpack\
+copy msgpack\vrefbuffer.h include\msgpack\
+copy msgpack\pack.h include\msgpack\
+copy msgpack\unpack.h include\msgpack\
+copy msgpack\object.h include\msgpack\
+copy msgpack\zone.h include\msgpack\
+copy msgpack.hpp include\
+copy msgpack\sbuffer.hpp include\msgpack\
+copy msgpack\vrefbuffer.hpp include\msgpack\
+copy msgpack\pack.hpp include\msgpack\
+copy msgpack\unpack.hpp include\msgpack\
+copy msgpack\object.hpp include\msgpack\
+copy msgpack\zone.hpp include\msgpack\
+copy msgpack\type.hpp include\msgpack\type\
+copy msgpack\type\bool.hpp include\msgpack\type\
+copy msgpack\type\float.hpp include\msgpack\type\
+copy msgpack\type\int.hpp include\msgpack\type\
+copy msgpack\type\list.hpp include\msgpack\type\
+copy msgpack\type\deque.hpp include\msgpack\type\
+copy msgpack\type\map.hpp include\msgpack\type\
+copy msgpack\type\nil.hpp include\msgpack\type\
+copy msgpack\type\pair.hpp include\msgpack\type\
+copy msgpack\type\raw.hpp include\msgpack\type\
+copy msgpack\type\set.hpp include\msgpack\type\
+copy msgpack\type\string.hpp include\msgpack\type\
+copy msgpack\type\vector.hpp include\msgpack\type\
+copy msgpack\type\tuple.hpp include\msgpack\type\
+copy msgpack\type\define.hpp include\msgpack\type\
+copy msgpack\type\tr1\unordered_map.hpp include\msgpack\type\
+copy msgpack\type\tr1\unordered_set.hpp include\msgpack\type\
+
diff --git a/cpp/msgpack_vc8.sln b/cpp/msgpack_vc8.sln
new file mode 100644
index 0000000..84718af
--- /dev/null
+++ b/cpp/msgpack_vc8.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MessagePack", "msgpack_vc8.vcproj", "{122A2EA4-B283-4241-9655-786DE78283B2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {122A2EA4-B283-4241-9655-786DE78283B2}.Debug|Win32.Build.0 = Debug|Win32
+ {122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.ActiveCfg = Release|Win32
+ {122A2EA4-B283-4241-9655-786DE78283B2}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/cpp/msgpack_vc8.vcproj b/cpp/msgpack_vc8.vcproj
new file mode 100644
index 0000000..a3fa28f
--- /dev/null
+++ b/cpp/msgpack_vc8.vcproj
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="MessagePack"
+ ProjectGUID="{122A2EA4-B283-4241-9655-786DE78283B2}"
+ RootNamespace="MessagePack"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Gathering header files"
+ CommandLine="msgpack_vc8.postbuild.bat"
+ Outputs="include"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="cpp;c;."
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="1"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="lib\$(ProjectName)d.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Gathering header files"
+ CommandLine="msgpack_vc8.postbuild.bat"
+ Outputs="include"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="cpp;c;."
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="lib\$(ProjectName).lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\c\object.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\cpp\object.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\c\unpack.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\c\vrefbuffer.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\c\zone.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\msgpack\pack_define.h"
+ >
+ </File>
+ <File
+ RelativePath=".\msgpack\pack_template.h"
+ >
+ </File>
+ <File
+ RelativePath=".\msgpack\sysdep.h"
+ >
+ </File>
+ <File
+ RelativePath=".\msgpack\unpack_define.h"
+ >
+ </File>
+ <File
+ RelativePath=".\msgpack\unpack_template.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/cpp/msgpackc_test.cpp b/cpp/msgpackc_test.cpp
new file mode 100644
index 0000000..f5646ea
--- /dev/null
+++ b/cpp/msgpackc_test.cpp
@@ -0,0 +1,424 @@
+#include "msgpack.h"
+
+#include <math.h>
+#include <vector>
+#include <limits>
+
+#include <gtest/gtest.h>
+
+using namespace std;
+
+const unsigned int kLoop = 10000;
+const double kEPS = 1e-10;
+
+#define GEN_TEST_SIGNED(test_type, func_type) \
+ do { \
+ vector<test_type> v; \
+ v.push_back(0); \
+ v.push_back(1); \
+ v.push_back(-1); \
+ v.push_back(numeric_limits<test_type>::min()); \
+ v.push_back(numeric_limits<test_type>::max()); \
+ for (unsigned int i = 0; i < kLoop; i++) \
+ v.push_back(rand()); \
+ for (unsigned int i = 0; i < v.size() ; i++) { \
+ test_type val = v[i]; \
+ msgpack_sbuffer sbuf; \
+ msgpack_sbuffer_init(&sbuf); \
+ msgpack_packer pk; \
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
+ msgpack_pack_##func_type(&pk, val); \
+ msgpack_zone z; \
+ msgpack_zone_init(&z, 2048); \
+ msgpack_object obj; \
+ msgpack_unpack_return ret = \
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
+ if (val < 0) { \
+ EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, obj.type); \
+ EXPECT_EQ(val, obj.via.i64); \
+ } else { \
+ EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
+ EXPECT_EQ(val, obj.via.u64); \
+ } \
+ msgpack_zone_destroy(&z); \
+ msgpack_sbuffer_destroy(&sbuf); \
+ } \
+ } while(0)
+
+#define GEN_TEST_UNSIGNED(test_type, func_type) \
+ do { \
+ vector<test_type> v; \
+ v.push_back(0); \
+ v.push_back(1); \
+ v.push_back(2); \
+ v.push_back(numeric_limits<test_type>::min()); \
+ v.push_back(numeric_limits<test_type>::max()); \
+ for (unsigned int i = 0; i < kLoop; i++) \
+ v.push_back(rand()); \
+ for (unsigned int i = 0; i < v.size() ; i++) { \
+ test_type val = v[i]; \
+ msgpack_sbuffer sbuf; \
+ msgpack_sbuffer_init(&sbuf); \
+ msgpack_packer pk; \
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
+ msgpack_pack_##func_type(&pk, val); \
+ msgpack_zone z; \
+ msgpack_zone_init(&z, 2048); \
+ msgpack_object obj; \
+ msgpack_unpack_return ret = \
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
+ EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
+ EXPECT_EQ(val, obj.via.u64); \
+ msgpack_zone_destroy(&z); \
+ msgpack_sbuffer_destroy(&sbuf); \
+ } \
+ } while(0)
+
+TEST(MSGPACKC, simple_buffer_short)
+{
+ GEN_TEST_SIGNED(short, short);
+}
+
+TEST(MSGPACKC, simple_buffer_int)
+{
+ GEN_TEST_SIGNED(int, int);
+}
+
+TEST(MSGPACKC, simple_buffer_long)
+{
+ GEN_TEST_SIGNED(long, long);
+}
+
+TEST(MSGPACKC, simple_buffer_long_long)
+{
+ GEN_TEST_SIGNED(long long, long_long);
+}
+
+TEST(MSGPACKC, simple_buffer_unsigned_short)
+{
+ GEN_TEST_UNSIGNED(unsigned short, unsigned_short);
+}
+
+TEST(MSGPACKC, simple_buffer_unsigned_int)
+{
+ GEN_TEST_UNSIGNED(unsigned int, unsigned_int);
+}
+
+TEST(MSGPACKC, simple_buffer_unsigned_long)
+{
+ GEN_TEST_UNSIGNED(unsigned long, unsigned_long);
+}
+
+TEST(MSGPACKC, simple_buffer_unsigned_long_long)
+{
+ GEN_TEST_UNSIGNED(unsigned long long, unsigned_long_long);
+}
+
+TEST(MSGPACKC, simple_buffer_uint8)
+{
+ GEN_TEST_UNSIGNED(uint8_t, uint8);
+}
+
+TEST(MSGPACKC, simple_buffer_uint16)
+{
+ GEN_TEST_UNSIGNED(uint16_t, uint16);
+}
+
+TEST(MSGPACKC, simple_buffer_uint32)
+{
+ GEN_TEST_UNSIGNED(uint32_t, uint32);
+}
+
+TEST(MSGPACKC, simple_buffer_uint64)
+{
+ GEN_TEST_UNSIGNED(uint64_t, uint64);
+}
+
+TEST(MSGPACKC, simple_buffer_int8)
+{
+ GEN_TEST_SIGNED(int8_t, int8);
+}
+
+TEST(MSGPACKC, simple_buffer_int16)
+{
+ GEN_TEST_SIGNED(int16_t, int16);
+}
+
+TEST(MSGPACKC, simple_buffer_int32)
+{
+ GEN_TEST_SIGNED(int32_t, int32);
+}
+
+TEST(MSGPACKC, simple_buffer_int64)
+{
+ GEN_TEST_SIGNED(int64_t, int64);
+}
+
+TEST(MSGPACKC, simple_buffer_float)
+{
+ vector<float> v;
+ v.push_back(0.0);
+ v.push_back(1.0);
+ v.push_back(-1.0);
+ v.push_back(numeric_limits<float>::min());
+ v.push_back(numeric_limits<float>::max());
+ v.push_back(nanf("tag"));
+ v.push_back(1.0/0.0); // inf
+ v.push_back(-(1.0/0.0)); // -inf
+ for (unsigned int i = 0; i < kLoop; i++) {
+ v.push_back(drand48());
+ v.push_back(-drand48());
+ }
+
+ for (unsigned int i = 0; i < v.size() ; i++) {
+ float val = v[i];
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_float(&pk, val);
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret =
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
+ if (isnan(val))
+ EXPECT_TRUE(isnan(obj.via.dec));
+ else if (isinf(val))
+ EXPECT_TRUE(isinf(obj.via.dec));
+ else
+ EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+ }
+}
+
+TEST(MSGPACKC, simple_buffer_double)
+{
+ vector<double> v;
+ v.push_back(0.0);
+ v.push_back(-0.0);
+ v.push_back(1.0);
+ v.push_back(-1.0);
+ v.push_back(numeric_limits<double>::min());
+ v.push_back(numeric_limits<double>::max());
+ v.push_back(nan("tag"));
+ v.push_back(1.0/0.0); // inf
+ v.push_back(-(1.0/0.0)); // -inf
+ for (unsigned int i = 0; i < kLoop; i++) {
+ v.push_back(drand48());
+ v.push_back(-drand48());
+ }
+
+ for (unsigned int i = 0; i < v.size() ; i++) {
+ double val = v[i];
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_double(&pk, val);
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret =
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
+ if (isnan(val))
+ EXPECT_TRUE(isnan(obj.via.dec));
+ else if (isinf(val))
+ EXPECT_TRUE(isinf(obj.via.dec));
+ else
+ EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+ }
+}
+
+TEST(MSGPACKC, simple_buffer_nil)
+{
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_nil(&pk);
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret =
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_NIL, obj.type);
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
+
+TEST(MSGPACKC, simple_buffer_true)
+{
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_true(&pk);
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret =
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
+ EXPECT_EQ(true, obj.via.boolean);
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
+
+TEST(MSGPACKC, simple_buffer_false)
+{
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_false(&pk);
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret =
+ msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
+ EXPECT_EQ(false, obj.via.boolean);
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
+
+TEST(MSGPACKC, simple_buffer_array)
+{
+ unsigned int array_size = 5;
+
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_array(&pk, array_size);
+ msgpack_pack_nil(&pk);
+ msgpack_pack_true(&pk);
+ msgpack_pack_false(&pk);
+ msgpack_pack_int(&pk, 10);
+ msgpack_pack_int(&pk, -10);
+
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret;
+ ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
+ EXPECT_EQ(array_size, obj.via.array.size);
+
+ for (unsigned int i = 0; i < obj.via.array.size; i++) {
+ msgpack_object o = obj.via.array.ptr[i];
+ switch (i) {
+ case 0:
+ EXPECT_EQ(MSGPACK_OBJECT_NIL, o.type);
+ break;
+ case 1:
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
+ EXPECT_EQ(true, o.via.boolean);
+ break;
+ case 2:
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
+ EXPECT_EQ(false, o.via.boolean);
+ break;
+ case 3:
+ EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, o.type);
+ EXPECT_EQ(10, o.via.u64);
+ break;
+ case 4:
+ EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, o.type);
+ EXPECT_EQ(-10, o.via.i64);
+ break;
+ }
+ }
+
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
+
+TEST(MSGPACKC, simple_buffer_map)
+{
+ unsigned int map_size = 2;
+
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_map(&pk, map_size);
+ msgpack_pack_true(&pk);
+ msgpack_pack_false(&pk);
+ msgpack_pack_int(&pk, 10);
+ msgpack_pack_int(&pk, -10);
+
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret;
+ ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
+ EXPECT_EQ(map_size, obj.via.map.size);
+
+ for (unsigned int i = 0; i < map_size; i++) {
+ msgpack_object key = obj.via.map.ptr[i].key;
+ msgpack_object val = obj.via.map.ptr[i].val;
+ switch (i) {
+ case 0:
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, key.type);
+ EXPECT_EQ(true, key.via.boolean);
+ EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, val.type);
+ EXPECT_EQ(false, val.via.boolean);
+ break;
+ case 1:
+ EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, key.type);
+ EXPECT_EQ(10, key.via.u64);
+ EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, val.type);
+ EXPECT_EQ(-10, val.via.i64);
+ break;
+ }
+ }
+
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
+
+TEST(MSGPACKC, simple_buffer_raw)
+{
+ unsigned int raw_size = 7;
+
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+ msgpack_packer pk;
+ msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
+ msgpack_pack_raw(&pk, raw_size);
+ msgpack_pack_raw_body(&pk, "fr", 2);
+ msgpack_pack_raw_body(&pk, "syuki", 5);
+ // invalid data
+ msgpack_pack_raw_body(&pk, "", 0);
+ msgpack_pack_raw_body(&pk, "kzk", 0);
+
+ msgpack_zone z;
+ msgpack_zone_init(&z, 2048);
+ msgpack_object obj;
+ msgpack_unpack_return ret;
+ ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
+ EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
+ EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type);
+ EXPECT_EQ(raw_size, obj.via.raw.size);
+ EXPECT_EQ(0, memcmp("frsyuki", obj.via.raw.ptr, raw_size));
+
+ msgpack_zone_destroy(&z);
+ msgpack_sbuffer_destroy(&sbuf);
+}
diff --git a/cpp/object.c b/cpp/object.c
new file mode 100644
index 0000000..a22ce21
--- /dev/null
+++ b/cpp/object.c
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+#include "msgpack/object.h"
+#include "msgpack/pack.h"
+#include <stdio.h>
+
+#ifndef _MSC_VER
+#include <inttypes.h>
+#else
+#ifndef PRIu64
+#define PRIu64 "I64u"
+#endif
+#ifndef PRIi64
+#define PRIi64 "I64d"
+#endif
+#endif
+
+
+int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
+{
+ switch(d.type) {
+ case MSGPACK_OBJECT_NIL:
+ return msgpack_pack_nil(pk);
+
+ case MSGPACK_OBJECT_BOOLEAN:
+ if(d.via.boolean) {
+ return msgpack_pack_true(pk);
+ } else {
+ return msgpack_pack_false(pk);
+ }
+
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ return msgpack_pack_uint64(pk, d.via.u64);
+
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ return msgpack_pack_int64(pk, d.via.i64);
+
+ case MSGPACK_OBJECT_DOUBLE:
+ return msgpack_pack_double(pk, d.via.dec);
+
+ case MSGPACK_OBJECT_RAW:
+ {
+ int ret = msgpack_pack_raw(pk, d.via.raw.size);
+ if(ret < 0) { return ret; }
+ return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size);
+ }
+
+ case MSGPACK_OBJECT_ARRAY:
+ {
+ int ret = msgpack_pack_array(pk, d.via.array.size);
+ if(ret < 0) { return ret; }
+
+ msgpack_object* o = d.via.array.ptr;
+ msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
+ for(; o != oend; ++o) {
+ ret = msgpack_pack_object(pk, *o);
+ if(ret < 0) { return ret; }
+ }
+
+ return 0;
+ }
+
+ case MSGPACK_OBJECT_MAP:
+ {
+ int ret = msgpack_pack_map(pk, d.via.map.size);
+ if(ret < 0) { return ret; }
+
+ msgpack_object_kv* kv = d.via.map.ptr;
+ msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
+ for(; kv != kvend; ++kv) {
+ ret = msgpack_pack_object(pk, kv->key);
+ if(ret < 0) { return ret; }
+ ret = msgpack_pack_object(pk, kv->val);
+ if(ret < 0) { return ret; }
+ }
+
+ return 0;
+ }
+
+ default:
+ return -1;
+ }
+}
+
+
+void msgpack_object_print(FILE* out, msgpack_object o)
+{
+ switch(o.type) {
+ case MSGPACK_OBJECT_NIL:
+ fprintf(out, "nil");
+ break;
+
+ case MSGPACK_OBJECT_BOOLEAN:
+ fprintf(out, (o.via.boolean ? "true" : "false"));
+ break;
+
+ case MSGPACK_OBJECT_POSITIVE_INTEGER:
+ fprintf(out, "%"PRIu64, o.via.u64);
+ break;
+
+ case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+ fprintf(out, "%"PRIi64, o.via.i64);
+ break;
+
+ case MSGPACK_OBJECT_DOUBLE:
+ fprintf(out, "%f", o.via.dec);
+ break;
+
+ case MSGPACK_OBJECT_RAW:
+ fprintf(out, "\"");
+ fwrite(o.via.raw.ptr, o.via.raw.size, 1, out);
+ fprintf(out, "\"");
+ break;
+
+ case MSGPACK_OBJECT_ARRAY:
+ fprintf(out, "[");
+ if(o.via.array.size != 0) {
+ msgpack_object* p = o.via.array.ptr;
+ msgpack_object_print(out, *p);
+ ++p;
+ msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
+ for(; p < pend; ++p) {
+ fprintf(out, ", ");
+ msgpack_object_print(out, *p);
+ }
+ }
+ fprintf(out, "]");
+ break;
+ // FIXME loop optimiziation
+
+ case MSGPACK_OBJECT_MAP:
+ fprintf(out, "{");
+ if(o.via.map.size != 0) {
+ msgpack_object_kv* p = o.via.map.ptr;
+ msgpack_object_print(out, p->key);
+ fprintf(out, "=>");
+ msgpack_object_print(out, p->val);
+ ++p;
+ msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
+ for(; p < pend; ++p) {
+ fprintf(out, ", ");
+ msgpack_object_print(out, p->key);
+ fprintf(out, "=>");
+ msgpack_object_print(out, p->val);
+ }
+ }
+ fprintf(out, "}");
+ break;
+ // FIXME loop optimiziation
+
+ default:
+ // FIXME
+ fprintf(out, "#<UNKNOWN %hu %"PRIu64">", o.type, o.via.u64);
+ }
+}
+
diff --git a/cpp/preprocess.sh b/cpp/preprocess
index 2e06c10..63af4c6 100755
--- a/cpp/preprocess.sh
+++ b/cpp/preprocess
@@ -14,4 +14,8 @@ preprocess() {
preprocess msgpack/type/tuple.hpp
preprocess msgpack/type/define.hpp
preprocess msgpack/zone.hpp
+cp -f ../msgpack/pack_define.h msgpack/
+cp -f ../msgpack/pack_template.h msgpack/
+cp -f ../msgpack/unpack_define.h msgpack/
+cp -f ../msgpack/unpack_template.h msgpack/
diff --git a/cpp/unpack.c b/cpp/unpack.c
new file mode 100644
index 0000000..4334974
--- /dev/null
+++ b/cpp/unpack.c
@@ -0,0 +1,407 @@
+/*
+ * 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.
+ */
+#include "msgpack/unpack.h"
+#include "msgpack/unpack_define.h"
+#include <stdlib.h>
+
+
+typedef struct {
+ msgpack_zone* z;
+ bool referenced;
+} unpack_user;
+
+
+#define msgpack_unpack_struct(name) \
+ struct template ## name
+
+#define msgpack_unpack_func(ret, name) \
+ ret template ## name
+
+#define msgpack_unpack_callback(name) \
+ template_callback ## name
+
+#define msgpack_unpack_object msgpack_object
+
+#define msgpack_unpack_user unpack_user
+
+
+struct template_context;
+typedef struct template_context template_context;
+
+static void template_init(template_context* ctx);
+static void template_destroy(template_context* ctx);
+
+static msgpack_object template_data(template_context* ctx);
+
+static int template_execute(template_context* ctx,
+ const char* data, size_t len, size_t* off);
+
+
+static inline msgpack_object template_callback_root(unpack_user* u)
+{ msgpack_object o = {}; return o; }
+
+static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+
+static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+
+static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+
+static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+
+static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o)
+{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+ else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
+
+static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o)
+{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+ else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
+
+static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o)
+{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+ else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
+
+static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o)
+{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
+ else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
+
+static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
+
+static inline int template_callback_double(unpack_user* u, double d, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
+
+static inline int template_callback_nil(unpack_user* u, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_NIL; return 0; }
+
+static inline int template_callback_true(unpack_user* u, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = true; return 0; }
+
+static inline int template_callback_false(unpack_user* u, msgpack_object* o)
+{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = false; return 0; }
+
+static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
+{
+ o->type = MSGPACK_OBJECT_ARRAY;
+ o->via.array.size = 0;
+ o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
+ if(o->via.array.ptr == NULL) { return -1; }
+ return 0;
+}
+
+static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
+{ c->via.array.ptr[c->via.array.size++] = o; return 0; }
+
+static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
+{
+ o->type = MSGPACK_OBJECT_MAP;
+ o->via.map.size = 0;
+ o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv));
+ if(o->via.map.ptr == NULL) { return -1; }
+ return 0;
+}
+
+static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
+{
+ c->via.map.ptr[c->via.map.size].key = k;
+ c->via.map.ptr[c->via.map.size].val = v;
+ ++c->via.map.size;
+ return 0;
+}
+
+static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
+{
+ o->type = MSGPACK_OBJECT_RAW;
+ o->via.raw.ptr = p;
+ o->via.raw.size = l;
+ u->referenced = true;
+ return 0;
+}
+
+#include "msgpack/unpack_template.h"
+
+
+#define CTX_CAST(m) ((template_context*)(m))
+#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
+
+#define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t))
+
+
+static inline void init_count(void* buffer)
+{
+ *(volatile _msgpack_atomic_counter_t*)buffer = 1;
+}
+
+static inline void decl_count(void* buffer)
+{
+ // atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
+ if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
+ free(buffer);
+ }
+}
+
+static inline void incr_count(void* buffer)
+{
+ // atomic ++*(_msgpack_atomic_counter_t*)buffer;
+ _msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
+}
+
+static inline _msgpack_atomic_counter_t get_count(void* buffer)
+{
+ return *(volatile _msgpack_atomic_counter_t*)buffer;
+}
+
+
+
+bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
+{
+ if(initial_buffer_size < COUNTER_SIZE) {
+ initial_buffer_size = COUNTER_SIZE;
+ }
+
+ char* buffer = (char*)malloc(initial_buffer_size);
+ if(buffer == NULL) {
+ return false;
+ }
+
+ void* ctx = malloc(sizeof(template_context));
+ if(ctx == NULL) {
+ free(buffer);
+ return false;
+ }
+
+ msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
+ if(z == NULL) {
+ free(ctx);
+ free(buffer);
+ return false;
+ }
+
+ mpac->buffer = buffer;
+ mpac->used = COUNTER_SIZE;
+ mpac->free = initial_buffer_size - mpac->used;
+ mpac->off = COUNTER_SIZE;
+ mpac->parsed = 0;
+ mpac->initial_buffer_size = initial_buffer_size;
+ mpac->z = z;
+ mpac->ctx = ctx;
+
+ init_count(mpac->buffer);
+
+ template_init(CTX_CAST(mpac->ctx));
+ CTX_CAST(mpac->ctx)->user.z = mpac->z;
+ CTX_CAST(mpac->ctx)->user.referenced = false;
+
+ return true;
+}
+
+void msgpack_unpacker_destroy(msgpack_unpacker* mpac)
+{
+ msgpack_zone_free(mpac->z);
+ template_destroy(mpac->ctx);
+ free(mpac->ctx);
+ decl_count(mpac->buffer);
+}
+
+
+msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size)
+{
+ msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker));
+ if(mpac == NULL) {
+ return NULL;
+ }
+
+ if(!msgpack_unpacker_init(mpac, initial_buffer_size)) {
+ free(mpac);
+ return NULL;
+ }
+
+ return mpac;
+}
+
+void msgpack_unpacker_free(msgpack_unpacker* mpac)
+{
+ msgpack_unpacker_destroy(mpac);
+ free(mpac);
+}
+
+bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size)
+{
+ if(mpac->used == mpac->off && get_count(mpac->buffer) == 1
+ && !CTX_REFERENCED(mpac)) {
+ // rewind buffer
+ mpac->free += mpac->used - COUNTER_SIZE;
+ mpac->used = COUNTER_SIZE;
+ mpac->off = COUNTER_SIZE;
+
+ if(mpac->free >= size) {
+ return true;
+ }
+ }
+
+ if(mpac->off == COUNTER_SIZE) {
+ size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE
+ while(next_size < size + mpac->used) {
+ next_size *= 2;
+ }
+
+ char* tmp = (char*)realloc(mpac->buffer, next_size);
+ if(tmp == NULL) {
+ return false;
+ }
+
+ mpac->buffer = tmp;
+ mpac->free = next_size - mpac->used;
+
+ } else {
+ size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE
+ size_t not_parsed = mpac->used - mpac->off;
+ while(next_size < size + not_parsed + COUNTER_SIZE) {
+ next_size *= 2;
+ }
+
+ char* tmp = (char*)malloc(next_size);
+ if(tmp == NULL) {
+ return false;
+ }
+
+ init_count(tmp);
+
+ memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed);
+
+ if(CTX_REFERENCED(mpac)) {
+ if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
+ free(tmp);
+ return false;
+ }
+ CTX_REFERENCED(mpac) = false;
+ } else {
+ decl_count(mpac->buffer);
+ }
+
+ mpac->buffer = tmp;
+ mpac->used = not_parsed + COUNTER_SIZE;
+ mpac->free = next_size - mpac->used;
+ mpac->off = COUNTER_SIZE;
+ }
+
+ return true;
+}
+
+int msgpack_unpacker_execute(msgpack_unpacker* mpac)
+{
+ size_t off = mpac->off;
+ int ret = template_execute(CTX_CAST(mpac->ctx),
+ mpac->buffer, mpac->used, &mpac->off);
+ if(mpac->off > off) {
+ mpac->parsed += mpac->off - off;
+ }
+ return ret;
+}
+
+msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
+{
+ return template_data(CTX_CAST(mpac->ctx));
+}
+
+msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
+{
+ if(!msgpack_unpacker_flush_zone(mpac)) {
+ return false;
+ }
+
+ msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
+ if(r == NULL) {
+ return NULL;
+ }
+
+ msgpack_zone* old = mpac->z;
+ mpac->z = r;
+
+ return old;
+}
+
+void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac)
+{
+ msgpack_zone_clear(mpac->z);
+}
+
+bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac)
+{
+ if(CTX_REFERENCED(mpac)) {
+ if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
+ return false;
+ }
+ CTX_REFERENCED(mpac) = false;
+
+ incr_count(mpac->buffer);
+ }
+
+ return true;
+}
+
+void msgpack_unpacker_reset(msgpack_unpacker* mpac)
+{
+ template_init(CTX_CAST(mpac->ctx));
+ // don't reset referenced flag
+ mpac->parsed = 0;
+}
+
+
+msgpack_unpack_return
+msgpack_unpack(const char* data, size_t len, size_t* off,
+ msgpack_zone* z, msgpack_object* result)
+{
+ msgpack_unpack_return ret = MSGPACK_UNPACK_SUCCESS;
+ template_context ctx;
+ template_init(&ctx);
+
+ ctx.user.z = z;
+ ctx.user.referenced = false;
+
+ size_t noff = 0;
+ if(off != NULL) { noff = *off; }
+
+ int e = template_execute(&ctx, data, len, &noff);
+ if(e < 0) {
+ ret = MSGPACK_UNPACK_PARSE_ERROR;
+ goto out;
+ }
+
+ if(off != NULL) { *off = noff; }
+
+ if(e == 0) {
+ ret = MSGPACK_UNPACK_CONTINUE;
+ goto out;
+ }
+
+ *result = template_data(&ctx);
+
+ if(noff < len) {
+ ret = MSGPACK_UNPACK_EXTRA_BYTES;
+ goto out;
+ }
+
+out:
+ template_destroy(&ctx);
+ return ret;
+}
+
diff --git a/cpp/vrefbuffer.c b/cpp/vrefbuffer.c
new file mode 100644
index 0000000..136372f
--- /dev/null
+++ b/cpp/vrefbuffer.c
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+#include "msgpack/vrefbuffer.h"
+#include <stdlib.h>
+#include <string.h>
+
+struct msgpack_vrefbuffer_chunk {
+ struct msgpack_vrefbuffer_chunk* next;
+ /* data ... */
+};
+
+bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
+ size_t ref_size, size_t chunk_size)
+{
+ vbuf->chunk_size = chunk_size;
+ vbuf->ref_size = ref_size;
+
+ size_t nfirst = (sizeof(struct iovec) < 72/2) ?
+ 72 / sizeof(struct iovec) : 8;
+
+ struct iovec* array = (struct iovec*)malloc(
+ sizeof(struct iovec) * nfirst);
+ if(array == NULL) {
+ return false;
+ }
+
+ vbuf->tail = array;
+ vbuf->end = array + nfirst;
+ vbuf->array = array;
+
+ msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
+ sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
+ if(chunk == NULL) {
+ free(array);
+ return false;
+ }
+
+ msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
+
+ ib->free = chunk_size;
+ ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
+ ib->head = chunk;
+ chunk->next = NULL;
+
+ return true;
+}
+
+void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
+{
+ msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
+ while(true) {
+ msgpack_vrefbuffer_chunk* n = c->next;
+ free(c);
+ if(n != NULL) {
+ c = n;
+ } else {
+ break;
+ }
+ }
+ free(vbuf->array);
+}
+
+int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
+ const char* buf, unsigned int len)
+{
+ if(vbuf->tail == vbuf->end) {
+ const size_t nused = vbuf->tail - vbuf->array;
+ const size_t nnext = nused * 2;
+
+ struct iovec* nvec = (struct iovec*)realloc(
+ vbuf->array, sizeof(struct iovec)*nnext);
+ if(nvec == NULL) {
+ return -1;
+ }
+
+ vbuf->array = nvec;
+ vbuf->end = nvec + nnext;
+ vbuf->tail = nvec + nused;
+ }
+
+ vbuf->tail->iov_base = (char*)buf;
+ vbuf->tail->iov_len = len;
+ ++vbuf->tail;
+
+ return 0;
+}
+
+int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
+ const char* buf, unsigned int len)
+{
+ msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
+
+ if(ib->free < len) {
+ size_t sz = vbuf->chunk_size;
+ if(sz < len) {
+ sz = len;
+ }
+
+ msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
+ sizeof(msgpack_vrefbuffer_chunk) + sz);
+ if(chunk == NULL) {
+ return -1;
+ }
+
+ chunk->next = ib->head;
+ ib->head = chunk;
+ ib->free = sz;
+ ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
+ }
+
+ char* m = ib->ptr;
+ memcpy(m, buf, len);
+ ib->free -= len;
+ ib->ptr += len;
+
+ if(vbuf->tail != vbuf->array && m ==
+ (const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
+ (vbuf->tail-1)->iov_len += len;
+ return 0;
+ } else {
+ return msgpack_vrefbuffer_append_ref(vbuf, m, len);
+ }
+}
+
+int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
+{
+ size_t sz = vbuf->chunk_size;
+
+ msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
+ sizeof(msgpack_vrefbuffer_chunk) + sz);
+ if(empty == NULL) {
+ return -1;
+ }
+
+ empty->next = NULL;
+
+
+ const size_t nused = vbuf->tail - vbuf->array;
+ if(to->tail + nused < vbuf->end) {
+ const size_t tosize = to->tail - to->array;
+ const size_t reqsize = nused + tosize;
+ size_t nnext = (to->end - to->array) * 2;
+ while(nnext < reqsize) {
+ nnext *= 2;
+ }
+
+ struct iovec* nvec = (struct iovec*)realloc(
+ to->array, sizeof(struct iovec)*nnext);
+ if(nvec == NULL) {
+ free(empty);
+ return -1;
+ }
+
+ to->array = nvec;
+ to->end = nvec + nnext;
+ to->tail = nvec + tosize;
+ }
+
+ memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
+
+ to->tail += nused;
+ vbuf->tail = vbuf->array;
+
+
+ msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
+ msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
+
+ msgpack_vrefbuffer_chunk* last = ib->head;
+ while(last->next != NULL) {
+ last = last->next;
+ }
+ last->next = toib->head;
+ toib->head = ib->head;
+
+ if(toib->free < ib->free) {
+ toib->free = ib->free;
+ toib->ptr = ib->ptr;
+ }
+
+ ib->head = empty;
+ ib->free = sz;
+ ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
+
+ return 0;
+}
+
diff --git a/cpp/zone.c b/cpp/zone.c
new file mode 100644
index 0000000..3d0634e
--- /dev/null
+++ b/cpp/zone.c
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+#include "msgpack/zone.h"
+#include <stdlib.h>
+#include <string.h>
+
+struct msgpack_zone_chunk {
+ struct msgpack_zone_chunk* next;
+ /* data ... */
+};
+
+static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
+{
+ msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
+ sizeof(msgpack_zone_chunk) + chunk_size);
+ if(chunk == NULL) {
+ return false;
+ }
+
+ cl->head = chunk;
+ cl->free = chunk_size;
+ cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
+ chunk->next = NULL;
+
+ return true;
+}
+
+static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
+{
+ msgpack_zone_chunk* c = cl->head;
+ while(true) {
+ msgpack_zone_chunk* n = c->next;
+ free(c);
+ if(n != NULL) {
+ c = n;
+ } else {
+ break;
+ }
+ }
+}
+
+static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
+{
+ msgpack_zone_chunk* c = cl->head;
+ while(true) {
+ msgpack_zone_chunk* n = c->next;
+ if(n != NULL) {
+ free(c);
+ c = n;
+ } else {
+ break;
+ }
+ }
+ cl->head->next = NULL;
+ cl->free = chunk_size;
+ cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
+}
+
+void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
+{
+ msgpack_zone_chunk_list* const cl = &zone->chunk_list;
+
+ size_t sz = zone->chunk_size;
+
+ while(sz < size) {
+ sz *= 2;
+ }
+
+ msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
+ sizeof(msgpack_zone_chunk) + sz);
+
+ char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
+
+ chunk->next = cl->head;
+ cl->head = chunk;
+ cl->free = sz - size;
+ cl->ptr = ptr + size;
+
+ return ptr;
+}
+
+
+static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
+{
+ fa->tail = NULL;
+ fa->end = NULL;
+ fa->array = NULL;
+}
+
+static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
+{
+ msgpack_zone_finalizer* fin = fa->tail;
+ for(; fin != fa->array; --fin) {
+ (*(fin-1)->func)((fin-1)->data);
+ }
+}
+
+static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
+{
+ call_finalizer_array(fa);
+ free(fa->array);
+}
+
+static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
+{
+ call_finalizer_array(fa);
+ fa->tail = fa->array;
+}
+
+bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
+ void (*func)(void* data), void* data)
+{
+ msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
+
+ const size_t nused = fa->end - fa->array;
+
+ size_t nnext;
+ if(nused == 0) {
+ nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
+ 72 / sizeof(msgpack_zone_finalizer) : 8;
+
+ } else {
+ nnext = nused * 2;
+ }
+
+ msgpack_zone_finalizer* tmp =
+ (msgpack_zone_finalizer*)realloc(fa->array,
+ sizeof(msgpack_zone_finalizer) * nnext);
+ if(tmp == NULL) {
+ return false;
+ }
+
+ fa->array = tmp;
+ fa->end = tmp + nnext;
+ fa->tail = tmp + nused;
+
+ fa->tail->func = func;
+ fa->tail->data = data;
+
+ ++fa->tail;
+
+ return true;
+}
+
+
+bool msgpack_zone_is_empty(msgpack_zone* zone)
+{
+ msgpack_zone_chunk_list* const cl = &zone->chunk_list;
+ msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
+ return cl->free == zone->chunk_size && cl->head->next == NULL &&
+ fa->tail == fa->array;
+}
+
+
+void msgpack_zone_destroy(msgpack_zone* zone)
+{
+ destroy_finalizer_array(&zone->finalizer_array);
+ destroy_chunk_list(&zone->chunk_list);
+}
+
+void msgpack_zone_clear(msgpack_zone* zone)
+{
+ clear_finalizer_array(&zone->finalizer_array);
+ clear_chunk_list(&zone->chunk_list, zone->chunk_size);
+}
+
+bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
+{
+ zone->chunk_size = chunk_size;
+
+ if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
+ return false;
+ }
+
+ init_finalizer_array(&zone->finalizer_array);
+
+ return true;
+}
+
+msgpack_zone* msgpack_zone_new(size_t chunk_size)
+{
+ msgpack_zone* zone = (msgpack_zone*)malloc(
+ sizeof(msgpack_zone) + chunk_size);
+ if(zone == NULL) {
+ return NULL;
+ }
+
+ zone->chunk_size = chunk_size;
+
+ if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
+ free(zone);
+ return false;
+ }
+
+ init_finalizer_array(&zone->finalizer_array);
+
+ return zone;
+}
+
+void msgpack_zone_free(msgpack_zone* zone)
+{
+ msgpack_zone_destroy(zone);
+ free(zone);
+}
+