From ab8e0c9e31585b24f1d4cbfb1e73b0ce249e408a Mon Sep 17 00:00:00 2001 From: frsyuki Date: Sun, 18 Apr 2010 00:08:03 +0900 Subject: c,cpp: reforms source tree --- AUTHORS | 1 - COPYING | 14 - ChangeLog | 0 LICENSE | 202 --------- Makefile.am | 18 - NEWS | 0 NOTICE | 4 - README | 70 --- README.md | 37 ++ bootstrap | 117 ----- c/Makefile.am | 29 -- c/bench.c | 323 -------------- c/bench.mk | 9 - c/msgpack.h | 23 - c/msgpack/object.h | 88 ---- c/msgpack/pack.h | 116 ----- c/msgpack/sbuffer.h | 86 ---- c/msgpack/unpack.h | 123 ------ c/msgpack/vrefbuffer.h | 110 ----- c/msgpack/zbuffer.h | 180 -------- c/msgpack/zone.h | 131 ------ c/object.c | 171 -------- c/test.cpp | 424 ------------------ c/unpack.c | 407 ----------------- c/vrefbuffer.c | 201 --------- c/zone.c | 220 ---------- configure.in | 61 --- cpp/AUTHORS | 1 + cpp/COPYING | 14 + cpp/ChangeLog | 0 cpp/LICENSE | 202 +++++++++ cpp/Makefile.am | 56 ++- cpp/NOTICE | 4 + cpp/bench.cpp | 188 -------- cpp/bench.mk | 9 - cpp/bootstrap | 126 ++++++ cpp/configure.in | 43 ++ cpp/msgpack.h | 23 + cpp/msgpack/object.h | 88 ++++ cpp/msgpack/pack.h | 116 +++++ cpp/msgpack/sbuffer.h | 86 ++++ cpp/msgpack/unpack.h | 123 ++++++ cpp/msgpack/vrefbuffer.h | 110 +++++ cpp/msgpack/zbuffer.h | 180 ++++++++ cpp/msgpack/zone.h | 131 ++++++ cpp/msgpack_test.cpp | 982 ++++++++++++++++++++++++++++++++++++++++++ cpp/msgpack_vc8.postbuild.bat | 49 +++ cpp/msgpack_vc8.sln | 20 + cpp/msgpack_vc8.vcproj | 283 ++++++++++++ cpp/msgpackc_test.cpp | 424 ++++++++++++++++++ cpp/object.c | 171 ++++++++ cpp/preprocess | 21 + cpp/preprocess.sh | 17 - cpp/test.cpp | 982 ------------------------------------------ cpp/unpack.c | 407 +++++++++++++++++ cpp/vrefbuffer.c | 201 +++++++++ cpp/zone.c | 220 ++++++++++ msgpack_vc8.postbuild.bat | 41 -- msgpack_vc8.sln | 20 - msgpack_vc8.vcproj | 283 ------------ 60 files changed, 4112 insertions(+), 4674 deletions(-) delete mode 100644 AUTHORS delete mode 100644 COPYING delete mode 100644 ChangeLog delete mode 100644 LICENSE delete mode 100644 Makefile.am delete mode 100644 NEWS delete mode 100644 NOTICE delete mode 100644 README create mode 100644 README.md delete mode 100755 bootstrap delete mode 100644 c/Makefile.am delete mode 100644 c/bench.c delete mode 100644 c/bench.mk delete mode 100644 c/msgpack.h delete mode 100644 c/msgpack/object.h delete mode 100644 c/msgpack/pack.h delete mode 100644 c/msgpack/sbuffer.h delete mode 100644 c/msgpack/unpack.h delete mode 100644 c/msgpack/vrefbuffer.h delete mode 100644 c/msgpack/zbuffer.h delete mode 100644 c/msgpack/zone.h delete mode 100644 c/object.c delete mode 100644 c/test.cpp delete mode 100644 c/unpack.c delete mode 100644 c/vrefbuffer.c delete mode 100644 c/zone.c delete mode 100644 configure.in create mode 100644 cpp/AUTHORS create mode 100644 cpp/COPYING create mode 100644 cpp/ChangeLog create mode 100644 cpp/LICENSE create mode 100644 cpp/NOTICE delete mode 100644 cpp/bench.cpp delete mode 100644 cpp/bench.mk create mode 100755 cpp/bootstrap create mode 100644 cpp/configure.in create mode 100644 cpp/msgpack.h create mode 100644 cpp/msgpack/object.h create mode 100644 cpp/msgpack/pack.h create mode 100644 cpp/msgpack/sbuffer.h create mode 100644 cpp/msgpack/unpack.h create mode 100644 cpp/msgpack/vrefbuffer.h create mode 100644 cpp/msgpack/zbuffer.h create mode 100644 cpp/msgpack/zone.h create mode 100644 cpp/msgpack_test.cpp create mode 100644 cpp/msgpack_vc8.postbuild.bat create mode 100644 cpp/msgpack_vc8.sln create mode 100644 cpp/msgpack_vc8.vcproj create mode 100644 cpp/msgpackc_test.cpp create mode 100644 cpp/object.c create mode 100755 cpp/preprocess delete mode 100755 cpp/preprocess.sh delete mode 100644 cpp/test.cpp create mode 100644 cpp/unpack.c create mode 100644 cpp/vrefbuffer.c create mode 100644 cpp/zone.c delete mode 100644 msgpack_vc8.postbuild.bat delete mode 100644 msgpack_vc8.sln delete mode 100755 msgpack_vc8.vcproj diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index ababacb..0000000 --- a/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -FURUHASHI Sadayuki diff --git a/COPYING b/COPYING deleted file mode 100644 index 4388e8f..0000000 --- a/COPYING +++ /dev/null @@ -1,14 +0,0 @@ -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/ChangeLog b/ChangeLog deleted file mode 100644 index e69de29..0000000 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d645695..0000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - 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/Makefile.am b/Makefile.am deleted file mode 100644 index 04f62d2..0000000 --- a/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -if ENABLE_CXX -SUBDIRS = c cpp -else -SUBDIRS = c -endif - -nobase_include_HEADERS = \ - msgpack/pack_define.h \ - msgpack/pack_template.h \ - msgpack/unpack_define.h \ - msgpack/unpack_template.h \ - msgpack/sysdep.h - -EXTRA_DIST = \ - msgpack_vc8.vcproj \ - msgpack_vc8.sln \ - msgpack_vc8.postbuild.bat - diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29..0000000 diff --git a/NOTICE b/NOTICE deleted file mode 100644 index e706f2a..0000000 --- a/NOTICE +++ /dev/null @@ -1,4 +0,0 @@ -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/README b/README deleted file mode 100644 index 6ca10d6..0000000 --- a/README +++ /dev/null @@ -1,70 +0,0 @@ -MessagePack ------------ -Binary-based efficient data interchange format. - - -*Requirements - - MessagePack is only tested on Linux and Mac OS X, but it may run on other - UNIX-like platforms. - - gcc >= 4.1 is required to build. - - -*Installation - - Simply run ./configure && make && make install to install C and C++ binding. - - $ ./configure - $ make - $ sudo make install - - To install Ruby binding, run ./makegem.sh script on ruby/ directory and install - generated gem package. - - $ cd ruby - $ ./makegem.sh - $ gem install msgpack-*.gem - - -*Usage - - C++: - include msgpack.hpp header and link libmsgpack library. - see example/simple.cc for example. - - g++ simple.cc -lmsgpack - g++ stream.cc -lmsgpack -lpthread - - - C: - include msgpack.h header and link libmsgpackc library. - see example/simple.c for example. - - gcc simple.c -lmsgpackc - - - Ruby: - require msgpack library. - see example/simple.rb for example. - - ruby -rubygems simple.rb - - - API Document is available at http://msgpack.sourceforge.jp/. - - -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/README.md b/README.md new file mode 100644 index 0000000..066c45e --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +MessagePack +=========== +Extremely efficient object serialization library. It's like JSON, but very fast and small. + + +## What's MessagePack? + +MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small. + +Typical small integer (like flags or error code) is saved only in 1 byte, and typical short string only needs 1 byte except the length of the string itself. \[1,2,3\] (3 elements array) is serialized in 4 bytes using MessagePack as follows: + + require 'msgpack' + msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03" + MessagePack.unpack(msg) #=> [1,2,3] + + +## Performance + +![Serialization + Deserialization Speed Test](http://msgpack.sourceforge.net/index/speedtest.png) + +In this test, it measured the elapsed time of serializing and deserializing 200,000 target objects. The target object consists of the three integers and 512 bytes string. +The source code of this test is available from [frsyuki' serializer-speed-test repository.](http://github.com/frsyuki/serializer-speed-test) + + +## Getting Started + +Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/) + + +## Learn More + + - [Project Web Site](http://msgpack.sourceforge.net/) + - [MessagePack format specification](http://msgpack.sourceforge.net/spec) + - [Repository at github](http://github.com/msgpack/msgpack) + - [Wiki](http://msgpack.sourceforge.net/start) + - [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc) + diff --git a/bootstrap b/bootstrap deleted file mode 100755 index 8ac504b..0000000 --- a/bootstrap +++ /dev/null @@ -1,117 +0,0 @@ -#!/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 -(cd cpp && ./preprocess.sh $@; cd ..) - - -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/c/Makefile.am b/c/Makefile.am deleted file mode 100644 index bbe547c..0000000 --- a/c/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -lib_LTLIBRARIES = libmsgpackc.la - -libmsgpackc_la_SOURCES = \ - unpack.c \ - object.c \ - vrefbuffer.c \ - zone.c - -nobase_include_HEADERS = \ - msgpack.h \ - msgpack/sbuffer.h \ - msgpack/vrefbuffer.h \ - msgpack/zbuffer.h \ - msgpack/pack.h \ - msgpack/unpack.h \ - msgpack/object.h \ - msgpack/zone.h - -# -version-info CURRENT:REVISION:AGE -libmsgpackc_la_LDFLAGS = -version-info 2:0:0 - -check_PROGRAMS = \ - msgpackc_test - -msgpackc_test_SOURCES = test.cpp -msgpackc_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c -msgpackc_test_LDADD = libmsgpackc.la -lgtest_main - -TESTS = $(check_PROGRAMS) diff --git a/c/bench.c b/c/bench.c deleted file mode 100644 index d72a10d..0000000 --- a/c/bench.c +++ /dev/null @@ -1,323 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include -#include - - -static struct timeval g_timer; - -void reset_timer() -{ - gettimeofday(&g_timer, NULL); -} - -void show_timer(size_t bufsz) -{ - struct timeval endtime; - gettimeofday(&endtime, NULL); - double sec = (endtime.tv_sec - g_timer.tv_sec) - + (double)(endtime.tv_usec - g_timer.tv_usec) / 1000 / 1000; - printf("%f sec\n", sec); - printf("%f MB\n", ((double)bufsz)/1024/1024); - printf("%f Mbps\n", ((double)bufsz)*8/sec/1000/1000); -} - - -static int reformat_null(void * ctx) { return 1; } -static int reformat_boolean(void * ctx, int boolean) { return 1; } -static int reformat_number(void * ctx, const char * s, unsigned int l) { return 1; } -static int reformat_string(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { return 1; } -static int reformat_map_key(void * ctx, const unsigned char * stringVal, unsigned int stringLen) { return 1; } -static int reformat_start_map(void * ctx) { return 1; } -static int reformat_end_map(void * ctx) { return 1; } -static int reformat_start_array(void * ctx) { return 1; } -static int reformat_end_array(void * ctx) { return 1; } - - -static void* unpack_uint8(void* data, uint8_t d) { return NULL; } -static void* unpack_uint16(void* data, uint16_t d) { return NULL; } -static void* unpack_uint32(void* data, uint32_t d) { return NULL; } -static void* unpack_uint64(void* data, uint64_t d) { return NULL; } -static void* unpack_int8(void* data, int8_t d) { return NULL; } -static void* unpack_int16(void* data, int16_t d) { return NULL; } -static void* unpack_int32(void* data, int32_t d) { return NULL; } -static void* unpack_int64(void* data, int64_t d) { return NULL; } -static void* unpack_float(void* data, float d) { return NULL; } -static void* unpack_double(void* data, double d) { return NULL; } -static void* unpack_nil(void* data) { return NULL; } -static void* unpack_true(void* data) { return NULL; } -static void* unpack_false(void* data) { return NULL; } -static void* unpack_array(void* data, unsigned int n) { return NULL; } -static void unpack_array_item(void* data, void* c, void* o) { } -static void* unpack_map(void* data, unsigned int n) { return NULL; } -static void unpack_map_item(void* data, void* c, void* k, void* v) { } -static void* unpack_raw(void* data, const char* b, const char* p, unsigned int l) { /*printf("unpack raw %p %lu\n",p,l);*/ return NULL; } - - -typedef struct { - size_t allocated; - size_t length; - char* buffer; -} pack_buffer; - -static const size_t PACK_INITIAL_BUFFER_SIZE = 32*1024; - -static void pack_buffer_init(pack_buffer* data) -{ - data->buffer = malloc(PACK_INITIAL_BUFFER_SIZE); - data->length = 0; - data->allocated = PACK_INITIAL_BUFFER_SIZE; -} - -static void pack_buffer_reset(pack_buffer* data) -{ - data->buffer = realloc(data->buffer, PACK_INITIAL_BUFFER_SIZE); - data->allocated = PACK_INITIAL_BUFFER_SIZE; - data->length = 0; -} - -static void pack_buffer_free(pack_buffer* data) -{ - free(data->buffer); -} - -static void pack_append_buffer(void* user, const char* b, unsigned int l) -{ - pack_buffer* data = (pack_buffer*)user; - if(data->allocated - data->length < l) { - data->buffer = realloc(data->buffer, data->allocated*2); - data->allocated *= 2; - } - memcpy(data->buffer + data->length, b, l); - data->length += l; -} - - -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<<20; -//static const unsigned int TASK_STR_LEN = 1<<12; -static const char* TASK_STR_PTR; - - -void bench_json(void) -{ - puts("== JSON =="); - - - yajl_gen_config gcfg = {0, NULL}; - yajl_gen g = yajl_gen_alloc(&gcfg); - - yajl_parser_config hcfg = { 0, 0 }; - yajl_callbacks callbacks = { - reformat_null, - reformat_boolean, - NULL, - NULL, - reformat_number, - reformat_string, - reformat_start_map, - reformat_map_key, - reformat_end_map, - reformat_start_array, - reformat_end_array - }; - yajl_handle h = yajl_alloc(&callbacks, &hcfg, NULL); - - - const unsigned char * buf; - unsigned int len; - - - puts("generate integer"); - reset_timer(); - { - unsigned int i; - yajl_gen_array_open(g); - for(i=0; i < TASK_INT_NUM; ++i) { - yajl_gen_integer(g, i); - } - yajl_gen_array_close(g); - } - show_timer(len); - - yajl_gen_get_buf(g, &buf, &len); - - puts("----"); - puts("parse integer"); - reset_timer(); - { - yajl_status stat = yajl_parse(h, buf, len); - if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { - unsigned char * str = yajl_get_error(h, 1, buf, len); - fprintf(stderr, (const char *) str); - } - } - show_timer(len); - - - //yajl_gen_clear(g); - yajl_gen_free(g); - g = yajl_gen_alloc(&gcfg); - yajl_free(h); - h = yajl_alloc(&callbacks, &hcfg, NULL); - - - puts("----"); - puts("generate string"); - reset_timer(); - { - unsigned int i; - yajl_gen_array_open(g); - for(i=0; i < TASK_STR_LEN; ++i) { - yajl_gen_string(g, (const unsigned char*)TASK_STR_PTR, i); - } - yajl_gen_array_close(g); - } - show_timer(len); - - yajl_gen_get_buf(g, &buf, &len); - - puts("----"); - puts("parse string"); - reset_timer(); - { - yajl_status stat = yajl_parse(h, buf, len); - if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { - unsigned char * str = yajl_get_error(h, 1, buf, len); - fprintf(stderr, (const char *) str); - } - } - show_timer(len); - - - yajl_gen_free(g); - yajl_free(h); -} - - -void bench_msgpack(void) -{ - puts("== MessagePack =="); - - - pack_buffer mpkbuf; - pack_buffer_init(&mpkbuf); - - msgpack_pack_t* mpk = msgpack_pack_new( - &mpkbuf, pack_append_buffer); - - msgpack_unpack_callback cb = { - unpack_uint8, - unpack_uint16, - unpack_uint32, - unpack_uint64, - unpack_int8, - unpack_int16, - unpack_int32, - unpack_int64, - unpack_float, - unpack_double, - unpack_nil, - unpack_true, - unpack_false, - unpack_array, - unpack_array_item, - unpack_map, - unpack_map_item, - unpack_raw, - }; - msgpack_unpack_t* mupk = msgpack_unpack_new(NULL, &cb); - - - size_t len; - const char* buf; - - - puts("pack integer"); - reset_timer(); - { - unsigned int i; - msgpack_pack_array(mpk, TASK_INT_NUM); - for(i=0; i < TASK_INT_NUM; ++i) { - msgpack_pack_unsigned_int(mpk, i); - } - } - show_timer(mpkbuf.length); - - len = mpkbuf.length; - buf = mpkbuf.buffer; - - puts("----"); - puts("unpack integer"); - reset_timer(); - { - size_t off = 0; - int ret = msgpack_unpack_execute(mupk, buf, len, &off); - if(ret < 0) { - fprintf(stderr, "Parse error.\n"); - } else if(ret == 0) { - fprintf(stderr, "Not finished.\n"); - } - } - show_timer(mpkbuf.length); - - - pack_buffer_reset(&mpkbuf); - msgpack_unpack_reset(mupk); - - - puts("----"); - puts("pack string"); - reset_timer(); - { - unsigned int i; - msgpack_pack_array(mpk, TASK_STR_LEN); - for(i=0; i < TASK_STR_LEN; ++i) { - msgpack_pack_raw(mpk, i); - msgpack_pack_raw_body(mpk, TASK_STR_PTR, i); - } - } - show_timer(mpkbuf.length); - - len = mpkbuf.length; - buf = mpkbuf.buffer; - - puts("----"); - puts("unpack string"); - reset_timer(); - { - size_t off = 0; - int ret = msgpack_unpack_execute(mupk, buf, len, &off); - if(ret < 0) { - fprintf(stderr, "Parse error.\n"); - } else if(ret == 0) { - fprintf(stderr, "Not finished.\n"); - } - } - show_timer(mpkbuf.length); - - - msgpack_unpack_free(mupk); - msgpack_pack_free(mpk); - pack_buffer_free(&mpkbuf); -} - -int main(int argc, char* argv[]) -{ - char* str = malloc(TASK_STR_LEN); - memset(str, 'a', TASK_STR_LEN); - TASK_STR_PTR = str; - - bench_msgpack(); - bench_json(); - - return 0; -} - - diff --git a/c/bench.mk b/c/bench.mk deleted file mode 100644 index c765e31..0000000 --- a/c/bench.mk +++ /dev/null @@ -1,9 +0,0 @@ - -CFLAGS += -Wall -g -I. -I.. -O4 -LDFLAGS += -lyajl - -all: bench - -bench: bench.o pack.o unpack.o pack.h unpack.h - $(CC) bench.o pack.o unpack.o $(CFLAGS) $(LDFLAGS) -o $@ - diff --git a/c/msgpack.h b/c/msgpack.h deleted file mode 100644 index 21729f4..0000000 --- a/c/msgpack.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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/c/msgpack/object.h b/c/msgpack/object.h deleted file mode 100644 index 9a014be..0000000 --- a/c/msgpack/object.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 - -#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/c/msgpack/pack.h b/c/msgpack/pack.h deleted file mode 100644 index 1525e0f..0000000 --- a/c/msgpack/pack.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 - -#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/c/msgpack/sbuffer.h b/c/msgpack/sbuffer.h deleted file mode 100644 index bc0a8fd..0000000 --- a/c/msgpack/sbuffer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 -#include - -#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/c/msgpack/unpack.h b/c/msgpack/unpack.h deleted file mode 100644 index e17d0d8..0000000 --- a/c/msgpack/unpack.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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/c/msgpack/vrefbuffer.h b/c/msgpack/vrefbuffer.h deleted file mode 100644 index 38ead67..0000000 --- a/c/msgpack/vrefbuffer.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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 -#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/c/msgpack/zbuffer.h b/c/msgpack/zbuffer.h deleted file mode 100644 index 2a32206..0000000 --- a/c/msgpack/zbuffer.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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 -#include -#include - -#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/c/msgpack/zone.h b/c/msgpack/zone.h deleted file mode 100644 index ce5be6d..0000000 --- a/c/msgpack/zone.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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/c/object.c b/c/object.c deleted file mode 100644 index a22ce21..0000000 --- a/c/object.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * 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 - -#ifndef _MSC_VER -#include -#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, "#", o.type, o.via.u64); - } -} - diff --git a/c/test.cpp b/c/test.cpp deleted file mode 100644 index f5646ea..0000000 --- a/c/test.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include "msgpack.h" - -#include -#include -#include - -#include - -using namespace std; - -const unsigned int kLoop = 10000; -const double kEPS = 1e-10; - -#define GEN_TEST_SIGNED(test_type, func_type) \ - do { \ - vector v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(-1); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::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 v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(2); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::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 v; - v.push_back(0.0); - v.push_back(1.0); - v.push_back(-1.0); - v.push_back(numeric_limits::min()); - v.push_back(numeric_limits::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 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::min()); - v.push_back(numeric_limits::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/c/unpack.c b/c/unpack.c deleted file mode 100644 index 4334974..0000000 --- a/c/unpack.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * 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 - - -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/c/vrefbuffer.c b/c/vrefbuffer.c deleted file mode 100644 index 136372f..0000000 --- a/c/vrefbuffer.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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 -#include - -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/c/zone.c b/c/zone.c deleted file mode 100644 index 3d0634e..0000000 --- a/c/zone.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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 -#include - -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); -} - diff --git a/configure.in b/configure.in deleted file mode 100644 index 0f2c5d0..0000000 --- a/configure.in +++ /dev/null @@ -1,61 +0,0 @@ -AC_INIT(msgpack/unpack_template.h) -AC_CONFIG_AUX_DIR(ac) -AM_INIT_AUTOMAKE(msgpack, 0.4.3) -AC_CONFIG_HEADER(config.h) - -AC_SUBST(CFLAGS) -if test "" = "$CFLAGS"; then - CFLAGS="-g -O4" -fi - -AC_PROG_CC - -CFLAGS="-O4 -Wall $CFLAGS -I.." - -AC_MSG_CHECKING([if c++ api is enabled]) -AC_ARG_ENABLE(cxx, - AS_HELP_STRING([--disable-cxx], - [don't build c++ api.]) ) -AC_MSG_RESULT($enable_cxx) -if test "$enable_cxx" != "no"; then - AC_SUBST(CXXFLAGS) - if test "" = "$CXXFLAGS"; then - CXXFLAGS="-g -O4" - fi -fi - -# FIXME enable_cxx -AC_PROG_CXX - -CXXFLAGS="-O4 -Wall $CXXFLAGS -I.. -I../c" - -# FIXME enable_cxx -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 - -AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no") - -AC_PROG_LIBTOOL - -AC_OUTPUT([Makefile c/Makefile cpp/Makefile]) - 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 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 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 -#include -#include -#include -#include -#include -#include - -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 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 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 + +#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 + +#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 +#include + +#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 +#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 +#include +#include + +#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/msgpack_test.cpp b/cpp/msgpack_test.cpp new file mode 100644 index 0000000..113914a --- /dev/null +++ b/cpp/msgpack_test.cpp @@ -0,0 +1,982 @@ +#include "msgpack.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +using namespace std; + +const unsigned int kLoop = 10000; +const unsigned int kElements = 100; +const double kEPS = 1e-10; + +#define GEN_TEST(test_type) \ + do { \ + vector v; \ + v.push_back(0); \ + v.push_back(1); \ + v.push_back(2); \ + v.push_back(numeric_limits::min()); \ + v.push_back(numeric_limits::max()); \ + for (unsigned int i = 0; i < kLoop; i++) \ + v.push_back(rand()); \ + for (unsigned int i = 0; i < v.size() ; i++) { \ + msgpack::sbuffer sbuf; \ + test_type val1 = v[i]; \ + msgpack::pack(sbuf, val1); \ + msgpack::zone z; \ + msgpack::object obj; \ + msgpack::unpack_return ret = \ + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ + test_type val2; \ + obj.convert(&val2); \ + EXPECT_EQ(val1, val2); \ + } \ +} while(0) + +TEST(MSGPACK, simple_buffer_short) +{ + GEN_TEST(short); +} + +TEST(MSGPACK, simple_buffer_int) +{ + GEN_TEST(int); +} + +TEST(MSGPACK, simple_buffer_long) +{ + GEN_TEST(long); +} + +TEST(MSGPACK, simple_buffer_long_long) +{ + GEN_TEST(long long); +} + +TEST(MSGPACK, simple_buffer_unsigned_short) +{ + GEN_TEST(unsigned short); +} + +TEST(MSGPACK, simple_buffer_unsigned_int) +{ + GEN_TEST(unsigned int); +} + +TEST(MSGPACK, simple_buffer_unsigned_long) +{ + GEN_TEST(unsigned long); +} + +TEST(MSGPACK, simple_buffer_unsigned_long_long) +{ + GEN_TEST(unsigned long long); +} + +TEST(MSGPACK, simple_buffer_uint8) +{ + GEN_TEST(uint8_t); +} + +TEST(MSGPACK, simple_buffer_uint16) +{ + GEN_TEST(uint16_t); +} + +TEST(MSGPACK, simple_buffer_uint32) +{ + GEN_TEST(uint32_t); +} + +TEST(MSGPACK, simple_buffer_uint64) +{ + GEN_TEST(uint64_t); +} + +TEST(MSGPACK, simple_buffer_int8) +{ + GEN_TEST(int8_t); +} + +TEST(MSGPACK, simple_buffer_int16) +{ + GEN_TEST(int16_t); +} + +TEST(MSGPACK, simple_buffer_int32) +{ + GEN_TEST(int32_t); +} + +TEST(MSGPACK, simple_buffer_int64) +{ + GEN_TEST(int64_t); +} + +TEST(MSGPACK, simple_buffer_float) +{ + vector 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::min()); + v.push_back(numeric_limits::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++) { + msgpack::sbuffer sbuf; + float val1 = v[i]; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + float val2; + obj.convert(&val2); + + if (isnan(val1)) + EXPECT_TRUE(isnan(val2)); + else if (isinf(val1)) + EXPECT_TRUE(isinf(val2)); + else + EXPECT_TRUE(fabs(val2 - val1) <= kEPS); + } +} + +TEST(MSGPACK, simple_buffer_double) +{ + vector 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::min()); + v.push_back(numeric_limits::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++) { + msgpack::sbuffer sbuf; + double val1 = v[i]; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + double val2; + obj.convert(&val2); + + if (isnan(val1)) + EXPECT_TRUE(isnan(val2)); + else if (isinf(val1)) + EXPECT_TRUE(isinf(val2)); + else + EXPECT_TRUE(fabs(val2 - val1) <= kEPS); + } +} + +TEST(MSGPACK, simple_buffer_true) +{ + msgpack::sbuffer sbuf; + bool val1 = true; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + bool val2; + obj.convert(&val2); + EXPECT_EQ(val1, val2); +} + +TEST(MSGPACK, simple_buffer_false) +{ + msgpack::sbuffer sbuf; + bool val1 = false; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + bool val2; + obj.convert(&val2); + EXPECT_EQ(val1, val2); +} + +//----------------------------------------------------------------------------- + +// STL + +TEST(MSGPACK_STL, simple_buffer_string) +{ + for (unsigned int k = 0; k < kLoop; k++) { + string val1; + for (unsigned int i = 0; i < kElements; i++) + val1 += 'a' + rand() % 26; + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + string val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(val1, val2); + } +} + +TEST(MSGPACK_STL, simple_buffer_vector) +{ + for (unsigned int k = 0; k < kLoop; k++) { + vector val1; + for (unsigned int i = 0; i < kElements; i++) + val1.push_back(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + vector val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_map) +{ + for (unsigned int k = 0; k < kLoop; k++) { + map val1; + for (unsigned int i = 0; i < kElements; i++) + val1[rand()] = rand(); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + map val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_deque) +{ + for (unsigned int k = 0; k < kLoop; k++) { + deque val1; + for (unsigned int i = 0; i < kElements; i++) + val1.push_back(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + deque val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_list) +{ + for (unsigned int k = 0; k < kLoop; k++) { + list val1; + for (unsigned int i = 0; i < kElements; i++) + val1.push_back(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + list val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_set) +{ + for (unsigned int k = 0; k < kLoop; k++) { + set val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + set val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_pair) +{ + for (unsigned int k = 0; k < kLoop; k++) { + pair val1 = make_pair(rand(), rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + pair val2; + obj.convert(&val2); + EXPECT_EQ(val1.first, val2.first); + EXPECT_EQ(val1.second, val2.second); + } +} + +TEST(MSGPACK_STL, simple_buffer_multimap) +{ + for (unsigned int k = 0; k < kLoop; k++) { + multimap val1; + for (unsigned int i = 0; i < kElements; i++) { + int i1 = rand(); + val1.insert(make_pair(i1, rand())); + val1.insert(make_pair(i1, rand())); + } + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + multimap val2; + obj.convert(&val2); + + vector > v1, v2; + multimap::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(make_pair(it->first, it->second)); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(make_pair(it->first, it->second)); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} + +TEST(MSGPACK_STL, simple_buffer_multiset) +{ + for (unsigned int k = 0; k < kLoop; k++) { + multiset val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + multiset val2; + obj.convert(&val2); + + vector v1, v2; + multiset::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(*it); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(*it); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} + +// TR1 + +#ifdef HAVE_TR1_UNORDERED_MAP +#include +#include "cpp/msgpack/type/tr1/unordered_map.hpp" +TEST(MSGPACK_TR1, simple_buffer_unordered_map) +{ + for (unsigned int k = 0; k < kLoop; k++) { + tr1::unordered_map val1; + for (unsigned int i = 0; i < kElements; i++) + val1[rand()] = rand(); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + tr1::unordered_map val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + tr1::unordered_map::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) { + EXPECT_TRUE(val2.find(it->first) != val2.end()); + EXPECT_EQ(it->second, val2.find(it->first)->second); + } + } +} + +TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) +{ + for (unsigned int k = 0; k < kLoop; k++) { + tr1::unordered_multimap val1; + for (unsigned int i = 0; i < kElements; i++) { + int i1 = rand(); + val1.insert(make_pair(i1, rand())); + val1.insert(make_pair(i1, rand())); + } + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + tr1::unordered_multimap val2; + obj.convert(&val2); + + vector > v1, v2; + tr1::unordered_multimap::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(make_pair(it->first, it->second)); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(make_pair(it->first, it->second)); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} +#endif + +#ifdef HAVE_TR1_UNORDERED_SET +#include +#include "cpp/msgpack/type/tr1/unordered_set.hpp" +TEST(MSGPACK_TR1, simple_buffer_unordered_set) +{ + for (unsigned int k = 0; k < kLoop; k++) { + tr1::unordered_set val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + tr1::unordered_set val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + tr1::unordered_set::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + EXPECT_TRUE(val2.find(*it) != val2.end()); + } +} + +TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) +{ + for (unsigned int k = 0; k < kLoop; k++) { + tr1::unordered_multiset val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + tr1::unordered_multiset val2; + obj.convert(&val2); + + vector v1, v2; + tr1::unordered_multiset::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(*it); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(*it); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} +#endif + +// User-Defined Structures + +class TestClass +{ +public: + TestClass() : i(0), s("kzk") {} + int i; + string s; + MSGPACK_DEFINE(i, s); +}; + +TEST(MSGPACK_USER_DEFINED, simple_buffer_class) +{ + for (unsigned int k = 0; k < kLoop; k++) { + TestClass val1; + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestClass val2; + val2.i = -1; + val2.s = ""; + obj.convert(&val2); + EXPECT_EQ(val1.i, val2.i); + EXPECT_EQ(val1.s, val2.s); + } +} + +class TestClass2 +{ +public: + TestClass2() : i(0), s("kzk") { + for (unsigned int i = 0; i < kElements; i++) + v.push_back(rand()); + } + int i; + string s; + vector v; + MSGPACK_DEFINE(i, s, v); +}; + +TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new) +{ + for (unsigned int k = 0; k < kLoop; k++) { + TestClass val1; + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestClass2 val2; + val2.i = -1; + val2.s = ""; + val2.v = vector(); + obj.convert(&val2); + EXPECT_EQ(val1.i, val2.i); + EXPECT_EQ(val1.s, val2.s); + EXPECT_FALSE(val2.s.empty()); + } +} + +TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old) +{ + for (unsigned int k = 0; k < kLoop; k++) { + TestClass2 val1; + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestClass val2; + val2.i = -1; + val2.s = ""; + obj.convert(&val2); + EXPECT_EQ(val1.i, val2.i); + EXPECT_EQ(val1.s, val2.s); + EXPECT_FALSE(val2.s.empty()); + } +} + +class TestEnumMemberClass +{ +public: + TestEnumMemberClass() + : t1(STATE_A), t2(STATE_B), t3(STATE_C) {} + + enum TestEnumType { + STATE_INVALID = 0, + STATE_A = 1, + STATE_B = 2, + STATE_C = 3 + }; + TestEnumType t1; + TestEnumType t2; + TestEnumType t3; + + MSGPACK_DEFINE((int&)t1, (int&)t2, (int&)t3); +}; + +TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member) +{ + TestEnumMemberClass val1; + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestEnumMemberClass val2; + val2.t1 = TestEnumMemberClass::STATE_INVALID; + val2.t2 = TestEnumMemberClass::STATE_INVALID; + val2.t3 = TestEnumMemberClass::STATE_INVALID; + obj.convert(&val2); + EXPECT_EQ(val1.t1, val2.t1); + EXPECT_EQ(val1.t2, val2.t2); + EXPECT_EQ(val1.t3, val2.t3); +} + +class TestUnionMemberClass +{ +public: + TestUnionMemberClass() {} + TestUnionMemberClass(double f) { + is_double = true; + value.f = f; + } + TestUnionMemberClass(int i) { + is_double = false; + value.i = i; + } + + union { + double f; + int i; + } value; + bool is_double; + + template + void msgpack_pack(Packer& pk) const + { + if (is_double) + pk.pack(msgpack::type::tuple(true, value.f)); + else + pk.pack(msgpack::type::tuple(false, value.i)); + } + + void msgpack_unpack(msgpack::object o) + { + msgpack::type::tuple tuple; + o.convert(&tuple); + + is_double = tuple.get<0>(); + if (is_double) + tuple.get<1>().convert(&value.f); + else + tuple.get<1>().convert(&value.i); + } +}; + +TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member) +{ + { + // double + TestUnionMemberClass val1(1.0); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestUnionMemberClass val2; + obj.convert(&val2); + EXPECT_EQ(val1.is_double, val2.is_double); + EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS); + } + { + // int + TestUnionMemberClass val1(1); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + TestUnionMemberClass val2; + obj.convert(&val2); + EXPECT_EQ(val1.is_double, val2.is_double); + EXPECT_EQ(val1.value.i, 1); + EXPECT_EQ(val1.value.i, val2.value.i); + } +} + +//----------------------------------------------------------------------------- + +#define GEN_TEST_VREF(test_type) \ + do { \ + vector v; \ + v.push_back(0); \ + for (unsigned int i = 0; i < v.size(); i++) { \ + test_type val1 = v[i]; \ + msgpack::vrefbuffer vbuf; \ + msgpack::pack(vbuf, val1); \ + msgpack::sbuffer sbuf; \ + const struct iovec* cur = vbuf.vector(); \ + const struct iovec* end = cur + vbuf.vector_size(); \ + for(; cur != end; ++cur) \ + sbuf.write((const char*)cur->iov_base, cur->iov_len); \ + msgpack::zone z; \ + msgpack::object obj; \ + msgpack::unpack_return ret = \ + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ + test_type val2; \ + obj.convert(&val2); \ + EXPECT_EQ(val1, val2); \ + } \ + } while(0); + +TEST(MSGPACK, vrefbuffer_short) +{ + GEN_TEST_VREF(short); +} + +TEST(MSGPACK, vrefbuffer_int) +{ + GEN_TEST_VREF(int); +} + +TEST(MSGPACK, vrefbuffer_long) +{ + GEN_TEST_VREF(long); +} + +TEST(MSGPACK, vrefbuffer_long_long) +{ + GEN_TEST_VREF(long long); +} + +TEST(MSGPACK, vrefbuffer_unsigned_short) +{ + GEN_TEST_VREF(unsigned short); +} + +TEST(MSGPACK, vrefbuffer_unsigned_int) +{ + GEN_TEST_VREF(unsigned int); +} + +TEST(MSGPACK, vrefbuffer_unsigned_long) +{ + GEN_TEST_VREF(unsigned long); +} + +TEST(MSGPACK, vrefbuffer_unsigned_long_long) +{ + GEN_TEST_VREF(unsigned long long); +} + +TEST(MSGPACK, vrefbuffer_uint8) +{ + GEN_TEST_VREF(uint8_t); +} + +TEST(MSGPACK, vrefbuffer_uint16) +{ + GEN_TEST_VREF(uint16_t); +} + +TEST(MSGPACK, vrefbuffer_uint32) +{ + GEN_TEST_VREF(uint32_t); +} + +TEST(MSGPACK, vrefbuffer_uint64) +{ + GEN_TEST_VREF(uint64_t); +} + +TEST(MSGPACK, vrefbuffer_int8) +{ + GEN_TEST_VREF(int8_t); +} + +TEST(MSGPACK, vrefbuffer_int16) +{ + GEN_TEST_VREF(int16_t); +} + +TEST(MSGPACK, vrefbuffer_int32) +{ + GEN_TEST_VREF(int32_t); +} + +TEST(MSGPACK, vrefbuffer_int64) +{ + GEN_TEST_VREF(int64_t); +} + +//----------------------------------------------------------------------------- + +#define GEN_TEST_STREAM(test_type) \ + for (unsigned int k = 0; k < kLoop; k++) { \ + msgpack::sbuffer sbuf; \ + msgpack::packer pk(sbuf); \ + typedef std::vector vec_type; \ + vec_type vec; \ + for(unsigned int i = 0; i < rand() % kLoop; ++i) { \ + vec_type::value_type r = rand(); \ + vec.push_back(r); \ + pk.pack(r); \ + } \ + msgpack::unpacker pac; \ + vec_type::const_iterator it = vec.begin(); \ + const char *p = sbuf.data(); \ + const char * const pend = p + sbuf.size(); \ + while (p < pend) { \ + const size_t sz = std::min(pend - p, rand() % 128); \ + pac.reserve_buffer(sz); \ + memcpy(pac.buffer(), p, sz); \ + pac.buffer_consumed(sz); \ + while (pac.execute()) { \ + if (it == vec.end()) goto out; \ + msgpack::object obj = pac.data(); \ + msgpack::zone *life = pac.release_zone(); \ + EXPECT_TRUE(life != NULL); \ + pac.reset(); \ + vec_type::value_type val; \ + obj.convert(&val); \ + EXPECT_EQ(*it, val); \ + ++it; \ + delete life; \ + } \ + p += sz; \ + } \ + out: \ + ; \ + } + +TEST(MSGPACK, stream_short) +{ + GEN_TEST_STREAM(short); +} + +TEST(MSGPACK, stream_int) +{ + GEN_TEST_STREAM(int); +} + +TEST(MSGPACK, stream_long) +{ + GEN_TEST_STREAM(long); +} + +TEST(MSGPACK, stream_long_long) +{ + GEN_TEST_STREAM(long long); +} + +TEST(MSGPACK, stream_unsigned_short) +{ + GEN_TEST_STREAM(unsigned short); +} + +TEST(MSGPACK, stream_unsigned_int) +{ + GEN_TEST_STREAM(unsigned int); +} + +TEST(MSGPACK, stream_unsigned_long) +{ + GEN_TEST_STREAM(unsigned long); +} + +TEST(MSGPACK, stream_unsigned_long_long) +{ + GEN_TEST_STREAM(unsigned long long); +} + +TEST(MSGPACK, stream_uint8) +{ + GEN_TEST_STREAM(uint8_t); +} + +TEST(MSGPACK, stream_uint16) +{ + GEN_TEST_STREAM(uint16_t); +} + +TEST(MSGPACK, stream_uint32) +{ + GEN_TEST_STREAM(uint32_t); +} + +TEST(MSGPACK, stream_uint64) +{ + GEN_TEST_STREAM(uint64_t); +} + +TEST(MSGPACK, stream_int8) +{ + GEN_TEST_STREAM(int8_t); +} + +TEST(MSGPACK, stream_int16) +{ + GEN_TEST_STREAM(int16_t); +} + +TEST(MSGPACK, stream_int32) +{ + GEN_TEST_STREAM(int32_t); +} + +TEST(MSGPACK, stream_int64) +{ + GEN_TEST_STREAM(int64_t); +} 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +#include +#include + +#include + +using namespace std; + +const unsigned int kLoop = 10000; +const double kEPS = 1e-10; + +#define GEN_TEST_SIGNED(test_type, func_type) \ + do { \ + vector v; \ + v.push_back(0); \ + v.push_back(1); \ + v.push_back(-1); \ + v.push_back(numeric_limits::min()); \ + v.push_back(numeric_limits::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 v; \ + v.push_back(0); \ + v.push_back(1); \ + v.push_back(2); \ + v.push_back(numeric_limits::min()); \ + v.push_back(numeric_limits::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 v; + v.push_back(0.0); + v.push_back(1.0); + v.push_back(-1.0); + v.push_back(numeric_limits::min()); + v.push_back(numeric_limits::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 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::min()); + v.push_back(numeric_limits::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 + +#ifndef _MSC_VER +#include +#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, "#", o.type, o.via.u64); + } +} + diff --git a/cpp/preprocess b/cpp/preprocess new file mode 100755 index 0000000..63af4c6 --- /dev/null +++ b/cpp/preprocess @@ -0,0 +1,21 @@ +#!/bin/sh + +preprocess() { + ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp + if [ "$?" != 0 ]; then + echo "" + echo "** preprocess failed **" + echo "" + else + mv $1.tmp $1 + fi +} + +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/preprocess.sh b/cpp/preprocess.sh deleted file mode 100755 index 2e06c10..0000000 --- a/cpp/preprocess.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -preprocess() { - ruby -r erb -e 'puts ERB.new(ARGF.read).result' $1.erb > $1.tmp - if [ "$?" != 0 ]; then - echo "" - echo "** preprocess failed **" - echo "" - else - mv $1.tmp $1 - fi -} - -preprocess msgpack/type/tuple.hpp -preprocess msgpack/type/define.hpp -preprocess msgpack/zone.hpp - diff --git a/cpp/test.cpp b/cpp/test.cpp deleted file mode 100644 index 113914a..0000000 --- a/cpp/test.cpp +++ /dev/null @@ -1,982 +0,0 @@ -#include "msgpack.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -using namespace std; - -const unsigned int kLoop = 10000; -const unsigned int kElements = 100; -const double kEPS = 1e-10; - -#define GEN_TEST(test_type) \ - do { \ - vector v; \ - v.push_back(0); \ - v.push_back(1); \ - v.push_back(2); \ - v.push_back(numeric_limits::min()); \ - v.push_back(numeric_limits::max()); \ - for (unsigned int i = 0; i < kLoop; i++) \ - v.push_back(rand()); \ - for (unsigned int i = 0; i < v.size() ; i++) { \ - msgpack::sbuffer sbuf; \ - test_type val1 = v[i]; \ - msgpack::pack(sbuf, val1); \ - msgpack::zone z; \ - msgpack::object obj; \ - msgpack::unpack_return ret = \ - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ - test_type val2; \ - obj.convert(&val2); \ - EXPECT_EQ(val1, val2); \ - } \ -} while(0) - -TEST(MSGPACK, simple_buffer_short) -{ - GEN_TEST(short); -} - -TEST(MSGPACK, simple_buffer_int) -{ - GEN_TEST(int); -} - -TEST(MSGPACK, simple_buffer_long) -{ - GEN_TEST(long); -} - -TEST(MSGPACK, simple_buffer_long_long) -{ - GEN_TEST(long long); -} - -TEST(MSGPACK, simple_buffer_unsigned_short) -{ - GEN_TEST(unsigned short); -} - -TEST(MSGPACK, simple_buffer_unsigned_int) -{ - GEN_TEST(unsigned int); -} - -TEST(MSGPACK, simple_buffer_unsigned_long) -{ - GEN_TEST(unsigned long); -} - -TEST(MSGPACK, simple_buffer_unsigned_long_long) -{ - GEN_TEST(unsigned long long); -} - -TEST(MSGPACK, simple_buffer_uint8) -{ - GEN_TEST(uint8_t); -} - -TEST(MSGPACK, simple_buffer_uint16) -{ - GEN_TEST(uint16_t); -} - -TEST(MSGPACK, simple_buffer_uint32) -{ - GEN_TEST(uint32_t); -} - -TEST(MSGPACK, simple_buffer_uint64) -{ - GEN_TEST(uint64_t); -} - -TEST(MSGPACK, simple_buffer_int8) -{ - GEN_TEST(int8_t); -} - -TEST(MSGPACK, simple_buffer_int16) -{ - GEN_TEST(int16_t); -} - -TEST(MSGPACK, simple_buffer_int32) -{ - GEN_TEST(int32_t); -} - -TEST(MSGPACK, simple_buffer_int64) -{ - GEN_TEST(int64_t); -} - -TEST(MSGPACK, simple_buffer_float) -{ - vector 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::min()); - v.push_back(numeric_limits::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++) { - msgpack::sbuffer sbuf; - float val1 = v[i]; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - float val2; - obj.convert(&val2); - - if (isnan(val1)) - EXPECT_TRUE(isnan(val2)); - else if (isinf(val1)) - EXPECT_TRUE(isinf(val2)); - else - EXPECT_TRUE(fabs(val2 - val1) <= kEPS); - } -} - -TEST(MSGPACK, simple_buffer_double) -{ - vector 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::min()); - v.push_back(numeric_limits::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++) { - msgpack::sbuffer sbuf; - double val1 = v[i]; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - double val2; - obj.convert(&val2); - - if (isnan(val1)) - EXPECT_TRUE(isnan(val2)); - else if (isinf(val1)) - EXPECT_TRUE(isinf(val2)); - else - EXPECT_TRUE(fabs(val2 - val1) <= kEPS); - } -} - -TEST(MSGPACK, simple_buffer_true) -{ - msgpack::sbuffer sbuf; - bool val1 = true; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - bool val2; - obj.convert(&val2); - EXPECT_EQ(val1, val2); -} - -TEST(MSGPACK, simple_buffer_false) -{ - msgpack::sbuffer sbuf; - bool val1 = false; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - bool val2; - obj.convert(&val2); - EXPECT_EQ(val1, val2); -} - -//----------------------------------------------------------------------------- - -// STL - -TEST(MSGPACK_STL, simple_buffer_string) -{ - for (unsigned int k = 0; k < kLoop; k++) { - string val1; - for (unsigned int i = 0; i < kElements; i++) - val1 += 'a' + rand() % 26; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - string val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(val1, val2); - } -} - -TEST(MSGPACK_STL, simple_buffer_vector) -{ - for (unsigned int k = 0; k < kLoop; k++) { - vector val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - vector val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_map) -{ - for (unsigned int k = 0; k < kLoop; k++) { - map val1; - for (unsigned int i = 0; i < kElements; i++) - val1[rand()] = rand(); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - map val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_deque) -{ - for (unsigned int k = 0; k < kLoop; k++) { - deque val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - deque val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_list) -{ - for (unsigned int k = 0; k < kLoop; k++) { - list val1; - for (unsigned int i = 0; i < kElements; i++) - val1.push_back(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - list val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_set) -{ - for (unsigned int k = 0; k < kLoop; k++) { - set val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - set val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); - } -} - -TEST(MSGPACK_STL, simple_buffer_pair) -{ - for (unsigned int k = 0; k < kLoop; k++) { - pair val1 = make_pair(rand(), rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - pair val2; - obj.convert(&val2); - EXPECT_EQ(val1.first, val2.first); - EXPECT_EQ(val1.second, val2.second); - } -} - -TEST(MSGPACK_STL, simple_buffer_multimap) -{ - for (unsigned int k = 0; k < kLoop; k++) { - multimap val1; - for (unsigned int i = 0; i < kElements; i++) { - int i1 = rand(); - val1.insert(make_pair(i1, rand())); - val1.insert(make_pair(i1, rand())); - } - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - multimap val2; - obj.convert(&val2); - - vector > v1, v2; - multimap::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(make_pair(it->first, it->second)); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(make_pair(it->first, it->second)); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} - -TEST(MSGPACK_STL, simple_buffer_multiset) -{ - for (unsigned int k = 0; k < kLoop; k++) { - multiset val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - multiset val2; - obj.convert(&val2); - - vector v1, v2; - multiset::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(*it); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(*it); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} - -// TR1 - -#ifdef HAVE_TR1_UNORDERED_MAP -#include -#include "cpp/msgpack/type/tr1/unordered_map.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_map) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_map val1; - for (unsigned int i = 0; i < kElements; i++) - val1[rand()] = rand(); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_map val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - tr1::unordered_map::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) { - EXPECT_TRUE(val2.find(it->first) != val2.end()); - EXPECT_EQ(it->second, val2.find(it->first)->second); - } - } -} - -TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_multimap val1; - for (unsigned int i = 0; i < kElements; i++) { - int i1 = rand(); - val1.insert(make_pair(i1, rand())); - val1.insert(make_pair(i1, rand())); - } - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_multimap val2; - obj.convert(&val2); - - vector > v1, v2; - tr1::unordered_multimap::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(make_pair(it->first, it->second)); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(make_pair(it->first, it->second)); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} -#endif - -#ifdef HAVE_TR1_UNORDERED_SET -#include -#include "cpp/msgpack/type/tr1/unordered_set.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_set) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_set val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_set val2; - obj.convert(&val2); - EXPECT_EQ(val1.size(), val2.size()); - tr1::unordered_set::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - EXPECT_TRUE(val2.find(*it) != val2.end()); - } -} - -TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) -{ - for (unsigned int k = 0; k < kLoop; k++) { - tr1::unordered_multiset val1; - for (unsigned int i = 0; i < kElements; i++) - val1.insert(rand()); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - tr1::unordered_multiset val2; - obj.convert(&val2); - - vector v1, v2; - tr1::unordered_multiset::const_iterator it; - for (it = val1.begin(); it != val1.end(); ++it) - v1.push_back(*it); - for (it = val2.begin(); it != val2.end(); ++it) - v2.push_back(*it); - EXPECT_EQ(val1.size(), val2.size()); - EXPECT_EQ(v1.size(), v2.size()); - sort(v1.begin(), v1.end()); - sort(v2.begin(), v2.end()); - EXPECT_TRUE(v1 == v2); - } -} -#endif - -// User-Defined Structures - -class TestClass -{ -public: - TestClass() : i(0), s("kzk") {} - int i; - string s; - MSGPACK_DEFINE(i, s); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass val2; - val2.i = -1; - val2.s = ""; - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - } -} - -class TestClass2 -{ -public: - TestClass2() : i(0), s("kzk") { - for (unsigned int i = 0; i < kElements; i++) - v.push_back(rand()); - } - int i; - string s; - vector v; - MSGPACK_DEFINE(i, s, v); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass2 val2; - val2.i = -1; - val2.s = ""; - val2.v = vector(); - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - EXPECT_FALSE(val2.s.empty()); - } -} - -TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old) -{ - for (unsigned int k = 0; k < kLoop; k++) { - TestClass2 val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestClass val2; - val2.i = -1; - val2.s = ""; - obj.convert(&val2); - EXPECT_EQ(val1.i, val2.i); - EXPECT_EQ(val1.s, val2.s); - EXPECT_FALSE(val2.s.empty()); - } -} - -class TestEnumMemberClass -{ -public: - TestEnumMemberClass() - : t1(STATE_A), t2(STATE_B), t3(STATE_C) {} - - enum TestEnumType { - STATE_INVALID = 0, - STATE_A = 1, - STATE_B = 2, - STATE_C = 3 - }; - TestEnumType t1; - TestEnumType t2; - TestEnumType t3; - - MSGPACK_DEFINE((int&)t1, (int&)t2, (int&)t3); -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member) -{ - TestEnumMemberClass val1; - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestEnumMemberClass val2; - val2.t1 = TestEnumMemberClass::STATE_INVALID; - val2.t2 = TestEnumMemberClass::STATE_INVALID; - val2.t3 = TestEnumMemberClass::STATE_INVALID; - obj.convert(&val2); - EXPECT_EQ(val1.t1, val2.t1); - EXPECT_EQ(val1.t2, val2.t2); - EXPECT_EQ(val1.t3, val2.t3); -} - -class TestUnionMemberClass -{ -public: - TestUnionMemberClass() {} - TestUnionMemberClass(double f) { - is_double = true; - value.f = f; - } - TestUnionMemberClass(int i) { - is_double = false; - value.i = i; - } - - union { - double f; - int i; - } value; - bool is_double; - - template - void msgpack_pack(Packer& pk) const - { - if (is_double) - pk.pack(msgpack::type::tuple(true, value.f)); - else - pk.pack(msgpack::type::tuple(false, value.i)); - } - - void msgpack_unpack(msgpack::object o) - { - msgpack::type::tuple tuple; - o.convert(&tuple); - - is_double = tuple.get<0>(); - if (is_double) - tuple.get<1>().convert(&value.f); - else - tuple.get<1>().convert(&value.i); - } -}; - -TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member) -{ - { - // double - TestUnionMemberClass val1(1.0); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestUnionMemberClass val2; - obj.convert(&val2); - EXPECT_EQ(val1.is_double, val2.is_double); - EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS); - } - { - // int - TestUnionMemberClass val1(1); - msgpack::sbuffer sbuf; - msgpack::pack(sbuf, val1); - msgpack::zone z; - msgpack::object obj; - msgpack::unpack_return ret = - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); - TestUnionMemberClass val2; - obj.convert(&val2); - EXPECT_EQ(val1.is_double, val2.is_double); - EXPECT_EQ(val1.value.i, 1); - EXPECT_EQ(val1.value.i, val2.value.i); - } -} - -//----------------------------------------------------------------------------- - -#define GEN_TEST_VREF(test_type) \ - do { \ - vector v; \ - v.push_back(0); \ - for (unsigned int i = 0; i < v.size(); i++) { \ - test_type val1 = v[i]; \ - msgpack::vrefbuffer vbuf; \ - msgpack::pack(vbuf, val1); \ - msgpack::sbuffer sbuf; \ - const struct iovec* cur = vbuf.vector(); \ - const struct iovec* end = cur + vbuf.vector_size(); \ - for(; cur != end; ++cur) \ - sbuf.write((const char*)cur->iov_base, cur->iov_len); \ - msgpack::zone z; \ - msgpack::object obj; \ - msgpack::unpack_return ret = \ - msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); \ - EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); \ - test_type val2; \ - obj.convert(&val2); \ - EXPECT_EQ(val1, val2); \ - } \ - } while(0); - -TEST(MSGPACK, vrefbuffer_short) -{ - GEN_TEST_VREF(short); -} - -TEST(MSGPACK, vrefbuffer_int) -{ - GEN_TEST_VREF(int); -} - -TEST(MSGPACK, vrefbuffer_long) -{ - GEN_TEST_VREF(long); -} - -TEST(MSGPACK, vrefbuffer_long_long) -{ - GEN_TEST_VREF(long long); -} - -TEST(MSGPACK, vrefbuffer_unsigned_short) -{ - GEN_TEST_VREF(unsigned short); -} - -TEST(MSGPACK, vrefbuffer_unsigned_int) -{ - GEN_TEST_VREF(unsigned int); -} - -TEST(MSGPACK, vrefbuffer_unsigned_long) -{ - GEN_TEST_VREF(unsigned long); -} - -TEST(MSGPACK, vrefbuffer_unsigned_long_long) -{ - GEN_TEST_VREF(unsigned long long); -} - -TEST(MSGPACK, vrefbuffer_uint8) -{ - GEN_TEST_VREF(uint8_t); -} - -TEST(MSGPACK, vrefbuffer_uint16) -{ - GEN_TEST_VREF(uint16_t); -} - -TEST(MSGPACK, vrefbuffer_uint32) -{ - GEN_TEST_VREF(uint32_t); -} - -TEST(MSGPACK, vrefbuffer_uint64) -{ - GEN_TEST_VREF(uint64_t); -} - -TEST(MSGPACK, vrefbuffer_int8) -{ - GEN_TEST_VREF(int8_t); -} - -TEST(MSGPACK, vrefbuffer_int16) -{ - GEN_TEST_VREF(int16_t); -} - -TEST(MSGPACK, vrefbuffer_int32) -{ - GEN_TEST_VREF(int32_t); -} - -TEST(MSGPACK, vrefbuffer_int64) -{ - GEN_TEST_VREF(int64_t); -} - -//----------------------------------------------------------------------------- - -#define GEN_TEST_STREAM(test_type) \ - for (unsigned int k = 0; k < kLoop; k++) { \ - msgpack::sbuffer sbuf; \ - msgpack::packer pk(sbuf); \ - typedef std::vector vec_type; \ - vec_type vec; \ - for(unsigned int i = 0; i < rand() % kLoop; ++i) { \ - vec_type::value_type r = rand(); \ - vec.push_back(r); \ - pk.pack(r); \ - } \ - msgpack::unpacker pac; \ - vec_type::const_iterator it = vec.begin(); \ - const char *p = sbuf.data(); \ - const char * const pend = p + sbuf.size(); \ - while (p < pend) { \ - const size_t sz = std::min(pend - p, rand() % 128); \ - pac.reserve_buffer(sz); \ - memcpy(pac.buffer(), p, sz); \ - pac.buffer_consumed(sz); \ - while (pac.execute()) { \ - if (it == vec.end()) goto out; \ - msgpack::object obj = pac.data(); \ - msgpack::zone *life = pac.release_zone(); \ - EXPECT_TRUE(life != NULL); \ - pac.reset(); \ - vec_type::value_type val; \ - obj.convert(&val); \ - EXPECT_EQ(*it, val); \ - ++it; \ - delete life; \ - } \ - p += sz; \ - } \ - out: \ - ; \ - } - -TEST(MSGPACK, stream_short) -{ - GEN_TEST_STREAM(short); -} - -TEST(MSGPACK, stream_int) -{ - GEN_TEST_STREAM(int); -} - -TEST(MSGPACK, stream_long) -{ - GEN_TEST_STREAM(long); -} - -TEST(MSGPACK, stream_long_long) -{ - GEN_TEST_STREAM(long long); -} - -TEST(MSGPACK, stream_unsigned_short) -{ - GEN_TEST_STREAM(unsigned short); -} - -TEST(MSGPACK, stream_unsigned_int) -{ - GEN_TEST_STREAM(unsigned int); -} - -TEST(MSGPACK, stream_unsigned_long) -{ - GEN_TEST_STREAM(unsigned long); -} - -TEST(MSGPACK, stream_unsigned_long_long) -{ - GEN_TEST_STREAM(unsigned long long); -} - -TEST(MSGPACK, stream_uint8) -{ - GEN_TEST_STREAM(uint8_t); -} - -TEST(MSGPACK, stream_uint16) -{ - GEN_TEST_STREAM(uint16_t); -} - -TEST(MSGPACK, stream_uint32) -{ - GEN_TEST_STREAM(uint32_t); -} - -TEST(MSGPACK, stream_uint64) -{ - GEN_TEST_STREAM(uint64_t); -} - -TEST(MSGPACK, stream_int8) -{ - GEN_TEST_STREAM(int8_t); -} - -TEST(MSGPACK, stream_int16) -{ - GEN_TEST_STREAM(int16_t); -} - -TEST(MSGPACK, stream_int32) -{ - GEN_TEST_STREAM(int32_t); -} - -TEST(MSGPACK, stream_int64) -{ - GEN_TEST_STREAM(int64_t); -} 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 + + +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 +#include + +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 +#include + +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); +} + diff --git a/msgpack_vc8.postbuild.bat b/msgpack_vc8.postbuild.bat deleted file mode 100644 index 7ee2586..0000000 --- a/msgpack_vc8.postbuild.bat +++ /dev/null @@ -1,41 +0,0 @@ -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 -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 c\msgpack.h include\ -copy c\msgpack\sbuffer.h include\msgpack\ -copy c\msgpack\vrefbuffer.h include\msgpack\ -copy c\msgpack\pack.h include\msgpack\ -copy c\msgpack\unpack.h include\msgpack\ -copy c\msgpack\object.h include\msgpack\ -copy c\msgpack\zone.h include\msgpack\ -copy cpp\msgpack.hpp include\ -copy cpp\msgpack\sbuffer.hpp include\msgpack\ -copy cpp\msgpack\vrefbuffer.hpp include\msgpack\ -copy cpp\msgpack\pack.hpp include\msgpack\ -copy cpp\msgpack\unpack.hpp include\msgpack\ -copy cpp\msgpack\object.hpp include\msgpack\ -copy cpp\msgpack\zone.hpp include\msgpack\ -copy cpp\msgpack\type.hpp include\msgpack\type\ -copy cpp\msgpack\type\bool.hpp include\msgpack\type\ -copy cpp\msgpack\type\float.hpp include\msgpack\type\ -copy cpp\msgpack\type\int.hpp include\msgpack\type\ -copy cpp\msgpack\type\list.hpp include\msgpack\type\ -copy cpp\msgpack\type\deque.hpp include\msgpack\type\ -copy cpp\msgpack\type\map.hpp include\msgpack\type\ -copy cpp\msgpack\type\nil.hpp include\msgpack\type\ -copy cpp\msgpack\type\pair.hpp include\msgpack\type\ -copy cpp\msgpack\type\raw.hpp include\msgpack\type\ -copy cpp\msgpack\type\set.hpp include\msgpack\type\ -copy cpp\msgpack\type\string.hpp include\msgpack\type\ -copy cpp\msgpack\type\vector.hpp include\msgpack\type\ -copy cpp\msgpack\type\tuple.hpp include\msgpack\type\ -copy cpp\msgpack\type\define.hpp include\msgpack\type\ -copy cpp\msgpack\type\tr1\unordered_map.hpp include\msgpack\type\ -copy cpp\msgpack\type\tr1\unordered_set.hpp include\msgpack\type\ - diff --git a/msgpack_vc8.sln b/msgpack_vc8.sln deleted file mode 100644 index 84718af..0000000 --- a/msgpack_vc8.sln +++ /dev/null @@ -1,20 +0,0 @@ - -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/msgpack_vc8.vcproj b/msgpack_vc8.vcproj deleted file mode 100755 index a3fa28f..0000000 --- a/msgpack_vc8.vcproj +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.1