c,cpp: reforms source tree

This commit is contained in:
frsyuki 2010-04-18 00:08:03 +09:00
parent c3f43fb0cf
commit ab8e0c9e31
36 changed files with 159 additions and 721 deletions

1
cpp/AUTHORS Normal file
View file

@ -0,0 +1 @@
FURUHASHI Sadayuki <frsyuki _at_ users.sourceforge.jp>

14
cpp/COPYING Normal file
View file

@ -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.

0
cpp/ChangeLog Normal file
View file

202
cpp/LICENSE Normal file
View file

@ -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.

View file

@ -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)

4
cpp/NOTICE Normal file
View file

@ -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/.

View file

@ -1,188 +0,0 @@
#include <msgpack/unpack.hpp>
#include <msgpack/pack.hpp>
#include <string.h>
#include <sys/time.h>
#include <iostream>
#include <stdexcept>
#include <string>
static const unsigned int TASK_INT_NUM = 1<<24;
static const unsigned int TASK_STR_LEN = 1<<15;
//static const unsigned int TASK_INT_NUM = 1<<22;
//static const unsigned int TASK_STR_LEN = 1<<13;
static const char* TASK_STR_PTR;
class simple_timer {
public:
void reset() { gettimeofday(&m_timeval, NULL); }
void show_stat(size_t bufsz)
{
struct timeval endtime;
gettimeofday(&endtime, NULL);
double sec = (endtime.tv_sec - m_timeval.tv_sec)
+ (double)(endtime.tv_usec - m_timeval.tv_usec) / 1000 / 1000;
std::cout << sec << " sec" << std::endl;
std::cout << (double(bufsz)/1024/1024) << " MB" << std::endl;
std::cout << (bufsz/sec/1000/1000*8) << " Mbps" << std::endl;
}
private:
timeval m_timeval;
};
class simple_buffer {
public:
static const size_t DEFAULT_INITIAL_SIZE = 32*1024;//512*1024*1024*2;
simple_buffer(size_t initial_size = DEFAULT_INITIAL_SIZE) :
m_storage((char*)malloc(initial_size)),
m_allocated(initial_size),
m_used(0)
{
if(!m_storage) { throw std::bad_alloc(); }
}
~simple_buffer()
{
free(m_storage);
}
public:
inline void write(const char* buf, size_t len)
{
if(m_allocated - m_used < len) {
expand_buffer(len);
}
memcpy(m_storage + m_used, buf, len);
m_used += len;
}
void clear()
{
m_used = 0;
}
private:
void expand_buffer(size_t req)
{
size_t nsize = m_allocated * 2;
size_t at_least = m_used + req;
while(nsize < at_least) { nsize *= 2; }
char* tmp = (char*)realloc(m_storage, nsize);
if(!tmp) { throw std::bad_alloc(); }
m_storage = tmp;
m_allocated = nsize;
}
public:
size_t size() const { return m_used; }
const char* data() const { return m_storage; }
private:
char* m_storage;
size_t m_allocated;
size_t m_used;
};
void bench_msgpack_int()
{
simple_buffer buf;
simple_timer timer;
std::cout << "----" << std::endl;
std::cout << "pack integer" << std::endl;
timer.reset();
{
msgpack::packer<simple_buffer> pk(buf);
pk.pack_array(TASK_INT_NUM);
for(unsigned int i=0; i < TASK_INT_NUM; ++i) {
pk.pack_unsigned_int(i);
}
}
timer.show_stat(buf.size());
std::cout << "----" << std::endl;
std::cout << "unpack integer" << std::endl;
msgpack::zone z;
msgpack::object obj;
timer.reset();
{
obj = msgpack::unpack(buf.data(), buf.size(), z);
}
timer.show_stat(buf.size());
/*
std::cout << "----" << std::endl;
std::cout << "dynamic pack integer" << std::endl;
buf.clear();
timer.reset();
msgpack::pack(buf, obj);
timer.show_stat(buf.size());
*/
}
void bench_msgpack_str()
{
simple_buffer buf;
simple_timer timer;
std::cout << "----" << std::endl;
std::cout << "pack string" << std::endl;
timer.reset();
{
msgpack::packer<simple_buffer> pk(buf);
pk.pack_array(TASK_STR_LEN);
for(unsigned int i=0; i < TASK_STR_LEN; ++i) {
pk.pack_raw(i);
pk.pack_raw_body(TASK_STR_PTR, i);
}
}
timer.show_stat(buf.size());
std::cout << "----" << std::endl;
std::cout << "unpack string" << std::endl;
msgpack::zone z;
msgpack::object obj;
timer.reset();
{
obj = msgpack::unpack(buf.data(), buf.size(), z);
}
timer.show_stat(buf.size());
/*
std::cout << "----" << std::endl;
std::cout << "dynamic pack string" << std::endl;
buf.clear();
timer.reset();
msgpack::pack(buf, obj);
timer.show_stat(buf.size());
*/
}
int main(void)
{
char* str = (char*)malloc(TASK_STR_LEN);
memset(str, 'a', TASK_STR_LEN);
TASK_STR_PTR = str;
bench_msgpack_int();
bench_msgpack_str();
return 0;
}

View file

@ -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 $@

126
cpp/bootstrap Executable file
View file

@ -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

43
cpp/configure.in Normal file
View file

@ -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])

23
cpp/msgpack.h Normal file
View file

@ -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"

88
cpp/msgpack/object.h Normal file
View file

@ -0,0 +1,88 @@
/*
* MessagePack for C dynamic typing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_OBJECT_H__
#define MSGPACK_OBJECT_H__
#include "msgpack/zone.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
MSGPACK_OBJECT_NIL = 0x01,
MSGPACK_OBJECT_BOOLEAN = 0x02,
MSGPACK_OBJECT_POSITIVE_INTEGER = 0x03,
MSGPACK_OBJECT_NEGATIVE_INTEGER = 0x04,
MSGPACK_OBJECT_DOUBLE = 0x05,
MSGPACK_OBJECT_RAW = 0x06,
MSGPACK_OBJECT_ARRAY = 0x07,
MSGPACK_OBJECT_MAP = 0x08,
} msgpack_object_type;
struct msgpack_object;
struct msgpack_object_kv;
typedef struct {
uint32_t size;
struct msgpack_object* ptr;
} msgpack_object_array;
typedef struct {
uint32_t size;
struct msgpack_object_kv* ptr;
} msgpack_object_map;
typedef struct {
uint32_t size;
const char* ptr;
} msgpack_object_raw;
typedef union {
bool boolean;
uint64_t u64;
int64_t i64;
double dec;
msgpack_object_array array;
msgpack_object_map map;
msgpack_object_raw raw;
} msgpack_object_union;
typedef struct msgpack_object {
msgpack_object_type type;
msgpack_object_union via;
} msgpack_object;
typedef struct msgpack_object_kv {
msgpack_object key;
msgpack_object val;
} msgpack_object_kv;
void msgpack_object_print(FILE* out, msgpack_object o);
#ifdef __cplusplus
}
#endif
#endif /* msgpack/object.h */

116
cpp/msgpack/pack.h Normal file
View file

@ -0,0 +1,116 @@
/*
* MessagePack for C packing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_PACK_H__
#define MSGPACK_PACK_H__
#include "msgpack/pack_define.h"
#include "msgpack/object.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*msgpack_packer_write)(void* data, const char* buf, unsigned int len);
typedef struct msgpack_packer {
void* data;
msgpack_packer_write callback;
} msgpack_packer;
static void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback);
static msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback);
static void msgpack_packer_free(msgpack_packer* pk);
static int msgpack_pack_short(msgpack_packer* pk, short d);
static int msgpack_pack_int(msgpack_packer* pk, int d);
static int msgpack_pack_long(msgpack_packer* pk, long d);
static int msgpack_pack_long_long(msgpack_packer* pk, long long d);
static int msgpack_pack_unsigned_short(msgpack_packer* pk, unsigned short d);
static int msgpack_pack_unsigned_int(msgpack_packer* pk, unsigned int d);
static int msgpack_pack_unsigned_long(msgpack_packer* pk, unsigned long d);
static int msgpack_pack_unsigned_long_long(msgpack_packer* pk, unsigned long long d);
static int msgpack_pack_uint8(msgpack_packer* pk, uint8_t d);
static int msgpack_pack_uint16(msgpack_packer* pk, uint16_t d);
static int msgpack_pack_uint32(msgpack_packer* pk, uint32_t d);
static int msgpack_pack_uint64(msgpack_packer* pk, uint64_t d);
static int msgpack_pack_int8(msgpack_packer* pk, int8_t d);
static int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
static int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
static int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
static int msgpack_pack_float(msgpack_packer* pk, float d);
static int msgpack_pack_double(msgpack_packer* pk, double d);
static int msgpack_pack_nil(msgpack_packer* pk);
static int msgpack_pack_true(msgpack_packer* pk);
static int msgpack_pack_false(msgpack_packer* pk);
static int msgpack_pack_array(msgpack_packer* pk, unsigned int n);
static int msgpack_pack_map(msgpack_packer* pk, unsigned int n);
static int msgpack_pack_raw(msgpack_packer* pk, size_t l);
static int msgpack_pack_raw_body(msgpack_packer* pk, const void* b, size_t l);
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
#define msgpack_pack_inline_func(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name
#define msgpack_pack_user msgpack_packer*
#define msgpack_pack_append_buffer(user, buf, len) \
return (*(user)->callback)((user)->data, (const char*)buf, len)
#include "msgpack/pack_template.h"
inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
{
pk->data = data;
pk->callback = callback;
}
inline msgpack_packer* msgpack_packer_new(void* data, msgpack_packer_write callback)
{
msgpack_packer* pk = (msgpack_packer*)calloc(1, sizeof(msgpack_packer));
if(!pk) { return NULL; }
msgpack_packer_init(pk, data, callback);
return pk;
}
inline void msgpack_packer_free(msgpack_packer* pk)
{
free(pk);
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/pack.h */

86
cpp/msgpack/sbuffer.h Normal file
View file

@ -0,0 +1,86 @@
/*
* MessagePack for C simple buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_SBUFFER_H__
#define MSGPACK_SBUFFER_H__
#include <stdlib.h>
#include <string.h>
#ifndef MSGPACK_SBUFFER_INIT_SIZE
#define MSGPACK_SBUFFER_INIT_SIZE 8192
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct msgpack_sbuffer {
size_t size;
char* data;
size_t alloc;
} msgpack_sbuffer;
static inline void msgpack_sbuffer_init(msgpack_sbuffer* sbuf)
{
memset(sbuf, 0, sizeof(msgpack_sbuffer));
}
static inline void msgpack_sbuffer_destroy(msgpack_sbuffer* sbuf)
{
free(sbuf->data);
}
static inline int msgpack_sbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_sbuffer* sbuf = (msgpack_sbuffer*)data;
if(sbuf->alloc - sbuf->size < len) {
size_t nsize = (sbuf->alloc) ?
sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
while(nsize < sbuf->size + len) { nsize *= 2; }
void* tmp = realloc(sbuf->data, nsize);
if(!tmp) { return -1; }
sbuf->data = (char*)tmp;
sbuf->alloc = nsize;
}
memcpy(sbuf->data + sbuf->size, buf, len);
sbuf->size += len;
return 0;
}
static inline char* msgpack_sbuffer_release(msgpack_sbuffer* sbuf)
{
char* tmp = sbuf->data;
sbuf->size = 0;
sbuf->data = NULL;
sbuf->alloc = 0;
return tmp;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/sbuffer.h */

123
cpp/msgpack/unpack.h Normal file
View file

@ -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 */

110
cpp/msgpack/vrefbuffer.h Normal file
View file

@ -0,0 +1,110 @@
/*
* MessagePack for C zero-copy buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_VREFBUFFER_H__
#define MSGPACK_VREFBUFFER_H__
#include "msgpack/zone.h"
#ifndef _WIN32
#include <sys/uio.h>
#else
struct iovec {
void *iov_base;
size_t iov_len;
};
#endif
#ifndef MSGPACK_VREFBUFFER_REF_SIZE
#define MSGPACK_VREFBUFFER_REF_SIZE 32
#endif
#ifndef MSGPACK_VREFBUFFER_CHUNK_SIZE
#define MSGPACK_VREFBUFFER_CHUNK_SIZE 8192
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_chunk msgpack_vrefbuffer_chunk;
typedef struct msgpack_vrefbuffer_inner_buffer {
size_t free;
char* ptr;
msgpack_vrefbuffer_chunk* head;
} msgpack_vrefbuffer_inner_buffer;
typedef struct msgpack_vrefbuffer {
struct iovec* tail;
struct iovec* end;
struct iovec* array;
size_t chunk_size;
size_t ref_size;
msgpack_vrefbuffer_inner_buffer inner_buffer;
} msgpack_vrefbuffer;
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size);
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf);
static inline int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len);
static inline const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref);
static inline size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref);
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len);
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len);
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to);
int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_vrefbuffer* vbuf = (msgpack_vrefbuffer*)data;
if(len < vbuf->ref_size) {
return msgpack_vrefbuffer_append_copy(vbuf, buf, len);
} else {
return msgpack_vrefbuffer_append_ref(vbuf, buf, len);
}
}
const struct iovec* msgpack_vrefbuffer_vec(const msgpack_vrefbuffer* vref)
{
return vref->array;
}
size_t msgpack_vrefbuffer_veclen(const msgpack_vrefbuffer* vref)
{
return vref->tail - vref->array;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/vrefbuffer.h */

180
cpp/msgpack/zbuffer.h Normal file
View file

@ -0,0 +1,180 @@
/*
* MessagePack for C deflate buffer implementation
*
* Copyright (C) 2010 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MSGPACK_ZBUFFER_H__
#define MSGPACK_ZBUFFER_H__
#include "msgpack/sysdep.h"
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
#ifndef MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE 8192
#endif
#ifndef MSGPACK_ZBUFFER_RESERVE_SIZE
#define MSGPACK_ZBUFFER_RESERVE_SIZE 512
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct msgpack_zbuffer {
z_stream stream;
char* data;
size_t init_size;
} msgpack_zbuffer;
static inline bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size);
static inline void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf);
static inline const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf);
static inline size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf);
static inline bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf);
static inline void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf);
static inline char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf);
static inline int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len);
static inline bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf);
bool msgpack_zbuffer_init(msgpack_zbuffer* zbuf,
int level, size_t init_size)
{
memset(zbuf, 0, sizeof(msgpack_zbuffer));
zbuf->init_size = init_size;
if(deflateInit(&zbuf->stream, level) != Z_OK) {
free(zbuf->data);
return false;
}
return true;
}
void msgpack_zbuffer_destroy(msgpack_zbuffer* zbuf)
{
deflateEnd(&zbuf->stream);
free(zbuf->data);
}
bool msgpack_zbuffer_expand(msgpack_zbuffer* zbuf)
{
size_t used = (char*)zbuf->stream.next_out - zbuf->data;
size_t csize = used + zbuf->stream.avail_out;
size_t nsize = (csize == 0) ? zbuf->init_size : csize * 2;
char* tmp = (char*)realloc(zbuf->data, nsize);
if(tmp == NULL) {
return false;
}
zbuf->data = tmp;
zbuf->stream.next_out = (Bytef*)(tmp + used);
zbuf->stream.avail_out = nsize - used;
return true;
}
int msgpack_zbuffer_write(void* data, const char* buf, unsigned int len)
{
msgpack_zbuffer* zbuf = (msgpack_zbuffer*)data;
zbuf->stream.next_in = (Bytef*)buf;
zbuf->stream.avail_in = len;
do {
if(zbuf->stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
if(!msgpack_zbuffer_expand(zbuf)) {
return -1;
}
}
if(deflate(&zbuf->stream, Z_NO_FLUSH) != Z_OK) {
return -1;
}
} while(zbuf->stream.avail_in > 0);
return 0;
}
char* msgpack_zbuffer_flush(msgpack_zbuffer* zbuf)
{
while(true) {
switch(deflate(&zbuf->stream, Z_FINISH)) {
case Z_STREAM_END:
return zbuf->data;
case Z_OK:
if(!msgpack_zbuffer_expand(zbuf)) {
return NULL;
}
break;
default:
return NULL;
}
}
}
const char* msgpack_zbuffer_data(const msgpack_zbuffer* zbuf)
{
return zbuf->data;
}
size_t msgpack_zbuffer_size(const msgpack_zbuffer* zbuf)
{
return (char*)zbuf->stream.next_out - zbuf->data;
}
void msgpack_zbuffer_reset_buffer(msgpack_zbuffer* zbuf)
{
zbuf->stream.avail_out += (char*)zbuf->stream.next_out - zbuf->data;
zbuf->stream.next_out = (Bytef*)zbuf->data;
}
bool msgpack_zbuffer_reset(msgpack_zbuffer* zbuf)
{
if(deflateReset(&zbuf->stream) != Z_OK) {
return false;
}
msgpack_zbuffer_reset_buffer(zbuf);
return true;
}
char* msgpack_zbuffer_release_buffer(msgpack_zbuffer* zbuf)
{
char* tmp = zbuf->data;
zbuf->data = NULL;
zbuf->stream.next_out = NULL;
zbuf->stream.avail_out = 0;
return tmp;
}
#ifdef __cplusplus
}
#endif
#endif /* msgpack/zbuffer.h */

131
cpp/msgpack/zone.h Normal file
View file

@ -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 */

View file

@ -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\

20
cpp/msgpack_vc8.sln Normal file
View file

@ -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

283
cpp/msgpack_vc8.vcproj Normal file
View file

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="MessagePack"
ProjectGUID="{122A2EA4-B283-4241-9655-786DE78283B2}"
RootNamespace="MessagePack"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description="Gathering header files"
CommandLine="msgpack_vc8.postbuild.bat"
Outputs="include"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="cpp;c;."
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="1"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="lib\$(ProjectName)d.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
Description="Gathering header files"
CommandLine="msgpack_vc8.postbuild.bat"
Outputs="include"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="cpp;c;."
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="lib\$(ProjectName).lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\c\object.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)\$(InputName)1.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\cpp\object.cpp"
>
</File>
<File
RelativePath=".\c\unpack.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\c\vrefbuffer.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\c\zone.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="2"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\msgpack\pack_define.h"
>
</File>
<File
RelativePath=".\msgpack\pack_template.h"
>
</File>
<File
RelativePath=".\msgpack\sysdep.h"
>
</File>
<File
RelativePath=".\msgpack\unpack_define.h"
>
</File>
<File
RelativePath=".\msgpack\unpack_template.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

424
cpp/msgpackc_test.cpp Normal file
View file

@ -0,0 +1,424 @@
#include "msgpack.h"
#include <math.h>
#include <vector>
#include <limits>
#include <gtest/gtest.h>
using namespace std;
const unsigned int kLoop = 10000;
const double kEPS = 1e-10;
#define GEN_TEST_SIGNED(test_type, func_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
v.push_back(1); \
v.push_back(-1); \
v.push_back(numeric_limits<test_type>::min()); \
v.push_back(numeric_limits<test_type>::max()); \
for (unsigned int i = 0; i < kLoop; i++) \
v.push_back(rand()); \
for (unsigned int i = 0; i < v.size() ; i++) { \
test_type val = v[i]; \
msgpack_sbuffer sbuf; \
msgpack_sbuffer_init(&sbuf); \
msgpack_packer pk; \
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
msgpack_pack_##func_type(&pk, val); \
msgpack_zone z; \
msgpack_zone_init(&z, 2048); \
msgpack_object obj; \
msgpack_unpack_return ret = \
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
if (val < 0) { \
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.i64); \
} else { \
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.u64); \
} \
msgpack_zone_destroy(&z); \
msgpack_sbuffer_destroy(&sbuf); \
} \
} while(0)
#define GEN_TEST_UNSIGNED(test_type, func_type) \
do { \
vector<test_type> v; \
v.push_back(0); \
v.push_back(1); \
v.push_back(2); \
v.push_back(numeric_limits<test_type>::min()); \
v.push_back(numeric_limits<test_type>::max()); \
for (unsigned int i = 0; i < kLoop; i++) \
v.push_back(rand()); \
for (unsigned int i = 0; i < v.size() ; i++) { \
test_type val = v[i]; \
msgpack_sbuffer sbuf; \
msgpack_sbuffer_init(&sbuf); \
msgpack_packer pk; \
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); \
msgpack_pack_##func_type(&pk, val); \
msgpack_zone z; \
msgpack_zone_init(&z, 2048); \
msgpack_object obj; \
msgpack_unpack_return ret = \
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); \
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); \
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type); \
EXPECT_EQ(val, obj.via.u64); \
msgpack_zone_destroy(&z); \
msgpack_sbuffer_destroy(&sbuf); \
} \
} while(0)
TEST(MSGPACKC, simple_buffer_short)
{
GEN_TEST_SIGNED(short, short);
}
TEST(MSGPACKC, simple_buffer_int)
{
GEN_TEST_SIGNED(int, int);
}
TEST(MSGPACKC, simple_buffer_long)
{
GEN_TEST_SIGNED(long, long);
}
TEST(MSGPACKC, simple_buffer_long_long)
{
GEN_TEST_SIGNED(long long, long_long);
}
TEST(MSGPACKC, simple_buffer_unsigned_short)
{
GEN_TEST_UNSIGNED(unsigned short, unsigned_short);
}
TEST(MSGPACKC, simple_buffer_unsigned_int)
{
GEN_TEST_UNSIGNED(unsigned int, unsigned_int);
}
TEST(MSGPACKC, simple_buffer_unsigned_long)
{
GEN_TEST_UNSIGNED(unsigned long, unsigned_long);
}
TEST(MSGPACKC, simple_buffer_unsigned_long_long)
{
GEN_TEST_UNSIGNED(unsigned long long, unsigned_long_long);
}
TEST(MSGPACKC, simple_buffer_uint8)
{
GEN_TEST_UNSIGNED(uint8_t, uint8);
}
TEST(MSGPACKC, simple_buffer_uint16)
{
GEN_TEST_UNSIGNED(uint16_t, uint16);
}
TEST(MSGPACKC, simple_buffer_uint32)
{
GEN_TEST_UNSIGNED(uint32_t, uint32);
}
TEST(MSGPACKC, simple_buffer_uint64)
{
GEN_TEST_UNSIGNED(uint64_t, uint64);
}
TEST(MSGPACKC, simple_buffer_int8)
{
GEN_TEST_SIGNED(int8_t, int8);
}
TEST(MSGPACKC, simple_buffer_int16)
{
GEN_TEST_SIGNED(int16_t, int16);
}
TEST(MSGPACKC, simple_buffer_int32)
{
GEN_TEST_SIGNED(int32_t, int32);
}
TEST(MSGPACKC, simple_buffer_int64)
{
GEN_TEST_SIGNED(int64_t, int64);
}
TEST(MSGPACKC, simple_buffer_float)
{
vector<float> v;
v.push_back(0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<float>::min());
v.push_back(numeric_limits<float>::max());
v.push_back(nanf("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
float val = v[i];
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_float(&pk, val);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
if (isnan(val))
EXPECT_TRUE(isnan(obj.via.dec));
else if (isinf(val))
EXPECT_TRUE(isinf(obj.via.dec));
else
EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
}
TEST(MSGPACKC, simple_buffer_double)
{
vector<double> v;
v.push_back(0.0);
v.push_back(-0.0);
v.push_back(1.0);
v.push_back(-1.0);
v.push_back(numeric_limits<double>::min());
v.push_back(numeric_limits<double>::max());
v.push_back(nan("tag"));
v.push_back(1.0/0.0); // inf
v.push_back(-(1.0/0.0)); // -inf
for (unsigned int i = 0; i < kLoop; i++) {
v.push_back(drand48());
v.push_back(-drand48());
}
for (unsigned int i = 0; i < v.size() ; i++) {
double val = v[i];
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_double(&pk, val);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, obj.type);
if (isnan(val))
EXPECT_TRUE(isnan(obj.via.dec));
else if (isinf(val))
EXPECT_TRUE(isinf(obj.via.dec));
else
EXPECT_TRUE(fabs(obj.via.dec - val) <= kEPS);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
}
TEST(MSGPACKC, simple_buffer_nil)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_nil(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_NIL, obj.type);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_true)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_true(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
EXPECT_EQ(true, obj.via.boolean);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_false)
{
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_false(&pk);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret =
msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, obj.type);
EXPECT_EQ(false, obj.via.boolean);
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_array)
{
unsigned int array_size = 5;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_array(&pk, array_size);
msgpack_pack_nil(&pk);
msgpack_pack_true(&pk);
msgpack_pack_false(&pk);
msgpack_pack_int(&pk, 10);
msgpack_pack_int(&pk, -10);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
EXPECT_EQ(array_size, obj.via.array.size);
for (unsigned int i = 0; i < obj.via.array.size; i++) {
msgpack_object o = obj.via.array.ptr[i];
switch (i) {
case 0:
EXPECT_EQ(MSGPACK_OBJECT_NIL, o.type);
break;
case 1:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
EXPECT_EQ(true, o.via.boolean);
break;
case 2:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, o.type);
EXPECT_EQ(false, o.via.boolean);
break;
case 3:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, o.type);
EXPECT_EQ(10, o.via.u64);
break;
case 4:
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, o.type);
EXPECT_EQ(-10, o.via.i64);
break;
}
}
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_map)
{
unsigned int map_size = 2;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_map(&pk, map_size);
msgpack_pack_true(&pk);
msgpack_pack_false(&pk);
msgpack_pack_int(&pk, 10);
msgpack_pack_int(&pk, -10);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
EXPECT_EQ(map_size, obj.via.map.size);
for (unsigned int i = 0; i < map_size; i++) {
msgpack_object key = obj.via.map.ptr[i].key;
msgpack_object val = obj.via.map.ptr[i].val;
switch (i) {
case 0:
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, key.type);
EXPECT_EQ(true, key.via.boolean);
EXPECT_EQ(MSGPACK_OBJECT_BOOLEAN, val.type);
EXPECT_EQ(false, val.via.boolean);
break;
case 1:
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, key.type);
EXPECT_EQ(10, key.via.u64);
EXPECT_EQ(MSGPACK_OBJECT_NEGATIVE_INTEGER, val.type);
EXPECT_EQ(-10, val.via.i64);
break;
}
}
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}
TEST(MSGPACKC, simple_buffer_raw)
{
unsigned int raw_size = 7;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pk;
msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write);
msgpack_pack_raw(&pk, raw_size);
msgpack_pack_raw_body(&pk, "fr", 2);
msgpack_pack_raw_body(&pk, "syuki", 5);
// invalid data
msgpack_pack_raw_body(&pk, "", 0);
msgpack_pack_raw_body(&pk, "kzk", 0);
msgpack_zone z;
msgpack_zone_init(&z, 2048);
msgpack_object obj;
msgpack_unpack_return ret;
ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj);
EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret);
EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type);
EXPECT_EQ(raw_size, obj.via.raw.size);
EXPECT_EQ(0, memcmp("frsyuki", obj.via.raw.ptr, raw_size));
msgpack_zone_destroy(&z);
msgpack_sbuffer_destroy(&sbuf);
}

171
cpp/object.c Normal file
View file

@ -0,0 +1,171 @@
/*
* MessagePack for C dynamic typing routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/object.h"
#include "msgpack/pack.h"
#include <stdio.h>
#ifndef _MSC_VER
#include <inttypes.h>
#else
#ifndef PRIu64
#define PRIu64 "I64u"
#endif
#ifndef PRIi64
#define PRIi64 "I64d"
#endif
#endif
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
{
switch(d.type) {
case MSGPACK_OBJECT_NIL:
return msgpack_pack_nil(pk);
case MSGPACK_OBJECT_BOOLEAN:
if(d.via.boolean) {
return msgpack_pack_true(pk);
} else {
return msgpack_pack_false(pk);
}
case MSGPACK_OBJECT_POSITIVE_INTEGER:
return msgpack_pack_uint64(pk, d.via.u64);
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return msgpack_pack_int64(pk, d.via.i64);
case MSGPACK_OBJECT_DOUBLE:
return msgpack_pack_double(pk, d.via.dec);
case MSGPACK_OBJECT_RAW:
{
int ret = msgpack_pack_raw(pk, d.via.raw.size);
if(ret < 0) { return ret; }
return msgpack_pack_raw_body(pk, d.via.raw.ptr, d.via.raw.size);
}
case MSGPACK_OBJECT_ARRAY:
{
int ret = msgpack_pack_array(pk, d.via.array.size);
if(ret < 0) { return ret; }
msgpack_object* o = d.via.array.ptr;
msgpack_object* const oend = d.via.array.ptr + d.via.array.size;
for(; o != oend; ++o) {
ret = msgpack_pack_object(pk, *o);
if(ret < 0) { return ret; }
}
return 0;
}
case MSGPACK_OBJECT_MAP:
{
int ret = msgpack_pack_map(pk, d.via.map.size);
if(ret < 0) { return ret; }
msgpack_object_kv* kv = d.via.map.ptr;
msgpack_object_kv* const kvend = d.via.map.ptr + d.via.map.size;
for(; kv != kvend; ++kv) {
ret = msgpack_pack_object(pk, kv->key);
if(ret < 0) { return ret; }
ret = msgpack_pack_object(pk, kv->val);
if(ret < 0) { return ret; }
}
return 0;
}
default:
return -1;
}
}
void msgpack_object_print(FILE* out, msgpack_object o)
{
switch(o.type) {
case MSGPACK_OBJECT_NIL:
fprintf(out, "nil");
break;
case MSGPACK_OBJECT_BOOLEAN:
fprintf(out, (o.via.boolean ? "true" : "false"));
break;
case MSGPACK_OBJECT_POSITIVE_INTEGER:
fprintf(out, "%"PRIu64, o.via.u64);
break;
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
fprintf(out, "%"PRIi64, o.via.i64);
break;
case MSGPACK_OBJECT_DOUBLE:
fprintf(out, "%f", o.via.dec);
break;
case MSGPACK_OBJECT_RAW:
fprintf(out, "\"");
fwrite(o.via.raw.ptr, o.via.raw.size, 1, out);
fprintf(out, "\"");
break;
case MSGPACK_OBJECT_ARRAY:
fprintf(out, "[");
if(o.via.array.size != 0) {
msgpack_object* p = o.via.array.ptr;
msgpack_object_print(out, *p);
++p;
msgpack_object* const pend = o.via.array.ptr + o.via.array.size;
for(; p < pend; ++p) {
fprintf(out, ", ");
msgpack_object_print(out, *p);
}
}
fprintf(out, "]");
break;
// FIXME loop optimiziation
case MSGPACK_OBJECT_MAP:
fprintf(out, "{");
if(o.via.map.size != 0) {
msgpack_object_kv* p = o.via.map.ptr;
msgpack_object_print(out, p->key);
fprintf(out, "=>");
msgpack_object_print(out, p->val);
++p;
msgpack_object_kv* const pend = o.via.map.ptr + o.via.map.size;
for(; p < pend; ++p) {
fprintf(out, ", ");
msgpack_object_print(out, p->key);
fprintf(out, "=>");
msgpack_object_print(out, p->val);
}
}
fprintf(out, "}");
break;
// FIXME loop optimiziation
default:
// FIXME
fprintf(out, "#<UNKNOWN %hu %"PRIu64">", o.type, o.via.u64);
}
}

View file

@ -14,4 +14,8 @@ preprocess() {
preprocess msgpack/type/tuple.hpp
preprocess msgpack/type/define.hpp
preprocess msgpack/zone.hpp
cp -f ../msgpack/pack_define.h msgpack/
cp -f ../msgpack/pack_template.h msgpack/
cp -f ../msgpack/unpack_define.h msgpack/
cp -f ../msgpack/unpack_template.h msgpack/

407
cpp/unpack.c Normal file
View file

@ -0,0 +1,407 @@
/*
* MessagePack for C unpacking routine
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/unpack.h"
#include "msgpack/unpack_define.h"
#include <stdlib.h>
typedef struct {
msgpack_zone* z;
bool referenced;
} unpack_user;
#define msgpack_unpack_struct(name) \
struct template ## name
#define msgpack_unpack_func(ret, name) \
ret template ## name
#define msgpack_unpack_callback(name) \
template_callback ## name
#define msgpack_unpack_object msgpack_object
#define msgpack_unpack_user unpack_user
struct template_context;
typedef struct template_context template_context;
static void template_init(template_context* ctx);
static void template_destroy(template_context* ctx);
static msgpack_object template_data(template_context* ctx);
static int template_execute(template_context* ctx,
const char* data, size_t len, size_t* off);
static inline msgpack_object template_callback_root(unpack_user* u)
{ msgpack_object o = {}; return o; }
static inline int template_callback_uint8(unpack_user* u, uint8_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint16(unpack_user* u, uint16_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint32(unpack_user* u, uint32_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_uint64(unpack_user* u, uint64_t d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
static inline int template_callback_int8(unpack_user* u, int8_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int16(unpack_user* u, int16_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int32(unpack_user* u, int32_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_int64(unpack_user* u, int64_t d, msgpack_object* o)
{ if(d >= 0) { o->type = MSGPACK_OBJECT_POSITIVE_INTEGER; o->via.u64 = d; return 0; }
else { o->type = MSGPACK_OBJECT_NEGATIVE_INTEGER; o->via.i64 = d; return 0; } }
static inline int template_callback_float(unpack_user* u, float d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
static inline int template_callback_double(unpack_user* u, double d, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_DOUBLE; o->via.dec = d; return 0; }
static inline int template_callback_nil(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_NIL; return 0; }
static inline int template_callback_true(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = true; return 0; }
static inline int template_callback_false(unpack_user* u, msgpack_object* o)
{ o->type = MSGPACK_OBJECT_BOOLEAN; o->via.boolean = false; return 0; }
static inline int template_callback_array(unpack_user* u, unsigned int n, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_ARRAY;
o->via.array.size = 0;
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
if(o->via.array.ptr == NULL) { return -1; }
return 0;
}
static inline int template_callback_array_item(unpack_user* u, msgpack_object* c, msgpack_object o)
{ c->via.array.ptr[c->via.array.size++] = o; return 0; }
static inline int template_callback_map(unpack_user* u, unsigned int n, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_MAP;
o->via.map.size = 0;
o->via.map.ptr = (msgpack_object_kv*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object_kv));
if(o->via.map.ptr == NULL) { return -1; }
return 0;
}
static inline int template_callback_map_item(unpack_user* u, msgpack_object* c, msgpack_object k, msgpack_object v)
{
c->via.map.ptr[c->via.map.size].key = k;
c->via.map.ptr[c->via.map.size].val = v;
++c->via.map.size;
return 0;
}
static inline int template_callback_raw(unpack_user* u, const char* b, const char* p, unsigned int l, msgpack_object* o)
{
o->type = MSGPACK_OBJECT_RAW;
o->via.raw.ptr = p;
o->via.raw.size = l;
u->referenced = true;
return 0;
}
#include "msgpack/unpack_template.h"
#define CTX_CAST(m) ((template_context*)(m))
#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
#define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t))
static inline void init_count(void* buffer)
{
*(volatile _msgpack_atomic_counter_t*)buffer = 1;
}
static inline void decl_count(void* buffer)
{
// atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
free(buffer);
}
}
static inline void incr_count(void* buffer)
{
// atomic ++*(_msgpack_atomic_counter_t*)buffer;
_msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
}
static inline _msgpack_atomic_counter_t get_count(void* buffer)
{
return *(volatile _msgpack_atomic_counter_t*)buffer;
}
bool msgpack_unpacker_init(msgpack_unpacker* mpac, size_t initial_buffer_size)
{
if(initial_buffer_size < COUNTER_SIZE) {
initial_buffer_size = COUNTER_SIZE;
}
char* buffer = (char*)malloc(initial_buffer_size);
if(buffer == NULL) {
return false;
}
void* ctx = malloc(sizeof(template_context));
if(ctx == NULL) {
free(buffer);
return false;
}
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(z == NULL) {
free(ctx);
free(buffer);
return false;
}
mpac->buffer = buffer;
mpac->used = COUNTER_SIZE;
mpac->free = initial_buffer_size - mpac->used;
mpac->off = COUNTER_SIZE;
mpac->parsed = 0;
mpac->initial_buffer_size = initial_buffer_size;
mpac->z = z;
mpac->ctx = ctx;
init_count(mpac->buffer);
template_init(CTX_CAST(mpac->ctx));
CTX_CAST(mpac->ctx)->user.z = mpac->z;
CTX_CAST(mpac->ctx)->user.referenced = false;
return true;
}
void msgpack_unpacker_destroy(msgpack_unpacker* mpac)
{
msgpack_zone_free(mpac->z);
template_destroy(mpac->ctx);
free(mpac->ctx);
decl_count(mpac->buffer);
}
msgpack_unpacker* msgpack_unpacker_new(size_t initial_buffer_size)
{
msgpack_unpacker* mpac = (msgpack_unpacker*)malloc(sizeof(msgpack_unpacker));
if(mpac == NULL) {
return NULL;
}
if(!msgpack_unpacker_init(mpac, initial_buffer_size)) {
free(mpac);
return NULL;
}
return mpac;
}
void msgpack_unpacker_free(msgpack_unpacker* mpac)
{
msgpack_unpacker_destroy(mpac);
free(mpac);
}
bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size)
{
if(mpac->used == mpac->off && get_count(mpac->buffer) == 1
&& !CTX_REFERENCED(mpac)) {
// rewind buffer
mpac->free += mpac->used - COUNTER_SIZE;
mpac->used = COUNTER_SIZE;
mpac->off = COUNTER_SIZE;
if(mpac->free >= size) {
return true;
}
}
if(mpac->off == COUNTER_SIZE) {
size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE
while(next_size < size + mpac->used) {
next_size *= 2;
}
char* tmp = (char*)realloc(mpac->buffer, next_size);
if(tmp == NULL) {
return false;
}
mpac->buffer = tmp;
mpac->free = next_size - mpac->used;
} else {
size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE
size_t not_parsed = mpac->used - mpac->off;
while(next_size < size + not_parsed + COUNTER_SIZE) {
next_size *= 2;
}
char* tmp = (char*)malloc(next_size);
if(tmp == NULL) {
return false;
}
init_count(tmp);
memcpy(tmp+COUNTER_SIZE, mpac->buffer+mpac->off, not_parsed);
if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
free(tmp);
return false;
}
CTX_REFERENCED(mpac) = false;
} else {
decl_count(mpac->buffer);
}
mpac->buffer = tmp;
mpac->used = not_parsed + COUNTER_SIZE;
mpac->free = next_size - mpac->used;
mpac->off = COUNTER_SIZE;
}
return true;
}
int msgpack_unpacker_execute(msgpack_unpacker* mpac)
{
size_t off = mpac->off;
int ret = template_execute(CTX_CAST(mpac->ctx),
mpac->buffer, mpac->used, &mpac->off);
if(mpac->off > off) {
mpac->parsed += mpac->off - off;
}
return ret;
}
msgpack_object msgpack_unpacker_data(msgpack_unpacker* mpac)
{
return template_data(CTX_CAST(mpac->ctx));
}
msgpack_zone* msgpack_unpacker_release_zone(msgpack_unpacker* mpac)
{
if(!msgpack_unpacker_flush_zone(mpac)) {
return false;
}
msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
if(r == NULL) {
return NULL;
}
msgpack_zone* old = mpac->z;
mpac->z = r;
return old;
}
void msgpack_unpacker_reset_zone(msgpack_unpacker* mpac)
{
msgpack_zone_clear(mpac->z);
}
bool msgpack_unpacker_flush_zone(msgpack_unpacker* mpac)
{
if(CTX_REFERENCED(mpac)) {
if(!msgpack_zone_push_finalizer(mpac->z, decl_count, mpac->buffer)) {
return false;
}
CTX_REFERENCED(mpac) = false;
incr_count(mpac->buffer);
}
return true;
}
void msgpack_unpacker_reset(msgpack_unpacker* mpac)
{
template_init(CTX_CAST(mpac->ctx));
// don't reset referenced flag
mpac->parsed = 0;
}
msgpack_unpack_return
msgpack_unpack(const char* data, size_t len, size_t* off,
msgpack_zone* z, msgpack_object* result)
{
msgpack_unpack_return ret = MSGPACK_UNPACK_SUCCESS;
template_context ctx;
template_init(&ctx);
ctx.user.z = z;
ctx.user.referenced = false;
size_t noff = 0;
if(off != NULL) { noff = *off; }
int e = template_execute(&ctx, data, len, &noff);
if(e < 0) {
ret = MSGPACK_UNPACK_PARSE_ERROR;
goto out;
}
if(off != NULL) { *off = noff; }
if(e == 0) {
ret = MSGPACK_UNPACK_CONTINUE;
goto out;
}
*result = template_data(&ctx);
if(noff < len) {
ret = MSGPACK_UNPACK_EXTRA_BYTES;
goto out;
}
out:
template_destroy(&ctx);
return ret;
}

201
cpp/vrefbuffer.c Normal file
View file

@ -0,0 +1,201 @@
/*
* MessagePack for C zero-copy buffer implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/vrefbuffer.h"
#include <stdlib.h>
#include <string.h>
struct msgpack_vrefbuffer_chunk {
struct msgpack_vrefbuffer_chunk* next;
/* data ... */
};
bool msgpack_vrefbuffer_init(msgpack_vrefbuffer* vbuf,
size_t ref_size, size_t chunk_size)
{
vbuf->chunk_size = chunk_size;
vbuf->ref_size = ref_size;
size_t nfirst = (sizeof(struct iovec) < 72/2) ?
72 / sizeof(struct iovec) : 8;
struct iovec* array = (struct iovec*)malloc(
sizeof(struct iovec) * nfirst);
if(array == NULL) {
return false;
}
vbuf->tail = array;
vbuf->end = array + nfirst;
vbuf->array = array;
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + chunk_size);
if(chunk == NULL) {
free(array);
return false;
}
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
ib->free = chunk_size;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
ib->head = chunk;
chunk->next = NULL;
return true;
}
void msgpack_vrefbuffer_destroy(msgpack_vrefbuffer* vbuf)
{
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head;
while(true) {
msgpack_vrefbuffer_chunk* n = c->next;
free(c);
if(n != NULL) {
c = n;
} else {
break;
}
}
free(vbuf->array);
}
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len)
{
if(vbuf->tail == vbuf->end) {
const size_t nused = vbuf->tail - vbuf->array;
const size_t nnext = nused * 2;
struct iovec* nvec = (struct iovec*)realloc(
vbuf->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) {
return -1;
}
vbuf->array = nvec;
vbuf->end = nvec + nnext;
vbuf->tail = nvec + nused;
}
vbuf->tail->iov_base = (char*)buf;
vbuf->tail->iov_len = len;
++vbuf->tail;
return 0;
}
int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
const char* buf, unsigned int len)
{
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
if(ib->free < len) {
size_t sz = vbuf->chunk_size;
if(sz < len) {
sz = len;
}
msgpack_vrefbuffer_chunk* chunk = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz);
if(chunk == NULL) {
return -1;
}
chunk->next = ib->head;
ib->head = chunk;
ib->free = sz;
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
}
char* m = ib->ptr;
memcpy(m, buf, len);
ib->free -= len;
ib->ptr += len;
if(vbuf->tail != vbuf->array && m ==
(const char*)((vbuf->tail-1)->iov_base) + (vbuf->tail-1)->iov_len) {
(vbuf->tail-1)->iov_len += len;
return 0;
} else {
return msgpack_vrefbuffer_append_ref(vbuf, m, len);
}
}
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
{
size_t sz = vbuf->chunk_size;
msgpack_vrefbuffer_chunk* empty = (msgpack_vrefbuffer_chunk*)malloc(
sizeof(msgpack_vrefbuffer_chunk) + sz);
if(empty == NULL) {
return -1;
}
empty->next = NULL;
const size_t nused = vbuf->tail - vbuf->array;
if(to->tail + nused < vbuf->end) {
const size_t tosize = to->tail - to->array;
const size_t reqsize = nused + tosize;
size_t nnext = (to->end - to->array) * 2;
while(nnext < reqsize) {
nnext *= 2;
}
struct iovec* nvec = (struct iovec*)realloc(
to->array, sizeof(struct iovec)*nnext);
if(nvec == NULL) {
free(empty);
return -1;
}
to->array = nvec;
to->end = nvec + nnext;
to->tail = nvec + tosize;
}
memcpy(to->tail, vbuf->array, sizeof(struct iovec)*nused);
to->tail += nused;
vbuf->tail = vbuf->array;
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
msgpack_vrefbuffer_inner_buffer* const toib = &to->inner_buffer;
msgpack_vrefbuffer_chunk* last = ib->head;
while(last->next != NULL) {
last = last->next;
}
last->next = toib->head;
toib->head = ib->head;
if(toib->free < ib->free) {
toib->free = ib->free;
toib->ptr = ib->ptr;
}
ib->head = empty;
ib->free = sz;
ib->ptr = ((char*)empty) + sizeof(msgpack_vrefbuffer_chunk);
return 0;
}

220
cpp/zone.c Normal file
View file

@ -0,0 +1,220 @@
/*
* MessagePack for C memory pool implementation
*
* Copyright (C) 2008-2009 FURUHASHI Sadayuki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "msgpack/zone.h"
#include <stdlib.h>
#include <string.h>
struct msgpack_zone_chunk {
struct msgpack_zone_chunk* next;
/* data ... */
};
static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + chunk_size);
if(chunk == NULL) {
return false;
}
cl->head = chunk;
cl->free = chunk_size;
cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = NULL;
return true;
}
static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
{
msgpack_zone_chunk* c = cl->head;
while(true) {
msgpack_zone_chunk* n = c->next;
free(c);
if(n != NULL) {
c = n;
} else {
break;
}
}
}
static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
{
msgpack_zone_chunk* c = cl->head;
while(true) {
msgpack_zone_chunk* n = c->next;
if(n != NULL) {
free(c);
c = n;
} else {
break;
}
}
cl->head->next = NULL;
cl->free = chunk_size;
cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
}
void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
{
msgpack_zone_chunk_list* const cl = &zone->chunk_list;
size_t sz = zone->chunk_size;
while(sz < size) {
sz *= 2;
}
msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
sizeof(msgpack_zone_chunk) + sz);
char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
chunk->next = cl->head;
cl->head = chunk;
cl->free = sz - size;
cl->ptr = ptr + size;
return ptr;
}
static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
{
fa->tail = NULL;
fa->end = NULL;
fa->array = NULL;
}
static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
{
msgpack_zone_finalizer* fin = fa->tail;
for(; fin != fa->array; --fin) {
(*(fin-1)->func)((fin-1)->data);
}
}
static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
{
call_finalizer_array(fa);
free(fa->array);
}
static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
{
call_finalizer_array(fa);
fa->tail = fa->array;
}
bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
void (*func)(void* data), void* data)
{
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
const size_t nused = fa->end - fa->array;
size_t nnext;
if(nused == 0) {
nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
72 / sizeof(msgpack_zone_finalizer) : 8;
} else {
nnext = nused * 2;
}
msgpack_zone_finalizer* tmp =
(msgpack_zone_finalizer*)realloc(fa->array,
sizeof(msgpack_zone_finalizer) * nnext);
if(tmp == NULL) {
return false;
}
fa->array = tmp;
fa->end = tmp + nnext;
fa->tail = tmp + nused;
fa->tail->func = func;
fa->tail->data = data;
++fa->tail;
return true;
}
bool msgpack_zone_is_empty(msgpack_zone* zone)
{
msgpack_zone_chunk_list* const cl = &zone->chunk_list;
msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
return cl->free == zone->chunk_size && cl->head->next == NULL &&
fa->tail == fa->array;
}
void msgpack_zone_destroy(msgpack_zone* zone)
{
destroy_finalizer_array(&zone->finalizer_array);
destroy_chunk_list(&zone->chunk_list);
}
void msgpack_zone_clear(msgpack_zone* zone)
{
clear_finalizer_array(&zone->finalizer_array);
clear_chunk_list(&zone->chunk_list, zone->chunk_size);
}
bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
{
zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
return false;
}
init_finalizer_array(&zone->finalizer_array);
return true;
}
msgpack_zone* msgpack_zone_new(size_t chunk_size)
{
msgpack_zone* zone = (msgpack_zone*)malloc(
sizeof(msgpack_zone) + chunk_size);
if(zone == NULL) {
return NULL;
}
zone->chunk_size = chunk_size;
if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
free(zone);
return false;
}
init_finalizer_array(&zone->finalizer_array);
return zone;
}
void msgpack_zone_free(msgpack_zone* zone)
{
msgpack_zone_destroy(zone);
free(zone);
}