mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-24 00:49:47 +02:00
Compare commits
425 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
466986b519 | ||
|
|
a6aac482dd | ||
|
|
bb984d3445 | ||
|
|
f8e2766d28 | ||
|
|
2d5d12f9a6 | ||
|
|
11a2a1b8ec | ||
|
|
b5e66150e9 | ||
|
|
e21e3245db | ||
|
|
07e7ad6b7e | ||
|
|
44b524529d | ||
|
|
fc65bc0682 | ||
|
|
ca12e6d39d | ||
|
|
db8578a62b | ||
|
|
4a292193f2 | ||
|
|
1e7fbc0349 | ||
|
|
479d50bd93 | ||
|
|
982787865f | ||
|
|
4c00f448aa | ||
|
|
3ddeb08e6e | ||
|
|
cd03ab62f8 | ||
|
|
44e41efa0c | ||
|
|
ecf4b09acd | ||
|
|
d6122b4a18 | ||
|
|
4fcb4777f3 | ||
|
|
03ed30ce03 | ||
|
|
6e810df2a4 | ||
|
|
0335df55e1 | ||
|
|
dd4043a616 | ||
|
|
6a8412d6de | ||
|
|
7491c1996a | ||
|
|
0ab14b4138 | ||
|
|
6e77c6df11 | ||
|
|
bcc91d78e9 | ||
|
|
32b65dba47 | ||
|
|
aa75e6ecd3 | ||
|
|
896dead7cc | ||
|
|
dfa277a9e0 | ||
|
|
370a9251f5 | ||
|
|
7737f1cb77 | ||
|
|
f72022037c | ||
|
|
865528f778 | ||
|
|
d54048eabe | ||
|
|
103a6c56e4 | ||
|
|
11f1d5fbbd | ||
|
|
7ebdb63131 | ||
|
|
a186725213 | ||
|
|
86ad026f11 | ||
|
|
93d0f0bd00 | ||
|
|
a0f5392876 | ||
|
|
5896ff3746 | ||
|
|
d15e49cb73 | ||
|
|
2103c12e05 | ||
|
|
f0a12a23a1 | ||
|
|
30b946ee85 | ||
|
|
a388000d47 | ||
|
|
4c888294b5 | ||
|
|
68bf4acb4b | ||
|
|
2c2df64427 | ||
|
|
4d6e9d6c05 | ||
|
|
f969f6f39c | ||
|
|
8920c49597 | ||
|
|
e18102d16f | ||
|
|
ea23bf843e | ||
|
|
e217e72c22 | ||
|
|
0bc4b3f599 | ||
|
|
b2f5893669 | ||
|
|
9a1ccaf155 | ||
|
|
0201c21b9a | ||
|
|
dee68403df | ||
|
|
0a99b9f933 | ||
|
|
17e696fc0d | ||
|
|
b5b459cfca | ||
|
|
7822bc787d | ||
|
|
1f5d6b9cac | ||
|
|
ce21ab0ebf | ||
|
|
5af6d36341 | ||
|
|
15a0d61a64 | ||
|
|
66014eebc0 | ||
|
|
fd566afeb4 | ||
|
|
e4d32b176e | ||
|
|
b27c87c9ed | ||
|
|
3729f334a1 | ||
|
|
55bf279a7c | ||
|
|
78e8cbdfb5 | ||
|
|
23d670f3bd | ||
|
|
6fab3594a2 | ||
|
|
421aeb5021 | ||
|
|
47f4ffe9f3 | ||
|
|
09325ed846 | ||
|
|
bfa428ab13 | ||
|
|
ecdeec9948 | ||
|
|
f11a811114 | ||
|
|
59b111e026 | ||
|
|
2a694f8c20 | ||
|
|
0380215982 | ||
|
|
0e48f65a4b | ||
|
|
aa79fc2ff4 | ||
|
|
cc571b8bb1 | ||
|
|
b0df21295c | ||
|
|
0889e6117e | ||
|
|
212f025f00 | ||
|
|
f6a5402194 | ||
|
|
6a349d0b28 | ||
|
|
dac5c60608 | ||
|
|
bc33317b7e | ||
|
|
754b1682a5 | ||
|
|
cb9eed8ccc | ||
|
|
862905742f | ||
|
|
ba98315f65 | ||
|
|
124a871923 | ||
|
|
378f6afccd | ||
|
|
1320863cb3 | ||
|
|
a951ea90b8 | ||
|
|
3b7a2f8f32 | ||
|
|
038c3e3518 | ||
|
|
c08439ff41 | ||
|
|
59d994ea5f | ||
|
|
ed51d23335 | ||
|
|
2be892bfda | ||
|
|
723d900098 | ||
|
|
13404a7444 | ||
|
|
a20594dfdc | ||
|
|
bff4cadeff | ||
|
|
6515577dc3 | ||
|
|
beebccd323 | ||
|
|
d70c44b723 | ||
|
|
33d3192ca2 | ||
|
|
0d13931844 | ||
|
|
293c839a22 | ||
|
|
f187ae35d9 | ||
|
|
74013e7e7d | ||
|
|
e2026c0507 | ||
|
|
c375e14705 | ||
|
|
fade0644c7 | ||
|
|
5fedaf285b | ||
|
|
fe82444db1 | ||
|
|
f7692691ca | ||
|
|
7fba3484c5 | ||
|
|
561b6b583d | ||
|
|
7675c15fa9 | ||
|
|
99971abc9b | ||
|
|
b7a1ba9ba0 | ||
|
|
63c26cd58b | ||
|
|
f8fc03b482 | ||
|
|
b0b1a0e9a7 | ||
|
|
4d2a9c23af | ||
|
|
c41154989a | ||
|
|
541ece13c0 | ||
|
|
b6b2ef5e57 | ||
|
|
4ef69da25d | ||
|
|
9bd339baf8 | ||
|
|
616be1aa60 | ||
|
|
415b14335f | ||
|
|
1fb707f93f | ||
|
|
aa4ed82b66 | ||
|
|
7ce8abe5d6 | ||
|
|
27629a8dd6 | ||
|
|
521a4f4190 | ||
|
|
bad3801eae | ||
|
|
72b3064a67 | ||
|
|
7593e5ce0e | ||
|
|
8a08548f36 | ||
|
|
56b0ad6809 | ||
|
|
f8561fbfd5 | ||
|
|
e80cbd4437 | ||
|
|
da601e4589 | ||
|
|
36a87b6968 | ||
|
|
e0b42939ba | ||
|
|
7d731f83a4 | ||
|
|
40ad7da455 | ||
|
|
e0d1e5c722 | ||
|
|
5b3a168b86 | ||
|
|
11afd4820f | ||
|
|
ec5c1194fc | ||
|
|
7eccd1029a | ||
|
|
c2ca709d68 | ||
|
|
197ed8c983 | ||
|
|
990860fe65 | ||
|
|
dbeb6e61c6 | ||
|
|
2b3f37f9e0 | ||
|
|
f50148a9cc | ||
|
|
9fc8ec5b61 | ||
|
|
751a6f98fe | ||
|
|
9d8e6b92fc | ||
|
|
c868da2879 | ||
|
|
e0c40c1c59 | ||
|
|
f185284776 | ||
|
|
1656ef0111 | ||
|
|
3cb2e4f7c6 | ||
|
|
3104f7e451 | ||
|
|
ab8e7ea822 | ||
|
|
6daef66ea7 | ||
|
|
04286eb9dc | ||
|
|
d15e30bf4a | ||
|
|
fb1d480faf | ||
|
|
c8fa0be345 | ||
|
|
643b0c9523 | ||
|
|
06930616b2 | ||
|
|
6e5fc6d396 | ||
|
|
17b0753023 | ||
|
|
7491348d40 | ||
|
|
eef2036c36 | ||
|
|
fbec8f4470 | ||
|
|
8e0137e1d2 | ||
|
|
1dac3f890a | ||
|
|
9f33266f23 | ||
|
|
d8c7fd5161 | ||
|
|
731bc643d0 | ||
|
|
12e8615ac5 | ||
|
|
22703d2cdb | ||
|
|
cb518f472a | ||
|
|
271f1fa319 | ||
|
|
9ecc4f0a1e | ||
|
|
977eab7c4a | ||
|
|
c9f342f4b2 | ||
|
|
126e4d8414 | ||
|
|
14ee1e5827 | ||
|
|
ecbb9055a2 | ||
|
|
862f04104d | ||
|
|
d47f72be0c | ||
|
|
98c5767372 | ||
|
|
97a7b7545a | ||
|
|
caf5616573 | ||
|
|
b8076fa71f | ||
|
|
2360466aa9 | ||
|
|
28370b36aa | ||
|
|
9d82356ea9 | ||
|
|
ca24e040c4 | ||
|
|
0fd629857d | ||
|
|
8eff14db11 | ||
|
|
81e26fe9b9 | ||
|
|
9eb4583dd5 | ||
|
|
5a23c86dc1 | ||
|
|
ffd0525607 | ||
|
|
3dc636bf3e | ||
|
|
260ce4aa1d | ||
|
|
8bc827ebf5 | ||
|
|
a97f764088 | ||
|
|
143b90af3e | ||
|
|
4e0a6ae624 | ||
|
|
0c60cfc5c0 | ||
|
|
deb6b0e334 | ||
|
|
27777dcd31 | ||
|
|
bdb397e043 | ||
|
|
cb4d851761 | ||
|
|
17aa517e41 | ||
|
|
7ac16f4834 | ||
|
|
bf7fece440 | ||
|
|
c04ef9efe5 | ||
|
|
b774c07d19 | ||
|
|
229467cb29 | ||
|
|
949b472f7e | ||
|
|
be67d3e362 | ||
|
|
2c1a1fd4f8 | ||
|
|
3e2ae7cc78 | ||
|
|
505660e1fa | ||
|
|
09d90e1231 | ||
|
|
5a9f89ae1f | ||
|
|
6f56345dd8 | ||
|
|
edef040688 | ||
|
|
9fc196e750 | ||
|
|
dc1698eaf4 | ||
|
|
53ded063a0 | ||
|
|
8a2c50c374 | ||
|
|
f71148f3a6 | ||
|
|
172105828c | ||
|
|
6cca6cb20d | ||
|
|
b7336f817c | ||
|
|
88356b79be | ||
|
|
ce9e543882 | ||
|
|
3ff3ba83f4 | ||
|
|
edb525a030 | ||
|
|
ea5314f076 | ||
|
|
be8e53163b | ||
|
|
79151f517f | ||
|
|
e8ffe7ef96 | ||
|
|
b5a7b5e277 | ||
|
|
85b5e1088f | ||
|
|
680ddb1557 | ||
|
|
44fff522bd | ||
|
|
90815f0d27 | ||
|
|
f07950c60a | ||
|
|
f8c4125892 | ||
|
|
1f30cc203a | ||
|
|
764bfdcb9f | ||
|
|
f290814f64 | ||
|
|
3a2508545d | ||
|
|
79a06a338a | ||
|
|
509f27eee1 | ||
|
|
e511c32a36 | ||
|
|
b463d9b687 | ||
|
|
e96e20ccfd | ||
|
|
06ebdbfd37 | ||
|
|
df9fd047b4 | ||
|
|
85d65c59d2 | ||
|
|
754126644f | ||
|
|
220436f4f9 | ||
|
|
b62a6ae1d0 | ||
|
|
eae0532b8c | ||
|
|
d642487f99 | ||
|
|
320510506b | ||
|
|
b2839ac78b | ||
|
|
834d5a0e72 | ||
|
|
13ce808c47 | ||
|
|
980a6529c1 | ||
|
|
c92384fe68 | ||
|
|
9f563f87b9 | ||
|
|
44f37b8d1b | ||
|
|
5f41c1cf3f | ||
|
|
2a664b9ae6 | ||
|
|
5456814199 | ||
|
|
33ceaeb208 | ||
|
|
b33e60b3ae | ||
|
|
9dd0a6eb86 | ||
|
|
ed6faf4e65 | ||
|
|
df2ee5de49 | ||
|
|
36fef91a67 | ||
|
|
3399148d75 | ||
|
|
0eea92de66 | ||
|
|
92975bb21d | ||
|
|
bf18e04134 | ||
|
|
4a0d7f18fd | ||
|
|
65c360a2ca | ||
|
|
71919f7523 | ||
|
|
31a49db68b | ||
|
|
0d615442ba | ||
|
|
8f35dbc306 | ||
|
|
154bcbc4f7 | ||
|
|
c96a39d315 | ||
|
|
06ba74c366 | ||
|
|
8786a8e6e0 | ||
|
|
748236fef0 | ||
|
|
ae1b06f20b | ||
|
|
b8aa93ce30 | ||
|
|
49d40a42f1 | ||
|
|
1845f34b81 | ||
|
|
43903d446a | ||
|
|
256da2124b | ||
|
|
7869e96bac | ||
|
|
79b51a6e4b | ||
|
|
cad9f6d46e | ||
|
|
da2960880a | ||
|
|
0eacc58e29 | ||
|
|
3bec736aee | ||
|
|
3241ffd1b4 | ||
|
|
d0d7b266bc | ||
|
|
c24948258b | ||
|
|
d36666bd98 | ||
|
|
2794b1d310 | ||
|
|
f456fa03da | ||
|
|
356b7b43f8 | ||
|
|
92718e2140 | ||
|
|
4021160a64 | ||
|
|
6f043e3326 | ||
|
|
74b0b1da21 | ||
|
|
3a5f676687 | ||
|
|
4fa7cffc37 | ||
|
|
79b83e78a5 | ||
|
|
048a3835e7 | ||
|
|
4a4891036a | ||
|
|
ff00c83f15 | ||
|
|
79d31b7452 | ||
|
|
20cc6f7463 | ||
|
|
8acabaa135 | ||
|
|
ba7183a5b4 | ||
|
|
28f4338a6c | ||
|
|
800a93a859 | ||
|
|
2e969e3a0a | ||
|
|
3fb31f651d | ||
|
|
682d25b551 | ||
|
|
bcad8d4c4c | ||
|
|
96bab8e02e | ||
|
|
fa4a615d0f | ||
|
|
f1265c4fed | ||
|
|
df01cd9a09 | ||
|
|
255bac642d | ||
|
|
6d8c3bd13d | ||
|
|
75b8272710 | ||
|
|
2f80e154f2 | ||
|
|
cc0114c482 | ||
|
|
e5e2b9095c | ||
|
|
6977edc032 | ||
|
|
177cc55ee5 | ||
|
|
feb7ec03ba | ||
|
|
6630a643d3 | ||
|
|
d70e64a434 | ||
|
|
896ad51102 | ||
|
|
be6d6560a7 | ||
|
|
709d0cc33e | ||
|
|
bd73742552 | ||
|
|
ed4518e09a | ||
|
|
6c8301eae8 | ||
|
|
6e30d504e3 | ||
|
|
cee09a0261 | ||
|
|
76a72558b3 | ||
|
|
22124a33ce | ||
|
|
3731373de1 | ||
|
|
bbaf8c2f67 | ||
|
|
f50694cc96 | ||
|
|
4930ea7dab | ||
|
|
96bb4cf49d | ||
|
|
5e7563ac5b | ||
|
|
f199b80453 | ||
|
|
5de8eec206 | ||
|
|
6cfea98501 | ||
|
|
33498d3673 | ||
|
|
ed3ead06fe | ||
|
|
94e5b0d78f | ||
|
|
0812eb1c04 | ||
|
|
8cb5ccad99 | ||
|
|
743d69ec0b | ||
|
|
f6de4c9479 | ||
|
|
fb59927d32 | ||
|
|
08974f00ed | ||
|
|
60643f023f | ||
|
|
68a98d3dd0 | ||
|
|
ca9015452e | ||
|
|
05ac2603e6 | ||
|
|
8e923777b8 | ||
|
|
8949551c2e | ||
|
|
0b45e9442b | ||
|
|
1d1a9d7933 | ||
|
|
1f372cf0cc | ||
|
|
c43d597aa9 | ||
|
|
df14629a25 |
53
.gitignore
vendored
53
.gitignore
vendored
@@ -1,8 +1,49 @@
|
|||||||
|
# Files generated by the bootstrap script.
|
||||||
|
/INSTALL
|
||||||
|
/NEWS
|
||||||
|
/README
|
||||||
|
/ac/
|
||||||
|
/aclocal.m4
|
||||||
|
/autom4te.cache/
|
||||||
|
/config.h.in
|
||||||
|
/configure
|
||||||
|
/msgpack_vc2008.sln
|
||||||
|
/msgpack_vc2008.vcproj
|
||||||
|
Makefile.in
|
||||||
|
|
||||||
|
# Files generated by the configure script.
|
||||||
|
|
||||||
|
/config.h
|
||||||
|
/config.log
|
||||||
|
/config.status
|
||||||
|
/libtool
|
||||||
|
/msgpack.pc
|
||||||
|
/src/msgpack/version.h
|
||||||
|
/src/msgpack/version.hpp
|
||||||
|
/stamp-h1
|
||||||
|
Makefile
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
|
||||||
|
# Files generated by make.
|
||||||
*.o
|
*.o
|
||||||
*.so
|
*.so
|
||||||
ruby/Makefile
|
*.lo
|
||||||
*.5
|
*.la
|
||||||
*.8
|
|
||||||
*.6
|
# Files generated by make check.
|
||||||
_obj
|
# TODO: Replace these with something like /test/*_test
|
||||||
_test
|
/test/buffer
|
||||||
|
/test/cases
|
||||||
|
/test/convert
|
||||||
|
/test/fixint
|
||||||
|
/test/fixint_c
|
||||||
|
/test/msgpack_test
|
||||||
|
/test/msgpackc_test
|
||||||
|
/test/object
|
||||||
|
/test/pack_unpack
|
||||||
|
/test/pack_unpack_c
|
||||||
|
/test/streaming
|
||||||
|
/test/streaming_c
|
||||||
|
/test/version
|
||||||
|
/test/zone
|
||||||
|
|||||||
34
.travis.yml
Normal file
34
.travis.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
language: cpp
|
||||||
|
cache:
|
||||||
|
- apt
|
||||||
|
compiler:
|
||||||
|
- clang
|
||||||
|
- gcc
|
||||||
|
before_install:
|
||||||
|
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
|
- sudo add-apt-repository -y ppa:h-rayflood/llvm
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get update
|
||||||
|
- sudo apt-get install valgrind
|
||||||
|
install:
|
||||||
|
- sudo apt-get install -qq gcc-4.8-multilib g++-4.8-multilib
|
||||||
|
- sudo apt-get install --allow-unauthenticated -qq clang-3.4
|
||||||
|
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90
|
||||||
|
- sudo apt-get install -y lib32gcc1
|
||||||
|
- sudo apt-get install -y libc6-i386
|
||||||
|
- sudo apt-get install -y lib32z1-dev
|
||||||
|
- sudo apt-get install -y lib32stdc++6
|
||||||
|
- wget https://googletest.googlecode.com/files/gtest-1.7.0.zip
|
||||||
|
- unzip gtest-1.7.0.zip && cd gtest-1.7.0 && sudo cp -r include/gtest /usr/local/include && g++ src/gtest-all.cc -I. -Iinclude -c && g++ src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mv *.a /usr/local/lib && g++ -m32 src/gtest-all.cc -I. -Iinclude -c && g++ -m32 src/gtest_main.cc -I. -Iinclude -c && ar -rv libgtest.a gtest-all.o && ar -rv libgtest_main.a gtest_main.o && sudo mkdir /usr/local/lib32 && sudo mv *.a /usr/local/lib32 && cd ..
|
||||||
|
env:
|
||||||
|
- ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib"
|
||||||
|
- ACTION="ci/build_autotools.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32"
|
||||||
|
- ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib"
|
||||||
|
- ACTION="ci/build_autotools.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32"
|
||||||
|
- ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="64" LIBPATH="/usr/local/lib"
|
||||||
|
- ACTION="ci/build_cmake.sh" VERSION="cpp11" ARCH="32" LIBPATH="/usr/local/lib32"
|
||||||
|
- ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="64" LIBPATH="/usr/local/lib"
|
||||||
|
- ACTION="ci/build_cmake.sh" VERSION="cpp03" ARCH="32" LIBPATH="/usr/local/lib32"
|
||||||
|
|
||||||
|
script:
|
||||||
|
- git clean -xdf && CMAKE_LIBRARY_PATH=${LIBPATH} ${ACTION} ${VERSION} ${ARCH}
|
||||||
253
CMakeLists.txt
Normal file
253
CMakeLists.txt
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
CMAKE_MINIMUM_REQUIRED (VERSION 2.8.6)
|
||||||
|
PROJECT (msgpack)
|
||||||
|
|
||||||
|
FILE (READ ${CMAKE_SOURCE_DIR}/include/msgpack/version_master.h contents)
|
||||||
|
STRING (REGEX MATCH "#define MSGPACK_VERSION_MAJOR *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
|
||||||
|
SET (VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||||
|
STRING (REGEX MATCH "#define MSGPACK_VERSION_MINOR *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
|
||||||
|
SET (VERSION_MINOR ${CMAKE_MATCH_1})
|
||||||
|
STRING (REGEX MATCH "#define MSGPACK_VERSION_REVISION *([0-9a-zA-Z_]*)" NULL_OUT ${contents})
|
||||||
|
SET (VERSION_REVISION ${CMAKE_MATCH_1})
|
||||||
|
SET (VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION})
|
||||||
|
|
||||||
|
SET (prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
|
SET (exec_prefix "\${prefix}")
|
||||||
|
SET (libdir "\${exec_prefix}/lib")
|
||||||
|
SET (includedir "\${prefix}/include")
|
||||||
|
|
||||||
|
OPTION (MSGPACK_CXX11 "Using c++11 compiler" OFF)
|
||||||
|
OPTION (MSGPACK_32BIT "32bit compile" OFF)
|
||||||
|
|
||||||
|
IF (MSGPACK_CXX11)
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
SET (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
|
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
SET (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
|
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
MESSAGE ( FATAL_ERROR "MSVC doesn't support C++11 yet.")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (MSGPACK_32BIT)
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
SET (CMAKE_CXX_FLAGS "-m32 ${CMAKE_CXX_FLAGS}")
|
||||||
|
SET (CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
|
||||||
|
SET (CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
SET (CMAKE_CXX_FLAGS "-m32 ${CMAKE_CXX_FLAGS}")
|
||||||
|
SET (CMAKE_C_FLAGS "-m32 ${CMAKE_C_FLAGS}")
|
||||||
|
SET (CMAKE_EXE_LINKER_FLAGS "-m32 ${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
FIND_PACKAGE (GTest)
|
||||||
|
FIND_PACKAGE (ZLIB)
|
||||||
|
FIND_PACKAGE (Threads)
|
||||||
|
IF (GTEST_FOUND AND ZLIB_FOUND AND THREADS_FOUND)
|
||||||
|
OPTION (MSGPACK_BUILD_TESTS "Build msgpack tests." ON)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
OPTION (MSGPACK_ENABLE_CXX "Enable C++ interface." ON)
|
||||||
|
|
||||||
|
INCLUDE (CheckCXXSourceCompiles)
|
||||||
|
CHECK_CXX_SOURCE_COMPILES ("
|
||||||
|
#include <bits/atomicity.h>
|
||||||
|
int atomic_sub(int i) { return __gnu_cxx::__exchange_and_add(&i, -1) - 1; }
|
||||||
|
int atomic_add(int i) { return __gnu_cxx::__exchange_and_add(&i, 1) + 1; }
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
atomic_sub(1);
|
||||||
|
atomic_add(1);
|
||||||
|
}
|
||||||
|
" MSGPACK_ENABLE_GCC_CXX_ATOMIC)
|
||||||
|
|
||||||
|
IF (MSGPACK_ENABLE_GCC_CXX_ATOMIC)
|
||||||
|
LIST (APPEND msgpack_SOURCES
|
||||||
|
src/gcc_atomic.cpp
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
|
||||||
|
LIST (APPEND msgpack_SOURCES
|
||||||
|
src/unpack.c
|
||||||
|
src/objectc.c
|
||||||
|
src/version.c
|
||||||
|
src/vrefbuffer.c
|
||||||
|
src/zone.c
|
||||||
|
)
|
||||||
|
|
||||||
|
LIST (APPEND msgpack_HEADERS
|
||||||
|
include/msgpack/pack_define.h
|
||||||
|
include/msgpack/pack_template.h
|
||||||
|
include/msgpack/unpack_define.h
|
||||||
|
include/msgpack/unpack_template.h
|
||||||
|
include/msgpack/util.h
|
||||||
|
include/msgpack/sysdep.h
|
||||||
|
include/msgpack/sbuffer.h
|
||||||
|
include/msgpack/version.h
|
||||||
|
include/msgpack/vrefbuffer.h
|
||||||
|
include/msgpack/zbuffer.h
|
||||||
|
include/msgpack/fbuffer.h
|
||||||
|
include/msgpack/pack.h
|
||||||
|
include/msgpack/unpack.h
|
||||||
|
include/msgpack/object.h
|
||||||
|
include/msgpack/zone.h
|
||||||
|
)
|
||||||
|
|
||||||
|
IF (MSGPACK_ENABLE_CXX)
|
||||||
|
LIST (APPEND msgpack_HEADERS
|
||||||
|
include/msgpack.hpp
|
||||||
|
include/msgpack_fwd.hpp
|
||||||
|
include/msgpack/adaptor/bool.hpp
|
||||||
|
include/msgpack/adaptor/bool_fwd.hpp
|
||||||
|
include/msgpack/adaptor/char_ptr.hpp
|
||||||
|
include/msgpack/adaptor/char_ptr_fwd.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/array.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/array_fwd.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/array_char.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/array_char_fwd.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/forward_list.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/forward_list_fwd.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/tuple.hpp
|
||||||
|
include/msgpack/adaptor/cpp11/tuple_fwd.hpp
|
||||||
|
include/msgpack/adaptor/define.hpp
|
||||||
|
include/msgpack/adaptor/deque.hpp
|
||||||
|
include/msgpack/adaptor/deque_fwd.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp03_define.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp03_msgpack_tuple.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp03_msgpack_tuple_fwd.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp11_define.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp
|
||||||
|
include/msgpack/adaptor/detail/cpp11_msgpack_tuple_fwd.hpp
|
||||||
|
include/msgpack/adaptor/fixint.hpp
|
||||||
|
include/msgpack/adaptor/fixint_fwd.hpp
|
||||||
|
include/msgpack/adaptor/float.hpp
|
||||||
|
include/msgpack/adaptor/float_fwd.hpp
|
||||||
|
include/msgpack/adaptor/int.hpp
|
||||||
|
include/msgpack/adaptor/int_fwd.hpp
|
||||||
|
include/msgpack/adaptor/list.hpp
|
||||||
|
include/msgpack/adaptor/list_fwd.hpp
|
||||||
|
include/msgpack/adaptor/map.hpp
|
||||||
|
include/msgpack/adaptor/map_fwd.hpp
|
||||||
|
include/msgpack/adaptor/msgpack_tuple.hpp
|
||||||
|
include/msgpack/adaptor/msgpack_tuple_fwd.hpp
|
||||||
|
include/msgpack/adaptor/nil.hpp
|
||||||
|
include/msgpack/adaptor/nil_fwd.hpp
|
||||||
|
include/msgpack/adaptor/pair.hpp
|
||||||
|
include/msgpack/adaptor/pair_fwd.hpp
|
||||||
|
include/msgpack/adaptor/raw.hpp
|
||||||
|
include/msgpack/adaptor/raw_fwd.hpp
|
||||||
|
include/msgpack/adaptor/set.hpp
|
||||||
|
include/msgpack/adaptor/set_fwd.hpp
|
||||||
|
include/msgpack/adaptor/string.hpp
|
||||||
|
include/msgpack/adaptor/string_fwd.hpp
|
||||||
|
include/msgpack/adaptor/tr1/unordered_map.hpp
|
||||||
|
include/msgpack/adaptor/tr1/unordered_map_fwd.hpp
|
||||||
|
include/msgpack/adaptor/tr1/unordered_set.hpp
|
||||||
|
include/msgpack/adaptor/tr1/unordered_set_fwd.hpp
|
||||||
|
include/msgpack/adaptor/vector.hpp
|
||||||
|
include/msgpack/adaptor/vector_fwd.hpp
|
||||||
|
include/msgpack/adaptor/vector_char.hpp
|
||||||
|
include/msgpack/adaptor/vector_char_fwd.hpp
|
||||||
|
include/msgpack/cpp_config.hpp
|
||||||
|
include/msgpack/detail/cpp03_zone.hpp
|
||||||
|
include/msgpack/detail/cpp11_zone.hpp
|
||||||
|
include/msgpack/fbuffer.hpp
|
||||||
|
include/msgpack/object.hpp
|
||||||
|
include/msgpack/object_fwd.hpp
|
||||||
|
include/msgpack/pack.hpp
|
||||||
|
include/msgpack/sbuffer.hpp
|
||||||
|
include/msgpack/type.hpp
|
||||||
|
include/msgpack/unpack.hpp
|
||||||
|
include/msgpack/version.hpp
|
||||||
|
include/msgpack/versioning.hpp
|
||||||
|
include/msgpack/vrefbuffer.hpp
|
||||||
|
include/msgpack/zbuffer.hpp
|
||||||
|
include/msgpack/zone.hpp
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
EXECUTE_PROCESS (
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src/msgpack
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIGURE_FILE (
|
||||||
|
msgpack.pc.in
|
||||||
|
msgpack.pc
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES (
|
||||||
|
./
|
||||||
|
include/
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_LIBRARY (msgpack SHARED
|
||||||
|
${msgpack_SOURCES}
|
||||||
|
${msgpack_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_LIBRARY (msgpack-static STATIC
|
||||||
|
${msgpack_SOURCES}
|
||||||
|
${msgpack_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES (msgpack-static PROPERTIES OUTPUT_NAME "msgpack")
|
||||||
|
SET_TARGET_PROPERTIES (msgpack PROPERTIES IMPORT_SUFFIX "_import.lib")
|
||||||
|
SET_TARGET_PROPERTIES (msgpack PROPERTIES SOVERSION 3 VERSION 4.0.0)
|
||||||
|
|
||||||
|
IF (MSGPACK_BUILD_TESTS)
|
||||||
|
ENABLE_TESTING ()
|
||||||
|
SET(CTEST_MEMORYCHECK_COMMAND "/usr/bin/valgrind")
|
||||||
|
INCLUDE(Dart)
|
||||||
|
SET(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1")
|
||||||
|
ADD_SUBDIRECTORY (test)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
SET_PROPERTY (TARGET msgpack APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -g -O3 -DPIC")
|
||||||
|
SET_PROPERTY (TARGET msgpack-static APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -g -O3" )
|
||||||
|
ENDIF ()
|
||||||
|
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
|
STRING(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
ELSE ()
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
|
ENDIF ()
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||||
|
SET(CMAKE_INSTALL_LIBDIR lib)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
|
INSTALL (TARGETS msgpack msgpack-static DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
INSTALL (DIRECTORY include DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||||
|
INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/msgpack.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
|
||||||
|
# Doxygen
|
||||||
|
FIND_PACKAGE (Doxygen)
|
||||||
|
IF (DOXYGEN_FOUND)
|
||||||
|
ADD_CUSTOM_TARGET (
|
||||||
|
doxygen_c
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "FILE_PATTERNS = *.h" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "OUTPUT_DIRECTORY = doc_c" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NAME = \"MessagePack for C\"" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
|
||||||
|
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_c
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
ADD_CUSTOM_TARGET (
|
||||||
|
doxygen_cpp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_cpp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "FILE_PATTERNS = *.hpp" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_cpp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "OUTPUT_DIRECTORY = doc_cpp" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_cpp
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NAME = \"MessagePack for C++\"" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_cpp
|
||||||
|
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile_cpp
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
ADD_CUSTOM_TARGET (
|
||||||
|
doxygen
|
||||||
|
DEPENDS doxygen_c doxygen_cpp
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
@@ -1,3 +1,28 @@
|
|||||||
|
2014-07-02 version 0.5.9:
|
||||||
|
|
||||||
|
* Support std::tr1 unordered containers by default (#51, #63, #68, #69)
|
||||||
|
* Remove some warnings (#56)
|
||||||
|
* Fix segmentation fault after malloc failures (#58, #59)
|
||||||
|
* Fix alloc/dealloc mismatch (#52, #61)
|
||||||
|
* Fix sample codes (#60, #64)
|
||||||
|
* Support implicit conversion from integer to float/double (#54)
|
||||||
|
* Improve documents (#45, #75, #82, #83)
|
||||||
|
* Support CMake (#20, #87)
|
||||||
|
* Remove Ruby dependencies in bootstrap (#86, #87)
|
||||||
|
* Add FILE* buffer (#40)
|
||||||
|
* Other bug fixes and refactoring: #39, #73, #77, #79, #80, #81, #84, #90
|
||||||
|
|
||||||
|
2013-12-23 version 0.5.8:
|
||||||
|
|
||||||
|
* Move to the new github repository msgpack/msgpack-c
|
||||||
|
* Support the new deserialization specification
|
||||||
|
* fixes the problem of unpack helpers for array and map with 32bit compilers (#37, #38)
|
||||||
|
* Other bug fixes and refactoring: #46, #41, #36, #35, #33, #32, #30, #29, #28, #27, #26, #25, #8, #3
|
||||||
|
* Update of documents: #23, #18, #17
|
||||||
|
|
||||||
|
2011-08-08 version 0.5.7:
|
||||||
|
|
||||||
|
* fixes compile error problem with llvm-gcc and Mac OS X Lion
|
||||||
|
|
||||||
2011-04-24 version 0.5.6:
|
2011-04-24 version 0.5.6:
|
||||||
|
|
||||||
@@ -6,12 +6,13 @@ DOC_FILES = \
|
|||||||
NOTICE \
|
NOTICE \
|
||||||
msgpack_vc8.vcproj \
|
msgpack_vc8.vcproj \
|
||||||
msgpack_vc8.sln \
|
msgpack_vc8.sln \
|
||||||
msgpack_vc2008.vcproj \
|
|
||||||
msgpack_vc2008.sln \
|
|
||||||
msgpack_vc.postbuild.bat
|
msgpack_vc.postbuild.bat
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
$(DOC_FILES)
|
$(DOC_FILES) CMakeLists.txt test/CMakeLists.txt
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = msgpack.pc
|
||||||
|
|
||||||
doxygen:
|
doxygen:
|
||||||
./preprocess clean
|
./preprocess clean
|
||||||
194
QUICKSTART-C.md
Normal file
194
QUICKSTART-C.md
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# Implementation Status
|
||||||
|
|
||||||
|
The serialization library is production-ready.
|
||||||
|
|
||||||
|
Currently, no RPC implementation is not available.
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
|
||||||
|
## Mac OS X with MacPorts
|
||||||
|
|
||||||
|
On Mac OS X, you can install MessagePack for C using MacPorts.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo port install msgpack
|
||||||
|
```
|
||||||
|
|
||||||
|
You might need to run `sudo port selfupdate` before installing to update the package repository.
|
||||||
|
|
||||||
|
You can also install via Homebrew.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ sudo brew install msgpack
|
||||||
|
```
|
||||||
|
|
||||||
|
## FreeBSD with Ports Collection
|
||||||
|
|
||||||
|
On FreeBSD, you can use Ports Collection. Install [net/msgpack|http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/msgpack/] package.
|
||||||
|
|
||||||
|
## Gentoo Linux with Portage
|
||||||
|
|
||||||
|
On Gentoo Linux, you can use emerge. Install [dev-libs/msgpack|http://gentoo-portage.com/dev-libs/msgpack] package.
|
||||||
|
|
||||||
|
## Other UNIX-like platform with ./configure
|
||||||
|
|
||||||
|
On the other UNIX-like platforms, download source package from [Releases|http://msgpack.org/releases/cpp/] and run `./configure && make && make install`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ wget http://msgpack.org/releases/cpp/msgpack-0.5.5.tar.gz
|
||||||
|
$ tar zxvf msgpack-0.5.5.tar.gz
|
||||||
|
$ cd msgpack-0.5.5
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
On Windows, download source package from [here|https://sourceforge.net/projects/msgpack/files/] and extract it.
|
||||||
|
Then open `msgpack_vc8.vcproj` file and build it using batch build. It builds libraries on `lib/` folder and header files on `include/` folder.
|
||||||
|
|
||||||
|
You can build using command line as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
> vcbuild msgpack_vc2008.vcproj
|
||||||
|
> dir lib % DLL files are here
|
||||||
|
> dir include % header files are here
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install from git repository
|
||||||
|
|
||||||
|
You need to install gcc (4.1.0 or higher), autotools.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone git@github.com:msgpack/msgpack.git
|
||||||
|
$ cd msgpack/cpp
|
||||||
|
$ ./bootstrap
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
# Serialization QuickStart for C
|
||||||
|
|
||||||
|
## First program
|
||||||
|
|
||||||
|
Include `msgpack.h` header and link `msgpack` library to use MessagePack on your program.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <msgpack.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
/* creates buffer and serializer instance. */
|
||||||
|
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
|
||||||
|
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
|
||||||
|
|
||||||
|
/* serializes ["Hello", "MessagePack"]. */
|
||||||
|
msgpack_pack_array(pk, 2);
|
||||||
|
msgpack_pack_raw(pk, 5);
|
||||||
|
msgpack_pack_raw_body(pk, "Hello", 5);
|
||||||
|
msgpack_pack_raw(pk, 11);
|
||||||
|
msgpack_pack_raw_body(pk, "MessagePack", 11);
|
||||||
|
|
||||||
|
/* deserializes it. */
|
||||||
|
msgpack_unpacked msg;
|
||||||
|
msgpack_unpacked_init(&msg);
|
||||||
|
bool success = msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
|
||||||
|
|
||||||
|
/* prints the deserialized object. */
|
||||||
|
msgpack_object obj = msg.data;
|
||||||
|
msgpack_object_print(stdout, obj); /*=> ["Hello", "MessagePack"] */
|
||||||
|
|
||||||
|
/* cleaning */
|
||||||
|
msgpack_sbuffer_free(buffer);
|
||||||
|
msgpack_packer_free(pk);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Simple program with a loop
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <msgpack.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
/* creates buffer and serializer instance. */
|
||||||
|
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
|
||||||
|
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for(j = 0; j<23; j++) {
|
||||||
|
/* NB: the buffer needs to be cleared on each iteration */
|
||||||
|
msgpack_sbuffer_clear(buffer);
|
||||||
|
|
||||||
|
/* serializes ["Hello", "MessagePack"]. */
|
||||||
|
msgpack_pack_array(pk, 3);
|
||||||
|
msgpack_pack_raw(pk, 5);
|
||||||
|
msgpack_pack_raw_body(pk, "Hello", 5);
|
||||||
|
msgpack_pack_raw(pk, 11);
|
||||||
|
msgpack_pack_raw_body(pk, "MessagePack", 11);
|
||||||
|
msgpack_pack_int(pk, j);
|
||||||
|
|
||||||
|
/* deserializes it. */
|
||||||
|
msgpack_unpacked msg;
|
||||||
|
msgpack_unpacked_init(&msg);
|
||||||
|
bool success = msgpack_unpack_next(&msg, buffer->data, buffer->size, NULL);
|
||||||
|
|
||||||
|
/* prints the deserialized object. */
|
||||||
|
msgpack_object obj = msg.data;
|
||||||
|
msgpack_object_print(stdout, obj); /*=> ["Hello", "MessagePack"] */
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleaning */
|
||||||
|
msgpack_sbuffer_free(buffer);
|
||||||
|
msgpack_packer_free(pk);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Streaming feature
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <msgpack.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
/* serializes multiple objects using msgpack_packer. */
|
||||||
|
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
|
||||||
|
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
|
||||||
|
msgpack_pack_int(pk, 1);
|
||||||
|
msgpack_pack_int(pk, 2);
|
||||||
|
msgpack_pack_int(pk, 3);
|
||||||
|
|
||||||
|
/* deserializes these objects using msgpack_unpacker. */
|
||||||
|
msgpack_unpacker pac;
|
||||||
|
msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
||||||
|
|
||||||
|
/* feeds the buffer. */
|
||||||
|
msgpack_unpacker_reserve_buffer(&pac, buffer->size);
|
||||||
|
memcpy(msgpack_unpacker_buffer(&pac), buffer->data, buffer->size);
|
||||||
|
msgpack_unpacker_buffer_consumed(&pac, buffer->size);
|
||||||
|
|
||||||
|
/* now starts streaming deserialization. */
|
||||||
|
msgpack_unpacked result;
|
||||||
|
msgpack_unpacked_init(&result);
|
||||||
|
|
||||||
|
while(msgpack_unpacker_next(&pac, &result)) {
|
||||||
|
msgpack_object_print(stdout, result.data);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* results:
|
||||||
|
* $ gcc stream.cc -lmsgpack -o stream
|
||||||
|
* $ ./stream
|
||||||
|
* 1
|
||||||
|
* 2
|
||||||
|
* 3
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
```
|
||||||
159
QUICKSTART-CPP.md
Normal file
159
QUICKSTART-CPP.md
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# Implementation Status
|
||||||
|
|
||||||
|
The serialization library is production-ready.
|
||||||
|
|
||||||
|
Currently, RPC implementation is testing phase. Requires newer kernel, not running on RHEL5/CentOS5.
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
Same as QuickStart for C Language.
|
||||||
|
|
||||||
|
# Serialization QuickStart for C+\+
|
||||||
|
|
||||||
|
## First program
|
||||||
|
|
||||||
|
Include `msgpack.hpp` header and link `msgpack` library to use MessagePack on your program.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// serializes this object.
|
||||||
|
std::vector<std::string> vec;
|
||||||
|
vec.push_back("Hello");
|
||||||
|
vec.push_back("MessagePack");
|
||||||
|
|
||||||
|
// serialize it into simple buffer.
|
||||||
|
msgpack::sbuffer sbuf;
|
||||||
|
msgpack::pack(sbuf, vec);
|
||||||
|
|
||||||
|
// deserialize it.
|
||||||
|
msgpack::unpacked msg;
|
||||||
|
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
||||||
|
|
||||||
|
// print the deserialized object.
|
||||||
|
msgpack::object obj = msg.get();
|
||||||
|
std::cout << obj << std::endl; //=> ["Hello", "MessagePack"]
|
||||||
|
|
||||||
|
// convert it into statically typed object.
|
||||||
|
std::vector<std::string> rvec;
|
||||||
|
obj.convert(&rvec);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Compile it as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ g++ hello.cc -lmsgpack -o hello
|
||||||
|
$ ./hello
|
||||||
|
["Hello", "MessagePack"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Streaming feature
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// serializes multiple objects using msgpack::packer.
|
||||||
|
msgpack::sbuffer buffer;
|
||||||
|
|
||||||
|
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||||
|
pk.pack(std::string("Log message ... 1"));
|
||||||
|
pk.pack(std::string("Log message ... 2"));
|
||||||
|
pk.pack(std::string("Log message ... 3"));
|
||||||
|
|
||||||
|
// deserializes these objects using msgpack::unpacker.
|
||||||
|
msgpack::unpacker pac;
|
||||||
|
|
||||||
|
// feeds the buffer.
|
||||||
|
pac.reserve_buffer(buffer.size());
|
||||||
|
memcpy(pac.buffer(), buffer.data(), buffer.size());
|
||||||
|
pac.buffer_consumed(buffer.size());
|
||||||
|
|
||||||
|
// now starts streaming deserialization.
|
||||||
|
msgpack::unpacked result;
|
||||||
|
while(pac.next(&result)) {
|
||||||
|
std::cout << result.get() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// results:
|
||||||
|
// $ g++ stream.cc -lmsgpack -o stream
|
||||||
|
// $ ./stream
|
||||||
|
// "Log message ... 1"
|
||||||
|
// "Log message ... 2"
|
||||||
|
// "Log message ... 3"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Streaming into an array or map
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
// serializes multiple objects into one message containing an array using msgpack::packer.
|
||||||
|
msgpack::sbuffer buffer;
|
||||||
|
|
||||||
|
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||||
|
pk.pack_array(3);
|
||||||
|
pk.pack(std::string("Log message ... 1"));
|
||||||
|
pk.pack(std::string("Log message ... 2"));
|
||||||
|
pk.pack(std::string("Log message ... 3"));
|
||||||
|
|
||||||
|
// serializes multiple objects into one message containing a map using msgpack::packer.
|
||||||
|
msgpack::sbuffer buffer2;
|
||||||
|
|
||||||
|
msgpack::packer<msgpack::sbuffer> pk2(&buffer2);
|
||||||
|
pk2.pack_map(2);
|
||||||
|
pk2.pack(std::string("x"));
|
||||||
|
pk2.pack(3);
|
||||||
|
pk2.pack(std::string("y"));
|
||||||
|
pk2.pack(3.4321);
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## User-defined classes
|
||||||
|
|
||||||
|
You can use serialize/deserializes user-defined classes using `MSGPACK_DEFINE` macro.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class myclass {
|
||||||
|
private:
|
||||||
|
std::string m_str;
|
||||||
|
std::vector<int> m_vec;
|
||||||
|
public:
|
||||||
|
MSGPACK_DEFINE(m_str, m_vec);
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
std::vector<myclass> vec;
|
||||||
|
// add some elements into vec...
|
||||||
|
|
||||||
|
// you can serialize myclass directly
|
||||||
|
msgpack::sbuffer sbuf;
|
||||||
|
msgpack::pack(sbuf, vec);
|
||||||
|
|
||||||
|
msgpack::unpacked msg;
|
||||||
|
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
||||||
|
|
||||||
|
msgpack::object obj = msg.get();
|
||||||
|
|
||||||
|
// you can convert object to myclass directly
|
||||||
|
std::vector<myclass> rvec;
|
||||||
|
obj.convert(&rvec);
|
||||||
|
}
|
||||||
|
```
|
||||||
163
README.md
163
README.md
@@ -1,37 +1,152 @@
|
|||||||
MessagePack
|
# Msgpack for C/C++
|
||||||
===========
|
|
||||||
Extremely efficient object serialization library. It's like JSON, but very fast and small.
|
It's like JSON but small and fast.
|
||||||
|
|
||||||
|
|
||||||
## What's MessagePack?
|
## Overview
|
||||||
|
|
||||||
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.
|
MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it's faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.
|
||||||
|
|
||||||
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
|
## License
|
||||||
|
|
||||||

|
Msgpack is Copyright (C) 2008-2014 FURUHASHI Sadayuki and licensed under the Apache License, Version 2.0 (the "License"). For details see the `COPYING` file in this directory.
|
||||||
|
|
||||||
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
|
## Contributing
|
||||||
|
|
||||||
Usage and other documents about implementations in each language are found at [the web site.](http://msgpack.sourceforge.net/)
|
The source for msgpack-c is held at [msgpack-c](https://github.com/msgpack/msgpack-c) github.com site.
|
||||||
|
|
||||||
|
To report an issue, use the [msgpack-c issue tracker](https://github.com/msgpack/msgpack-c/issues) at github.com.
|
||||||
|
|
||||||
|
## Version
|
||||||
|
0.6.0 [](https://travis-ci.org/msgpack/msgpack-c)
|
||||||
|
|
||||||
|
## Using Msgpack
|
||||||
|
|
||||||
|
### Header only library for C++
|
||||||
|
When you use msgpack on C++03 and C++11, you just add msgpack-c/include to your include path. You don't need to link any msgpack libraries.
|
||||||
|
|
||||||
|
e.g.)
|
||||||
|
|
||||||
|
g++ -I msgpack-c/include your_source_file.cpp
|
||||||
|
|
||||||
|
If you want to use C version of msgpack, you need to build it. You can also install C and C++ version of msgpack.
|
||||||
|
|
||||||
|
### Building and Installing
|
||||||
|
|
||||||
|
#### Install from git repository
|
||||||
|
|
||||||
|
##### Using autotools
|
||||||
|
You will need gcc (4.1.0 or higher), autotools.
|
||||||
|
|
||||||
|
For C:
|
||||||
|
C++03 and C:
|
||||||
|
|
||||||
|
$ git clone https://github.com/redboltz/msgpack-c/tree/cxx_separate
|
||||||
|
$ cd msgpack-c
|
||||||
|
$ ./bootstrap
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
For C++11:
|
||||||
|
|
||||||
|
$ git clone https://github.com/msgpack/msgpack-c.git
|
||||||
|
$ cd msgpack-c
|
||||||
|
$ ./bootstrap
|
||||||
|
$ ./configure CXXFLAGS="-std=c++11"
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
You need the compiler that fully supports C++11.
|
||||||
|
|
||||||
|
##### Using cmake
|
||||||
|
|
||||||
|
###### CUI
|
||||||
|
|
||||||
|
You will need gcc (4.1.0 or higher), cmake.
|
||||||
|
|
||||||
|
$ git clone https://github.com/msgpack/msgpack-c.git
|
||||||
|
$ cd msgpack-c
|
||||||
|
$ cmake .
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
If you want to setup C++11 version of msgpack, execute the following command:
|
||||||
|
|
||||||
|
$ git clone https://github.com/msgpack/msgpack-c.git
|
||||||
|
$ cd msgpack-c
|
||||||
|
$ cmake -DMSGPACK_CXX11=ON .
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
You need the compiler that fully supports C++11.
|
||||||
|
|
||||||
|
##### GUI on Windows
|
||||||
|
|
||||||
|
Clone msgpack-c git repository.
|
||||||
|
|
||||||
|
$ git clone https://github.com/msgpack/msgpack-c.git
|
||||||
|
|
||||||
|
or using GUI git client.
|
||||||
|
|
||||||
|
e.g.) tortoise git https://code.google.com/p/tortoisegit/
|
||||||
|
|
||||||
|
1. Launch cmake GUI client. http://www.cmake.org/cmake/resources/software.html
|
||||||
|
|
||||||
|
1. Set 'Where is the source code:' text box and 'Where to build the binaries:' text box.
|
||||||
|
|
||||||
|
1. Click 'Configure' button.
|
||||||
|
|
||||||
|
1. Choose your Visual Studio version.
|
||||||
|
|
||||||
|
1. Click 'Generate' button.
|
||||||
|
|
||||||
|
1. Open the created msgpack.sln on Visual Studio.
|
||||||
|
|
||||||
|
1. Build all.
|
||||||
|
|
||||||
|
|
||||||
## Learn More
|
#### Install from package
|
||||||
|
|
||||||
- [Project Web Site](http://msgpack.sourceforge.net/)
|
Install from package for this branch (poc/0.6) is not supported yet.
|
||||||
- [MessagePack format specification](http://msgpack.sourceforge.net/spec)
|
|
||||||
- [Repository at github](http://github.com/msgpack/msgpack)
|
### Code Example
|
||||||
- [Wiki](http://msgpack.sourceforge.net/start)
|
|
||||||
- [MessagePack-RPC](http://github.com/msgpack/msgpack-rpc)
|
#include <msgpack.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// This is target object.
|
||||||
|
std::vector<std::string> target;
|
||||||
|
target.push_back("Hello,");
|
||||||
|
target.push_back("World!");
|
||||||
|
|
||||||
|
// Serialize it.
|
||||||
|
msgpack::sbuffer sbuf; // simple buffer
|
||||||
|
msgpack::pack(&sbuf, target);
|
||||||
|
|
||||||
|
// Deserialize the serialized data.
|
||||||
|
msgpack::unpacked msg; // includes memory pool and deserialized object
|
||||||
|
msgpack::unpack(msg, sbuf.data(), sbuf.size());
|
||||||
|
msgpack::object obj = msg.get();
|
||||||
|
|
||||||
|
// Print the deserialized object to stdout.
|
||||||
|
std::cout << obj << std::endl; // ["Hello," "World!"]
|
||||||
|
|
||||||
|
// Convert the deserialized object to staticaly typed object.
|
||||||
|
std::vector<std::string> result;
|
||||||
|
obj.convert(&result);
|
||||||
|
|
||||||
|
// If the type is mismatched, it throws msgpack::type_error.
|
||||||
|
obj.as<int>(); // type is mismatched, msgpack::type_error is thrown
|
||||||
|
}
|
||||||
|
|
||||||
|
### Documents
|
||||||
|
|
||||||
|
You can get addtional information on the wiki:
|
||||||
|
|
||||||
|
https://github.com/msgpack/msgpack-c/wiki/cpp_overview
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ as comparing that implementations.
|
|||||||
or
|
or
|
||||||
$ port install msgpack # MacPorts
|
$ port install msgpack # MacPorts
|
||||||
|
|
||||||
$ g++ -Wall -lmsgpack crosslang.cc -o crosslang
|
$ g++ -Wall crosslang.cc -lmsgpack -o crosslang
|
||||||
|
|
||||||
$ ./crosslang
|
$ ./crosslang
|
||||||
Usage: ./crosslang [in-file] [out-file]
|
Usage: ./crosslang [in-file] [out-file]
|
||||||
@@ -38,13 +38,6 @@ test -f ChangeLog || touch ChangeLog
|
|||||||
test -f NEWS || touch NEWS
|
test -f NEWS || touch NEWS
|
||||||
test -f README || cp -f README.md README
|
test -f README || cp -f README.md README
|
||||||
|
|
||||||
./preprocess
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ACLOCAL="aclocal"
|
ACLOCAL="aclocal"
|
||||||
ACLOCAL_FILES="aclocal.m4"
|
ACLOCAL_FILES="aclocal.m4"
|
||||||
ALWAYS_CLEAN="config.status config.log config.cache libtool"
|
ALWAYS_CLEAN="config.status config.log config.cache libtool"
|
||||||
57
ci/build_autotools.sh
Executable file
57
ci/build_autotools.sh
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
./bootstrap
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $1 = "cpp11" ]
|
||||||
|
then
|
||||||
|
if [ $2 = "32" ]
|
||||||
|
then
|
||||||
|
./configure CFLAGS="-m32" CXXFLAGS="-std=c++11 -m32"
|
||||||
|
else
|
||||||
|
./configure CXXFLAGS="-std=c++11"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ $2 = "32" ]
|
||||||
|
then
|
||||||
|
./configure CFLAGS="-m32" CXXFLAGS="-m32"
|
||||||
|
else
|
||||||
|
./configure
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make check
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make install DESTDIR=`pwd`/install
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
84
ci/build_cmake.sh
Executable file
84
ci/build_cmake.sh
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir build
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $1 = "cpp11" ]
|
||||||
|
then
|
||||||
|
if [ $2 = "32" ]
|
||||||
|
then
|
||||||
|
cmake -DMSGPACK_CXX11=ON -DMSGPACK_32BIT=ON ..
|
||||||
|
else
|
||||||
|
cmake -DMSGPACK_CXX11=ON ..
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ $2 = "32" ]
|
||||||
|
then
|
||||||
|
cmake -DMSGPACK_32BIT=ON ..
|
||||||
|
else
|
||||||
|
cmake ..
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make test
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
make install DESTDIR=`pwd`/install
|
||||||
|
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $2 != "32" ]
|
||||||
|
then
|
||||||
|
ctest -T memcheck | tee memcheck.log
|
||||||
|
|
||||||
|
ret=${PIPESTATUS[0]}
|
||||||
|
if [ $ret -ne 0 ]
|
||||||
|
then
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
cat memcheck.log | grep "Memory Leak" > /dev/null
|
||||||
|
ret=$?
|
||||||
|
if [ $ret -eq 0 ]
|
||||||
|
then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
||||||
98
configure.in
Normal file
98
configure.in
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
AC_INIT(msgpack, m4_esyscmd([cat include/msgpack/version_master.h | tr -d "\n" | sed -e 's/#define MSGPACK_VERSION_MAJOR\s*\(\w*\)/\1./g' -e 's/#define MSGPACK_VERSION_MINOR\s*\(\w*\)/\1./g' -e 's/#define MSGPACK_VERSION_REVISION\s*\(\w*\)/\1/g']))
|
||||||
|
AC_CONFIG_AUX_DIR(ac)
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
AC_SUBST(CFLAGS)
|
||||||
|
CFLAGS="-O3 -Wall $CFLAGS"
|
||||||
|
|
||||||
|
AC_SUBST(CXXFLAGS)
|
||||||
|
CXXFLAGS="-O3 -Wall $CXXFLAGS"
|
||||||
|
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
|
||||||
|
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_PROG_CXX
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no")
|
||||||
|
|
||||||
|
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AM_PROG_AS
|
||||||
|
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if debug option is enabled])
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
AS_HELP_STRING([--disable-debug],
|
||||||
|
[disable assert macros and omit -g option]) )
|
||||||
|
AC_MSG_RESULT([$enable_debug])
|
||||||
|
if test "$enable_debug" != "no"; then
|
||||||
|
CXXFLAGS="$CXXFLAGS -g"
|
||||||
|
CFLAGS="$CFLAGS -g"
|
||||||
|
else
|
||||||
|
CXXFLAGS="$CXXFLAGS -DNDEBUG"
|
||||||
|
CFLAGS="$CFLAGS -DNDEBUG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
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); }
|
||||||
|
], [atomic_sub(1); atomic_add(1);], msgpack_cv_atomic_ops="yes")
|
||||||
|
])
|
||||||
|
if test "$msgpack_cv_atomic_ops" != "yes"; then
|
||||||
|
if test "$enable_cxx" = "no"; then
|
||||||
|
AC_MSG_ERROR([__sync_* atomic operations are not found. Try to enable C++ support.
|
||||||
|
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
|
||||||
|
add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
|
||||||
|
|
||||||
|
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_LANG_PUSH([C++])
|
||||||
|
AC_CACHE_CHECK([for __gnu_cxx::__exchange_and_add], msgpack_cv_gcc_cxx_atomic_ops, [
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#include <bits/atomicity.h>
|
||||||
|
int atomic_sub(int i) { return __gnu_cxx::__exchange_and_add(&i, -1) - 1; }
|
||||||
|
int atomic_add(int i) { return __gnu_cxx::__exchange_and_add(&i, 1) + 1; }
|
||||||
|
], [atomic_sub(1); atomic_add(1);], msgpack_cv_gcc_cxx_atomic_ops="yes")
|
||||||
|
])
|
||||||
|
AC_LANG_POP([C++])
|
||||||
|
|
||||||
|
if test "$msgpack_cv_gcc_cxx_atomic_ops" != "yes"; then
|
||||||
|
AC_MSG_ERROR([__sync_* atomic operations nor __gnu_cxx::__exchange_and_add are not found.
|
||||||
|
|
||||||
|
If you are using gcc >= 4.1 and the default target CPU architecture is "i386", try to
|
||||||
|
add CFLAGS="-march=i686" and CXXFLAGS="-march=i686" options to ./configure as follows:
|
||||||
|
|
||||||
|
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
|
||||||
|
])
|
||||||
|
|
||||||
|
else
|
||||||
|
enable_gcc_cxx_atomic=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(ENABLE_GCC_CXX_ATOMIC, test "$enable_gcc_cxx_atomic" = "yes")
|
||||||
|
|
||||||
|
major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).\([[0-9]]*\).*/\1/'`
|
||||||
|
minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).\([[0-9]]*\).*/\2/'`
|
||||||
|
revision=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).\([[0-9]]*\).*/\3/'`
|
||||||
|
AC_SUBST(VERSION_MAJOR, $major)
|
||||||
|
AC_SUBST(VERSION_MINOR, $minor)
|
||||||
|
AC_SUBST(VERSION_REVISION, $revision)
|
||||||
|
|
||||||
|
|
||||||
|
AC_OUTPUT([Makefile
|
||||||
|
msgpack.pc
|
||||||
|
src/Makefile
|
||||||
|
test/Makefile])
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
MessagePack for C/C++
|
|
||||||
=====================
|
|
||||||
Binary-based efficient object serialization library.
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Download latest package from [releases of MessagePack](http://sourceforge.net/projects/msgpack/files/) and extract it.
|
|
||||||
|
|
||||||
On UNIX-like platform, run ./configure && make && sudo make install:
|
|
||||||
|
|
||||||
$ ./configure
|
|
||||||
$ make
|
|
||||||
$ sudo make install
|
|
||||||
|
|
||||||
On Windows, open msgpack_vc8.vcproj or msgpack_vc2008 file and build it using batch build. DLLs are built on lib folder,
|
|
||||||
and the headers are built on include folder.
|
|
||||||
|
|
||||||
To use the library in your program, include msgpack.hpp header and link "msgpack" library.
|
|
||||||
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
#include <msgpack.hpp>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
// This is target object.
|
|
||||||
std::vector<std::string> target;
|
|
||||||
target.push_back("Hello,");
|
|
||||||
target.push_back("World!");
|
|
||||||
|
|
||||||
// Serialize it.
|
|
||||||
msgpack::sbuffer buffer; // simple buffer
|
|
||||||
msgpack::pack(&buffer, target);
|
|
||||||
|
|
||||||
// Deserialize the serialized data.
|
|
||||||
msgpack::unpacked msg; // includes memory pool and deserialized object
|
|
||||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
|
||||||
msgpack::object obj = msg.get();
|
|
||||||
|
|
||||||
// Print the deserialized object to stdout.
|
|
||||||
std::cout << obj << std::endl; // ["Hello," "World!"]
|
|
||||||
|
|
||||||
// Convert the deserialized object to staticaly typed object.
|
|
||||||
std::vector<std::string> result;
|
|
||||||
obj.convert(&result);
|
|
||||||
|
|
||||||
// If the type is mismatched, it throws msgpack::type_error.
|
|
||||||
obj.as<int>(); // type is mismatched, msgpack::type_error is thrown
|
|
||||||
}
|
|
||||||
|
|
||||||
API documents and other example codes are available at the [wiki.](http://redmine.msgpack.org/projects/msgpack/wiki)
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
See also NOTICE file.
|
|
||||||
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
AC_INIT(src/object.cpp)
|
|
||||||
AC_CONFIG_AUX_DIR(ac)
|
|
||||||
AM_INIT_AUTOMAKE(msgpack, 0.5.6)
|
|
||||||
AC_CONFIG_HEADER(config.h)
|
|
||||||
|
|
||||||
AC_SUBST(CFLAGS)
|
|
||||||
CFLAGS="-O4 -Wall $CFLAGS"
|
|
||||||
|
|
||||||
AC_SUBST(CXXFLAGS)
|
|
||||||
CXXFLAGS="-O4 -Wall $CXXFLAGS"
|
|
||||||
|
|
||||||
|
|
||||||
AC_PROG_CC
|
|
||||||
|
|
||||||
|
|
||||||
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_PROG_CXX
|
|
||||||
AM_PROG_CC_C_O
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(ENABLE_CXX, test "$enable_cxx" != "no")
|
|
||||||
|
|
||||||
|
|
||||||
AC_PROG_LIBTOOL
|
|
||||||
AM_PROG_AS
|
|
||||||
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([if debug option is enabled])
|
|
||||||
AC_ARG_ENABLE(debug,
|
|
||||||
AS_HELP_STRING([--disable-debug],
|
|
||||||
[disable assert macros and omit -g option]) )
|
|
||||||
AC_MSG_RESULT([$enable_debug])
|
|
||||||
if test "$enable_debug" != "no"; then
|
|
||||||
CXXFLAGS="$CXXFLAGS -g"
|
|
||||||
CFLAGS="$CFLAGS -g"
|
|
||||||
else
|
|
||||||
CXXFLAGS="$CXXFLAGS -DNDEBUG"
|
|
||||||
CFLAGS="$CFLAGS -DNDEBUG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
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=i686" options to ./configure as follows:
|
|
||||||
|
|
||||||
$ ./configure CFLAGS="-march=i686" CXXFLAGS="-march=i686"
|
|
||||||
])
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
major=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
|
|
||||||
minor=`echo $VERSION | sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
|
|
||||||
AC_SUBST(VERSION_MAJOR, $major)
|
|
||||||
AC_SUBST(VERSION_MINOR, $minor)
|
|
||||||
|
|
||||||
|
|
||||||
AC_OUTPUT([Makefile
|
|
||||||
src/Makefile
|
|
||||||
src/msgpack/version.h
|
|
||||||
test/Makefile])
|
|
||||||
|
|
||||||
@@ -1,34 +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 ""
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
mv $1.tmp $1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$1" = "clean" ];then
|
|
||||||
rm -f src/msgpack/type/tuple.hpp
|
|
||||||
rm -f src/msgpack/type/define.hpp
|
|
||||||
rm -f src/msgpack/zone.hpp
|
|
||||||
else
|
|
||||||
preprocess src/msgpack/type/tuple.hpp
|
|
||||||
preprocess src/msgpack/type/define.hpp
|
|
||||||
preprocess src/msgpack/zone.hpp
|
|
||||||
fi
|
|
||||||
cp -f ../msgpack/sysdep.h src/msgpack/
|
|
||||||
cp -f ../msgpack/pack_define.h src/msgpack/
|
|
||||||
cp -f ../msgpack/pack_template.h src/msgpack/
|
|
||||||
cp -f ../msgpack/unpack_define.h src/msgpack/
|
|
||||||
cp -f ../msgpack/unpack_template.h src/msgpack/
|
|
||||||
cp -f ../test/cases.mpac test/
|
|
||||||
cp -f ../test/cases_compact.mpac test/
|
|
||||||
|
|
||||||
sed -e 's/8\.00/9.00/' < msgpack_vc8.vcproj > msgpack_vc2008.vcproj
|
|
||||||
sed -e 's/9\.00/10.00/' -e 's/msgpack_vc8/msgpack_vc2008/' < msgpack_vc8.sln > msgpack_vc2008.sln
|
|
||||||
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
|
|
||||||
lib_LTLIBRARIES = libmsgpack.la
|
|
||||||
|
|
||||||
libmsgpack_la_SOURCES = \
|
|
||||||
unpack.c \
|
|
||||||
objectc.c \
|
|
||||||
version.c \
|
|
||||||
vrefbuffer.c \
|
|
||||||
zone.c
|
|
||||||
|
|
||||||
if ENABLE_CXX
|
|
||||||
libmsgpack_la_SOURCES += \
|
|
||||||
object.cpp
|
|
||||||
endif
|
|
||||||
|
|
||||||
# -version-info CURRENT:REVISION:AGE
|
|
||||||
libmsgpack_la_LDFLAGS = -version-info 3:0:0
|
|
||||||
|
|
||||||
|
|
||||||
# backward compatibility
|
|
||||||
lib_LTLIBRARIES += libmsgpackc.la
|
|
||||||
|
|
||||||
libmsgpackc_la_SOURCES = \
|
|
||||||
unpack.c \
|
|
||||||
objectc.c \
|
|
||||||
version.c \
|
|
||||||
vrefbuffer.c \
|
|
||||||
zone.c
|
|
||||||
|
|
||||||
libmsgpackc_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/version.h \
|
|
||||||
msgpack/vrefbuffer.h \
|
|
||||||
msgpack/zbuffer.h \
|
|
||||||
msgpack/pack.h \
|
|
||||||
msgpack/unpack.h \
|
|
||||||
msgpack/object.h \
|
|
||||||
msgpack/zone.h
|
|
||||||
|
|
||||||
if ENABLE_CXX
|
|
||||||
nobase_include_HEADERS += \
|
|
||||||
msgpack.hpp \
|
|
||||||
msgpack/sbuffer.hpp \
|
|
||||||
msgpack/vrefbuffer.hpp \
|
|
||||||
msgpack/zbuffer.hpp \
|
|
||||||
msgpack/pack.hpp \
|
|
||||||
msgpack/unpack.hpp \
|
|
||||||
msgpack/object.hpp \
|
|
||||||
msgpack/zone.hpp \
|
|
||||||
msgpack/type.hpp \
|
|
||||||
msgpack/type/bool.hpp \
|
|
||||||
msgpack/type/deque.hpp \
|
|
||||||
msgpack/type/float.hpp \
|
|
||||||
msgpack/type/fixint.hpp \
|
|
||||||
msgpack/type/int.hpp \
|
|
||||||
msgpack/type/list.hpp \
|
|
||||||
msgpack/type/map.hpp \
|
|
||||||
msgpack/type/nil.hpp \
|
|
||||||
msgpack/type/pair.hpp \
|
|
||||||
msgpack/type/raw.hpp \
|
|
||||||
msgpack/type/set.hpp \
|
|
||||||
msgpack/type/string.hpp \
|
|
||||||
msgpack/type/vector.hpp \
|
|
||||||
msgpack/type/tuple.hpp \
|
|
||||||
msgpack/type/define.hpp \
|
|
||||||
msgpack/type/tr1/unordered_map.hpp \
|
|
||||||
msgpack/type/tr1/unordered_set.hpp
|
|
||||||
endif
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
msgpack/version.h.in \
|
|
||||||
msgpack/zone.hpp.erb \
|
|
||||||
msgpack/type/define.hpp.erb \
|
|
||||||
msgpack/type/tuple.hpp.erb
|
|
||||||
|
|
||||||
|
|
||||||
doxygen_c:
|
|
||||||
cat ../Doxyfile > Doxyfile_c
|
|
||||||
echo "FILE_PATTERNS = *.h" >> Doxyfile_c
|
|
||||||
echo "OUTPUT_DIRECTORY = doc_c" >> Doxyfile_c
|
|
||||||
echo "PROJECT_NAME = \"MessagePack for C\"" >> Doxyfile_c
|
|
||||||
doxygen Doxyfile_c
|
|
||||||
|
|
||||||
doxygen_cpp:
|
|
||||||
cat ../Doxyfile > Doxyfile_cpp
|
|
||||||
echo "FILE_PATTERNS = *.hpp" >> Doxyfile_cpp
|
|
||||||
echo "OUTPUT_DIRECTORY = doc_cpp" >> Doxyfile_cpp
|
|
||||||
echo "PROJECT_NAME = \"MessagePack for C++\"" >> Doxyfile_cpp
|
|
||||||
doxygen Doxyfile_cpp
|
|
||||||
|
|
||||||
doxygen: doxygen_c doxygen_cpp
|
|
||||||
|
|
||||||
@@ -1,412 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_OBJECT_HPP__
|
|
||||||
#define MSGPACK_OBJECT_HPP__
|
|
||||||
|
|
||||||
#include "object.h"
|
|
||||||
#include "pack.hpp"
|
|
||||||
#include "zone.hpp"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <limits>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
class type_error : public std::bad_cast { };
|
|
||||||
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
enum object_type {
|
|
||||||
NIL = MSGPACK_OBJECT_NIL,
|
|
||||||
BOOLEAN = MSGPACK_OBJECT_BOOLEAN,
|
|
||||||
POSITIVE_INTEGER = MSGPACK_OBJECT_POSITIVE_INTEGER,
|
|
||||||
NEGATIVE_INTEGER = MSGPACK_OBJECT_NEGATIVE_INTEGER,
|
|
||||||
DOUBLE = MSGPACK_OBJECT_DOUBLE,
|
|
||||||
RAW = MSGPACK_OBJECT_RAW,
|
|
||||||
ARRAY = MSGPACK_OBJECT_ARRAY,
|
|
||||||
MAP = MSGPACK_OBJECT_MAP,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct object;
|
|
||||||
struct object_kv;
|
|
||||||
|
|
||||||
struct object_array {
|
|
||||||
uint32_t size;
|
|
||||||
object* ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object_map {
|
|
||||||
uint32_t size;
|
|
||||||
object_kv* ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object_raw {
|
|
||||||
uint32_t size;
|
|
||||||
const char* ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object {
|
|
||||||
union union_type {
|
|
||||||
bool boolean;
|
|
||||||
uint64_t u64;
|
|
||||||
int64_t i64;
|
|
||||||
double dec;
|
|
||||||
object_array array;
|
|
||||||
object_map map;
|
|
||||||
object_raw raw;
|
|
||||||
object_raw ref; // obsolete
|
|
||||||
};
|
|
||||||
|
|
||||||
type::object_type type;
|
|
||||||
union_type via;
|
|
||||||
|
|
||||||
bool is_nil() const { return type == type::NIL; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T as() const;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void convert(T* v) const;
|
|
||||||
|
|
||||||
object();
|
|
||||||
|
|
||||||
object(msgpack_object o);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
explicit object(const T& v);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
object(const T& v, zone* z);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
object& operator=(const T& v);
|
|
||||||
|
|
||||||
operator msgpack_object() const;
|
|
||||||
|
|
||||||
struct with_zone;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct implicit_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
implicit_type convert() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object_kv {
|
|
||||||
object key;
|
|
||||||
object val;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct object::with_zone : object {
|
|
||||||
with_zone(msgpack::zone* zone) : zone(zone) { }
|
|
||||||
msgpack::zone* zone;
|
|
||||||
private:
|
|
||||||
with_zone();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
bool operator==(const object x, const object y);
|
|
||||||
bool operator!=(const object x, const object y);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool operator==(const object x, const T& y);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool operator==(const T& y, const object x);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool operator!=(const object x, const T& y);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool operator!=(const T& y, const object x);
|
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& s, const object o);
|
|
||||||
|
|
||||||
|
|
||||||
// serialize operator
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
packer<Stream>& operator<< (packer<Stream>& o, const T& v);
|
|
||||||
|
|
||||||
// convert operator
|
|
||||||
template <typename T>
|
|
||||||
T& operator>> (object o, T& v);
|
|
||||||
|
|
||||||
// deconvert operator
|
|
||||||
template <typename T>
|
|
||||||
void operator<< (object::with_zone& o, const T& v);
|
|
||||||
|
|
||||||
|
|
||||||
struct object::implicit_type {
|
|
||||||
implicit_type(object o) : obj(o) { }
|
|
||||||
~implicit_type() { }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
operator T() { return obj.as<T>(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
object obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
template <typename Type>
|
|
||||||
class define : public Type {
|
|
||||||
public:
|
|
||||||
typedef Type msgpack_type;
|
|
||||||
typedef define<Type> define_type;
|
|
||||||
|
|
||||||
define() {}
|
|
||||||
define(const msgpack_type& v) : msgpack_type(v) {}
|
|
||||||
|
|
||||||
template <typename Packer>
|
|
||||||
void msgpack_pack(Packer& o) const
|
|
||||||
{
|
|
||||||
o << static_cast<const msgpack_type&>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void msgpack_unpack(object o)
|
|
||||||
{
|
|
||||||
o >> static_cast<msgpack_type&>(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
template <typename T>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack(const T& v)
|
|
||||||
{
|
|
||||||
*this << v;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object& operator>> (object o, object& v)
|
|
||||||
{
|
|
||||||
v = o;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T& operator>> (object o, T& v)
|
|
||||||
{
|
|
||||||
v.msgpack_unpack(o.convert());
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
|
|
||||||
{
|
|
||||||
v.msgpack_pack(o);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void operator<< (object::with_zone& o, const T& v)
|
|
||||||
{
|
|
||||||
v.msgpack_object(static_cast<object*>(&o), o.zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool operator==(const object x, const object y)
|
|
||||||
{
|
|
||||||
return msgpack_object_equal(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool operator==(const object x, const T& y)
|
|
||||||
try {
|
|
||||||
return x == object(y);
|
|
||||||
} catch (msgpack::type_error&) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const object x, const object y)
|
|
||||||
{ return !(x == y); }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool operator==(const T& y, const object x)
|
|
||||||
{ return x == y; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool operator!=(const object x, const T& y)
|
|
||||||
{ return !(x == y); }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool operator!=(const T& y, const object x)
|
|
||||||
{ return x != y; }
|
|
||||||
|
|
||||||
|
|
||||||
inline object::implicit_type object::convert() const
|
|
||||||
{
|
|
||||||
return implicit_type(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void object::convert(T* v) const
|
|
||||||
{
|
|
||||||
*this >> *v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T object::as() const
|
|
||||||
{
|
|
||||||
T v;
|
|
||||||
convert(&v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline object::object()
|
|
||||||
{
|
|
||||||
type = type::NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline object::object(const T& v)
|
|
||||||
{
|
|
||||||
*this << v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline object& object::operator=(const T& v)
|
|
||||||
{
|
|
||||||
*this = object(v);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
object::object(const T& v, zone* z)
|
|
||||||
{
|
|
||||||
with_zone oz(z);
|
|
||||||
oz << v;
|
|
||||||
type = oz.type;
|
|
||||||
via = oz.via;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline object::object(msgpack_object o)
|
|
||||||
{
|
|
||||||
// FIXME beter way?
|
|
||||||
::memcpy(this, &o, sizeof(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator<< (object& o, msgpack_object v)
|
|
||||||
{
|
|
||||||
// FIXME beter way?
|
|
||||||
::memcpy(&o, &v, sizeof(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object::operator msgpack_object() const
|
|
||||||
{
|
|
||||||
// FIXME beter way?
|
|
||||||
msgpack_object obj;
|
|
||||||
::memcpy(&obj, this, sizeof(obj));
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
template <typename T>
|
|
||||||
inline void convert(T& v, object o)
|
|
||||||
{
|
|
||||||
o.convert(&v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline void pack(packer<Stream>& o, const T& v)
|
|
||||||
{
|
|
||||||
o.pack(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline void pack_copy(packer<Stream>& o, T v)
|
|
||||||
{
|
|
||||||
pack(o, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
packer<Stream>& operator<< (packer<Stream>& o, const object& v)
|
|
||||||
{
|
|
||||||
switch(v.type) {
|
|
||||||
case type::NIL:
|
|
||||||
o.pack_nil();
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::BOOLEAN:
|
|
||||||
if(v.via.boolean) {
|
|
||||||
o.pack_true();
|
|
||||||
} else {
|
|
||||||
o.pack_false();
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::POSITIVE_INTEGER:
|
|
||||||
o.pack_uint64(v.via.u64);
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::NEGATIVE_INTEGER:
|
|
||||||
o.pack_int64(v.via.i64);
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::DOUBLE:
|
|
||||||
o.pack_double(v.via.dec);
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::RAW:
|
|
||||||
o.pack_raw(v.via.raw.size);
|
|
||||||
o.pack_raw_body(v.via.raw.ptr, v.via.raw.size);
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::ARRAY:
|
|
||||||
o.pack_array(v.via.array.size);
|
|
||||||
for(object* p(v.via.array.ptr),
|
|
||||||
* const pend(v.via.array.ptr + v.via.array.size);
|
|
||||||
p < pend; ++p) {
|
|
||||||
o << *p;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
|
|
||||||
case type::MAP:
|
|
||||||
o.pack_map(v.via.map.size);
|
|
||||||
for(object_kv* p(v.via.map.ptr),
|
|
||||||
* const pend(v.via.map.ptr + v.via.map.size);
|
|
||||||
p < pend; ++p) {
|
|
||||||
o << p->key;
|
|
||||||
o << p->val;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw type_error();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#include "msgpack/type.hpp"
|
|
||||||
|
|
||||||
#endif /* msgpack/object.hpp */
|
|
||||||
|
|
||||||
@@ -1,318 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ serializing routine
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_PACK_HPP__
|
|
||||||
#define MSGPACK_PACK_HPP__
|
|
||||||
|
|
||||||
#include "pack_define.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
class packer {
|
|
||||||
public:
|
|
||||||
packer(Stream* s);
|
|
||||||
packer(Stream& s);
|
|
||||||
~packer();
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <typename T>
|
|
||||||
packer<Stream>& pack(const T& v);
|
|
||||||
|
|
||||||
packer<Stream>& pack_uint8(uint8_t d);
|
|
||||||
packer<Stream>& pack_uint16(uint16_t d);
|
|
||||||
packer<Stream>& pack_uint32(uint32_t d);
|
|
||||||
packer<Stream>& pack_uint64(uint64_t d);
|
|
||||||
packer<Stream>& pack_int8(int8_t d);
|
|
||||||
packer<Stream>& pack_int16(int16_t d);
|
|
||||||
packer<Stream>& pack_int32(int32_t d);
|
|
||||||
packer<Stream>& pack_int64(int64_t d);
|
|
||||||
|
|
||||||
packer<Stream>& pack_fix_uint8(uint8_t d);
|
|
||||||
packer<Stream>& pack_fix_uint16(uint16_t d);
|
|
||||||
packer<Stream>& pack_fix_uint32(uint32_t d);
|
|
||||||
packer<Stream>& pack_fix_uint64(uint64_t d);
|
|
||||||
packer<Stream>& pack_fix_int8(int8_t d);
|
|
||||||
packer<Stream>& pack_fix_int16(int16_t d);
|
|
||||||
packer<Stream>& pack_fix_int32(int32_t d);
|
|
||||||
packer<Stream>& pack_fix_int64(int64_t d);
|
|
||||||
|
|
||||||
packer<Stream>& pack_short(short d);
|
|
||||||
packer<Stream>& pack_int(int d);
|
|
||||||
packer<Stream>& pack_long(long d);
|
|
||||||
packer<Stream>& pack_long_long(long long d);
|
|
||||||
packer<Stream>& pack_unsigned_short(unsigned short d);
|
|
||||||
packer<Stream>& pack_unsigned_int(unsigned int d);
|
|
||||||
packer<Stream>& pack_unsigned_long(unsigned long d);
|
|
||||||
packer<Stream>& pack_unsigned_long_long(unsigned long long d);
|
|
||||||
|
|
||||||
packer<Stream>& pack_float(float d);
|
|
||||||
packer<Stream>& pack_double(double d);
|
|
||||||
|
|
||||||
packer<Stream>& pack_nil();
|
|
||||||
packer<Stream>& pack_true();
|
|
||||||
packer<Stream>& pack_false();
|
|
||||||
|
|
||||||
packer<Stream>& pack_array(unsigned int n);
|
|
||||||
|
|
||||||
packer<Stream>& pack_map(unsigned int n);
|
|
||||||
|
|
||||||
packer<Stream>& pack_raw(size_t l);
|
|
||||||
packer<Stream>& pack_raw_body(const char* b, size_t l);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void _pack_uint8(Stream& x, uint8_t d);
|
|
||||||
static void _pack_uint16(Stream& x, uint16_t d);
|
|
||||||
static void _pack_uint32(Stream& x, uint32_t d);
|
|
||||||
static void _pack_uint64(Stream& x, uint64_t d);
|
|
||||||
static void _pack_int8(Stream& x, int8_t d);
|
|
||||||
static void _pack_int16(Stream& x, int16_t d);
|
|
||||||
static void _pack_int32(Stream& x, int32_t d);
|
|
||||||
static void _pack_int64(Stream& x, int64_t d);
|
|
||||||
|
|
||||||
static void _pack_fix_uint8(Stream& x, uint8_t d);
|
|
||||||
static void _pack_fix_uint16(Stream& x, uint16_t d);
|
|
||||||
static void _pack_fix_uint32(Stream& x, uint32_t d);
|
|
||||||
static void _pack_fix_uint64(Stream& x, uint64_t d);
|
|
||||||
static void _pack_fix_int8(Stream& x, int8_t d);
|
|
||||||
static void _pack_fix_int16(Stream& x, int16_t d);
|
|
||||||
static void _pack_fix_int32(Stream& x, int32_t d);
|
|
||||||
static void _pack_fix_int64(Stream& x, int64_t d);
|
|
||||||
|
|
||||||
static void _pack_short(Stream& x, short d);
|
|
||||||
static void _pack_int(Stream& x, int d);
|
|
||||||
static void _pack_long(Stream& x, long d);
|
|
||||||
static void _pack_long_long(Stream& x, long long d);
|
|
||||||
static void _pack_unsigned_short(Stream& x, unsigned short d);
|
|
||||||
static void _pack_unsigned_int(Stream& x, unsigned int d);
|
|
||||||
static void _pack_unsigned_long(Stream& x, unsigned long d);
|
|
||||||
static void _pack_unsigned_long_long(Stream& x, unsigned long long d);
|
|
||||||
|
|
||||||
static void _pack_float(Stream& x, float d);
|
|
||||||
static void _pack_double(Stream& x, double d);
|
|
||||||
|
|
||||||
static void _pack_nil(Stream& x);
|
|
||||||
static void _pack_true(Stream& x);
|
|
||||||
static void _pack_false(Stream& x);
|
|
||||||
|
|
||||||
static void _pack_array(Stream& x, unsigned int n);
|
|
||||||
|
|
||||||
static void _pack_map(Stream& x, unsigned int n);
|
|
||||||
|
|
||||||
static void _pack_raw(Stream& x, size_t l);
|
|
||||||
static void _pack_raw_body(Stream& x, const void* b, size_t l);
|
|
||||||
|
|
||||||
static void append_buffer(Stream& x, const unsigned char* buf, unsigned int len)
|
|
||||||
{ x.write((const char*)buf, len); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Stream& m_stream;
|
|
||||||
|
|
||||||
private:
|
|
||||||
packer();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline void pack(Stream* s, const T& v)
|
|
||||||
{
|
|
||||||
packer<Stream>(s).pack(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline void pack(Stream& s, const T& v)
|
|
||||||
{
|
|
||||||
packer<Stream>(s).pack(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define msgpack_pack_inline_func(name) \
|
|
||||||
template <typename Stream> \
|
|
||||||
inline void packer<Stream>::_pack ## name
|
|
||||||
|
|
||||||
#define msgpack_pack_inline_func_cint(name) \
|
|
||||||
template <typename Stream> \
|
|
||||||
inline void packer<Stream>::_pack ## name
|
|
||||||
|
|
||||||
#define msgpack_pack_inline_func_fixint(name) \
|
|
||||||
template <typename Stream> \
|
|
||||||
inline void packer<Stream>::_pack_fix ## name
|
|
||||||
|
|
||||||
#define msgpack_pack_user Stream&
|
|
||||||
|
|
||||||
#define msgpack_pack_append_buffer append_buffer
|
|
||||||
|
|
||||||
#include "pack_template.h"
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
packer<Stream>::packer(Stream* s) : m_stream(*s) { }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
packer<Stream>::packer(Stream& s) : m_stream(s) { }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
packer<Stream>::~packer() { }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_uint8(uint8_t d)
|
|
||||||
{ _pack_uint8(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_uint16(uint16_t d)
|
|
||||||
{ _pack_uint16(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_uint32(uint32_t d)
|
|
||||||
{ _pack_uint32(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_uint64(uint64_t d)
|
|
||||||
{ _pack_uint64(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_int8(int8_t d)
|
|
||||||
{ _pack_int8(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_int16(int16_t d)
|
|
||||||
{ _pack_int16(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_int32(int32_t d)
|
|
||||||
{ _pack_int32(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_int64(int64_t d)
|
|
||||||
{ _pack_int64(m_stream, d); return *this;}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_uint8(uint8_t d)
|
|
||||||
{ _pack_fix_uint8(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_uint16(uint16_t d)
|
|
||||||
{ _pack_fix_uint16(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_uint32(uint32_t d)
|
|
||||||
{ _pack_fix_uint32(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_uint64(uint64_t d)
|
|
||||||
{ _pack_fix_uint64(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_int8(int8_t d)
|
|
||||||
{ _pack_fix_int8(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_int16(int16_t d)
|
|
||||||
{ _pack_fix_int16(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_int32(int32_t d)
|
|
||||||
{ _pack_fix_int32(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_fix_int64(int64_t d)
|
|
||||||
{ _pack_fix_int64(m_stream, d); return *this;}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_short(short d)
|
|
||||||
{ _pack_short(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_int(int d)
|
|
||||||
{ _pack_int(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_long(long d)
|
|
||||||
{ _pack_long(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_long_long(long long d)
|
|
||||||
{ _pack_long_long(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_unsigned_short(unsigned short d)
|
|
||||||
{ _pack_unsigned_short(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_unsigned_int(unsigned int d)
|
|
||||||
{ _pack_unsigned_int(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_unsigned_long(unsigned long d)
|
|
||||||
{ _pack_unsigned_long(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_unsigned_long_long(unsigned long long d)
|
|
||||||
{ _pack_unsigned_long_long(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_float(float d)
|
|
||||||
{ _pack_float(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_double(double d)
|
|
||||||
{ _pack_double(m_stream, d); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_nil()
|
|
||||||
{ _pack_nil(m_stream); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_true()
|
|
||||||
{ _pack_true(m_stream); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_false()
|
|
||||||
{ _pack_false(m_stream); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_array(unsigned int n)
|
|
||||||
{ _pack_array(m_stream, n); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_map(unsigned int n)
|
|
||||||
{ _pack_map(m_stream, n); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_raw(size_t l)
|
|
||||||
{ _pack_raw(m_stream, l); return *this; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& packer<Stream>::pack_raw_body(const char* b, size_t l)
|
|
||||||
{ _pack_raw_body(m_stream, b, l); return *this; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/pack.hpp */
|
|
||||||
|
|
||||||
@@ -1,112 +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_HPP__
|
|
||||||
#define MSGPACK_SBUFFER_HPP__
|
|
||||||
|
|
||||||
#include "sbuffer.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
class sbuffer : public msgpack_sbuffer {
|
|
||||||
public:
|
|
||||||
sbuffer(size_t initsz = MSGPACK_SBUFFER_INIT_SIZE)
|
|
||||||
{
|
|
||||||
if(initsz == 0) {
|
|
||||||
base::data = NULL;
|
|
||||||
} else {
|
|
||||||
base::data = (char*)::malloc(initsz);
|
|
||||||
if(!base::data) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
base::size = 0;
|
|
||||||
base::alloc = initsz;
|
|
||||||
}
|
|
||||||
|
|
||||||
~sbuffer()
|
|
||||||
{
|
|
||||||
::free(base::data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void write(const char* buf, unsigned int len)
|
|
||||||
{
|
|
||||||
if(base::alloc - base::size < len) {
|
|
||||||
expand_buffer(len);
|
|
||||||
}
|
|
||||||
memcpy(base::data + base::size, buf, len);
|
|
||||||
base::size += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* data()
|
|
||||||
{
|
|
||||||
return base::data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* data() const
|
|
||||||
{
|
|
||||||
return base::data;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
return base::size;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* release()
|
|
||||||
{
|
|
||||||
return msgpack_sbuffer_release(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
msgpack_sbuffer_clear(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void expand_buffer(size_t len)
|
|
||||||
{
|
|
||||||
size_t nsize = (base::alloc > 0) ?
|
|
||||||
base::alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE;
|
|
||||||
|
|
||||||
while(nsize < base::size + len) { nsize *= 2; }
|
|
||||||
|
|
||||||
void* tmp = realloc(base::data, nsize);
|
|
||||||
if(!tmp) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
|
|
||||||
base::data = (char*)tmp;
|
|
||||||
base::alloc = nsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef msgpack_sbuffer base;
|
|
||||||
|
|
||||||
private:
|
|
||||||
sbuffer(const sbuffer&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/sbuffer.hpp */
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#include "type/bool.hpp"
|
|
||||||
#include "type/deque.hpp"
|
|
||||||
#include "type/fixint.hpp"
|
|
||||||
#include "type/float.hpp"
|
|
||||||
#include "type/int.hpp"
|
|
||||||
#include "type/list.hpp"
|
|
||||||
#include "type/map.hpp"
|
|
||||||
#include "type/nil.hpp"
|
|
||||||
#include "type/pair.hpp"
|
|
||||||
#include "type/raw.hpp"
|
|
||||||
#include "type/set.hpp"
|
|
||||||
#include "type/string.hpp"
|
|
||||||
#include "type/vector.hpp"
|
|
||||||
#include "type/tuple.hpp"
|
|
||||||
#include "type/define.hpp"
|
|
||||||
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_DEFINE_HPP__
|
|
||||||
#define MSGPACK_TYPE_DEFINE_HPP__
|
|
||||||
|
|
||||||
#define MSGPACK_DEFINE(...) \
|
|
||||||
template <typename Packer> \
|
|
||||||
void msgpack_pack(Packer& pk) const \
|
|
||||||
{ \
|
|
||||||
msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
|
|
||||||
} \
|
|
||||||
void msgpack_unpack(msgpack::object o) \
|
|
||||||
{ \
|
|
||||||
msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
|
|
||||||
}\
|
|
||||||
template <typename MSGPACK_OBJECT> \
|
|
||||||
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \
|
|
||||||
{ \
|
|
||||||
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
namespace type {
|
|
||||||
|
|
||||||
|
|
||||||
<% GENERATION_LIMIT = 31 %>
|
|
||||||
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
|
|
||||||
struct define;
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct define<> {
|
|
||||||
typedef define<> value_type;
|
|
||||||
typedef tuple<> tuple_type;
|
|
||||||
template <typename Packer>
|
|
||||||
void msgpack_pack(Packer& pk) const
|
|
||||||
{
|
|
||||||
pk.pack_array(1);
|
|
||||||
}
|
|
||||||
void msgpack_unpack(msgpack::object o)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
}
|
|
||||||
void msgpack_object(msgpack::object* o, msgpack::zone* z) const
|
|
||||||
{
|
|
||||||
o->type = type::ARRAY;
|
|
||||||
o->via.array.ptr = NULL;
|
|
||||||
o->via.array.size = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
|
|
||||||
typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
|
|
||||||
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type;
|
|
||||||
define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) :
|
|
||||||
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
|
|
||||||
template <typename Packer>
|
|
||||||
void msgpack_pack(Packer& pk) const
|
|
||||||
{
|
|
||||||
pk.pack_array(<%=i+1%>);
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
pk.pack(a<%=j%>);<%}%>
|
|
||||||
}
|
|
||||||
void msgpack_unpack(msgpack::object o)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
const size_t size = o.via.array.size;
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
if(size <= <%=j%>) { return; } o.via.array.ptr[<%=j%>].convert(&a<%=j%>);<%}%>
|
|
||||||
}
|
|
||||||
void msgpack_object(msgpack::object* o, msgpack::zone* z) const
|
|
||||||
{
|
|
||||||
o->type = type::ARRAY;
|
|
||||||
o->via.array.ptr = (object*)z->malloc(sizeof(object)*<%=i+1%>);
|
|
||||||
o->via.array.size = <%=i+1%>;
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%>
|
|
||||||
}
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
A<%=j%>& a<%=j%>;<%}%>
|
|
||||||
};
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
inline define<> make_define()
|
|
||||||
{
|
|
||||||
return define<>();
|
|
||||||
}
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>)
|
|
||||||
{
|
|
||||||
return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
} // namespace type
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* msgpack/type/define.hpp */
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_DEQUE_HPP__
|
|
||||||
#define MSGPACK_TYPE_DEQUE_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <deque>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::deque<T>& operator>> (object o, std::deque<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
v.resize(o.via.array.size);
|
|
||||||
object* p = o.via.array.ptr;
|
|
||||||
object* const pend = o.via.array.ptr + o.via.array.size;
|
|
||||||
typename std::deque<T>::iterator it = v.begin();
|
|
||||||
for(; p < pend; ++p, ++it) {
|
|
||||||
p->convert(&*it);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::deque<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::deque<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::deque<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::deque<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/deque.hpp */
|
|
||||||
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2020 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_FIXINT_HPP__
|
|
||||||
#define MSGPACK_TYPE_FIXINT_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include "msgpack/type/int.hpp"
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct fix_int {
|
|
||||||
fix_int() : value(0) { }
|
|
||||||
fix_int(T value) : value(value) { }
|
|
||||||
|
|
||||||
operator T() const { return value; }
|
|
||||||
|
|
||||||
T get() const { return value; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
T value;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef fix_int<uint8_t> fix_uint8;
|
|
||||||
typedef fix_int<uint16_t> fix_uint16;
|
|
||||||
typedef fix_int<uint32_t> fix_uint32;
|
|
||||||
typedef fix_int<uint64_t> fix_uint64;
|
|
||||||
|
|
||||||
typedef fix_int<int8_t> fix_int8;
|
|
||||||
typedef fix_int<int16_t> fix_int16;
|
|
||||||
typedef fix_int<int32_t> fix_int32;
|
|
||||||
typedef fix_int<int64_t> fix_int64;
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace type
|
|
||||||
|
|
||||||
|
|
||||||
inline type::fix_int8& operator>> (object o, type::fix_int8& v)
|
|
||||||
{ v = type::detail::convert_integer<int8_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_int16& operator>> (object o, type::fix_int16& v)
|
|
||||||
{ v = type::detail::convert_integer<int16_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_int32& operator>> (object o, type::fix_int32& v)
|
|
||||||
{ v = type::detail::convert_integer<int32_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_int64& operator>> (object o, type::fix_int64& v)
|
|
||||||
{ v = type::detail::convert_integer<int64_t>(o); return v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline type::fix_uint8& operator>> (object o, type::fix_uint8& v)
|
|
||||||
{ v = type::detail::convert_integer<uint8_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_uint16& operator>> (object o, type::fix_uint16& v)
|
|
||||||
{ v = type::detail::convert_integer<uint16_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_uint32& operator>> (object o, type::fix_uint32& v)
|
|
||||||
{ v = type::detail::convert_integer<uint32_t>(o); return v; }
|
|
||||||
|
|
||||||
inline type::fix_uint64& operator>> (object o, type::fix_uint64& v)
|
|
||||||
{ v = type::detail::convert_integer<uint64_t>(o); return v; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v)
|
|
||||||
{ o.pack_fix_int8(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int16& v)
|
|
||||||
{ o.pack_fix_int16(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int32& v)
|
|
||||||
{ o.pack_fix_int32(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v)
|
|
||||||
{ o.pack_fix_int64(v); return o; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v)
|
|
||||||
{ o.pack_fix_uint8(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint16& v)
|
|
||||||
{ o.pack_fix_uint16(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint32& v)
|
|
||||||
{ o.pack_fix_uint32(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v)
|
|
||||||
{ o.pack_fix_uint64(v); return o; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_int8 v)
|
|
||||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_int16 v)
|
|
||||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_int32 v)
|
|
||||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_int64 v)
|
|
||||||
{ v.get() < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v.get() : o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_uint8 v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_uint16 v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_uint32 v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, type::fix_uint64 v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v.get(); }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_int8 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_int16 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_int32 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_int64 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_uint8 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_uint16 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_uint32 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, type::fix_uint64 v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/fixint.hpp */
|
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_FLOAT_HPP__
|
|
||||||
#define MSGPACK_TYPE_FLOAT_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME check overflow, underflow
|
|
||||||
|
|
||||||
|
|
||||||
inline float& operator>> (object o, float& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::DOUBLE) { throw type_error(); }
|
|
||||||
v = (float)o.via.dec;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const float& v)
|
|
||||||
{
|
|
||||||
o.pack_float(v);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline double& operator>> (object o, double& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::DOUBLE) { throw type_error(); }
|
|
||||||
v = o.via.dec;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
|
|
||||||
{
|
|
||||||
o.pack_double(v);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object& o, float v)
|
|
||||||
{
|
|
||||||
o.type = type::DOUBLE;
|
|
||||||
o.via.dec = (double)v;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator<< (object& o, double v)
|
|
||||||
{
|
|
||||||
o.type = type::DOUBLE;
|
|
||||||
o.via.dec = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, float v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, double v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/float.hpp */
|
|
||||||
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_INT_HPP__
|
|
||||||
#define MSGPACK_TYPE_INT_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
namespace detail {
|
|
||||||
template <typename T, bool Signed>
|
|
||||||
struct convert_integer_sign;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct convert_integer_sign<T, true> {
|
|
||||||
static inline T convert(object o) {
|
|
||||||
if(o.type == type::POSITIVE_INTEGER) {
|
|
||||||
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
|
|
||||||
{ throw type_error(); }
|
|
||||||
return (T)o.via.u64;
|
|
||||||
} else if(o.type == type::NEGATIVE_INTEGER) {
|
|
||||||
if(o.via.i64 < (int64_t)std::numeric_limits<T>::min())
|
|
||||||
{ throw type_error(); }
|
|
||||||
return (T)o.via.i64;
|
|
||||||
}
|
|
||||||
throw type_error();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct convert_integer_sign<T, false> {
|
|
||||||
static inline T convert(object o) {
|
|
||||||
if(o.type == type::POSITIVE_INTEGER) {
|
|
||||||
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
|
|
||||||
{ throw type_error(); }
|
|
||||||
return (T)o.via.u64;
|
|
||||||
}
|
|
||||||
throw type_error();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static inline T convert_integer(object o)
|
|
||||||
{
|
|
||||||
return detail::convert_integer_sign<T, std::numeric_limits<T>::is_signed>::convert(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace type
|
|
||||||
|
|
||||||
|
|
||||||
inline signed char& operator>> (object o, signed char& v)
|
|
||||||
{ v = type::detail::convert_integer<signed char>(o); return v; }
|
|
||||||
|
|
||||||
inline signed short& operator>> (object o, signed short& v)
|
|
||||||
{ v = type::detail::convert_integer<signed short>(o); return v; }
|
|
||||||
|
|
||||||
inline signed int& operator>> (object o, signed int& v)
|
|
||||||
{ v = type::detail::convert_integer<signed int>(o); return v; }
|
|
||||||
|
|
||||||
inline signed long& operator>> (object o, signed long& v)
|
|
||||||
{ v = type::detail::convert_integer<signed long>(o); return v; }
|
|
||||||
|
|
||||||
inline signed long long& operator>> (object o, signed long long& v)
|
|
||||||
{ v = type::detail::convert_integer<signed long long>(o); return v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline unsigned char& operator>> (object o, unsigned char& v)
|
|
||||||
{ v = type::detail::convert_integer<unsigned char>(o); return v; }
|
|
||||||
|
|
||||||
inline unsigned short& operator>> (object o, unsigned short& v)
|
|
||||||
{ v = type::detail::convert_integer<unsigned short>(o); return v; }
|
|
||||||
|
|
||||||
inline unsigned int& operator>> (object o, unsigned int& v)
|
|
||||||
{ v = type::detail::convert_integer<unsigned int>(o); return v; }
|
|
||||||
|
|
||||||
inline unsigned long& operator>> (object o, unsigned long& v)
|
|
||||||
{ v = type::detail::convert_integer<unsigned long>(o); return v; }
|
|
||||||
|
|
||||||
inline unsigned long long& operator>> (object o, unsigned long long& v)
|
|
||||||
{ v = type::detail::convert_integer<unsigned long long>(o); return v; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const signed char& v)
|
|
||||||
{ o.pack_int8(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const signed short& v)
|
|
||||||
{ o.pack_short(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const signed int& v)
|
|
||||||
{ o.pack_int(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long& v)
|
|
||||||
{ o.pack_long(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long long& v)
|
|
||||||
{ o.pack_long_long(v); return o; }
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned char& v)
|
|
||||||
{ o.pack_uint8(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned short& v)
|
|
||||||
{ o.pack_unsigned_short(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned int& v)
|
|
||||||
{ o.pack_unsigned_int(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long& v)
|
|
||||||
{ o.pack_unsigned_long(v); return o; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& v)
|
|
||||||
{ o.pack_unsigned_long_long(v); return o; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object& o, signed char v)
|
|
||||||
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, signed short v)
|
|
||||||
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, signed int v)
|
|
||||||
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, signed long v)
|
|
||||||
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, signed long long v)
|
|
||||||
{ v < 0 ? o.type = type::NEGATIVE_INTEGER, o.via.i64 = v : o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object& o, unsigned char v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, unsigned short v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, unsigned int v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, unsigned long v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
inline void operator<< (object& o, unsigned long long v)
|
|
||||||
{ o.type = type::POSITIVE_INTEGER, o.via.u64 = v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, signed char v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, signed short v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, signed int v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, signed long v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, signed long long v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, unsigned char v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, unsigned short v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, unsigned int v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, unsigned long v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, unsigned long long v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/int.hpp */
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_LIST_HPP__
|
|
||||||
#define MSGPACK_TYPE_LIST_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::list<T>& operator>> (object o, std::list<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
v.resize(o.via.array.size);
|
|
||||||
object* p = o.via.array.ptr;
|
|
||||||
object* const pend = o.via.array.ptr + o.via.array.size;
|
|
||||||
typename std::list<T>::iterator it = v.begin();
|
|
||||||
for(; p < pend; ++p, ++it) {
|
|
||||||
p->convert(&*it);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::list<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::list<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::list<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::list<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/list.hpp */
|
|
||||||
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_MAP_HPP__
|
|
||||||
#define MSGPACK_TYPE_MAP_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
class assoc_vector : public std::vector< std::pair<K, V> > {};
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template <typename K, typename V>
|
|
||||||
struct pair_first_less {
|
|
||||||
bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
|
|
||||||
{ return x.first < y.first; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace type
|
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline type::assoc_vector<K,V>& operator>> (object o, type::assoc_vector<K,V>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::MAP) { throw type_error(); }
|
|
||||||
v.resize(o.via.map.size);
|
|
||||||
object_kv* p = o.via.map.ptr;
|
|
||||||
object_kv* const pend = o.via.map.ptr + o.via.map.size;
|
|
||||||
std::pair<K, V>* it(&v.front());
|
|
||||||
for(; p < pend; ++p, ++it) {
|
|
||||||
p->key.convert(&it->first);
|
|
||||||
p->val.convert(&it->second);
|
|
||||||
}
|
|
||||||
std::sort(v.begin(), v.end(), type::detail::pair_first_less<K,V>());
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename K, typename V>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v)
|
|
||||||
{
|
|
||||||
o.pack_map(v.size());
|
|
||||||
for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(it->first);
|
|
||||||
o.pack(it->second);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void operator<< (object::with_zone& o, const type::assoc_vector<K,V>& v)
|
|
||||||
{
|
|
||||||
o.type = type::MAP;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.map.ptr = NULL;
|
|
||||||
o.via.map.size = 0;
|
|
||||||
} else {
|
|
||||||
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
|
|
||||||
object_kv* const pend = p + v.size();
|
|
||||||
o.via.map.ptr = p;
|
|
||||||
o.via.map.size = v.size();
|
|
||||||
typename type::assoc_vector<K,V>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
p->key = object(it->first, o.zone);
|
|
||||||
p->val = object(it->second, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline std::map<K, V> operator>> (object o, std::map<K, V>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::MAP) { throw type_error(); }
|
|
||||||
object_kv* p(o.via.map.ptr);
|
|
||||||
object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
|
||||||
for(; p != pend; ++p) {
|
|
||||||
K key;
|
|
||||||
p->key.convert(&key);
|
|
||||||
typename std::map<K,V>::iterator it(v.lower_bound(key));
|
|
||||||
if(it != v.end() && !(key < it->first)) {
|
|
||||||
p->val.convert(&it->second);
|
|
||||||
} else {
|
|
||||||
V val;
|
|
||||||
p->val.convert(&val);
|
|
||||||
v.insert(it, std::pair<K,V>(key, val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename K, typename V>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v)
|
|
||||||
{
|
|
||||||
o.pack_map(v.size());
|
|
||||||
for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(it->first);
|
|
||||||
o.pack(it->second);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::map<K,V>& v)
|
|
||||||
{
|
|
||||||
o.type = type::MAP;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.map.ptr = NULL;
|
|
||||||
o.via.map.size = 0;
|
|
||||||
} else {
|
|
||||||
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
|
|
||||||
object_kv* const pend = p + v.size();
|
|
||||||
o.via.map.ptr = p;
|
|
||||||
o.via.map.size = v.size();
|
|
||||||
typename std::map<K,V>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
p->key = object(it->first, o.zone);
|
|
||||||
p->val = object(it->second, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::MAP) { throw type_error(); }
|
|
||||||
object_kv* p(o.via.map.ptr);
|
|
||||||
object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
|
||||||
for(; p != pend; ++p) {
|
|
||||||
std::pair<K, V> value;
|
|
||||||
p->key.convert(&value.first);
|
|
||||||
p->val.convert(&value.second);
|
|
||||||
v.insert(value);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename K, typename V>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v)
|
|
||||||
{
|
|
||||||
o.pack_map(v.size());
|
|
||||||
for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(it->first);
|
|
||||||
o.pack(it->second);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::multimap<K,V>& v)
|
|
||||||
{
|
|
||||||
o.type = type::MAP;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.map.ptr = NULL;
|
|
||||||
o.via.map.size = 0;
|
|
||||||
} else {
|
|
||||||
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
|
|
||||||
object_kv* const pend = p + v.size();
|
|
||||||
o.via.map.ptr = p;
|
|
||||||
o.via.map.size = v.size();
|
|
||||||
typename std::multimap<K,V>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
p->key = object(it->first, o.zone);
|
|
||||||
p->val = object(it->second, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/map.hpp */
|
|
||||||
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_RAW_HPP__
|
|
||||||
#define MSGPACK_TYPE_RAW_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <string.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
|
|
||||||
struct raw_ref {
|
|
||||||
raw_ref() : size(0), ptr(NULL) {}
|
|
||||||
raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {}
|
|
||||||
|
|
||||||
uint32_t size;
|
|
||||||
const char* ptr;
|
|
||||||
|
|
||||||
std::string str() const { return std::string(ptr, size); }
|
|
||||||
|
|
||||||
bool operator== (const raw_ref& x) const
|
|
||||||
{
|
|
||||||
return size == x.size && memcmp(ptr, x.ptr, size) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!= (const raw_ref& x) const
|
|
||||||
{
|
|
||||||
return !(*this != x);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator< (const raw_ref& x) const
|
|
||||||
{
|
|
||||||
if(size == x.size) { return memcmp(ptr, x.ptr, size) < 0; }
|
|
||||||
else { return size < x.size; }
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator> (const raw_ref& x) const
|
|
||||||
{
|
|
||||||
if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; }
|
|
||||||
else { return size > x.size; }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace type
|
|
||||||
|
|
||||||
|
|
||||||
inline type::raw_ref& operator>> (object o, type::raw_ref& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::RAW) { throw type_error(); }
|
|
||||||
v.ptr = o.via.raw.ptr;
|
|
||||||
v.size = o.via.raw.size;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v)
|
|
||||||
{
|
|
||||||
o.pack_raw(v.size);
|
|
||||||
o.pack_raw_body(v.ptr, v.size);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator<< (object& o, const type::raw_ref& v)
|
|
||||||
{
|
|
||||||
o.type = type::RAW;
|
|
||||||
o.via.raw.ptr = v.ptr;
|
|
||||||
o.via.raw.size = v.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void operator<< (object::with_zone& o, const type::raw_ref& v)
|
|
||||||
{ static_cast<object&>(o) << v; }
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/raw.hpp */
|
|
||||||
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_SET_HPP__
|
|
||||||
#define MSGPACK_TYPE_SET_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::set<T>& operator>> (object o, std::set<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
object* p = o.via.array.ptr + o.via.array.size;
|
|
||||||
object* const pbegin = o.via.array.ptr;
|
|
||||||
while(p > pbegin) {
|
|
||||||
--p;
|
|
||||||
v.insert(p->as<T>());
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::set<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::set<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::set<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::set<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::multiset<T>& operator>> (object o, std::multiset<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
object* p = o.via.array.ptr + o.via.array.size;
|
|
||||||
object* const pbegin = o.via.array.ptr;
|
|
||||||
while(p > pbegin) {
|
|
||||||
--p;
|
|
||||||
v.insert(p->as<T>());
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multiset<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::multiset<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::multiset<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::multiset<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/set.hpp */
|
|
||||||
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__
|
|
||||||
#define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <tr1/unordered_map>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline std::tr1::unordered_map<K, V> operator>> (object o, std::tr1::unordered_map<K, V>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::MAP) { throw type_error(); }
|
|
||||||
object_kv* p(o.via.map.ptr);
|
|
||||||
object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
|
||||||
for(; p != pend; ++p) {
|
|
||||||
K key;
|
|
||||||
p->key.convert(&key);
|
|
||||||
p->val.convert(&v[key]);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename K, typename V>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_map<K,V>& v)
|
|
||||||
{
|
|
||||||
o.pack_map(v.size());
|
|
||||||
for(typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(it->first);
|
|
||||||
o.pack(it->second);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::tr1::unordered_map<K,V>& v)
|
|
||||||
{
|
|
||||||
o.type = type::MAP;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.map.ptr = NULL;
|
|
||||||
o.via.map.size = 0;
|
|
||||||
} else {
|
|
||||||
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
|
|
||||||
object_kv* const pend = p + v.size();
|
|
||||||
o.via.map.ptr = p;
|
|
||||||
o.via.map.size = v.size();
|
|
||||||
typename std::tr1::unordered_map<K,V>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
p->key = object(it->first, o.zone);
|
|
||||||
p->val = object(it->second, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline std::tr1::unordered_multimap<K, V> operator>> (object o, std::tr1::unordered_multimap<K, V>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::MAP) { throw type_error(); }
|
|
||||||
object_kv* p(o.via.map.ptr);
|
|
||||||
object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
|
||||||
for(; p != pend; ++p) {
|
|
||||||
std::pair<K, V> value;
|
|
||||||
p->key.convert(&value.first);
|
|
||||||
p->val.convert(&value.second);
|
|
||||||
v.insert(value);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename K, typename V>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multimap<K,V>& v)
|
|
||||||
{
|
|
||||||
o.pack_map(v.size());
|
|
||||||
for(typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(it->first);
|
|
||||||
o.pack(it->second);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename K, typename V>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap<K,V>& v)
|
|
||||||
{
|
|
||||||
o.type = type::MAP;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.map.ptr = NULL;
|
|
||||||
o.via.map.size = 0;
|
|
||||||
} else {
|
|
||||||
object_kv* p = (object_kv*)o.zone->malloc(sizeof(object_kv)*v.size());
|
|
||||||
object_kv* const pend = p + v.size();
|
|
||||||
o.via.map.ptr = p;
|
|
||||||
o.via.map.size = v.size();
|
|
||||||
typename std::tr1::unordered_multimap<K,V>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
p->key = object(it->first, o.zone);
|
|
||||||
p->val = object(it->second, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/map.hpp */
|
|
||||||
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__
|
|
||||||
#define MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <tr1/unordered_set>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::tr1::unordered_set<T>& operator>> (object o, std::tr1::unordered_set<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
object* p = o.via.array.ptr + o.via.array.size;
|
|
||||||
object* const pbegin = o.via.array.ptr;
|
|
||||||
while(p > pbegin) {
|
|
||||||
--p;
|
|
||||||
v.insert(p->as<T>());
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_set<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::tr1::unordered_set<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::tr1::unordered_set<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::tr1::unordered_set<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::tr1::unordered_multiset<T>& operator>> (object o, std::tr1::unordered_multiset<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
object* p = o.via.array.ptr + o.via.array.size;
|
|
||||||
object* const pbegin = o.via.array.ptr;
|
|
||||||
while(p > pbegin) {
|
|
||||||
--p;
|
|
||||||
v.insert(p->as<T>());
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::tr1::unordered_multiset<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::tr1::unordered_multiset<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/set.hpp */
|
|
||||||
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_TUPLE_HPP__
|
|
||||||
#define MSGPACK_TYPE_TUPLE_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
namespace type {
|
|
||||||
|
|
||||||
// FIXME operator==
|
|
||||||
// FIXME operator!=
|
|
||||||
<% GENERATION_LIMIT = 31 %>
|
|
||||||
|
|
||||||
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
|
|
||||||
struct tuple;
|
|
||||||
|
|
||||||
template <typename Tuple, int N>
|
|
||||||
struct tuple_element;
|
|
||||||
|
|
||||||
template <typename Tuple, int N>
|
|
||||||
struct const_tuple_element;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct tuple_type {
|
|
||||||
typedef T type;
|
|
||||||
typedef T value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef const T& transparent_reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct tuple_type<T&> {
|
|
||||||
typedef T type;
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef T& transparent_reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct tuple_type<const T&> {
|
|
||||||
typedef T type;
|
|
||||||
typedef T& value_type;
|
|
||||||
typedef T& reference;
|
|
||||||
typedef const T& const_reference;
|
|
||||||
typedef const T& transparent_reference;
|
|
||||||
};
|
|
||||||
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
|
||||||
struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
|
|
||||||
tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : _x(x.a<%=j%>) {}
|
|
||||||
typename tuple_type<A<%=j%>>::reference get() { return _x; }
|
|
||||||
typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
|
|
||||||
private:
|
|
||||||
typename tuple_type<A<%=j%>>::reference _x;
|
|
||||||
};
|
|
||||||
<%}%>
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
|
||||||
struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
|
|
||||||
const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : _x(x.a<%=j%>) {}
|
|
||||||
typename tuple_type<A<%=j%>>::const_reference get() const { return _x; }
|
|
||||||
private:
|
|
||||||
typename tuple_type<A<%=j%>>::const_reference _x;
|
|
||||||
};
|
|
||||||
<%}%>
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct tuple<> {
|
|
||||||
tuple() {}
|
|
||||||
tuple(object o) { o.convert(this); }
|
|
||||||
typedef tuple<> value_type;
|
|
||||||
};
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
|
|
||||||
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
|
|
||||||
tuple() {}
|
|
||||||
tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) :
|
|
||||||
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
|
|
||||||
tuple(object o) { o.convert(this); }
|
|
||||||
template <int N> typename tuple_element<value_type, N>::reference get()
|
|
||||||
{ return tuple_element<value_type, N>(*this).get(); }
|
|
||||||
template <int N> typename const_tuple_element<value_type, N>::const_reference get() const
|
|
||||||
{ return const_tuple_element<value_type, N>(*this).get(); }
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
A<%=j%> a<%=j%>;<%}%>
|
|
||||||
};
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
inline tuple<> make_tuple()
|
|
||||||
{
|
|
||||||
return tuple<>();
|
|
||||||
}
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>)
|
|
||||||
{
|
|
||||||
return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
} // namespace type
|
|
||||||
|
|
||||||
|
|
||||||
inline type::tuple<>& operator>> (
|
|
||||||
object o,
|
|
||||||
type::tuple<>& v) {
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> (
|
|
||||||
object o,
|
|
||||||
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
if(o.via.array.size < <%=i+1%>) { throw type_error(); }
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(&v.template get<<%=j%>>());<%}%>
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
const packer<Stream>& operator<< (
|
|
||||||
packer<Stream>& o,
|
|
||||||
const type::tuple<>& v) {
|
|
||||||
o.pack_array(0);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
const packer<Stream>& operator<< (
|
|
||||||
packer<Stream>& o,
|
|
||||||
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
|
||||||
o.pack_array(<%=i+1%>);
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
o.pack(v.template get<<%=j%>>());<%}%>
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
inline void operator<< (
|
|
||||||
object::with_zone& o,
|
|
||||||
const type::tuple<>& v) {
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
}
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
inline void operator<< (
|
|
||||||
object::with_zone& o,
|
|
||||||
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
o.via.array.ptr = (object*)o.zone->malloc(sizeof(object)*<%=i+1%>);
|
|
||||||
o.via.array.size = <%=i+1%>;
|
|
||||||
<%0.upto(i) {|j|%>
|
|
||||||
o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%>
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
|
|
||||||
//inline std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v) {
|
|
||||||
// return o << "[]";
|
|
||||||
//}
|
|
||||||
//<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
//template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
//inline std::ostream& operator<< (std::ostream& o,
|
|
||||||
// const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
|
||||||
// return o << "["
|
|
||||||
// <%0.upto(i) {|j|%>
|
|
||||||
// <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%>
|
|
||||||
// << "]";
|
|
||||||
//}
|
|
||||||
//<%}%>
|
|
||||||
|
|
||||||
#endif /* msgpack/type/tuple.hpp */
|
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ static resolution routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_TYPE_VECTOR_HPP__
|
|
||||||
#define MSGPACK_TYPE_VECTOR_HPP__
|
|
||||||
|
|
||||||
#include "msgpack/object.hpp"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::vector<T>& operator>> (object o, std::vector<T>& v)
|
|
||||||
{
|
|
||||||
if(o.type != type::ARRAY) { throw type_error(); }
|
|
||||||
v.resize(o.via.array.size);
|
|
||||||
if(o.via.array.size > 0) {
|
|
||||||
object* p = o.via.array.ptr;
|
|
||||||
object* const pend = o.via.array.ptr + o.via.array.size;
|
|
||||||
T* it = &v[0];
|
|
||||||
do {
|
|
||||||
p->convert(it);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Stream, typename T>
|
|
||||||
inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v)
|
|
||||||
{
|
|
||||||
o.pack_array(v.size());
|
|
||||||
for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
|
|
||||||
it != it_end; ++it) {
|
|
||||||
o.pack(*it);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void operator<< (object::with_zone& o, const std::vector<T>& v)
|
|
||||||
{
|
|
||||||
o.type = type::ARRAY;
|
|
||||||
if(v.empty()) {
|
|
||||||
o.via.array.ptr = NULL;
|
|
||||||
o.via.array.size = 0;
|
|
||||||
} else {
|
|
||||||
object* p = (object*)o.zone->malloc(sizeof(object)*v.size());
|
|
||||||
object* const pend = p + v.size();
|
|
||||||
o.via.array.ptr = p;
|
|
||||||
o.via.array.size = v.size();
|
|
||||||
typename std::vector<T>::const_iterator it(v.begin());
|
|
||||||
do {
|
|
||||||
*p = object(*it, o.zone);
|
|
||||||
++p;
|
|
||||||
++it;
|
|
||||||
} while(p < pend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/type/vector.hpp */
|
|
||||||
|
|
||||||
@@ -1,374 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ deserializing routine
|
|
||||||
//
|
|
||||||
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_UNPACK_HPP__
|
|
||||||
#define MSGPACK_UNPACK_HPP__
|
|
||||||
|
|
||||||
#include "unpack.h"
|
|
||||||
#include "object.hpp"
|
|
||||||
#include "zone.hpp"
|
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
// backward compatibility
|
|
||||||
#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
|
|
||||||
#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE MSGPACK_UNPACKER_INIT_BUFFER_SIZE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
struct unpack_error : public std::runtime_error {
|
|
||||||
unpack_error(const std::string& msg) :
|
|
||||||
std::runtime_error(msg) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class unpacked {
|
|
||||||
public:
|
|
||||||
unpacked() { }
|
|
||||||
|
|
||||||
unpacked(object obj, std::auto_ptr<msgpack::zone> z) :
|
|
||||||
m_obj(obj), m_zone(z) { }
|
|
||||||
|
|
||||||
object& get()
|
|
||||||
{ return m_obj; }
|
|
||||||
|
|
||||||
const object& get() const
|
|
||||||
{ return m_obj; }
|
|
||||||
|
|
||||||
std::auto_ptr<msgpack::zone>& zone()
|
|
||||||
{ return m_zone; }
|
|
||||||
|
|
||||||
const std::auto_ptr<msgpack::zone>& zone() const
|
|
||||||
{ return m_zone; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
object m_obj;
|
|
||||||
std::auto_ptr<msgpack::zone> m_zone;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class unpacker : public msgpack_unpacker {
|
|
||||||
public:
|
|
||||||
unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
|
||||||
~unpacker();
|
|
||||||
|
|
||||||
public:
|
|
||||||
/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
|
|
||||||
void reserve_buffer(size_t size = MSGPACK_UNPACKER_RESERVE_SIZE);
|
|
||||||
|
|
||||||
/*! 2. read data to the buffer() up to buffer_capacity() bytes */
|
|
||||||
char* buffer();
|
|
||||||
size_t buffer_capacity() const;
|
|
||||||
|
|
||||||
/*! 3. specify the number of bytes actually copied */
|
|
||||||
void buffer_consumed(size_t size);
|
|
||||||
|
|
||||||
/*! 4. repeat next() until it retunrs false */
|
|
||||||
bool next(unpacked* result);
|
|
||||||
|
|
||||||
/*! 5. check if the size of message doesn't exceed assumption. */
|
|
||||||
size_t message_size() const;
|
|
||||||
|
|
||||||
// Basic usage of the unpacker is as following:
|
|
||||||
//
|
|
||||||
// msgpack::unpacker pac;
|
|
||||||
// while( /* input is readable */ ) {
|
|
||||||
//
|
|
||||||
// // 1.
|
|
||||||
// pac.reserve_buffer(32*1024);
|
|
||||||
//
|
|
||||||
// // 2.
|
|
||||||
// size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity());
|
|
||||||
//
|
|
||||||
// // error handling ...
|
|
||||||
//
|
|
||||||
// // 3.
|
|
||||||
// pac.buffer_consumed(bytes);
|
|
||||||
//
|
|
||||||
// // 4.
|
|
||||||
// msgpack::unpacked result;
|
|
||||||
// while(pac.next(&result)) {
|
|
||||||
// // do some with the object with the zone.
|
|
||||||
// msgpack::object obj = result.get();
|
|
||||||
// std::auto_ptr<msgpack:zone> z = result.zone();
|
|
||||||
// on_message(obj, z);
|
|
||||||
//
|
|
||||||
// //// boost::shared_ptr is also usable:
|
|
||||||
// // boost::shared_ptr<msgpack::zone> life(z.release());
|
|
||||||
// // on_message(result.get(), life);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 5.
|
|
||||||
// if(pac.message_size() > 10*1024*1024) {
|
|
||||||
// throw std::runtime_error("message is too large");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
|
|
||||||
/*! for backward compatibility */
|
|
||||||
bool execute();
|
|
||||||
|
|
||||||
/*! for backward compatibility */
|
|
||||||
object data();
|
|
||||||
|
|
||||||
/*! for backward compatibility */
|
|
||||||
zone* release_zone();
|
|
||||||
|
|
||||||
/*! for backward compatibility */
|
|
||||||
void reset_zone();
|
|
||||||
|
|
||||||
/*! for backward compatibility */
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
public:
|
|
||||||
// These functions are usable when non-MessagePack message follows after
|
|
||||||
// MessagePack message.
|
|
||||||
size_t parsed_size() const;
|
|
||||||
|
|
||||||
/*! get address of the buffer that is not parsed */
|
|
||||||
char* nonparsed_buffer();
|
|
||||||
size_t nonparsed_size() const;
|
|
||||||
|
|
||||||
/*! skip specified size of non-parsed buffer, leaving the buffer */
|
|
||||||
// Note that the `size' argument must be smaller than nonparsed_size()
|
|
||||||
void skip_nonparsed_buffer(size_t size);
|
|
||||||
|
|
||||||
/*! remove unparsed buffer from unpacker */
|
|
||||||
// Note that reset() leaves non-parsed buffer.
|
|
||||||
void remove_nonparsed_buffer();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef msgpack_unpacker base;
|
|
||||||
|
|
||||||
private:
|
|
||||||
unpacker(const unpacker&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void unpack(unpacked* result,
|
|
||||||
const char* data, size_t len, size_t* offset = NULL);
|
|
||||||
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
typedef enum {
|
|
||||||
UNPACK_SUCCESS = 2,
|
|
||||||
UNPACK_EXTRA_BYTES = 1,
|
|
||||||
UNPACK_CONTINUE = 0,
|
|
||||||
UNPACK_PARSE_ERROR = -1,
|
|
||||||
} unpack_return;
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
static unpack_return unpack(const char* data, size_t len, size_t* off,
|
|
||||||
zone* z, object* result);
|
|
||||||
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);
|
|
||||||
|
|
||||||
|
|
||||||
inline unpacker::unpacker(size_t initial_buffer_size)
|
|
||||||
{
|
|
||||||
if(!msgpack_unpacker_init(this, initial_buffer_size)) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unpacker::~unpacker()
|
|
||||||
{
|
|
||||||
msgpack_unpacker_destroy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void unpacker::reserve_buffer(size_t size)
|
|
||||||
{
|
|
||||||
if(!msgpack_unpacker_reserve_buffer(this, size)) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* unpacker::buffer()
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_buffer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t unpacker::buffer_capacity() const
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_buffer_capacity(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unpacker::buffer_consumed(size_t size)
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_buffer_consumed(this, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool unpacker::next(unpacked* result)
|
|
||||||
{
|
|
||||||
int ret = msgpack_unpacker_execute(this);
|
|
||||||
|
|
||||||
if(ret < 0) {
|
|
||||||
throw unpack_error("parse error");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ret == 0) {
|
|
||||||
result->zone().reset();
|
|
||||||
result->get() = object();
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
result->zone().reset( release_zone() );
|
|
||||||
result->get() = data();
|
|
||||||
reset();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline bool unpacker::execute()
|
|
||||||
{
|
|
||||||
int ret = msgpack_unpacker_execute(this);
|
|
||||||
if(ret < 0) {
|
|
||||||
throw unpack_error("parse error");
|
|
||||||
} else if(ret == 0) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object unpacker::data()
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_data(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline zone* unpacker::release_zone()
|
|
||||||
{
|
|
||||||
return static_cast<msgpack::zone*>(msgpack_unpacker_release_zone(static_cast<msgpack_unpacker*>(this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unpacker::reset_zone()
|
|
||||||
{
|
|
||||||
msgpack_unpacker_reset_zone(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unpacker::reset()
|
|
||||||
{
|
|
||||||
msgpack_unpacker_reset(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline size_t unpacker::message_size() const
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_message_size(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t unpacker::parsed_size() const
|
|
||||||
{
|
|
||||||
return msgpack_unpacker_parsed_size(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char* unpacker::nonparsed_buffer()
|
|
||||||
{
|
|
||||||
return base::buffer + base::off;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t unpacker::nonparsed_size() const
|
|
||||||
{
|
|
||||||
return base::used - base::off;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unpacker::skip_nonparsed_buffer(size_t size)
|
|
||||||
{
|
|
||||||
base::off += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void unpacker::remove_nonparsed_buffer()
|
|
||||||
{
|
|
||||||
base::used = base::off;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void unpack(unpacked* result,
|
|
||||||
const char* data, size_t len, size_t* offset)
|
|
||||||
{
|
|
||||||
msgpack::object obj;
|
|
||||||
std::auto_ptr<msgpack::zone> z(new zone());
|
|
||||||
|
|
||||||
unpack_return ret = (unpack_return)msgpack_unpack(
|
|
||||||
data, len, offset, z.get(),
|
|
||||||
reinterpret_cast<msgpack_object*>(&obj));
|
|
||||||
|
|
||||||
switch(ret) {
|
|
||||||
case UNPACK_SUCCESS:
|
|
||||||
result->get() = obj;
|
|
||||||
result->zone() = z;
|
|
||||||
return;
|
|
||||||
|
|
||||||
case UNPACK_EXTRA_BYTES:
|
|
||||||
result->get() = obj;
|
|
||||||
result->zone() = z;
|
|
||||||
return;
|
|
||||||
|
|
||||||
case UNPACK_CONTINUE:
|
|
||||||
throw unpack_error("insufficient bytes");
|
|
||||||
|
|
||||||
case UNPACK_PARSE_ERROR:
|
|
||||||
default:
|
|
||||||
throw unpack_error("parse error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
inline unpack_return unpack(const char* data, size_t len, size_t* off,
|
|
||||||
zone* z, object* result)
|
|
||||||
{
|
|
||||||
return (unpack_return)msgpack_unpack(data, len, off,
|
|
||||||
z, reinterpret_cast<msgpack_object*>(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
// obsolete
|
|
||||||
inline object unpack(const char* data, size_t len, zone& z, size_t* off)
|
|
||||||
{
|
|
||||||
object result;
|
|
||||||
|
|
||||||
switch( msgpack::unpack(data, len, off, &z, &result) ) {
|
|
||||||
case UNPACK_SUCCESS:
|
|
||||||
return result;
|
|
||||||
|
|
||||||
case UNPACK_EXTRA_BYTES:
|
|
||||||
if(off) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
throw unpack_error("extra bytes");
|
|
||||||
}
|
|
||||||
|
|
||||||
case UNPACK_CONTINUE:
|
|
||||||
throw unpack_error("insufficient bytes");
|
|
||||||
|
|
||||||
case UNPACK_PARSE_ERROR:
|
|
||||||
default:
|
|
||||||
throw unpack_error("parse error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/unpack.hpp */
|
|
||||||
|
|
||||||
@@ -1,97 +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_HPP__
|
|
||||||
#define MSGPACK_VREFBUFFER_HPP__
|
|
||||||
|
|
||||||
#include "vrefbuffer.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
class vrefbuffer : public msgpack_vrefbuffer {
|
|
||||||
public:
|
|
||||||
vrefbuffer(size_t ref_size = MSGPACK_VREFBUFFER_REF_SIZE,
|
|
||||||
size_t chunk_size = MSGPACK_VREFBUFFER_CHUNK_SIZE)
|
|
||||||
{
|
|
||||||
msgpack_vrefbuffer_init(this, ref_size, chunk_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~vrefbuffer()
|
|
||||||
{
|
|
||||||
msgpack_vrefbuffer_destroy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void write(const char* buf, unsigned int len)
|
|
||||||
{
|
|
||||||
if(len < base::ref_size) {
|
|
||||||
append_copy(buf, len);
|
|
||||||
} else {
|
|
||||||
append_ref(buf, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_ref(const char* buf, size_t len)
|
|
||||||
{
|
|
||||||
if(msgpack_vrefbuffer_append_ref(this, buf, len) < 0) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_copy(const char* buf, size_t len)
|
|
||||||
{
|
|
||||||
if(msgpack_vrefbuffer_append_copy(this, buf, len) < 0) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct iovec* vector() const
|
|
||||||
{
|
|
||||||
return msgpack_vrefbuffer_vec(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t vector_size() const
|
|
||||||
{
|
|
||||||
return msgpack_vrefbuffer_veclen(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void migrate(vrefbuffer* to)
|
|
||||||
{
|
|
||||||
if(msgpack_vrefbuffer_migrate(this, to) < 0) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
msgpack_vrefbuffer_clear(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef msgpack_vrefbuffer base;
|
|
||||||
|
|
||||||
private:
|
|
||||||
vrefbuffer(const vrefbuffer&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/vrefbuffer.hpp */
|
|
||||||
|
|
||||||
@@ -1,100 +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_HPP__
|
|
||||||
#define MSGPACK_ZBUFFER_HPP__
|
|
||||||
|
|
||||||
#include "zbuffer.h"
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
class zbuffer : public msgpack_zbuffer {
|
|
||||||
public:
|
|
||||||
zbuffer(int level = Z_DEFAULT_COMPRESSION,
|
|
||||||
size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
|
|
||||||
{
|
|
||||||
msgpack_zbuffer_init(this, level, init_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~zbuffer()
|
|
||||||
{
|
|
||||||
msgpack_zbuffer_destroy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
void write(const char* buf, unsigned int len)
|
|
||||||
{
|
|
||||||
if(msgpack_zbuffer_write(this, buf, len) < 0) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* flush()
|
|
||||||
{
|
|
||||||
char* buf = msgpack_zbuffer_flush(this);
|
|
||||||
if(!buf) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* data()
|
|
||||||
{
|
|
||||||
return base::data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* data() const
|
|
||||||
{
|
|
||||||
return base::data;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const
|
|
||||||
{
|
|
||||||
return msgpack_zbuffer_size(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
if(!msgpack_zbuffer_reset(this)) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_buffer()
|
|
||||||
{
|
|
||||||
msgpack_zbuffer_reset_buffer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* release_buffer()
|
|
||||||
{
|
|
||||||
return msgpack_zbuffer_release_buffer(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef msgpack_zbuffer base;
|
|
||||||
|
|
||||||
private:
|
|
||||||
zbuffer(const zbuffer&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/zbuffer.hpp */
|
|
||||||
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ memory pool
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
#ifndef MSGPACK_ZONE_HPP__
|
|
||||||
#define MSGPACK_ZONE_HPP__
|
|
||||||
|
|
||||||
#include "zone.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
<% GENERATION_LIMIT = 15 %>
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
class zone : public msgpack_zone {
|
|
||||||
public:
|
|
||||||
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
|
|
||||||
~zone();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void* malloc(size_t size);
|
|
||||||
void* malloc_no_align(size_t size);
|
|
||||||
|
|
||||||
void push_finalizer(void (*func)(void*), void* data);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void push_finalizer(std::auto_ptr<T> obj);
|
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
void swap(zone& o);
|
|
||||||
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
private:
|
|
||||||
void undo_malloc(size_t size);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static void object_destructor(void* obj);
|
|
||||||
|
|
||||||
typedef msgpack_zone base;
|
|
||||||
|
|
||||||
private:
|
|
||||||
zone(const zone&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline zone::zone(size_t chunk_size)
|
|
||||||
{
|
|
||||||
msgpack_zone_init(this, chunk_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline zone::~zone()
|
|
||||||
{
|
|
||||||
msgpack_zone_destroy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* zone::malloc(size_t size)
|
|
||||||
{
|
|
||||||
void* ptr = msgpack_zone_malloc(this, size);
|
|
||||||
if(!ptr) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* zone::malloc_no_align(size_t size)
|
|
||||||
{
|
|
||||||
void* ptr = msgpack_zone_malloc_no_align(this, size);
|
|
||||||
if(!ptr) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void zone::push_finalizer(void (*func)(void*), void* data)
|
|
||||||
{
|
|
||||||
if(!msgpack_zone_push_finalizer(this, func, data)) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void zone::push_finalizer(std::auto_ptr<T> obj)
|
|
||||||
{
|
|
||||||
if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, obj.get())) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
obj.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void zone::clear()
|
|
||||||
{
|
|
||||||
msgpack_zone_clear(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void zone::swap(zone& o)
|
|
||||||
{
|
|
||||||
msgpack_zone_swap(this, &o);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void zone::object_destructor(void* obj)
|
|
||||||
{
|
|
||||||
reinterpret_cast<T*>(obj)->~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void zone::undo_malloc(size_t size)
|
|
||||||
{
|
|
||||||
base::chunk_list.ptr -= size;
|
|
||||||
base::chunk_list.free += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
|
||||||
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
|
||||||
T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
|
|
||||||
{
|
|
||||||
void* x = malloc(sizeof(T));
|
|
||||||
if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, x)) {
|
|
||||||
undo_malloc(sizeof(T));
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
|
|
||||||
} catch (...) {
|
|
||||||
--base::finalizer_array.tail;
|
|
||||||
undo_malloc(sizeof(T));
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<%}%>
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
#endif /* msgpack/zone.hpp */
|
|
||||||
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
//
|
|
||||||
// MessagePack for C++ dynamic typed objects
|
|
||||||
//
|
|
||||||
// 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.hpp"
|
|
||||||
|
|
||||||
namespace msgpack {
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& s, const object o)
|
|
||||||
{
|
|
||||||
switch(o.type) {
|
|
||||||
case type::NIL:
|
|
||||||
s << "nil";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::BOOLEAN:
|
|
||||||
s << (o.via.boolean ? "true" : "false");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::POSITIVE_INTEGER:
|
|
||||||
s << o.via.u64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::NEGATIVE_INTEGER:
|
|
||||||
s << o.via.i64;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::DOUBLE:
|
|
||||||
s << o.via.dec;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::RAW:
|
|
||||||
(s << '"').write(o.via.raw.ptr, o.via.raw.size) << '"';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::ARRAY:
|
|
||||||
s << "[";
|
|
||||||
if(o.via.array.size != 0) {
|
|
||||||
object* p(o.via.array.ptr);
|
|
||||||
s << *p;
|
|
||||||
++p;
|
|
||||||
for(object* const pend(o.via.array.ptr + o.via.array.size);
|
|
||||||
p < pend; ++p) {
|
|
||||||
s << ", " << *p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s << "]";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case type::MAP:
|
|
||||||
s << "{";
|
|
||||||
if(o.via.map.size != 0) {
|
|
||||||
object_kv* p(o.via.map.ptr);
|
|
||||||
s << p->key << "=>" << p->val;
|
|
||||||
++p;
|
|
||||||
for(object_kv* const pend(o.via.map.ptr + o.via.map.size);
|
|
||||||
p < pend; ++p) {
|
|
||||||
s << ", " << p->key << "=>" << p->val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s << "}";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// FIXME
|
|
||||||
s << "#<UNKNOWN " << (uint16_t)o.type << ">";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace msgpack
|
|
||||||
|
|
||||||
@@ -1,237 +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 <stdio.h>
|
|
||||||
#include <string.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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// FIXME
|
|
||||||
fprintf(out, "#<UNKNOWN %i %"PRIu64">", o.type, o.via.u64);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool msgpack_object_equal(const msgpack_object x, const msgpack_object y)
|
|
||||||
{
|
|
||||||
if(x.type != y.type) { return false; }
|
|
||||||
|
|
||||||
switch(x.type) {
|
|
||||||
case MSGPACK_OBJECT_NIL:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_BOOLEAN:
|
|
||||||
return x.via.boolean == y.via.boolean;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_POSITIVE_INTEGER:
|
|
||||||
return x.via.u64 == y.via.u64;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
|
|
||||||
return x.via.i64 == y.via.i64;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_DOUBLE:
|
|
||||||
return x.via.dec == y.via.dec;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_RAW:
|
|
||||||
return x.via.raw.size == y.via.raw.size &&
|
|
||||||
memcmp(x.via.raw.ptr, y.via.raw.ptr, x.via.raw.size) == 0;
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_ARRAY:
|
|
||||||
if(x.via.array.size != y.via.array.size) {
|
|
||||||
return false;
|
|
||||||
} else if(x.via.array.size == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
msgpack_object* px = x.via.array.ptr;
|
|
||||||
msgpack_object* const pxend = x.via.array.ptr + x.via.array.size;
|
|
||||||
msgpack_object* py = y.via.array.ptr;
|
|
||||||
do {
|
|
||||||
if(!msgpack_object_equal(*px, *py)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
++px;
|
|
||||||
++py;
|
|
||||||
} while(px < pxend);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case MSGPACK_OBJECT_MAP:
|
|
||||||
if(x.via.map.size != y.via.map.size) {
|
|
||||||
return false;
|
|
||||||
} else if(x.via.map.size == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
msgpack_object_kv* px = x.via.map.ptr;
|
|
||||||
msgpack_object_kv* const pxend = x.via.map.ptr + x.via.map.size;
|
|
||||||
msgpack_object_kv* py = y.via.map.ptr;
|
|
||||||
do {
|
|
||||||
if(!msgpack_object_equal(px->key, py->key) || !msgpack_object_equal(px->val, py->val)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
++px;
|
|
||||||
++py;
|
|
||||||
} while(px < pxend);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
464
cpp/src/unpack.c
464
cpp/src/unpack.c
@@ -1,464 +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 <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef _msgpack_atomic_counter_header
|
|
||||||
#include _msgpack_atomic_counter_header
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
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 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);
|
|
||||||
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 NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgpack_zone* r = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
|
|
||||||
if(r == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgpack_zone* old = mpac->z;
|
|
||||||
mpac->z = r;
|
|
||||||
CTX_CAST(mpac->ctx)->user.z = mpac->z;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool msgpack_unpacker_next(msgpack_unpacker* mpac, msgpack_unpacked* result)
|
|
||||||
{
|
|
||||||
if(result->zone != NULL) {
|
|
||||||
msgpack_zone_free(result->zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = msgpack_unpacker_execute(mpac);
|
|
||||||
|
|
||||||
if(ret <= 0) {
|
|
||||||
result->zone = NULL;
|
|
||||||
memset(&result->data, 0, sizeof(msgpack_object));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
result->zone = msgpack_unpacker_release_zone(mpac);
|
|
||||||
result->data = msgpack_unpacker_data(mpac);
|
|
||||||
msgpack_unpacker_reset(mpac);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
msgpack_unpack_return
|
|
||||||
msgpack_unpack(const char* data, size_t len, size_t* off,
|
|
||||||
msgpack_zone* result_zone, msgpack_object* result)
|
|
||||||
{
|
|
||||||
size_t noff = 0;
|
|
||||||
if(off != NULL) { noff = *off; }
|
|
||||||
|
|
||||||
if(len <= noff) {
|
|
||||||
// FIXME
|
|
||||||
return MSGPACK_UNPACK_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
template_context ctx;
|
|
||||||
template_init(&ctx);
|
|
||||||
|
|
||||||
ctx.user.z = result_zone;
|
|
||||||
ctx.user.referenced = false;
|
|
||||||
|
|
||||||
int e = template_execute(&ctx, data, len, &noff);
|
|
||||||
if(e < 0) {
|
|
||||||
return MSGPACK_UNPACK_PARSE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(off != NULL) { *off = noff; }
|
|
||||||
|
|
||||||
if(e == 0) {
|
|
||||||
return MSGPACK_UNPACK_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = template_data(&ctx);
|
|
||||||
|
|
||||||
if(noff < len) {
|
|
||||||
return MSGPACK_UNPACK_EXTRA_BYTES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MSGPACK_UNPACK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool msgpack_unpack_next(msgpack_unpacked* result,
|
|
||||||
const char* data, size_t len, size_t* off)
|
|
||||||
{
|
|
||||||
msgpack_unpacked_destroy(result);
|
|
||||||
|
|
||||||
size_t noff = 0;
|
|
||||||
if(off != NULL) { noff = *off; }
|
|
||||||
|
|
||||||
if(len <= noff) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgpack_zone* z = msgpack_zone_new(MSGPACK_ZONE_CHUNK_SIZE);
|
|
||||||
|
|
||||||
template_context ctx;
|
|
||||||
template_init(&ctx);
|
|
||||||
|
|
||||||
ctx.user.z = z;
|
|
||||||
ctx.user.referenced = false;
|
|
||||||
|
|
||||||
int e = template_execute(&ctx, data, len, &noff);
|
|
||||||
if(e <= 0) {
|
|
||||||
msgpack_zone_free(z);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(off != NULL) { *off = noff; }
|
|
||||||
|
|
||||||
result->zone = z;
|
|
||||||
result->data = template_data(&ctx);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#include "msgpack.h"
|
|
||||||
|
|
||||||
const char* msgpack_version(void)
|
|
||||||
{
|
|
||||||
return MSGPACK_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
int msgpack_version_major(void)
|
|
||||||
{
|
|
||||||
return MSGPACK_VERSION_MAJOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int msgpack_version_minor(void)
|
|
||||||
{
|
|
||||||
return MSGPACK_VERSION_MINOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,220 +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 <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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void msgpack_vrefbuffer_clear(msgpack_vrefbuffer* vbuf)
|
|
||||||
{
|
|
||||||
msgpack_vrefbuffer_chunk* c = vbuf->inner_buffer.head->next;
|
|
||||||
msgpack_vrefbuffer_chunk* n;
|
|
||||||
while(c != NULL) {
|
|
||||||
n = c->next;
|
|
||||||
free(c);
|
|
||||||
c = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgpack_vrefbuffer_inner_buffer* const ib = &vbuf->inner_buffer;
|
|
||||||
msgpack_vrefbuffer_chunk* chunk = ib->head;
|
|
||||||
chunk->next = NULL;
|
|
||||||
ib->free = vbuf->chunk_size;
|
|
||||||
ib->ptr = ((char*)chunk) + sizeof(msgpack_vrefbuffer_chunk);
|
|
||||||
|
|
||||||
vbuf->tail = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
221
cpp/src/zone.c
221
cpp/src/zone.c
@@ -1,221 +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 <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 NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
init_finalizer_array(&zone->finalizer_array);
|
|
||||||
|
|
||||||
return zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void msgpack_zone_free(msgpack_zone* zone)
|
|
||||||
{
|
|
||||||
if(zone == NULL) { return; }
|
|
||||||
msgpack_zone_destroy(zone);
|
|
||||||
free(zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
|
|
||||||
AM_CPPFLAGS = -I../src
|
|
||||||
AM_C_CPPFLAGS = -I../src
|
|
||||||
AM_LDFLAGS = ../src/libmsgpack.la -lgtest_main -pthread
|
|
||||||
|
|
||||||
check_PROGRAMS = \
|
|
||||||
zone \
|
|
||||||
pack_unpack \
|
|
||||||
pack_unpack_c \
|
|
||||||
streaming \
|
|
||||||
streaming_c \
|
|
||||||
object \
|
|
||||||
convert \
|
|
||||||
buffer \
|
|
||||||
cases \
|
|
||||||
fixint \
|
|
||||||
fixint_c \
|
|
||||||
version \
|
|
||||||
msgpackc_test \
|
|
||||||
msgpack_test
|
|
||||||
|
|
||||||
TESTS = $(check_PROGRAMS)
|
|
||||||
|
|
||||||
zone_SOURCES = zone.cc
|
|
||||||
|
|
||||||
pack_unpack_SOURCES = pack_unpack.cc
|
|
||||||
|
|
||||||
pack_unpack_c_SOURCES = pack_unpack_c.cc
|
|
||||||
|
|
||||||
streaming_SOURCES = streaming.cc
|
|
||||||
|
|
||||||
streaming_c_SOURCES = streaming_c.cc
|
|
||||||
|
|
||||||
object_SOURCES = object.cc
|
|
||||||
|
|
||||||
convert_SOURCES = convert.cc
|
|
||||||
|
|
||||||
buffer_SOURCES = buffer.cc
|
|
||||||
buffer_LDADD = -lz
|
|
||||||
|
|
||||||
cases_SOURCES = cases.cc
|
|
||||||
|
|
||||||
fixint_SOURCES = fixint.cc
|
|
||||||
|
|
||||||
fixint_c_SOURCES = fixint_c.cc
|
|
||||||
|
|
||||||
version_SOURCES = version.cc
|
|
||||||
|
|
||||||
msgpackc_test_SOURCES = msgpackc_test.cpp
|
|
||||||
|
|
||||||
msgpack_test_SOURCES = msgpack_test.cpp
|
|
||||||
|
|
||||||
EXTRA_DIST = cases.mpac cases_compact.mpac
|
|
||||||
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <msgpack/zbuffer.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
TEST(buffer, sbuffer)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
|
|
||||||
EXPECT_EQ(3, sbuf.size());
|
|
||||||
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
|
|
||||||
|
|
||||||
sbuf.clear();
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
sbuf.write("a", 1);
|
|
||||||
|
|
||||||
EXPECT_EQ(3, sbuf.size());
|
|
||||||
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(buffer, vrefbuffer)
|
|
||||||
{
|
|
||||||
msgpack::vrefbuffer vbuf;
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
|
|
||||||
const struct iovec* vec = vbuf.vector();
|
|
||||||
size_t veclen = vbuf.vector_size();
|
|
||||||
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
for(size_t i=0; i < veclen; ++i) {
|
|
||||||
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(3, sbuf.size());
|
|
||||||
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
|
|
||||||
|
|
||||||
|
|
||||||
vbuf.clear();
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
vbuf.write("a", 1);
|
|
||||||
|
|
||||||
vec = vbuf.vector();
|
|
||||||
veclen = vbuf.vector_size();
|
|
||||||
|
|
||||||
sbuf.clear();
|
|
||||||
for(size_t i=0; i < veclen; ++i) {
|
|
||||||
sbuf.write((const char*)vec[i].iov_base, vec[i].iov_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(3, sbuf.size());
|
|
||||||
EXPECT_TRUE( memcmp(sbuf.data(), "aaa", 3) == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(buffer, zbuffer)
|
|
||||||
{
|
|
||||||
msgpack::zbuffer zbuf;
|
|
||||||
zbuf.write("a", 1);
|
|
||||||
zbuf.write("a", 1);
|
|
||||||
zbuf.write("a", 1);
|
|
||||||
|
|
||||||
zbuf.flush();
|
|
||||||
|
|
||||||
char* data = zbuf.data();
|
|
||||||
size_t size = zbuf.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <fstream>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
static void feed_file(msgpack::unpacker& pac, const char* path)
|
|
||||||
{
|
|
||||||
std::ifstream fin(path);
|
|
||||||
while(true) {
|
|
||||||
pac.reserve_buffer(32*1024);
|
|
||||||
fin.read(pac.buffer(), pac.buffer_capacity());
|
|
||||||
if(fin.bad()) {
|
|
||||||
throw std::runtime_error("read failed");
|
|
||||||
}
|
|
||||||
pac.buffer_consumed(fin.gcount());
|
|
||||||
if(fin.fail()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(cases, format)
|
|
||||||
{
|
|
||||||
msgpack::unpacker pac;
|
|
||||||
msgpack::unpacker pac_compact;
|
|
||||||
|
|
||||||
feed_file(pac, "cases.mpac");
|
|
||||||
feed_file(pac_compact, "cases_compact.mpac");
|
|
||||||
|
|
||||||
msgpack::unpacked result;
|
|
||||||
while(pac.next(&result)) {
|
|
||||||
msgpack::unpacked result_compact;
|
|
||||||
EXPECT_TRUE( pac_compact.next(&result_compact) );
|
|
||||||
EXPECT_EQ(result_compact.get(), result.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_FALSE( pac_compact.next(&result) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
class compatibility {
|
|
||||||
public:
|
|
||||||
compatibility() : str1("default"), str2("default") { }
|
|
||||||
|
|
||||||
std::string str1;
|
|
||||||
std::string str2;
|
|
||||||
|
|
||||||
MSGPACK_DEFINE(str1, str2);
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(convert, compatibility_less)
|
|
||||||
{
|
|
||||||
std::vector<std::string> src(1);
|
|
||||||
src[0] = "kumofs";
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj(src, &z);
|
|
||||||
|
|
||||||
compatibility c;
|
|
||||||
EXPECT_NO_THROW( obj.convert(&c) );
|
|
||||||
|
|
||||||
EXPECT_EQ("kumofs", c.str1);
|
|
||||||
EXPECT_EQ("default", c.str2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(convert, compatibility_more)
|
|
||||||
{
|
|
||||||
std::vector<std::string> src(3);
|
|
||||||
src[0] = "kumofs";
|
|
||||||
src[1] = "mpio";
|
|
||||||
src[2] = "cloudy";
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj(src, &z);
|
|
||||||
|
|
||||||
compatibility to;
|
|
||||||
EXPECT_NO_THROW( obj.convert(&to) );
|
|
||||||
|
|
||||||
EXPECT_EQ("kumofs", to.str1);
|
|
||||||
EXPECT_EQ("mpio", to.str2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class enum_member {
|
|
||||||
public:
|
|
||||||
enum_member() : flag(A) { }
|
|
||||||
|
|
||||||
enum flags_t {
|
|
||||||
A = 0,
|
|
||||||
B = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
flags_t flag;
|
|
||||||
|
|
||||||
MSGPACK_DEFINE((int&)flag);
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(convert, enum_member)
|
|
||||||
{
|
|
||||||
enum_member src;
|
|
||||||
src.flag = enum_member::B;
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj(src, &z);
|
|
||||||
|
|
||||||
enum_member to;
|
|
||||||
EXPECT_NO_THROW( obj.convert(&to) );
|
|
||||||
|
|
||||||
EXPECT_EQ(enum_member::B, to.flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void check_size(size_t size) {
|
|
||||||
T v(0);
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, v);
|
|
||||||
EXPECT_EQ(size, sbuf.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(fixint, size)
|
|
||||||
{
|
|
||||||
check_size<msgpack::type::fix_int8>(2);
|
|
||||||
check_size<msgpack::type::fix_int16>(3);
|
|
||||||
check_size<msgpack::type::fix_int32>(5);
|
|
||||||
check_size<msgpack::type::fix_int64>(9);
|
|
||||||
|
|
||||||
check_size<msgpack::type::fix_uint8>(2);
|
|
||||||
check_size<msgpack::type::fix_uint16>(3);
|
|
||||||
check_size<msgpack::type::fix_uint32>(5);
|
|
||||||
check_size<msgpack::type::fix_uint64>(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void check_convert() {
|
|
||||||
T v1(-11);
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, v1);
|
|
||||||
|
|
||||||
msgpack::unpacked msg;
|
|
||||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size());
|
|
||||||
|
|
||||||
T v2;
|
|
||||||
msg.get().convert(&v2);
|
|
||||||
|
|
||||||
EXPECT_EQ(v1.get(), v2.get());
|
|
||||||
|
|
||||||
EXPECT_EQ(msg.get(), msgpack::object(T(v1.get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(fixint, convert)
|
|
||||||
{
|
|
||||||
check_convert<msgpack::type::fix_int8>();
|
|
||||||
check_convert<msgpack::type::fix_int16>();
|
|
||||||
check_convert<msgpack::type::fix_int32>();
|
|
||||||
check_convert<msgpack::type::fix_int64>();
|
|
||||||
|
|
||||||
check_convert<msgpack::type::fix_uint8>();
|
|
||||||
check_convert<msgpack::type::fix_uint16>();
|
|
||||||
check_convert<msgpack::type::fix_uint32>();
|
|
||||||
check_convert<msgpack::type::fix_uint64>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(fixint, size)
|
|
||||||
{
|
|
||||||
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
|
|
||||||
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
|
|
||||||
|
|
||||||
size_t sum = 0;
|
|
||||||
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_int8(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=2, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_int16(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=3, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_int32(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=5, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_int64(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=9, sbuf->size);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_uint8(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=2, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_uint16(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=3, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_uint32(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=5, sbuf->size);
|
|
||||||
EXPECT_EQ(0, msgpack_pack_fix_uint64(pk, 0));
|
|
||||||
EXPECT_EQ(sum+=9, sbuf->size);
|
|
||||||
|
|
||||||
msgpack_sbuffer_free(sbuf);
|
|
||||||
msgpack_packer_free(pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,982 +0,0 @@
|
|||||||
#include "msgpack.hpp"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <deque>
|
|
||||||
#include <set>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
#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<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++) { \
|
|
||||||
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<float> 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<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++) {
|
|
||||||
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<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(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<int> 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<int> 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<int, int> 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<int, int> 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<int> 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<int> 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<int> 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<int> 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<int> 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<int> 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<int, int> 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<int, int> 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<int, int> 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<int, int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
|
|
||||||
vector<pair<int, int> > v1, v2;
|
|
||||||
multimap<int, int>::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<int> 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<int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
|
|
||||||
vector<int> v1, v2;
|
|
||||||
multiset<int>::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 <tr1/unordered_map>
|
|
||||||
#include "msgpack/type/tr1/unordered_map.hpp"
|
|
||||||
TEST(MSGPACK_TR1, simple_buffer_unordered_map)
|
|
||||||
{
|
|
||||||
for (unsigned int k = 0; k < kLoop; k++) {
|
|
||||||
tr1::unordered_map<int, int> 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<int, int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
EXPECT_EQ(val1.size(), val2.size());
|
|
||||||
tr1::unordered_map<int, int>::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<int, int> 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<int, int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
|
|
||||||
vector<pair<int, int> > v1, v2;
|
|
||||||
tr1::unordered_multimap<int, int>::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 <tr1/unordered_set>
|
|
||||||
#include "msgpack/type/tr1/unordered_set.hpp"
|
|
||||||
TEST(MSGPACK_TR1, simple_buffer_unordered_set)
|
|
||||||
{
|
|
||||||
for (unsigned int k = 0; k < kLoop; k++) {
|
|
||||||
tr1::unordered_set<int> 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<int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
EXPECT_EQ(val1.size(), val2.size());
|
|
||||||
tr1::unordered_set<int>::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<int> 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<int> val2;
|
|
||||||
obj.convert(&val2);
|
|
||||||
|
|
||||||
vector<int> v1, v2;
|
|
||||||
tr1::unordered_multiset<int>::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<int> 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<int>();
|
|
||||||
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 <typename Packer>
|
|
||||||
void msgpack_pack(Packer& pk) const
|
|
||||||
{
|
|
||||||
if (is_double)
|
|
||||||
pk.pack(msgpack::type::tuple<bool, double>(true, value.f));
|
|
||||||
else
|
|
||||||
pk.pack(msgpack::type::tuple<bool, int>(false, value.i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void msgpack_unpack(msgpack::object o)
|
|
||||||
{
|
|
||||||
msgpack::type::tuple<bool, msgpack::object> 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<test_type> 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<msgpack::sbuffer> pk(sbuf); \
|
|
||||||
typedef std::vector<test_type> 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<size_t>(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);
|
|
||||||
}
|
|
||||||
@@ -1,424 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
struct myclass {
|
|
||||||
myclass() : num(0), str("default") { }
|
|
||||||
|
|
||||||
myclass(int num, const std::string& str) :
|
|
||||||
num(0), str("default") { }
|
|
||||||
|
|
||||||
~myclass() { }
|
|
||||||
|
|
||||||
int num;
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
MSGPACK_DEFINE(num, str);
|
|
||||||
|
|
||||||
bool operator==(const myclass& o) const
|
|
||||||
{
|
|
||||||
return num == o.num && str == o.str;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, const myclass& m)
|
|
||||||
{
|
|
||||||
return o << "myclass("<<m.num<<",\""<<m.str<<"\")";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, convert)
|
|
||||||
{
|
|
||||||
myclass m1;
|
|
||||||
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, m1);
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj;
|
|
||||||
|
|
||||||
msgpack::unpack_return ret =
|
|
||||||
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
|
|
||||||
|
|
||||||
myclass m2;
|
|
||||||
obj.convert(&m2);
|
|
||||||
|
|
||||||
EXPECT_EQ(m1, m2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, as)
|
|
||||||
{
|
|
||||||
myclass m1;
|
|
||||||
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, m1);
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj;
|
|
||||||
|
|
||||||
msgpack::unpack_return ret =
|
|
||||||
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
|
|
||||||
|
|
||||||
EXPECT_EQ(m1, obj.as<myclass>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, print)
|
|
||||||
{
|
|
||||||
msgpack::object obj;
|
|
||||||
std::cout << obj << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, is_nil)
|
|
||||||
{
|
|
||||||
msgpack::object obj;
|
|
||||||
EXPECT_TRUE(obj.is_nil());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, type_error)
|
|
||||||
{
|
|
||||||
msgpack::object obj(1);
|
|
||||||
EXPECT_THROW(obj.as<std::string>(), msgpack::type_error);
|
|
||||||
EXPECT_THROW(obj.as<std::vector<int> >(), msgpack::type_error);
|
|
||||||
EXPECT_EQ(1, obj.as<int>());
|
|
||||||
EXPECT_EQ(1, obj.as<short>());
|
|
||||||
EXPECT_EQ(1u, obj.as<unsigned int>());
|
|
||||||
EXPECT_EQ(1u, obj.as<unsigned long>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, equal_primitive)
|
|
||||||
{
|
|
||||||
msgpack::object obj_nil;
|
|
||||||
EXPECT_EQ(obj_nil, msgpack::object());
|
|
||||||
|
|
||||||
msgpack::object obj_int(1);
|
|
||||||
EXPECT_EQ(obj_int, msgpack::object(1));
|
|
||||||
EXPECT_EQ(obj_int, 1);
|
|
||||||
|
|
||||||
msgpack::object obj_double(1.2);
|
|
||||||
EXPECT_EQ(obj_double, msgpack::object(1.2));
|
|
||||||
EXPECT_EQ(obj_double, 1.2);
|
|
||||||
|
|
||||||
msgpack::object obj_bool(true);
|
|
||||||
EXPECT_EQ(obj_bool, msgpack::object(true));
|
|
||||||
EXPECT_EQ(obj_bool, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(object, construct_primitive)
|
|
||||||
{
|
|
||||||
msgpack::object obj_nil;
|
|
||||||
EXPECT_EQ(msgpack::type::NIL, obj_nil.type);
|
|
||||||
|
|
||||||
msgpack::object obj_uint(1);
|
|
||||||
EXPECT_EQ(msgpack::type::POSITIVE_INTEGER, obj_uint.type);
|
|
||||||
EXPECT_EQ(1u, obj_uint.via.u64);
|
|
||||||
|
|
||||||
msgpack::object obj_int(-1);
|
|
||||||
EXPECT_EQ(msgpack::type::NEGATIVE_INTEGER, obj_int.type);
|
|
||||||
EXPECT_EQ(-1, obj_int.via.i64);
|
|
||||||
|
|
||||||
msgpack::object obj_double(1.2);
|
|
||||||
EXPECT_EQ(msgpack::type::DOUBLE, obj_double.type);
|
|
||||||
EXPECT_EQ(1.2, obj_double.via.dec);
|
|
||||||
|
|
||||||
msgpack::object obj_bool(true);
|
|
||||||
EXPECT_EQ(msgpack::type::BOOLEAN, obj_bool.type);
|
|
||||||
EXPECT_EQ(true, obj_bool.via.boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
TEST(pack, num)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(pack, vector)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
std::vector<int> vec;
|
|
||||||
vec.push_back(1);
|
|
||||||
vec.push_back(2);
|
|
||||||
vec.push_back(3);
|
|
||||||
msgpack::pack(sbuf, vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(pack, to_ostream)
|
|
||||||
{
|
|
||||||
std::ostringstream stream;
|
|
||||||
msgpack::pack(stream, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct myclass {
|
|
||||||
myclass() : num(0), str("default") { }
|
|
||||||
|
|
||||||
myclass(int num, const std::string& str) :
|
|
||||||
num(0), str("default") { }
|
|
||||||
|
|
||||||
~myclass() { }
|
|
||||||
|
|
||||||
int num;
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
MSGPACK_DEFINE(num, str);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
TEST(pack, myclass)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
myclass m(1, "msgpack");
|
|
||||||
msgpack::pack(sbuf, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(unpack, myclass)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
myclass m1(1, "phraser");
|
|
||||||
msgpack::pack(sbuf, m1);
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj;
|
|
||||||
|
|
||||||
msgpack::unpack_return ret =
|
|
||||||
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj);
|
|
||||||
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
|
|
||||||
|
|
||||||
myclass m2 = obj.as<myclass>();
|
|
||||||
EXPECT_EQ(m1.num, m2.num);
|
|
||||||
EXPECT_EQ(m1.str, m2.str);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(unpack, sequence)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, 1);
|
|
||||||
msgpack::pack(sbuf, 2);
|
|
||||||
msgpack::pack(sbuf, 3);
|
|
||||||
|
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
msgpack::unpacked msg;
|
|
||||||
|
|
||||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
|
|
||||||
EXPECT_EQ(1, msg.get().as<int>());
|
|
||||||
|
|
||||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
|
|
||||||
EXPECT_EQ(2, msg.get().as<int>());
|
|
||||||
|
|
||||||
msgpack::unpack(&msg, sbuf.data(), sbuf.size(), &offset);
|
|
||||||
EXPECT_EQ(3, msg.get().as<int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(unpack, sequence_compat)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer sbuf;
|
|
||||||
msgpack::pack(sbuf, 1);
|
|
||||||
msgpack::pack(sbuf, 2);
|
|
||||||
msgpack::pack(sbuf, 3);
|
|
||||||
|
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
msgpack::zone z;
|
|
||||||
msgpack::object obj;
|
|
||||||
msgpack::unpack_return ret;
|
|
||||||
|
|
||||||
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
|
|
||||||
EXPECT_TRUE(ret >= 0);
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
|
|
||||||
EXPECT_EQ(1, obj.as<int>());
|
|
||||||
|
|
||||||
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
|
|
||||||
EXPECT_TRUE(ret >= 0);
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_EXTRA_BYTES);
|
|
||||||
EXPECT_EQ(2, obj.as<int>());
|
|
||||||
|
|
||||||
ret = msgpack::unpack(sbuf.data(), sbuf.size(), &offset, &z, &obj);
|
|
||||||
EXPECT_TRUE(ret >= 0);
|
|
||||||
EXPECT_EQ(ret, msgpack::UNPACK_SUCCESS);
|
|
||||||
EXPECT_EQ(3, obj.as<int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
#include <msgpack.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
TEST(pack, num)
|
|
||||||
{
|
|
||||||
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
|
|
||||||
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
|
|
||||||
|
|
||||||
msgpack_sbuffer_free(sbuf);
|
|
||||||
msgpack_packer_free(pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(pack, array)
|
|
||||||
{
|
|
||||||
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
|
|
||||||
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, msgpack_pack_array(pk, 3));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
|
|
||||||
|
|
||||||
msgpack_sbuffer_free(sbuf);
|
|
||||||
msgpack_packer_free(pk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(unpack, sequence)
|
|
||||||
{
|
|
||||||
msgpack_sbuffer* sbuf = msgpack_sbuffer_new();
|
|
||||||
msgpack_packer* pk = msgpack_packer_new(sbuf, msgpack_sbuffer_write);
|
|
||||||
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
|
|
||||||
|
|
||||||
msgpack_packer_free(pk);
|
|
||||||
|
|
||||||
bool success;
|
|
||||||
size_t offset = 0;
|
|
||||||
|
|
||||||
msgpack_unpacked msg;
|
|
||||||
msgpack_unpacked_init(&msg);
|
|
||||||
|
|
||||||
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
|
|
||||||
EXPECT_TRUE(success);
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
|
|
||||||
EXPECT_EQ(1, msg.data.via.u64);
|
|
||||||
|
|
||||||
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
|
|
||||||
EXPECT_TRUE(success);
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
|
|
||||||
EXPECT_EQ(2, msg.data.via.u64);
|
|
||||||
|
|
||||||
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
|
|
||||||
EXPECT_TRUE(success);
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, msg.data.type);
|
|
||||||
EXPECT_EQ(3, msg.data.via.u64);
|
|
||||||
|
|
||||||
success = msgpack_unpack_next(&msg, sbuf->data, sbuf->size, &offset);
|
|
||||||
EXPECT_FALSE(success);
|
|
||||||
|
|
||||||
msgpack_sbuffer_free(sbuf);
|
|
||||||
msgpack_unpacked_destroy(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
TEST(streaming, basic)
|
|
||||||
{
|
|
||||||
msgpack::sbuffer buffer;
|
|
||||||
|
|
||||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
|
||||||
pk.pack(1);
|
|
||||||
pk.pack(2);
|
|
||||||
pk.pack(3);
|
|
||||||
|
|
||||||
const char* input = buffer.data();
|
|
||||||
const char* const eof = input + buffer.size();
|
|
||||||
|
|
||||||
msgpack::unpacker pac;
|
|
||||||
msgpack::unpacked result;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while(count < 3) {
|
|
||||||
pac.reserve_buffer(32*1024);
|
|
||||||
|
|
||||||
// read buffer into pac.buffer() upto
|
|
||||||
// pac.buffer_capacity() bytes.
|
|
||||||
size_t len = 1;
|
|
||||||
memcpy(pac.buffer(), input, len);
|
|
||||||
input += len;
|
|
||||||
|
|
||||||
pac.buffer_consumed(len);
|
|
||||||
|
|
||||||
while(pac.next(&result)) {
|
|
||||||
msgpack::object obj = result.get();
|
|
||||||
switch(count++) {
|
|
||||||
case 0:
|
|
||||||
EXPECT_EQ(1, obj.as<int>());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
EXPECT_EQ(2, obj.as<int>());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
EXPECT_EQ(3, obj.as<int>());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_TRUE(input < eof);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class event_handler {
|
|
||||||
public:
|
|
||||||
event_handler(std::istream& input) : input(input) { }
|
|
||||||
~event_handler() { }
|
|
||||||
|
|
||||||
void on_read()
|
|
||||||
{
|
|
||||||
while(true) {
|
|
||||||
pac.reserve_buffer(32*1024);
|
|
||||||
|
|
||||||
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
|
|
||||||
|
|
||||||
if(len == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pac.buffer_consumed(len);
|
|
||||||
|
|
||||||
msgpack::unpacked result;
|
|
||||||
while(pac.next(&result)) {
|
|
||||||
on_message(result.get(), result.zone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pac.message_size() > 10*1024*1024) {
|
|
||||||
throw std::runtime_error("message is too large");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z)
|
|
||||||
{
|
|
||||||
EXPECT_EQ(expect, obj.as<int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
int expect;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::istream& input;
|
|
||||||
msgpack::unpacker pac;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(streaming, event)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
msgpack::packer<std::ostream> pk(&stream);
|
|
||||||
|
|
||||||
event_handler handler(stream);
|
|
||||||
|
|
||||||
pk.pack(1);
|
|
||||||
handler.expect = 1;
|
|
||||||
handler.on_read();
|
|
||||||
|
|
||||||
pk.pack(2);
|
|
||||||
handler.expect = 2;
|
|
||||||
handler.on_read();
|
|
||||||
|
|
||||||
pk.pack(3);
|
|
||||||
handler.expect = 3;
|
|
||||||
handler.on_read();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// backward compatibility
|
|
||||||
TEST(streaming, basic_compat)
|
|
||||||
{
|
|
||||||
std::ostringstream stream;
|
|
||||||
msgpack::packer<std::ostream> pk(&stream);
|
|
||||||
|
|
||||||
pk.pack(1);
|
|
||||||
pk.pack(2);
|
|
||||||
pk.pack(3);
|
|
||||||
|
|
||||||
std::istringstream input(stream.str());
|
|
||||||
|
|
||||||
msgpack::unpacker pac;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while(count < 3) {
|
|
||||||
pac.reserve_buffer(32*1024);
|
|
||||||
|
|
||||||
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
|
|
||||||
pac.buffer_consumed(len);
|
|
||||||
|
|
||||||
while(pac.execute()) {
|
|
||||||
std::auto_ptr<msgpack::zone> z(pac.release_zone());
|
|
||||||
msgpack::object obj = pac.data();
|
|
||||||
pac.reset();
|
|
||||||
|
|
||||||
switch(count++) {
|
|
||||||
case 0:
|
|
||||||
EXPECT_EQ(1, obj.as<int>());
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
EXPECT_EQ(2, obj.as<int>());
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
EXPECT_EQ(3, obj.as<int>());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// backward compatibility
|
|
||||||
class event_handler_compat {
|
|
||||||
public:
|
|
||||||
event_handler_compat(std::istream& input) : input(input) { }
|
|
||||||
~event_handler_compat() { }
|
|
||||||
|
|
||||||
void on_read()
|
|
||||||
{
|
|
||||||
while(true) {
|
|
||||||
pac.reserve_buffer(32*1024);
|
|
||||||
|
|
||||||
size_t len = input.readsome(pac.buffer(), pac.buffer_capacity());
|
|
||||||
|
|
||||||
if(len == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pac.buffer_consumed(len);
|
|
||||||
|
|
||||||
while(pac.execute()) {
|
|
||||||
std::auto_ptr<msgpack::zone> z(pac.release_zone());
|
|
||||||
msgpack::object obj = pac.data();
|
|
||||||
pac.reset();
|
|
||||||
on_message(obj, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pac.message_size() > 10*1024*1024) {
|
|
||||||
throw std::runtime_error("message is too large");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void on_message(msgpack::object obj, std::auto_ptr<msgpack::zone> z)
|
|
||||||
{
|
|
||||||
EXPECT_EQ(expect, obj.as<int>());
|
|
||||||
}
|
|
||||||
|
|
||||||
int expect;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::istream& input;
|
|
||||||
msgpack::unpacker pac;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(streaming, event_compat)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
msgpack::packer<std::ostream> pk(&stream);
|
|
||||||
|
|
||||||
event_handler_compat handler(stream);
|
|
||||||
|
|
||||||
pk.pack(1);
|
|
||||||
handler.expect = 1;
|
|
||||||
handler.on_read();
|
|
||||||
|
|
||||||
pk.pack(2);
|
|
||||||
handler.expect = 2;
|
|
||||||
handler.on_read();
|
|
||||||
|
|
||||||
pk.pack(3);
|
|
||||||
handler.expect = 3;
|
|
||||||
handler.on_read();
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#include <msgpack.h>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
TEST(streaming, basic)
|
|
||||||
{
|
|
||||||
msgpack_sbuffer* buffer = msgpack_sbuffer_new();
|
|
||||||
|
|
||||||
msgpack_packer* pk = msgpack_packer_new(buffer, msgpack_sbuffer_write);
|
|
||||||
|
|
||||||
// 1, 2, 3, "raw", ["data"], {0.3: 0.4}
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 1));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 2));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_int(pk, 3));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_raw(pk, 3));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_raw_body(pk, "raw", 3));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_array(pk, 1));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_raw(pk, 4));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_raw_body(pk, "data", 4));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_map(pk, 1));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_float(pk, 0.4));
|
|
||||||
EXPECT_EQ(0, msgpack_pack_double(pk, 0.8));
|
|
||||||
int max_count = 6;
|
|
||||||
|
|
||||||
msgpack_packer_free(pk);
|
|
||||||
|
|
||||||
const char* input = buffer->data;
|
|
||||||
const char* const eof = input + buffer->size;
|
|
||||||
|
|
||||||
msgpack_unpacker pac;
|
|
||||||
msgpack_unpacker_init(&pac, MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
msgpack_unpacked result;
|
|
||||||
msgpack_unpacked_init(&result);
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while(count < max_count) {
|
|
||||||
bool unpacked = false;
|
|
||||||
|
|
||||||
msgpack_unpacker_reserve_buffer(&pac, 32*1024);
|
|
||||||
|
|
||||||
while(!unpacked) {
|
|
||||||
/* read buffer into msgpack_unapcker_buffer(&pac) upto
|
|
||||||
* msgpack_unpacker_buffer_capacity(&pac) bytes. */
|
|
||||||
memcpy(msgpack_unpacker_buffer(&pac), input, 1);
|
|
||||||
input += 1;
|
|
||||||
|
|
||||||
EXPECT_TRUE(input <= eof);
|
|
||||||
|
|
||||||
msgpack_unpacker_buffer_consumed(&pac, 1);
|
|
||||||
|
|
||||||
while(msgpack_unpacker_next(&pac, &result)) {
|
|
||||||
unpacked = 1;
|
|
||||||
msgpack_object obj = result.data;
|
|
||||||
msgpack_object e;
|
|
||||||
switch(count++) {
|
|
||||||
case 0:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
|
||||||
EXPECT_EQ(1, obj.via.u64);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
|
||||||
EXPECT_EQ(2, obj.via.u64);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_POSITIVE_INTEGER, obj.type);
|
|
||||||
EXPECT_EQ(3, obj.via.u64);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_RAW, obj.type);
|
|
||||||
EXPECT_EQ(std::string("raw",3), std::string(obj.via.raw.ptr, obj.via.raw.size));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_ARRAY, obj.type);
|
|
||||||
EXPECT_EQ(1, obj.via.array.size);
|
|
||||||
e = obj.via.array.ptr[0];
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_RAW, e.type);
|
|
||||||
EXPECT_EQ(std::string("data",4), std::string(e.via.raw.ptr, e.via.raw.size));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_MAP, obj.type);
|
|
||||||
EXPECT_EQ(1, obj.via.map.size);
|
|
||||||
e = obj.via.map.ptr[0].key;
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
|
|
||||||
ASSERT_FLOAT_EQ(0.4, (float)e.via.dec);
|
|
||||||
e = obj.via.map.ptr[0].val;
|
|
||||||
EXPECT_EQ(MSGPACK_OBJECT_DOUBLE, e.type);
|
|
||||||
ASSERT_DOUBLE_EQ(0.8, e.via.dec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msgpack_unpacker_destroy(&pac);
|
|
||||||
msgpack_unpacked_destroy(&result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(version, print)
|
|
||||||
{
|
|
||||||
printf("MSGPACK_VERSION : %s\n", MSGPACK_VERSION);
|
|
||||||
printf("MSGPACK_VERSION_MAJOR : %d\n", MSGPACK_VERSION_MAJOR);
|
|
||||||
printf("MSGPACK_VERSION_MINOR : %d\n", MSGPACK_VERSION_MINOR);
|
|
||||||
printf("msgpack_version() : %s\n", msgpack_version());
|
|
||||||
printf("msgpack_version_major() : %d\n", msgpack_version_major());
|
|
||||||
printf("msgpack_version_minor() : %d\n", msgpack_version_minor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#include <msgpack.hpp>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(zone, malloc)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
char* buf1 = (char*)z.malloc(4);
|
|
||||||
memcpy(buf1, "test", 4);
|
|
||||||
char* buf2 = (char*)z.malloc(4);
|
|
||||||
memcpy(buf2, "test", 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class myclass {
|
|
||||||
public:
|
|
||||||
myclass() : num(0), str("default") { }
|
|
||||||
|
|
||||||
myclass(int num, const std::string& str) :
|
|
||||||
num(num), str(str) { }
|
|
||||||
|
|
||||||
~myclass() { }
|
|
||||||
|
|
||||||
int num;
|
|
||||||
std::string str;
|
|
||||||
|
|
||||||
private:
|
|
||||||
myclass(const myclass&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
TEST(zone, allocate)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
myclass* m = z.allocate<myclass>();
|
|
||||||
EXPECT_EQ(m->num, 0);
|
|
||||||
EXPECT_EQ(m->str, "default");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(zone, allocate_constructor)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
myclass* m = z.allocate<myclass>(7, "msgpack");
|
|
||||||
EXPECT_EQ(m->num, 7);
|
|
||||||
EXPECT_EQ(m->str, "msgpack");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void custom_finalizer_func(void* user)
|
|
||||||
{
|
|
||||||
myclass* m = (myclass*)user;
|
|
||||||
delete m;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(zone, push_finalizer)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
myclass* m = new myclass();
|
|
||||||
z.push_finalizer(custom_finalizer_func, (void*)m);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(zone, push_finalizer_auto_ptr)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
std::auto_ptr<myclass> am(new myclass());
|
|
||||||
z.push_finalizer(am);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(zone, malloc_no_align)
|
|
||||||
{
|
|
||||||
msgpack::zone z;
|
|
||||||
char* buf1 = (char*)z.malloc_no_align(4);
|
|
||||||
char* buf2 = (char*)z.malloc_no_align(4);
|
|
||||||
EXPECT_EQ(buf1+4, buf2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// or
|
// or
|
||||||
// $ port install msgpack # MacPorts
|
// $ port install msgpack # MacPorts
|
||||||
//
|
//
|
||||||
// $ g++ -Wall -lmsgpack crosslang.cc
|
// $ g++ -Wall crosslang.cc -lmsgpack
|
||||||
//
|
//
|
||||||
#include <msgpack.hpp>
|
#include <msgpack.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
155
erb/cpp03_define.hpp.erb
Normal file
155
erb/cpp03_define.hpp.erb
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for C++ static resolution routine
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
#ifndef MSGPACK_CPP03_DEFINE_HPP
|
||||||
|
#define MSGPACK_CPP03_DEFINE_HPP
|
||||||
|
|
||||||
|
#include "msgpack/versioning.hpp"
|
||||||
|
#include "msgpack/adaptor/msgpack_tuple_fwd.hpp"
|
||||||
|
#include "msgpack/object_fwd.hpp"
|
||||||
|
|
||||||
|
#define MSGPACK_DEFINE(...) \
|
||||||
|
template <typename Packer> \
|
||||||
|
void msgpack_pack(Packer& pk) const \
|
||||||
|
{ \
|
||||||
|
msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \
|
||||||
|
} \
|
||||||
|
void msgpack_unpack(msgpack::object const& o) \
|
||||||
|
{ \
|
||||||
|
msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \
|
||||||
|
}\
|
||||||
|
template <typename MSGPACK_OBJECT> \
|
||||||
|
void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \
|
||||||
|
{ \
|
||||||
|
msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// MSGPACK_ADD_ENUM must be used in the global namespace.
|
||||||
|
#define MSGPACK_ADD_ENUM(enum) \
|
||||||
|
namespace msgpack { \
|
||||||
|
MSGPACK_API_VERSION_NAMESPACE(v1) { \
|
||||||
|
template <> \
|
||||||
|
inline object const& operator>> (object const& o, enum& v) \
|
||||||
|
{ \
|
||||||
|
int tmp; \
|
||||||
|
o >> tmp; \
|
||||||
|
v = static_cast<enum>(tmp); \
|
||||||
|
return o; \
|
||||||
|
} \
|
||||||
|
template <> \
|
||||||
|
inline void operator<< (object::with_zone& o, const enum& v) \
|
||||||
|
{ \
|
||||||
|
o << static_cast<int>(v); \
|
||||||
|
} \
|
||||||
|
namespace detail { \
|
||||||
|
template <typename Stream> \
|
||||||
|
struct packer_serializer<Stream, enum> { \
|
||||||
|
static packer<Stream>& pack(packer<Stream>& o, const enum& v) { \
|
||||||
|
return o << static_cast<int>(v); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace msgpack {
|
||||||
|
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||||
|
namespace type {
|
||||||
|
|
||||||
|
|
||||||
|
<% GENERATION_LIMIT = 31 %>
|
||||||
|
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
|
||||||
|
struct define;
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct define<> {
|
||||||
|
typedef define<> value_type;
|
||||||
|
typedef tuple<> tuple_type;
|
||||||
|
template <typename Packer>
|
||||||
|
void msgpack_pack(Packer& pk) const
|
||||||
|
{
|
||||||
|
pk.pack_array(0);
|
||||||
|
}
|
||||||
|
void msgpack_unpack(msgpack::object const& o)
|
||||||
|
{
|
||||||
|
if(o.type != type::ARRAY) { throw type_error(); }
|
||||||
|
}
|
||||||
|
void msgpack_object(msgpack::object* o, msgpack::zone&) const
|
||||||
|
{
|
||||||
|
o->type = type::ARRAY;
|
||||||
|
o->via.array.ptr = nullptr;
|
||||||
|
o->via.array.size = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
struct define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
|
||||||
|
typedef define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
|
||||||
|
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type;
|
||||||
|
define(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) :
|
||||||
|
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
|
||||||
|
template <typename Packer>
|
||||||
|
void msgpack_pack(Packer& pk) const
|
||||||
|
{
|
||||||
|
pk.pack_array(<%=i+1%>);
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
pk.pack(a<%=j%>);<%}%>
|
||||||
|
}
|
||||||
|
void msgpack_unpack(msgpack::object const& o)
|
||||||
|
{
|
||||||
|
if(o.type != type::ARRAY) { throw type_error(); }
|
||||||
|
const size_t size = o.via.array.size;
|
||||||
|
if(size > 0) {
|
||||||
|
msgpack::object *ptr = o.via.array.ptr;
|
||||||
|
switch(size) {
|
||||||
|
default:<%(i).downto(0) {|j|%>
|
||||||
|
case <%=j+1%>: ptr[<%=j%>].convert(a<%=j%>);<%}%>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void msgpack_object(msgpack::object* o, msgpack::zone& z) const
|
||||||
|
{
|
||||||
|
o->type = type::ARRAY;
|
||||||
|
o->via.array.ptr = static_cast<object*>(z.allocate_align(sizeof(object)*<%=i+1%>));
|
||||||
|
o->via.array.size = <%=i+1%>;
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
o->via.array.ptr[<%=j%>] = object(a<%=j%>, z);<%}%>
|
||||||
|
}
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
A<%=j%>& a<%=j%>;<%}%>
|
||||||
|
};
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
inline define<> make_define()
|
||||||
|
{
|
||||||
|
return define<>();
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>)
|
||||||
|
{
|
||||||
|
return define<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // namespace type
|
||||||
|
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||||
|
} // namespace msgpack
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MSGPACK_CPP03_DEFINE_HPP
|
||||||
216
erb/cpp03_msgpack_tuple.hpp.erb
Normal file
216
erb/cpp03_msgpack_tuple.hpp.erb
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for C++ static resolution routine
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
|
||||||
|
//
|
||||||
|
// 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_CPP03_MSGPACK_TUPLE_HPP
|
||||||
|
#define MSGPACK_CPP03_MSGPACK_TUPLE_HPP
|
||||||
|
|
||||||
|
#include "msgpack/versioning.hpp"
|
||||||
|
#include "msgpack/object.hpp"
|
||||||
|
|
||||||
|
namespace msgpack {
|
||||||
|
|
||||||
|
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||||
|
|
||||||
|
namespace type {
|
||||||
|
|
||||||
|
// FIXME operator==
|
||||||
|
// FIXME operator!=
|
||||||
|
<% GENERATION_LIMIT = 31 %>
|
||||||
|
|
||||||
|
template <typename A0<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%><%}%>>
|
||||||
|
struct tuple;
|
||||||
|
|
||||||
|
template <typename Tuple, int N>
|
||||||
|
struct tuple_element;
|
||||||
|
|
||||||
|
template <typename Tuple, int N>
|
||||||
|
struct const_tuple_element;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct tuple_type {
|
||||||
|
typedef T type;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T& transparent_reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct tuple_type<T&> {
|
||||||
|
typedef T type;
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T& transparent_reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct tuple_type<const T&> {
|
||||||
|
typedef T type;
|
||||||
|
typedef T& value_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef const T& transparent_reference;
|
||||||
|
};
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
||||||
|
struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
|
||||||
|
tuple_element(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : m_x(x.a<%=j%>) {}
|
||||||
|
typename tuple_type<A<%=j%>>::reference get() { return m_x; }
|
||||||
|
typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; }
|
||||||
|
private:
|
||||||
|
typename tuple_type<A<%=j%>>::reference m_x;
|
||||||
|
};
|
||||||
|
<%}%>
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
||||||
|
struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_type<A<%=j%>> {
|
||||||
|
const_tuple_element(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : m_x(x.a<%=j%>) {}
|
||||||
|
typename tuple_type<A<%=j%>>::const_reference get() const { return m_x; }
|
||||||
|
private:
|
||||||
|
typename tuple_type<A<%=j%>>::const_reference m_x;
|
||||||
|
};
|
||||||
|
<%}%>
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct tuple<> {
|
||||||
|
tuple() {}
|
||||||
|
tuple(object const& o) { o.convert(*this); }
|
||||||
|
typedef tuple<> value_type;
|
||||||
|
};
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
|
||||||
|
typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type;
|
||||||
|
tuple() {}
|
||||||
|
tuple(typename tuple_type<A0>::transparent_reference _a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference _a<%=j%><%}%>) :
|
||||||
|
a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
|
||||||
|
tuple(object const& o) { o.convert(*this); }
|
||||||
|
template <int N> typename tuple_element<value_type, N>::reference get()
|
||||||
|
{ return tuple_element<value_type, N>(*this).get(); }
|
||||||
|
template <int N> typename const_tuple_element<value_type, N>::const_reference get() const
|
||||||
|
{ return const_tuple_element<value_type, N>(*this).get(); }
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
A<%=j%> a<%=j%>;<%}%>
|
||||||
|
};
|
||||||
|
|
||||||
|
template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline typename type::tuple_element<type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::reference get(type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& t)
|
||||||
|
{ return t.template get<N>(); }
|
||||||
|
template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline typename type::const_tuple_element<type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::const_reference get(type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> const& t)
|
||||||
|
{ return t.template get<N>(); }
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
inline tuple<> make_tuple()
|
||||||
|
{
|
||||||
|
return tuple<>();
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>)
|
||||||
|
{
|
||||||
|
return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // namespace type
|
||||||
|
|
||||||
|
inline object const& operator>> (
|
||||||
|
object const& o,
|
||||||
|
type::tuple<>&) {
|
||||||
|
if(o.type != type::ARRAY) { throw type_error(); }
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline object const& operator>> (
|
||||||
|
object const& o,
|
||||||
|
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
||||||
|
if(o.type != type::ARRAY) { throw type_error(); }
|
||||||
|
if(o.via.array.size < <%=i+1%>) { throw type_error(); }
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
o.via.array.ptr[<%=j%>].convert<typename type::tuple_type<A<%=j%>>::type>(v.template get<<%=j%>>());<%}%>
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
template <typename Stream>
|
||||||
|
inline const packer<Stream>& operator<< (
|
||||||
|
packer<Stream>& o,
|
||||||
|
const type::tuple<>&) {
|
||||||
|
o.pack_array(0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline const packer<Stream>& operator<< (
|
||||||
|
packer<Stream>& o,
|
||||||
|
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
||||||
|
o.pack_array(<%=i+1%>);
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
o.pack(v.template get<<%=j%>>());<%}%>
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
inline void operator<< (
|
||||||
|
object::with_zone& o,
|
||||||
|
const type::tuple<>&) {
|
||||||
|
o.type = type::ARRAY;
|
||||||
|
o.via.array.ptr = nullptr;
|
||||||
|
o.via.array.size = 0;
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
inline void operator<< (
|
||||||
|
object::with_zone& o,
|
||||||
|
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
||||||
|
o.type = type::ARRAY;
|
||||||
|
o.via.array.ptr = static_cast<object*>(o.zone.allocate_align(sizeof(object)*<%=i+1%>));
|
||||||
|
o.via.array.size = <%=i+1%>;
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
o.via.array.ptr[<%=j%>] = object(v.template get<<%=j%>>(), o.zone);<%}%>
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||||
|
|
||||||
|
} // namespace msgpack
|
||||||
|
|
||||||
|
|
||||||
|
//inline std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v) {
|
||||||
|
// return o << "[]";
|
||||||
|
//}
|
||||||
|
//<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
//template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
//inline std::ostream& operator<< (std::ostream& o,
|
||||||
|
// const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
|
||||||
|
// return o << "["
|
||||||
|
// <%0.upto(i) {|j|%>
|
||||||
|
// <<<%if j != 0 then%> ", " <<<%end%> v.template get<<%=j%>>()<%}%>
|
||||||
|
// << "]";
|
||||||
|
//}
|
||||||
|
//<%}%>
|
||||||
|
|
||||||
|
#endif // MSGPACK_CPP03_MSGPACK_TUPLE_HPP
|
||||||
125
erb/cpp03_msgpack_tuple_fwd.hpp.erb
Normal file
125
erb/cpp03_msgpack_tuple_fwd.hpp.erb
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for C++ static resolution routine
|
||||||
|
//
|
||||||
|
// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi
|
||||||
|
//
|
||||||
|
// 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_CPP03_MSGPACK_TUPLE_FWD_HPP
|
||||||
|
#define MSGPACK_CPP03_MSGPACK_TUPLE_FWD_HPP
|
||||||
|
|
||||||
|
#include "msgpack/versioning.hpp"
|
||||||
|
#include "msgpack/object_fwd.hpp"
|
||||||
|
|
||||||
|
namespace msgpack {
|
||||||
|
|
||||||
|
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||||
|
|
||||||
|
namespace type {
|
||||||
|
|
||||||
|
// FIXME operator==
|
||||||
|
// FIXME operator!=
|
||||||
|
<% GENERATION_LIMIT = 31 %>
|
||||||
|
|
||||||
|
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
|
||||||
|
struct tuple;
|
||||||
|
|
||||||
|
template <typename Tuple, int N>
|
||||||
|
struct tuple_element;
|
||||||
|
|
||||||
|
template <typename Tuple, int N>
|
||||||
|
struct const_tuple_element;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct tuple_type;
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
||||||
|
struct tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>>;
|
||||||
|
<%}%>
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
<%0.upto(i) {|j|%>
|
||||||
|
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
|
||||||
|
struct const_tuple_element<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>>;
|
||||||
|
<%}%>
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct tuple<>;
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>;
|
||||||
|
|
||||||
|
template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
typename type::tuple_element<type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::reference get(type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& t);
|
||||||
|
template <int N, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
typename type::const_tuple_element<type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::const_reference get(type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> const& t);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
tuple<> make_tuple();
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(typename tuple_type<A0>::transparent_reference a0<%1.upto(i) {|j|%>, typename tuple_type<A<%=j%>>::transparent_reference a<%=j%><%}%>);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // namespace type
|
||||||
|
|
||||||
|
object const& operator>> (
|
||||||
|
object const& o,
|
||||||
|
type::tuple<>&);
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
object const& operator>> (
|
||||||
|
object const& o,
|
||||||
|
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
template <typename Stream>
|
||||||
|
const packer<Stream>& operator<< (
|
||||||
|
packer<Stream>& o,
|
||||||
|
const type::tuple<>&);
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
const packer<Stream>& operator<< (
|
||||||
|
packer<Stream>& o,
|
||||||
|
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
void operator<< (
|
||||||
|
object::with_zone& o,
|
||||||
|
const type::tuple<>&);
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
void operator<< (
|
||||||
|
object::with_zone& o,
|
||||||
|
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||||
|
|
||||||
|
} // namespace msgpack
|
||||||
|
|
||||||
|
|
||||||
|
//std::ostream& operator<< (std::ostream& o, const msgpack::type::tuple<>& v);
|
||||||
|
//<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
//template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
//std::ostream& operator<< (std::ostream& o,
|
||||||
|
// const msgpack::type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v);
|
||||||
|
//<%}%>
|
||||||
|
|
||||||
|
#endif // MSGPACK_CPP03_MSGPACK_TUPLE_FWD_HPP
|
||||||
310
erb/cpp03_zone.hpp.erb
Normal file
310
erb/cpp03_zone.hpp.erb
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for C++ memory pool
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
#ifndef MSGPACK_CPP03_ZONE_HPP
|
||||||
|
#define MSGPACK_CPP03_ZONE_HPP
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "msgpack/versioning.hpp"
|
||||||
|
|
||||||
|
#ifndef MSGPACK_ZONE_CHUNK_SIZE
|
||||||
|
#define MSGPACK_ZONE_CHUNK_SIZE 8192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MSGPACK_ZONE_ALIGN
|
||||||
|
#define MSGPACK_ZONE_ALIGN sizeof(int)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
<% GENERATION_LIMIT = 15 %>
|
||||||
|
namespace msgpack {
|
||||||
|
|
||||||
|
MSGPACK_API_VERSION_NAMESPACE(v1) {
|
||||||
|
|
||||||
|
class zone {
|
||||||
|
struct finalizer {
|
||||||
|
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
|
||||||
|
void operator()() { m_func(m_data); }
|
||||||
|
void (*m_func)(void*);
|
||||||
|
void* m_data;
|
||||||
|
};
|
||||||
|
struct finalizer_array {
|
||||||
|
finalizer_array():m_tail(nullptr), m_end(nullptr), m_array(nullptr) {}
|
||||||
|
void call() {
|
||||||
|
finalizer* fin = m_tail;
|
||||||
|
for(; fin != m_array; --fin) (*(fin-1))();
|
||||||
|
}
|
||||||
|
~finalizer_array() {
|
||||||
|
call();
|
||||||
|
::free(m_array);
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
call();
|
||||||
|
m_tail = m_array;
|
||||||
|
}
|
||||||
|
void push(void (*func)(void* data), void* data)
|
||||||
|
{
|
||||||
|
finalizer* fin = m_tail;
|
||||||
|
|
||||||
|
if(fin == m_end) {
|
||||||
|
push_expand(func, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fin->m_func = func;
|
||||||
|
fin->m_data = data;
|
||||||
|
|
||||||
|
++m_tail;
|
||||||
|
}
|
||||||
|
void push_expand(void (*func)(void*), void* data) {
|
||||||
|
const size_t nused = m_end - m_array;
|
||||||
|
size_t nnext;
|
||||||
|
if(nused == 0) {
|
||||||
|
nnext = (sizeof(finalizer) < 72/2) ?
|
||||||
|
72 / sizeof(finalizer) : 8;
|
||||||
|
} else {
|
||||||
|
nnext = nused * 2;
|
||||||
|
}
|
||||||
|
finalizer* tmp =
|
||||||
|
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
|
||||||
|
if(!tmp) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
m_array = tmp;
|
||||||
|
m_end = tmp + nnext;
|
||||||
|
m_tail = tmp + nused;
|
||||||
|
new (m_tail) finalizer(func, data);
|
||||||
|
|
||||||
|
++m_tail;
|
||||||
|
}
|
||||||
|
finalizer* m_tail;
|
||||||
|
finalizer* m_end;
|
||||||
|
finalizer* m_array;
|
||||||
|
};
|
||||||
|
struct chunk {
|
||||||
|
chunk* m_next;
|
||||||
|
};
|
||||||
|
struct chunk_list {
|
||||||
|
chunk_list(size_t chunk_size)
|
||||||
|
{
|
||||||
|
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
|
||||||
|
if(!c) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_head = c;
|
||||||
|
m_free = chunk_size;
|
||||||
|
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
||||||
|
c->m_next = nullptr;
|
||||||
|
}
|
||||||
|
~chunk_list()
|
||||||
|
{
|
||||||
|
chunk* c = m_head;
|
||||||
|
while(c) {
|
||||||
|
chunk* n = c->m_next;
|
||||||
|
::free(c);
|
||||||
|
c = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void clear(size_t chunk_size)
|
||||||
|
{
|
||||||
|
chunk* c = m_head;
|
||||||
|
while(true) {
|
||||||
|
chunk* n = c->m_next;
|
||||||
|
if(n) {
|
||||||
|
::free(c);
|
||||||
|
c = n;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_head->m_next = nullptr;
|
||||||
|
m_free = chunk_size;
|
||||||
|
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
|
||||||
|
}
|
||||||
|
size_t m_free;
|
||||||
|
char* m_ptr;
|
||||||
|
chunk* m_head;
|
||||||
|
};
|
||||||
|
size_t m_chunk_size;
|
||||||
|
chunk_list m_chunk_list;
|
||||||
|
finalizer_array m_finalizer_array;
|
||||||
|
|
||||||
|
public:
|
||||||
|
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE) /* throw() */;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void* allocate_align(size_t size);
|
||||||
|
void* allocate_no_align(size_t size);
|
||||||
|
|
||||||
|
void push_finalizer(void (*func)(void*), void* data);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void push_finalizer(msgpack::unique_ptr<T> obj);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void swap(zone& o);
|
||||||
|
static void* operator new(std::size_t size) throw(std::bad_alloc)
|
||||||
|
{
|
||||||
|
void* p = ::malloc(size);
|
||||||
|
if (!p) throw std::bad_alloc();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
static void operator delete(void *p) throw()
|
||||||
|
{
|
||||||
|
::free(p);
|
||||||
|
}
|
||||||
|
static void* operator new(std::size_t size, void* place) throw()
|
||||||
|
{
|
||||||
|
return ::operator new(size, place);
|
||||||
|
}
|
||||||
|
static void operator delete(void* p, void* place) throw()
|
||||||
|
{
|
||||||
|
::operator delete(p, place);
|
||||||
|
}
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
T* allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>);
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
private:
|
||||||
|
void undo_allocate(size_t size);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void object_destruct(void* obj);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void object_delete(void* obj);
|
||||||
|
|
||||||
|
void* allocate_expand(size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline zone::zone(size_t chunk_size) /* throw() */ :m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* zone::allocate_align(size_t size)
|
||||||
|
{
|
||||||
|
return allocate_no_align(
|
||||||
|
((size)+((MSGPACK_ZONE_ALIGN)-1)) & ~((MSGPACK_ZONE_ALIGN)-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* zone::allocate_no_align(size_t size)
|
||||||
|
{
|
||||||
|
if(m_chunk_list.m_free < size) {
|
||||||
|
return allocate_expand(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* ptr = m_chunk_list.m_ptr;
|
||||||
|
m_chunk_list.m_free -= size;
|
||||||
|
m_chunk_list.m_ptr += size;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* zone::allocate_expand(size_t size)
|
||||||
|
{
|
||||||
|
chunk_list* const cl = &m_chunk_list;
|
||||||
|
|
||||||
|
size_t sz = m_chunk_size;
|
||||||
|
|
||||||
|
while(sz < size) {
|
||||||
|
sz *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
|
||||||
|
if (!c) throw std::bad_alloc();
|
||||||
|
|
||||||
|
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
|
||||||
|
|
||||||
|
c->m_next = cl->m_head;
|
||||||
|
cl->m_head = c;
|
||||||
|
cl->m_free = sz - size;
|
||||||
|
cl->m_ptr = ptr + size;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void zone::push_finalizer(void (*func)(void*), void* data)
|
||||||
|
{
|
||||||
|
m_finalizer_array.push(func, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
|
||||||
|
{
|
||||||
|
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void zone::clear()
|
||||||
|
{
|
||||||
|
m_finalizer_array.clear();
|
||||||
|
m_chunk_list.clear(m_chunk_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void zone::swap(zone& o)
|
||||||
|
{
|
||||||
|
std::swap(*this, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void zone::object_destruct(void* obj)
|
||||||
|
{
|
||||||
|
static_cast<T*>(obj)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void zone::object_delete(void* obj)
|
||||||
|
{
|
||||||
|
delete static_cast<T*>(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void zone::undo_allocate(size_t size)
|
||||||
|
{
|
||||||
|
m_chunk_list.m_ptr -= size;
|
||||||
|
m_chunk_list.m_free += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
|
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
|
||||||
|
T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
|
||||||
|
{
|
||||||
|
void* x = allocate_align(sizeof(T));
|
||||||
|
try {
|
||||||
|
m_finalizer_array.push(&zone::object_destruct<T>, x);
|
||||||
|
} catch (...) {
|
||||||
|
undo_allocate(sizeof(T));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
|
||||||
|
} catch (...) {
|
||||||
|
--m_finalizer_array.m_tail;
|
||||||
|
undo_allocate(sizeof(T));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
|
} // MSGPACK_API_VERSION_NAMESPACE(v1)
|
||||||
|
|
||||||
|
} // namespace msgpack
|
||||||
|
|
||||||
|
#endif // MSGPACK_CPP03_ZONE_HPP
|
||||||
5
erlang/.gitignore
vendored
5
erlang/.gitignore
vendored
@@ -1,5 +0,0 @@
|
|||||||
MANIFEST
|
|
||||||
*.beam
|
|
||||||
.omakedb*
|
|
||||||
*.omc
|
|
||||||
*~
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
# Permission is hereby granted, free of charge, to any person
|
|
||||||
# obtaining a copy of this file, to deal in the File without
|
|
||||||
# restriction, including without limitation the rights to use,
|
|
||||||
# copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
# sell copies of the File, and to permit persons to whom the
|
|
||||||
# File is furnished to do so, subject to the following condition:
|
|
||||||
#
|
|
||||||
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR
|
|
||||||
# THE USE OR OTHER DEALINGS IN THE FILE.
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# The standard OMakefile.
|
|
||||||
# You will usually need to modify this file for your project.
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# Phony targets are scoped, so you probably want to declare them first.
|
|
||||||
#
|
|
||||||
|
|
||||||
.PHONY: all clean test edoc dialyzer #install
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# Subdirectories.
|
|
||||||
# You may want to include some subdirectories in this project.
|
|
||||||
# If so, define the subdirectory targets and uncomment this section.
|
|
||||||
#
|
|
||||||
|
|
||||||
.DEFAULT: msgpack.beam
|
|
||||||
|
|
||||||
msgpack.beam: msgpack.erl
|
|
||||||
erlc -Wall +debug_info $<
|
|
||||||
|
|
||||||
msgpack.html: msgpack.erl
|
|
||||||
erl -noshell -run edoc_run file $<
|
|
||||||
|
|
||||||
test: msgpack.beam
|
|
||||||
erl -noshell -s msgpack test -s init stop
|
|
||||||
|
|
||||||
edoc: msgpack.erl
|
|
||||||
erl -noshell -eval 'ok=edoc:files(["msgpack.erl"], [{dir, "edoc"}]).' -s init stop
|
|
||||||
|
|
||||||
dialyzer: msgpack.erl
|
|
||||||
dialyzer --src $<
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -f *.beam *.html
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
########################################################################
|
|
||||||
# Permission is hereby granted, free of charge, to any person
|
|
||||||
# obtaining a copy of this file, to deal in the File without
|
|
||||||
# restriction, including without limitation the rights to use,
|
|
||||||
# copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
# sell copies of the File, and to permit persons to whom the
|
|
||||||
# File is furnished to do so, subject to the following condition:
|
|
||||||
#
|
|
||||||
# THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE FILE OR
|
|
||||||
# THE USE OR OTHER DEALINGS IN THE FILE.
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# The standard OMakeroot file.
|
|
||||||
# You will not normally need to modify this file.
|
|
||||||
# By default, your changes should be placed in the
|
|
||||||
# OMakefile in this directory.
|
|
||||||
#
|
|
||||||
# If you decide to modify this file, note that it uses exactly
|
|
||||||
# the same syntax as the OMakefile.
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Include the standard installed configuration files.
|
|
||||||
# Any of these can be deleted if you are not using them,
|
|
||||||
# but you probably want to keep the Common file.
|
|
||||||
#
|
|
||||||
open build/C
|
|
||||||
open build/OCaml
|
|
||||||
open build/LaTeX
|
|
||||||
|
|
||||||
#
|
|
||||||
# The command-line variables are defined *after* the
|
|
||||||
# standard configuration has been loaded.
|
|
||||||
#
|
|
||||||
DefineCommandVars()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Include the OMakefile in this directory.
|
|
||||||
#
|
|
||||||
.SUBDIRS: .
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
MessagePack for Erlang
|
|
||||||
======================
|
|
||||||
Binary-based efficient object serialization library.
|
|
||||||
|
|
||||||
see wiki ( http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartErlang ) for details
|
|
||||||
|
|
||||||
# Status
|
|
||||||
|
|
||||||
0.1.0 released.
|
|
||||||
4
erlang/edoc/.gitignore
vendored
4
erlang/edoc/.gitignore
vendored
@@ -1,4 +0,0 @@
|
|||||||
*.html
|
|
||||||
*.css
|
|
||||||
*.png
|
|
||||||
edoc-info
|
|
||||||
@@ -1,395 +0,0 @@
|
|||||||
%%
|
|
||||||
%% MessagePack for Erlang
|
|
||||||
%%
|
|
||||||
%% Copyright (C) 2009-2010 UENISHI Kota
|
|
||||||
%%
|
|
||||||
%% 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.
|
|
||||||
|
|
||||||
|
|
||||||
%% @doc <a href="http://msgpack.org/">MessagePack</a> codec for Erlang.
|
|
||||||
%%
|
|
||||||
%% APIs are almost compatible with <a href="http://redmine.msgpack.org/projects/msgpack/wiki/QuickStartC">C API</a>
|
|
||||||
%% except for buffering functions (both copying and zero-copying), which are unavailable.
|
|
||||||
%%
|
|
||||||
%% <table border="1">
|
|
||||||
%% <caption>Equivalence between Erlang and <a href="http://msgpack.sourceforge.jp/spec">Msgpack type</a> :</caption>
|
|
||||||
%% <tr><th> erlang </th><th> msgpack </th></tr>
|
|
||||||
%% <tr><td> integer() </td><td> pos_fixnum/neg_fixnum/uint8/uint16/uint32/uint64/int8/int16/int32/int64 </td></tr>
|
|
||||||
%% <tr><td> float() </td><td> float/double </td></tr>
|
|
||||||
%% <tr><td> nil </td><td> nil </td></tr>
|
|
||||||
%% <tr><td> boolean() </td><td> boolean </td></tr>
|
|
||||||
%% <tr><td> binary() </td><td> fix_raw/raw16/raw32 </td></tr>
|
|
||||||
%% <tr><td> list() </td><td> fix_array/array16/array32 </td></tr>
|
|
||||||
%% <tr><td> {proplist()} </td><td> fix_map/map16/map32 </td></tr>
|
|
||||||
%% </table>
|
|
||||||
%% @end
|
|
||||||
|
|
||||||
-module(msgpack).
|
|
||||||
-author('kuenishi+msgpack@gmail.com').
|
|
||||||
|
|
||||||
-export([pack/1, unpack/1, unpack_all/1]).
|
|
||||||
|
|
||||||
% @type msgpack_term() = [msgpack_term()]
|
|
||||||
% | {[{msgpack_term(),msgpack_term()}]}
|
|
||||||
% | integer() | float() | binary().
|
|
||||||
% Erlang representation of msgpack data.
|
|
||||||
-type msgpack_term() :: [msgpack_term()]
|
|
||||||
| {[{msgpack_term(),msgpack_term()}]}
|
|
||||||
| integer() | float() | binary().
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% external APIs
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
% @doc Encode an erlang term into an msgpack binary.
|
|
||||||
% Returns {error, {badarg, term()}} if the input is illegal.
|
|
||||||
% @spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}
|
|
||||||
-spec pack(Term::msgpack_term()) -> binary() | {error, {badarg, term()}}.
|
|
||||||
pack(Term)->
|
|
||||||
try
|
|
||||||
pack_(Term)
|
|
||||||
catch
|
|
||||||
throw:Exception ->
|
|
||||||
{error, Exception}
|
|
||||||
end.
|
|
||||||
|
|
||||||
% @doc Decode an msgpack binary into an erlang term.
|
|
||||||
% It only decodes the first msgpack packet contained in the binary; the rest is returned as is.
|
|
||||||
% Returns {error, {badarg, term()}} if the input is corrupted.
|
|
||||||
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
|
|
||||||
% @spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}
|
|
||||||
-spec unpack(Bin::binary()) -> {msgpack_term(), binary()} | {error, incomplete} | {error, {badarg, term()}}.
|
|
||||||
unpack(Bin) when is_binary(Bin) ->
|
|
||||||
try
|
|
||||||
unpack_(Bin)
|
|
||||||
catch
|
|
||||||
throw:Exception ->
|
|
||||||
{error, Exception}
|
|
||||||
end;
|
|
||||||
unpack(Other) ->
|
|
||||||
{error, {badarg, Other}}.
|
|
||||||
|
|
||||||
% @doc Decode an msgpack binary into an erlang terms.
|
|
||||||
% It only decodes ALL msgpack packets contained in the binary. No packets should not remain.
|
|
||||||
% Returns {error, {badarg, term()}} if the input is corrupted.
|
|
||||||
% Returns {error, incomplete} if the input is not a full msgpack packet (caller should gather more data and try again).
|
|
||||||
% @spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}
|
|
||||||
-spec unpack_all(binary()) -> [msgpack_term()] | {error, incomplete} | {error, {badarg, term()}}.
|
|
||||||
unpack_all(Data)->
|
|
||||||
try
|
|
||||||
unpack_all_(Data)
|
|
||||||
catch
|
|
||||||
throw:Exception ->
|
|
||||||
{error, Exception}
|
|
||||||
end.
|
|
||||||
unpack_all_(Data)->
|
|
||||||
case unpack_(Data) of
|
|
||||||
{ Term, <<>> } ->
|
|
||||||
[Term];
|
|
||||||
{ Term, Binary } when is_binary(Binary) ->
|
|
||||||
[Term|unpack_all_(Binary)]
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% internal APIs
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
% pack them all
|
|
||||||
-spec pack_(msgpack_term()) -> binary() | no_return().
|
|
||||||
pack_(I) when is_integer(I) andalso I < 0 ->
|
|
||||||
pack_int_(I);
|
|
||||||
pack_(I) when is_integer(I) ->
|
|
||||||
pack_uint_(I);
|
|
||||||
pack_(F) when is_float(F) ->
|
|
||||||
pack_double(F);
|
|
||||||
pack_(nil) ->
|
|
||||||
<< 16#C0:8 >>;
|
|
||||||
pack_(true) ->
|
|
||||||
<< 16#C3:8 >>;
|
|
||||||
pack_(false) ->
|
|
||||||
<< 16#C2:8 >>;
|
|
||||||
pack_(Bin) when is_binary(Bin) ->
|
|
||||||
pack_raw(Bin);
|
|
||||||
pack_(List) when is_list(List) ->
|
|
||||||
pack_array(List);
|
|
||||||
pack_({Map}) when is_list(Map) ->
|
|
||||||
pack_map(Map);
|
|
||||||
pack_(Other) ->
|
|
||||||
throw({badarg, Other}).
|
|
||||||
|
|
||||||
|
|
||||||
-spec pack_uint_(non_neg_integer()) -> binary().
|
|
||||||
% positive fixnum
|
|
||||||
pack_uint_(N) when N < 128 ->
|
|
||||||
<< 2#0:1, N:7 >>;
|
|
||||||
% uint 8
|
|
||||||
pack_uint_(N) when N < 256 ->
|
|
||||||
<< 16#CC:8, N:8 >>;
|
|
||||||
% uint 16
|
|
||||||
pack_uint_(N) when N < 65536 ->
|
|
||||||
<< 16#CD:8, N:16/big-unsigned-integer-unit:1 >>;
|
|
||||||
% uint 32
|
|
||||||
pack_uint_(N) when N < 16#FFFFFFFF->
|
|
||||||
<< 16#CE:8, N:32/big-unsigned-integer-unit:1 >>;
|
|
||||||
% uint 64
|
|
||||||
pack_uint_(N) ->
|
|
||||||
<< 16#CF:8, N:64/big-unsigned-integer-unit:1 >>.
|
|
||||||
|
|
||||||
-spec pack_int_(integer()) -> binary().
|
|
||||||
% negative fixnum
|
|
||||||
pack_int_(N) when N >= -32->
|
|
||||||
<< 2#111:3, N:5 >>;
|
|
||||||
% int 8
|
|
||||||
pack_int_(N) when N > -128 ->
|
|
||||||
<< 16#D0:8, N:8/big-signed-integer-unit:1 >>;
|
|
||||||
% int 16
|
|
||||||
pack_int_(N) when N > -32768 ->
|
|
||||||
<< 16#D1:8, N:16/big-signed-integer-unit:1 >>;
|
|
||||||
% int 32
|
|
||||||
pack_int_(N) when N > -16#FFFFFFFF ->
|
|
||||||
<< 16#D2:8, N:32/big-signed-integer-unit:1 >>;
|
|
||||||
% int 64
|
|
||||||
pack_int_(N) ->
|
|
||||||
<< 16#D3:8, N:64/big-signed-integer-unit:1 >>.
|
|
||||||
|
|
||||||
|
|
||||||
-spec pack_double(float()) -> binary().
|
|
||||||
% float : erlang's float is always IEEE 754 64bit format.
|
|
||||||
% pack_float(F) when is_float(F)->
|
|
||||||
% << 16#CA:8, F:32/big-float-unit:1 >>.
|
|
||||||
% pack_double(F).
|
|
||||||
% double
|
|
||||||
pack_double(F) ->
|
|
||||||
<< 16#CB:8, F:64/big-float-unit:1 >>.
|
|
||||||
|
|
||||||
|
|
||||||
-spec pack_raw(binary()) -> binary().
|
|
||||||
% raw bytes
|
|
||||||
pack_raw(Bin) ->
|
|
||||||
case byte_size(Bin) of
|
|
||||||
Len when Len < 6->
|
|
||||||
<< 2#101:3, Len:5, Bin/binary >>;
|
|
||||||
Len when Len < 16#10000 -> % 65536
|
|
||||||
<< 16#DA:8, Len:16/big-unsigned-integer-unit:1, Bin/binary >>;
|
|
||||||
Len ->
|
|
||||||
<< 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >>
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
-spec pack_array([msgpack_term()]) -> binary() | no_return().
|
|
||||||
% list
|
|
||||||
pack_array(L) ->
|
|
||||||
case length(L) of
|
|
||||||
Len when Len < 16 ->
|
|
||||||
<< 2#1001:4, Len:4/integer-unit:1, (pack_array_(L, <<>>))/binary >>;
|
|
||||||
Len when Len < 16#10000 -> % 65536
|
|
||||||
<< 16#DC:8, Len:16/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>;
|
|
||||||
Len ->
|
|
||||||
<< 16#DD:8, Len:32/big-unsigned-integer-unit:1, (pack_array_(L, <<>>))/binary >>
|
|
||||||
end.
|
|
||||||
|
|
||||||
pack_array_([], Acc) -> Acc;
|
|
||||||
pack_array_([Head|Tail], Acc) ->
|
|
||||||
pack_array_(Tail, <<Acc/binary, (pack_(Head))/binary>>).
|
|
||||||
|
|
||||||
% Users SHOULD NOT send too long list: this uses lists:reverse/1
|
|
||||||
-spec unpack_array_(binary(), non_neg_integer(), [msgpack_term()]) -> {[msgpack_term()], binary()} | no_return().
|
|
||||||
unpack_array_(Bin, 0, Acc) -> {lists:reverse(Acc), Bin};
|
|
||||||
unpack_array_(Bin, Len, Acc) ->
|
|
||||||
{Term, Rest} = unpack_(Bin),
|
|
||||||
unpack_array_(Rest, Len-1, [Term|Acc]).
|
|
||||||
|
|
||||||
|
|
||||||
-spec pack_map(M::[{msgpack_term(),msgpack_term()}]) -> binary() | no_return().
|
|
||||||
pack_map(M)->
|
|
||||||
case length(M) of
|
|
||||||
Len when Len < 16 ->
|
|
||||||
<< 2#1000:4, Len:4/integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
|
||||||
Len when Len < 16#10000 -> % 65536
|
|
||||||
<< 16#DE:8, Len:16/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>;
|
|
||||||
Len ->
|
|
||||||
<< 16#DF:8, Len:32/big-unsigned-integer-unit:1, (pack_map_(M, <<>>))/binary >>
|
|
||||||
end.
|
|
||||||
|
|
||||||
pack_map_([], Acc) -> Acc;
|
|
||||||
pack_map_([{Key,Value}|Tail], Acc) ->
|
|
||||||
pack_map_(Tail, << Acc/binary, (pack_(Key))/binary, (pack_(Value))/binary>>).
|
|
||||||
|
|
||||||
% Users SHOULD NOT send too long list: this uses lists:reverse/1
|
|
||||||
-spec unpack_map_(binary(), non_neg_integer(), [{msgpack_term(), msgpack_term()}]) ->
|
|
||||||
{{[{msgpack_term(), msgpack_term()}]}, binary()} | no_return().
|
|
||||||
unpack_map_(Bin, 0, Acc) -> {{lists:reverse(Acc)}, Bin};
|
|
||||||
unpack_map_(Bin, Len, Acc) ->
|
|
||||||
{Key, Rest} = unpack_(Bin),
|
|
||||||
{Value, Rest2} = unpack_(Rest),
|
|
||||||
unpack_map_(Rest2, Len-1, [{Key,Value}|Acc]).
|
|
||||||
|
|
||||||
% unpack them all
|
|
||||||
-spec unpack_(Bin::binary()) -> {msgpack_term(), binary()} | no_return().
|
|
||||||
unpack_(Bin) ->
|
|
||||||
case Bin of
|
|
||||||
% ATOMS
|
|
||||||
<<16#C0, Rest/binary>> -> {nil, Rest};
|
|
||||||
<<16#C2, Rest/binary>> -> {false, Rest};
|
|
||||||
<<16#C3, Rest/binary>> -> {true, Rest};
|
|
||||||
% Floats
|
|
||||||
<<16#CA, V:32/float-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#CB, V:64/float-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
% Unsigned integers
|
|
||||||
<<16#CC, V:8/unsigned-integer, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#CD, V:16/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#CE, V:32/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#CF, V:64/big-unsigned-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
% Signed integers
|
|
||||||
<<16#D0, V:8/signed-integer, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#D1, V:16/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#D2, V:32/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#D3, V:64/big-signed-integer-unit:1, Rest/binary>> -> {V, Rest};
|
|
||||||
% Raw bytes
|
|
||||||
<<16#DA, L:16/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest};
|
|
||||||
<<16#DB, L:32/unsigned-integer-unit:1, V:L/binary, Rest/binary>> -> {V, Rest};
|
|
||||||
% Arrays
|
|
||||||
<<16#DC, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []);
|
|
||||||
<<16#DD, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_array_(Rest, L, []);
|
|
||||||
% Maps
|
|
||||||
<<16#DE, L:16/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []);
|
|
||||||
<<16#DF, L:32/big-unsigned-integer-unit:1, Rest/binary>> -> unpack_map_(Rest, L, []);
|
|
||||||
|
|
||||||
% Tag-encoded lengths (kept last, for speed)
|
|
||||||
<<0:1, V:7, Rest/binary>> -> {V, Rest}; % positive int
|
|
||||||
<<2#111:3, V:5, Rest/binary>> -> {V - 2#100000, Rest}; % negative int
|
|
||||||
<<2#101:3, L:5, V:L/binary, Rest/binary>> -> {V, Rest}; % raw bytes
|
|
||||||
<<2#1001:4, L:4, Rest/binary>> -> unpack_array_(Rest, L, []); % array
|
|
||||||
<<2#1000:4, L:4, Rest/binary>> -> unpack_map_(Rest, L, []); % map
|
|
||||||
|
|
||||||
% Invalid data
|
|
||||||
<<F, R/binary>> when F==16#C1;
|
|
||||||
F==16#C4; F==16#C5; F==16#C6; F==16#C7; F==16#C8; F==16#C9;
|
|
||||||
F==16#D4; F==16#D5; F==16#D6; F==16#D7; F==16#D8; F==16#D9 ->
|
|
||||||
throw({badarg, <<F, R/binary>>});
|
|
||||||
% Incomplete data (we've covered every complete/invalid case; anything left is incomplete)
|
|
||||||
_ ->
|
|
||||||
throw(incomplete)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
% unit tests
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
|
||||||
-ifdef(EUNIT).
|
|
||||||
|
|
||||||
compare_all([], [])-> ok;
|
|
||||||
compare_all([], R)-> {toomuchrhs, R};
|
|
||||||
compare_all(L, [])-> {toomuchlhs, L};
|
|
||||||
compare_all([LH|LTL], [RH|RTL]) ->
|
|
||||||
?assertEqual(LH, RH),
|
|
||||||
compare_all(LTL, RTL).
|
|
||||||
|
|
||||||
port_receive(Port) ->
|
|
||||||
port_receive(Port, <<>>).
|
|
||||||
port_receive(Port, Acc) ->
|
|
||||||
receive
|
|
||||||
{Port, {data, Data}} -> port_receive(Port, <<Acc/binary, Data/binary>>);
|
|
||||||
{Port, eof} -> Acc
|
|
||||||
after 1000 -> Acc
|
|
||||||
end.
|
|
||||||
|
|
||||||
test_([]) -> 0;
|
|
||||||
test_([Term|Rest])->
|
|
||||||
Pack = msgpack:pack(Term),
|
|
||||||
?assertEqual({Term, <<>>}, msgpack:unpack( Pack )),
|
|
||||||
1+test_(Rest).
|
|
||||||
|
|
||||||
test_data()->
|
|
||||||
[true, false, nil,
|
|
||||||
0, 1, 2, 123, 512, 1230, 678908, 16#FFFFFFFFFF,
|
|
||||||
-1, -23, -512, -1230, -567898, -16#FFFFFFFFFF,
|
|
||||||
123.123, -234.4355, 1.0e-34, 1.0e64,
|
|
||||||
[23, 234, 0.23],
|
|
||||||
<<"hogehoge">>, <<"243546rf7g68h798j", 0, 23, 255>>,
|
|
||||||
<<"hoasfdafdas][">>,
|
|
||||||
[0,42, <<"sum">>, [1,2]], [1,42, nil, [3]],
|
|
||||||
-234, -40000, -16#10000000, -16#100000000,
|
|
||||||
42
|
|
||||||
].
|
|
||||||
|
|
||||||
basic_test()->
|
|
||||||
Tests = test_data(),
|
|
||||||
Passed = test_(Tests),
|
|
||||||
Passed = length(Tests).
|
|
||||||
|
|
||||||
port_test()->
|
|
||||||
Tests = test_data(),
|
|
||||||
?assertEqual({[Tests],<<>>}, msgpack:unpack(msgpack:pack([Tests]))),
|
|
||||||
|
|
||||||
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary, eof]),
|
|
||||||
true = port_command(Port, msgpack:pack(Tests)),
|
|
||||||
?assertEqual({Tests, <<>>}, msgpack:unpack(port_receive(Port))),
|
|
||||||
port_close(Port).
|
|
||||||
|
|
||||||
test_p(Len,Term,OrigBin,Len) ->
|
|
||||||
{Term, <<>>}=msgpack:unpack(OrigBin);
|
|
||||||
test_p(I,_,OrigBin,Len) when I < Len->
|
|
||||||
<<Bin:I/binary, _/binary>> = OrigBin,
|
|
||||||
?assertEqual({error,incomplete}, msgpack:unpack(Bin)).
|
|
||||||
|
|
||||||
partial_test()-> % error handling test.
|
|
||||||
Term = lists:seq(0, 45),
|
|
||||||
Bin=msgpack:pack(Term),
|
|
||||||
BinLen = byte_size(Bin),
|
|
||||||
[test_p(X, Term, Bin, BinLen) || X <- lists:seq(0,BinLen)].
|
|
||||||
|
|
||||||
long_test()->
|
|
||||||
Longer = lists:seq(0, 655),
|
|
||||||
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)).
|
|
||||||
|
|
||||||
map_test()->
|
|
||||||
Ints = lists:seq(0, 65),
|
|
||||||
Map = {[ {X, X*2} || X <- Ints ] ++ [{<<"hage">>, 324}, {43542, [nil, true, false]}]},
|
|
||||||
{Map2, <<>>} = msgpack:unpack(msgpack:pack(Map)),
|
|
||||||
?assertEqual(Map, Map2),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
unknown_test()->
|
|
||||||
Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary, eof]),
|
|
||||||
Tests = [0, 1, 2, 123, 512, 1230, 678908,
|
|
||||||
-1, -23, -512, -1230, -567898,
|
|
||||||
<<"hogehoge">>, <<"243546rf7g68h798j">>,
|
|
||||||
123.123,
|
|
||||||
-234.4355, 1.0e-34, 1.0e64,
|
|
||||||
[23, 234, 0.23],
|
|
||||||
[0,42,<<"sum">>, [1,2]], [1,42, nil, [3]],
|
|
||||||
{[{1,2},{<<"hoge">>,nil}]}, % map
|
|
||||||
-234, -50000,
|
|
||||||
42
|
|
||||||
],
|
|
||||||
?assertEqual(ok, compare_all(Tests, msgpack:unpack_all(port_receive(Port)))),
|
|
||||||
port_close(Port).
|
|
||||||
|
|
||||||
other_test()->
|
|
||||||
?assertEqual({error,incomplete},msgpack:unpack(<<>>)).
|
|
||||||
|
|
||||||
benchmark_test()->
|
|
||||||
Data=[test_data() || _ <- lists:seq(0, 10000)],
|
|
||||||
S=?debugTime(" serialize", msgpack:pack(Data)),
|
|
||||||
{Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)),
|
|
||||||
?debugFmt("for ~p KB test data.", [byte_size(S) div 1024]).
|
|
||||||
|
|
||||||
error_test()->
|
|
||||||
?assertEqual({error,{badarg, atom}}, msgpack:pack(atom)),
|
|
||||||
Term = {"hoge", "hage", atom},
|
|
||||||
?assertEqual({error,{badarg, Term}}, msgpack:pack(Term)).
|
|
||||||
|
|
||||||
-endif.
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
begin
|
|
||||||
require 'rubygems'
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
require 'msgpack'
|
|
||||||
|
|
||||||
def usage
|
|
||||||
puts <<EOF
|
|
||||||
Usage: #{$0} [out-file]
|
|
||||||
|
|
||||||
This tool is for testing of accepting MessagePack random-term.
|
|
||||||
This does following behavior:
|
|
||||||
|
|
||||||
1. serializes the objects in this file, using Ruby implementation
|
|
||||||
of MessagePack (Note that Ruby implementation is considered valid)
|
|
||||||
2. Writes the serialized binaries into <out-file> (default: stdout)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
|
|
||||||
code = 1
|
|
||||||
outio = $stdout
|
|
||||||
|
|
||||||
if ARGV.length > 2
|
|
||||||
usage
|
|
||||||
end
|
|
||||||
|
|
||||||
if fname = ARGV[0]
|
|
||||||
unless fname == "-"
|
|
||||||
begin
|
|
||||||
outio = File.open(fname, "w")
|
|
||||||
rescue
|
|
||||||
puts "can't open output file: #{$!}"
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
objs = [0, 1, 2, 123, 512, 1230, 678908,
|
|
||||||
-1, -23, -512, -1230, -567898,
|
|
||||||
"hogehoge", "243546rf7g68h798j",
|
|
||||||
123.123,
|
|
||||||
-234.4355, 1.0e-34, 1.0e64,
|
|
||||||
[23, 234, 0.23],
|
|
||||||
[0,42,"sum", [1,2]], [1,42, nil, [3]],
|
|
||||||
{ 1 => 2, "hoge" => nil },
|
|
||||||
-234, -50000,
|
|
||||||
42
|
|
||||||
]
|
|
||||||
begin
|
|
||||||
objs.each do |obj|
|
|
||||||
outio.write MessagePack.pack(obj)
|
|
||||||
outio.flush
|
|
||||||
end
|
|
||||||
rescue EOFError
|
|
||||||
code=0
|
|
||||||
rescue
|
|
||||||
$stderr.puts $!
|
|
||||||
code=1
|
|
||||||
end
|
|
||||||
|
|
||||||
outio.close
|
|
||||||
exit code
|
|
||||||
|
|
||||||
@@ -30,9 +30,9 @@ int main(void)
|
|||||||
msgpack::sbuffer sbuf;
|
msgpack::sbuffer sbuf;
|
||||||
msgpack::pack(sbuf, oc);
|
msgpack::pack(sbuf, oc);
|
||||||
|
|
||||||
msgpack::zone zone;
|
msgpack::unpacked result;
|
||||||
msgpack::object obj;
|
msgpack::unpack(result, sbuf.data(), sbuf.size());
|
||||||
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj);
|
msgpack::object obj = result.get();
|
||||||
|
|
||||||
obj.convert(&nc);
|
obj.convert(&nc);
|
||||||
|
|
||||||
@@ -46,9 +46,9 @@ int main(void)
|
|||||||
msgpack::sbuffer sbuf;
|
msgpack::sbuffer sbuf;
|
||||||
msgpack::pack(sbuf, nc);
|
msgpack::pack(sbuf, nc);
|
||||||
|
|
||||||
msgpack::zone zone;
|
msgpack::unpacked result;
|
||||||
msgpack::object obj;
|
msgpack::unpack(result, sbuf.data(), sbuf.size());
|
||||||
msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &zone, &obj);
|
msgpack::object obj = result.get();
|
||||||
|
|
||||||
obj.convert(&oc);
|
obj.convert(&oc);
|
||||||
|
|
||||||
|
|||||||
119
example/lib_buffer_unpack.c
Normal file
119
example/lib_buffer_unpack.c
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include <msgpack.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct receiver {
|
||||||
|
msgpack_sbuffer sbuf;
|
||||||
|
size_t rest;
|
||||||
|
} receiver;
|
||||||
|
|
||||||
|
receiver r;
|
||||||
|
|
||||||
|
size_t receiver_init(receiver *r) {
|
||||||
|
msgpack_packer pk;
|
||||||
|
|
||||||
|
msgpack_sbuffer_init(&r->sbuf);
|
||||||
|
msgpack_packer_init(&pk, &r->sbuf, msgpack_sbuffer_write);
|
||||||
|
/* 1st object */
|
||||||
|
msgpack_pack_array(&pk, 3);
|
||||||
|
msgpack_pack_int(&pk, 1);
|
||||||
|
msgpack_pack_true(&pk);
|
||||||
|
msgpack_pack_str(&pk, 7);
|
||||||
|
msgpack_pack_str_body(&pk, "example", 7);
|
||||||
|
/* 2nd object */
|
||||||
|
msgpack_pack_str(&pk, 6);
|
||||||
|
msgpack_pack_str_body(&pk, "second", 6);
|
||||||
|
/* 3rd object */
|
||||||
|
msgpack_pack_array(&pk, 2);
|
||||||
|
msgpack_pack_int(&pk, 42);
|
||||||
|
msgpack_pack_false(&pk);
|
||||||
|
r->rest = r->sbuf.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t receiver_recv(receiver *r, char* buf, size_t try_size) {
|
||||||
|
size_t off = r->sbuf.size - r->rest;
|
||||||
|
|
||||||
|
size_t actual_size = try_size;
|
||||||
|
if (actual_size > r->rest) actual_size = r->rest;
|
||||||
|
|
||||||
|
memcpy(buf, r->sbuf.data + off, actual_size);
|
||||||
|
r->rest -= actual_size;
|
||||||
|
|
||||||
|
return actual_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EACH_RECV_SIZE 4
|
||||||
|
|
||||||
|
void unpack(receiver* r) {
|
||||||
|
/* buf is allocated by unpacker. */
|
||||||
|
msgpack_unpacker* unp = msgpack_unpacker_new(100);
|
||||||
|
msgpack_unpacked result;
|
||||||
|
msgpack_unpack_return ret;
|
||||||
|
char* buf;
|
||||||
|
size_t recv_len;
|
||||||
|
|
||||||
|
msgpack_unpacked_init(&result);
|
||||||
|
if (msgpack_unpacker_buffer_capacity(unp) < EACH_RECV_SIZE) {
|
||||||
|
bool expanded = msgpack_unpacker_reserve_buffer(unp, 100);
|
||||||
|
assert(expanded);
|
||||||
|
}
|
||||||
|
buf = msgpack_unpacker_buffer(unp);
|
||||||
|
|
||||||
|
recv_len = receiver_recv(r, buf, EACH_RECV_SIZE);
|
||||||
|
msgpack_unpacker_buffer_consumed(unp, recv_len);
|
||||||
|
|
||||||
|
|
||||||
|
int recv_count = 0;
|
||||||
|
while (recv_len > 0) {
|
||||||
|
int i = 0;
|
||||||
|
printf("receive count: %d %d bytes received.:\n", recv_count++, recv_len);
|
||||||
|
ret = msgpack_unpacker_next(unp, &result);
|
||||||
|
while (ret == MSGPACK_UNPACK_SUCCESS) {
|
||||||
|
msgpack_object obj = result.data;
|
||||||
|
|
||||||
|
/* Use obj. */
|
||||||
|
printf("Object no %d:\n", i++);
|
||||||
|
msgpack_object_print(stdout, obj);
|
||||||
|
printf("\n");
|
||||||
|
/* If you want to allocate something on the zone, you can use zone. */
|
||||||
|
/* msgpack_zone* zone = result.zone; */
|
||||||
|
/* The lifetime of the obj and the zone, */
|
||||||
|
|
||||||
|
ret = msgpack_unpacker_next(unp, &result);
|
||||||
|
}
|
||||||
|
if (ret == MSGPACK_UNPACK_PARSE_ERROR) {
|
||||||
|
printf("The data in the buf is invalid format.\n");
|
||||||
|
msgpack_unpacked_destroy(&result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (msgpack_unpacker_buffer_capacity(unp) < EACH_RECV_SIZE) {
|
||||||
|
bool expanded = msgpack_unpacker_reserve_buffer(unp, 100);
|
||||||
|
assert(expanded);
|
||||||
|
}
|
||||||
|
buf = msgpack_unpacker_buffer(unp);
|
||||||
|
recv_len = receiver_recv(r, buf, 4);
|
||||||
|
msgpack_unpacker_buffer_consumed(unp, recv_len);
|
||||||
|
}
|
||||||
|
msgpack_unpacked_destroy(&result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
receiver r;
|
||||||
|
receiver_init(&r);
|
||||||
|
|
||||||
|
unpack(&r);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Object no 1:
|
||||||
|
[1, true, "example"]
|
||||||
|
Object no 2:
|
||||||
|
"second"
|
||||||
|
Object no 3:
|
||||||
|
[42, false]
|
||||||
|
*/
|
||||||
@@ -11,17 +11,17 @@ namespace myprotocol {
|
|||||||
Get() { }
|
Get() { }
|
||||||
Get(uint32_t f, const std::string& k) :
|
Get(uint32_t f, const std::string& k) :
|
||||||
define_type(msgpack_type(f, k)) { }
|
define_type(msgpack_type(f, k)) { }
|
||||||
uint32_t& flags() { return get<0>(); }
|
uint32_t& flags() { return msgpack::type::get<0>(*this); }
|
||||||
std::string& key() { return get<1>(); }
|
std::string& key() { return msgpack::type::get<1>(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Put : define< tuple<uint32_t, std::string, raw_ref> > {
|
struct Put : define< tuple<uint32_t, std::string, raw_ref> > {
|
||||||
Put() { }
|
Put() { }
|
||||||
Put(uint32_t f, const std::string& k, const char* valref, size_t vallen) :
|
Put(uint32_t f, const std::string& k, const char* valref, uint32_t vallen) :
|
||||||
define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { }
|
define_type(msgpack_type( f, k, raw_ref(valref,vallen) )) { }
|
||||||
uint32_t& flags() { return get<0>(); }
|
uint32_t& flags() { return msgpack::type::get<0>(*this); }
|
||||||
std::string& key() { return get<1>(); }
|
std::string& key() { return msgpack::type::get<1>(*this); }
|
||||||
raw_ref& value() { return get<2>(); }
|
raw_ref& value() { return msgpack::type::get<2>(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MultiGet : define< std::vector<Get> > {
|
struct MultiGet : define< std::vector<Get> > {
|
||||||
@@ -46,12 +46,12 @@ int main(void)
|
|||||||
{
|
{
|
||||||
std::string buffer(stream.str());
|
std::string buffer(stream.str());
|
||||||
|
|
||||||
msgpack::zone mempool;
|
msgpack::unpacked result;
|
||||||
msgpack::object o =
|
msgpack::unpack(result, buffer.data(), buffer.size());
|
||||||
msgpack::unpack(buffer.data(), buffer.size(), mempool);
|
msgpack::object o = result.get();
|
||||||
|
|
||||||
myprotocol::Get req;
|
myprotocol::Get req;
|
||||||
msgpack::convert(req, o);
|
o.convert(req);
|
||||||
std::cout << "received: " << o << std::endl;
|
std::cout << "received: " << o << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +74,13 @@ int main(void)
|
|||||||
{
|
{
|
||||||
std::string buffer(stream.str());
|
std::string buffer(stream.str());
|
||||||
|
|
||||||
msgpack::zone mempool;
|
msgpack::unpacked result;
|
||||||
msgpack::object o =
|
msgpack::unpack(result, buffer.data(), buffer.size());
|
||||||
msgpack::unpack(buffer.data(), buffer.size(), mempool);
|
msgpack::object o = result.get();
|
||||||
|
|
||||||
|
|
||||||
myprotocol::MultiGet req;
|
myprotocol::MultiGet req;
|
||||||
msgpack::convert(req, o);
|
o.convert(req);
|
||||||
std::cout << "received: " << o << std::endl;
|
std::cout << "received: " << o << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ int main(void)
|
|||||||
msgpack_pack_array(&pk, 3);
|
msgpack_pack_array(&pk, 3);
|
||||||
msgpack_pack_int(&pk, 1);
|
msgpack_pack_int(&pk, 1);
|
||||||
msgpack_pack_true(&pk);
|
msgpack_pack_true(&pk);
|
||||||
msgpack_pack_raw(&pk, 7);
|
msgpack_pack_str(&pk, 7);
|
||||||
msgpack_pack_raw_body(&pk, "example", 7);
|
msgpack_pack_str_body(&pk, "example", 7);
|
||||||
|
|
||||||
/* deserialize the buffer into msgpack_object instance. */
|
/* deserialize the buffer into msgpack_object instance. */
|
||||||
/* deserialized object is valid during the msgpack_zone instance alive. */
|
/* deserialized object is valid during the msgpack_zone instance alive. */
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ int main(void)
|
|||||||
// deserialize the buffer into msgpack::object instance.
|
// deserialize the buffer into msgpack::object instance.
|
||||||
std::string str(buffer.str());
|
std::string str(buffer.str());
|
||||||
|
|
||||||
// deserialized object is valid during the msgpack::zone instance alive.
|
msgpack::unpacked result;
|
||||||
msgpack::zone mempool;
|
|
||||||
|
|
||||||
msgpack::object deserialized;
|
msgpack::unpack(result, str.data(), str.size());
|
||||||
msgpack::unpack(str.data(), str.size(), NULL, &mempool, &deserialized);
|
|
||||||
|
// deserialized object is valid during the msgpack::unpacked instance alive.
|
||||||
|
msgpack::object deserialized = result.get();
|
||||||
|
|
||||||
// msgpack::object supports ostream.
|
// msgpack::object supports ostream.
|
||||||
std::cout << deserialized << std::endl;
|
std::cout << deserialized << std::endl;
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
require 'msgpack'
|
|
||||||
|
|
||||||
serialized = [1, -1, true, false, nil, {"key" => "value"}].to_msgpack
|
|
||||||
p MessagePack.unpack(serialized)
|
|
||||||
|
|
||||||
55
example/speed_test.cc
Normal file
55
example/speed_test.cc
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// g++ -std=c++11 -O3 -g -Ipath_to_msgpack_src -Ipath_to_boost speed_test.cc -Lpath_to_boost_lib -lboost_timer -lboost_system
|
||||||
|
// export LD_LIBRARY_PATH=path_to_boost_lib
|
||||||
|
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <map>
|
||||||
|
#include <boost/timer/timer.hpp>
|
||||||
|
|
||||||
|
void test_map_pack_unpack() {
|
||||||
|
std::cout << "[TEST][map_pack_unpack]" << std::endl;
|
||||||
|
// setup
|
||||||
|
std::cout << "Setting up map data..." << std::endl;
|
||||||
|
std::map<int, int> m1;
|
||||||
|
int const num = 30000000L;
|
||||||
|
for (int i = 0; i < num; ++i) m1[i] = i;
|
||||||
|
std::cout << "Start packing..." << std::endl;
|
||||||
|
std::stringstream buffer;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
msgpack::pack(buffer, m1);
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Pack finished..." << std::endl;
|
||||||
|
|
||||||
|
buffer.seekg(0);
|
||||||
|
std::string str(buffer.str());
|
||||||
|
|
||||||
|
msgpack::unpacked unpacked;
|
||||||
|
std::cout << "Start unpacking...by void unpack(unpacked& result, const char* data, size_t len)" << std::endl;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
msgpack::unpack(unpacked, str.data(), str.size());
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Unpack finished..." << std::endl;
|
||||||
|
std::map<int, int> m2;
|
||||||
|
std::cout << "Start converting..." << std::endl;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
unpacked.get().convert(&m2);
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Convert finished..." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_map_pack_unpack();
|
||||||
|
}
|
||||||
|
|
||||||
78
example/speed_test_nested_array.cc
Normal file
78
example/speed_test_nested_array.cc
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// g++ -std=c++11 -O3 -g -Ipath_to_msgpack_src -Ipath_to_boost speed_test.cc -Lpath_to_boost_lib -lboost_timer -lboost_system
|
||||||
|
// export LD_LIBRARY_PATH=path_to_boost_lib
|
||||||
|
|
||||||
|
#include <msgpack.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/timer/timer.hpp>
|
||||||
|
|
||||||
|
template <typename T, std::size_t level>
|
||||||
|
struct vecvec {
|
||||||
|
typedef std::vector<typename vecvec<T, level - 1>::type> type;
|
||||||
|
static void fill(type& v, std::size_t num_of_elems, T const& val) {
|
||||||
|
for (int elem = 0; elem < num_of_elems; ++elem) {
|
||||||
|
typename vecvec<T, level - 1>::type child;
|
||||||
|
vecvec<T, level - 1>::fill(child, num_of_elems, val);
|
||||||
|
v.push_back(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct vecvec<T, 0> {
|
||||||
|
typedef std::vector<T> type;
|
||||||
|
static void fill(type& v, std::size_t num_of_elems, T const& val) {
|
||||||
|
for (int elem = 0; elem < num_of_elems; ++elem) {
|
||||||
|
v.push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_array_of_array() {
|
||||||
|
std::cout << "[TEST][array_of_array]" << std::endl;
|
||||||
|
// setup
|
||||||
|
int const depth = 16;
|
||||||
|
std::cout << "Setting up array data..." << std::endl;
|
||||||
|
typename vecvec<int, depth>::type v1;
|
||||||
|
vecvec<int, depth>::fill(v1, 3, 42);
|
||||||
|
|
||||||
|
std::cout << "Start packing..." << std::endl;
|
||||||
|
std::stringstream buffer;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
msgpack::pack(buffer, v1);
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Pack finished..." << std::endl;
|
||||||
|
|
||||||
|
buffer.seekg(0);
|
||||||
|
std::string str(buffer.str());
|
||||||
|
|
||||||
|
msgpack::unpacked unpacked;
|
||||||
|
std::cout << "Start unpacking...by void unpack(unpacked& result, const char* data, size_t len)" << std::endl;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
msgpack::unpack(unpacked, str.data(), str.size());
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Unpack finished..." << std::endl;
|
||||||
|
typename vecvec<int, depth>::type v2;
|
||||||
|
std::cout << "Start converting..." << std::endl;
|
||||||
|
{
|
||||||
|
boost::timer::cpu_timer timer;
|
||||||
|
unpacked.get().convert(&v2);
|
||||||
|
std::string result = timer.format();
|
||||||
|
std::cout << result << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Convert finished..." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_array_of_array();
|
||||||
|
}
|
||||||
|
|
||||||
36
example/speed_test_uint32_array.c
Normal file
36
example/speed_test_uint32_array.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include <msgpack.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
size_t size = 10000000;
|
||||||
|
msgpack_sbuffer buf;
|
||||||
|
msgpack_sbuffer_init(&buf);
|
||||||
|
|
||||||
|
msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write);
|
||||||
|
|
||||||
|
msgpack_pack_array(pk, size);
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
for (; idx < size; ++idx)
|
||||||
|
msgpack_pack_uint32(pk, 1);
|
||||||
|
}
|
||||||
|
msgpack_packer_free(pk);
|
||||||
|
|
||||||
|
|
||||||
|
size_t upk_pos = 0;
|
||||||
|
msgpack_unpacked msg;
|
||||||
|
msgpack_unpacked_init(&msg);
|
||||||
|
|
||||||
|
while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
msgpack_sbuffer_destroy(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (; i < 10; ++i) test();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
37
example/speed_test_uint64_array.c
Normal file
37
example/speed_test_uint64_array.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include <msgpack.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
uint64_t test_u64 = 0xFFF0000000000001LL;
|
||||||
|
size_t size = 10000000;
|
||||||
|
msgpack_sbuffer buf;
|
||||||
|
msgpack_sbuffer_init(&buf);
|
||||||
|
|
||||||
|
msgpack_packer * pk = msgpack_packer_new(&buf, msgpack_sbuffer_write);
|
||||||
|
|
||||||
|
msgpack_pack_array(pk, size);
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
for (; idx < size; ++idx)
|
||||||
|
msgpack_pack_uint64(pk, test_u64);
|
||||||
|
}
|
||||||
|
msgpack_packer_free(pk);
|
||||||
|
|
||||||
|
|
||||||
|
size_t upk_pos = 0;
|
||||||
|
msgpack_unpacked msg;
|
||||||
|
msgpack_unpacked_init(&msg);
|
||||||
|
|
||||||
|
while (msgpack_unpack_next(&msg, buf.data, buf.size, &upk_pos)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
msgpack_sbuffer_destroy(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (; i < 10; ++i) test();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ public:
|
|||||||
|
|
||||||
~Server() { }
|
~Server() { }
|
||||||
|
|
||||||
typedef std::auto_ptr<msgpack::zone> auto_zone;
|
typedef msgpack::unique_ptr<msgpack::zone> auto_zone;
|
||||||
|
|
||||||
void socket_readable()
|
void socket_readable()
|
||||||
{
|
{
|
||||||
@@ -34,13 +34,10 @@ public:
|
|||||||
|
|
||||||
m_pac.buffer_consumed(count);
|
m_pac.buffer_consumed(count);
|
||||||
|
|
||||||
while(m_pac.execute()) {
|
msgpack::unpacked result;
|
||||||
msgpack::object msg = m_pac.data();
|
while (m_pac.next(&result)) {
|
||||||
|
msgpack::object msg = result.get();
|
||||||
auto_zone life( m_pac.release_zone() );
|
auto_zone& life = result.zone();
|
||||||
|
|
||||||
m_pac.reset();
|
|
||||||
|
|
||||||
process_message(msg, life);
|
process_message(msg, life);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
require 'msgpack'
|
|
||||||
|
|
||||||
class Server
|
|
||||||
def initialize(sock)
|
|
||||||
@sock = sock
|
|
||||||
@pk = MessagePack::Unpacker.new
|
|
||||||
@buffer = ''
|
|
||||||
@nread = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def run
|
|
||||||
while true
|
|
||||||
begin
|
|
||||||
data = @sock.sysread(1024)
|
|
||||||
rescue
|
|
||||||
puts "connection closed (#{$!})"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
receive_data(data)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def receive_data(data)
|
|
||||||
@buffer << data
|
|
||||||
|
|
||||||
while true
|
|
||||||
@nread = @pk.execute(@buffer, @nread)
|
|
||||||
|
|
||||||
if @pk.finished?
|
|
||||||
msg = @pk.data
|
|
||||||
process_message(msg)
|
|
||||||
|
|
||||||
@pk.reset
|
|
||||||
@buffer.slice!(0, @nread)
|
|
||||||
@nread = 0
|
|
||||||
|
|
||||||
next unless @buffer.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
if @buffer.length > 10*1024*1024
|
|
||||||
raise "message is too large"
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue
|
|
||||||
puts "error while processing client packet: #{$!}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def process_message(msg)
|
|
||||||
puts "message reached: #{msg.inspect}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
rpipe, wpipe = IO.pipe
|
|
||||||
|
|
||||||
# run server thread
|
|
||||||
thread = Thread.new(Server.new(rpipe)) {|srv|
|
|
||||||
srv.run
|
|
||||||
}
|
|
||||||
|
|
||||||
# client thread:
|
|
||||||
wpipe.write ["put", "apple", "red"].to_msgpack
|
|
||||||
wpipe.write ["put", "lemon", "yellow"].to_msgpack
|
|
||||||
wpipe.write ["get", "apple"].to_msgpack
|
|
||||||
wpipe.close
|
|
||||||
|
|
||||||
thread.join
|
|
||||||
|
|
||||||
75
example/user_buffer_unpack.c
Normal file
75
example/user_buffer_unpack.c
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#include <msgpack.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
void prepare(msgpack_sbuffer* sbuf) {
|
||||||
|
msgpack_packer pk;
|
||||||
|
|
||||||
|
msgpack_packer_init(&pk, sbuf, msgpack_sbuffer_write);
|
||||||
|
/* 1st object */
|
||||||
|
msgpack_pack_array(&pk, 3);
|
||||||
|
msgpack_pack_int(&pk, 1);
|
||||||
|
msgpack_pack_true(&pk);
|
||||||
|
msgpack_pack_str(&pk, 7);
|
||||||
|
msgpack_pack_str_body(&pk, "example", 7);
|
||||||
|
/* 2nd object */
|
||||||
|
msgpack_pack_str(&pk, 6);
|
||||||
|
msgpack_pack_str_body(&pk, "second", 6);
|
||||||
|
/* 3rd object */
|
||||||
|
msgpack_pack_array(&pk, 2);
|
||||||
|
msgpack_pack_int(&pk, 42);
|
||||||
|
msgpack_pack_false(&pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpack(char const* buf, size_t len) {
|
||||||
|
/* buf is allocated by client. */
|
||||||
|
msgpack_unpacked result;
|
||||||
|
size_t off = 0;
|
||||||
|
msgpack_unpack_return ret;
|
||||||
|
int i = 0;
|
||||||
|
msgpack_unpacked_init(&result);
|
||||||
|
ret = msgpack_unpack_next(&result, buf, len, &off);
|
||||||
|
while (ret == MSGPACK_UNPACK_SUCCESS) {
|
||||||
|
msgpack_object obj = result.data;
|
||||||
|
|
||||||
|
/* Use obj. */
|
||||||
|
printf("Object no %d:\n", i++);
|
||||||
|
msgpack_object_print(stdout, obj);
|
||||||
|
printf("\n");
|
||||||
|
/* If you want to allocate something on the zone, you can use zone. */
|
||||||
|
/* msgpack_zone* zone = result.zone; */
|
||||||
|
/* The lifetime of the obj and the zone, */
|
||||||
|
|
||||||
|
ret = msgpack_unpack_next(&result, buf, len, &off);
|
||||||
|
}
|
||||||
|
msgpack_unpacked_destroy(&result);
|
||||||
|
|
||||||
|
if (ret == MSGPACK_UNPACK_CONTINUE) {
|
||||||
|
printf("All msgpack_object in the buffer is consumed.\n");
|
||||||
|
}
|
||||||
|
else if (ret == MSGPACK_UNPACK_PARSE_ERROR) {
|
||||||
|
printf("The data in the buf is invalid format.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
msgpack_sbuffer sbuf;
|
||||||
|
msgpack_sbuffer_init(&sbuf);
|
||||||
|
|
||||||
|
prepare(&sbuf);
|
||||||
|
unpack(sbuf.data, sbuf.size);
|
||||||
|
|
||||||
|
msgpack_sbuffer_destroy(&sbuf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Object no 1:
|
||||||
|
[1, true, "example"]
|
||||||
|
Object no 2:
|
||||||
|
"second"
|
||||||
|
Object no 3:
|
||||||
|
[42, false]
|
||||||
|
*/
|
||||||
11
go/Makefile
11
go/Makefile
@@ -1,11 +0,0 @@
|
|||||||
include $(GOROOT)/src/Make.inc
|
|
||||||
|
|
||||||
TARG=msgpack
|
|
||||||
|
|
||||||
GOFILES=pack.go unpack.go
|
|
||||||
|
|
||||||
include $(GOROOT)/src/Make.pkg
|
|
||||||
|
|
||||||
%: install %.go
|
|
||||||
$(GC) $*.go
|
|
||||||
$(LD) -o $@ $*.$O
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
package msgpack_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
. "msgpack"
|
|
||||||
"testing"
|
|
||||||
"bytes"
|
|
||||||
"reflect"
|
|
||||||
"math"
|
|
||||||
);
|
|
||||||
|
|
||||||
func equal(lhs reflect.Value, rhs reflect.Value) bool {
|
|
||||||
{
|
|
||||||
_rhs, ok := rhs.(*reflect.InterfaceValue)
|
|
||||||
if ok { return equal(lhs, _rhs.Elem()) }
|
|
||||||
}
|
|
||||||
switch _lhs := lhs.(type) {
|
|
||||||
case *reflect.InterfaceValue:
|
|
||||||
return equal(_lhs.Elem(), rhs)
|
|
||||||
case *reflect.BoolValue:
|
|
||||||
_rhs, ok := rhs.(*reflect.BoolValue)
|
|
||||||
return ok && _lhs.Get() == _rhs.Get()
|
|
||||||
case *reflect.UintValue:
|
|
||||||
_rhs, ok := rhs.(*reflect.UintValue)
|
|
||||||
return ok && _lhs.Get() == _rhs.Get()
|
|
||||||
case *reflect.IntValue:
|
|
||||||
_rhs, ok := rhs.(*reflect.IntValue)
|
|
||||||
return ok && _lhs.Get() == _rhs.Get()
|
|
||||||
case *reflect.FloatValue:
|
|
||||||
_rhs, ok := rhs.(*reflect.FloatValue)
|
|
||||||
return ok && _lhs.Get() == _rhs.Get()
|
|
||||||
case reflect.ArrayOrSliceValue:
|
|
||||||
_rhs := rhs.(reflect.ArrayOrSliceValue)
|
|
||||||
if _lhs.Len() != _rhs.Len() { return false; }
|
|
||||||
for i := 0; i < _lhs.Len(); i++ {
|
|
||||||
if !equal(_lhs.Elem(i), _rhs.Elem(i)) { return false; }
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case *reflect.MapValue:
|
|
||||||
_rhs := rhs.(*reflect.MapValue)
|
|
||||||
if _lhs.Len() != _rhs.Len() { return false; }
|
|
||||||
for _, k := range _lhs.Keys() {
|
|
||||||
lv, rv := _lhs.Elem(k), _rhs.Elem(k)
|
|
||||||
if lv == nil || rv == nil || !equal(lv, rv) { return false; }
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackUint8(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []uint8 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255 } {
|
|
||||||
_, err := PackUint8(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackUint16(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []uint16 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535 } {
|
|
||||||
_, err := PackUint16(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackUint32(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []uint32 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535, 65536, 4294967293, 4294967294, 4294967295 } {
|
|
||||||
_, err := PackUint32(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff, 0xce, 0x00, 0x01, 0x00, 0x00, 0xce, 0xff, 0xff, 0xff, 0xfd, 0xce, 0xff, 0xff, 0xff, 0xfe, 0xce, 0xff, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackUint64(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []uint64 { 0, 1, 2, 125, 126, 127, 128, 253, 254, 255, 256, 65533, 65534, 65535, 65536, 4294967293, 4294967294, 4294967295, 4294967296, 18446744073709551613, 18446744073709551614, 18446744073709551615 } {
|
|
||||||
_, err := PackUint64(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xcd, 0x01, 0x00, 0xcd, 0xff, 0xfd, 0xcd, 0xff, 0xfe, 0xcd, 0xff, 0xff, 0xce, 0x00, 0x01, 0x00, 0x00, 0xce, 0xff, 0xff, 0xff, 0xfd, 0xce, 0xff, 0xff, 0xff, 0xfe, 0xce, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackInt8(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []int8 { -128, -127, -34, -33, -32, -31, 0, 1, 126, 127 } {
|
|
||||||
_, err := PackInt8(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackInt16(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []int16 { -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767 } {
|
|
||||||
_, err := PackInt16(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackInt32(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []int32 { -2147483648, -2147483647, -2147483646, -32771, -32770, -32769, -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767, 32768, 32769, 32770, 2147483645, 2147483646, 2147483647 } {
|
|
||||||
_, err := PackInt32(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xd2, 0x80, 0x00, 0x00, 0x00, 0xd2, 0x80, 0x00, 0x00, 0x01, 0xd2, 0x80, 0x00, 0x00, 0x02, 0xd2, 0xff, 0xff, 0x7f, 0xfd, 0xd2, 0xff, 0xff, 0x7f, 0xfe, 0xd2, 0xff, 0xff, 0x7f, 0xff, 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff, 0xd2, 0x00, 0x00, 0x80, 0x00, 0xd2, 0x00, 0x00, 0x80, 0x01, 0xd2, 0x00, 0x00, 0x80, 0x02, 0xd2, 0x7f, 0xff, 0xff, 0xfd, 0xd2, 0x7f, 0xff, 0xff, 0xfe, 0xd2, 0x7f, 0xff, 0xff, 0xff }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackInt64(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []int64 { -9223372036854775808, -9223372036854775807, -9223372036854775806, -2147483651, -2147483650, -2147483649, -2147483648, -2147483647, -2147483646, -32771, -32770, -32769, -32768, -32767, -131, -130, -129, -128, -127, -34, -33, -32, -31, 0, 1, 126, 127, 128, 129, 130, 32765, 32766, 32767, 32768, 32769, 32770, 2147483645, 2147483646, 2147483647, 2147483648, 2147483649, 2147483650, 4294967296, 4294967297, 4294967298 } {
|
|
||||||
_, err := PackInt64(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfd, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xfe, 0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xd2, 0x80, 0x00, 0x00, 0x00, 0xd2, 0x80, 0x00, 0x00, 0x01, 0xd2, 0x80, 0x00, 0x00, 0x02, 0xd2, 0xff, 0xff, 0x7f, 0xfd, 0xd2, 0xff, 0xff, 0x7f, 0xfe, 0xd2, 0xff, 0xff, 0x7f, 0xff, 0xd1, 0x80, 0x00, 0xd1, 0x80, 0x01, 0xd1, 0xff, 0x7d, 0xd1, 0xff, 0x7e, 0xd1, 0xff, 0x7f, 0xd0, 0x80, 0xd0, 0x81, 0xd0, 0xde, 0xd0, 0xdf, 0xe0, 0xe1, 0x00, 0x01, 0x7e, 0x7f, 0xd1, 0x00, 0x80, 0xd1, 0x00, 0x81, 0xd1, 0x00, 0x82, 0xd1, 0x7f, 0xfd, 0xd1, 0x7f, 0xfe, 0xd1, 0x7f, 0xff, 0xd2, 0x00, 0x00, 0x80, 0x00, 0xd2, 0x00, 0x00, 0x80, 0x01, 0xd2, 0x00, 0x00, 0x80, 0x02, 0xd2, 0x7f, 0xff, 0xff, 0xfd, 0xd2, 0x7f, 0xff, 0xff, 0xfe, 0xd2, 0x7f, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x02, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackNil(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
nbyteswrite, err := PackNil(b)
|
|
||||||
if nbyteswrite != 1 { t.Error("nbyteswrite != 1") }
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xc0 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackBool(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range []bool { false, true } {
|
|
||||||
nbyteswrite, err := PackBool(b, i)
|
|
||||||
if nbyteswrite != 1 { t.Error("nbyteswrite != 1") }
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xc2, 0xc3 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackInt32Array(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
_, err := PackInt32Array(b, []int32 {})
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackInt32Array(b, []int32 { 0 })
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackInt32Array(b, []int32 { 0, 1 })
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackInt32Array(b, []int32 { 0, 1, 2 })
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0x00, 0x01, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackArray(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
_, err := PackArray(b, reflect.NewValue([]int32 {}).(reflect.ArrayOrSliceValue))
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0 }).(reflect.ArrayOrSliceValue))
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0, 1 }).(reflect.ArrayOrSliceValue))
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
_, err = PackArray(b, reflect.NewValue([]int32 { 0, 1, 2 }).(reflect.ArrayOrSliceValue))
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0x00, 0x01, 0x02 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPackMap(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
_, err := PackMap(b, reflect.NewValue(map[int] int { 0: 1, 2: 3, 4: 5 }).(*reflect.MapValue))
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0x83, 0x00, 0x01, 0x04, 0x05, 0x02, 0x03 }) != 0 { t.Error("wrong output", b.Bytes()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPack(t *testing.T) {
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
for _, i := range [](interface{}) { nil, false, true, 0, 1, 2, 3, 127, -32, -1, -33, 128 } {
|
|
||||||
_, err := Pack(b, i)
|
|
||||||
if err != nil { t.Error("err != nil") }
|
|
||||||
}
|
|
||||||
if bytes.Compare(b.Bytes(), []byte { 0xc0, 0xc2, 0xc3, 0x00, 0x01, 0x02, 0x03, 0x7f, 0xf0, 0xff, 0xd0, 0xef, 0xd1, 0x00, 0x80 }) == 0 { t.Error("wrong output") }
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnpackArray(t *testing.T) {
|
|
||||||
b := bytes.NewBuffer([]byte { 0x90, 0x91, 0x00, 0x92, 0x00, 0x01, 0x93, 0xd1, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x02, 0x00, 0x01, 0xdd, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03 })
|
|
||||||
for _, v := range [](interface{}) { [](interface{}) {}, [](interface{}) { int8(0) }, [](interface{}) { int8(0), int8(1) }, [](interface{}) { int16(0), int32(1), int64(2) }, [](interface{}){ int8(0), int8(1) }, [](interface{}) { int8(0), int8(1), int8(2), int8(3) } } {
|
|
||||||
retval, _, e := Unpack(b)
|
|
||||||
if e != nil { t.Error("err != nil") }
|
|
||||||
if !equal(reflect.NewValue(retval.Interface()), reflect.NewValue(v)) { t.Errorf("%s != %s", retval.Interface(), v) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnpackInt(t *testing.T) {
|
|
||||||
b := bytes.NewBuffer([]byte { 0xff, 0xe0, 0x00, 0x01, 0x02, 0x7d, 0x7e, 0x7f, 0xd0, 0x01, 0xd0, 0x80, 0xd0, 0xff, 0xcc, 0x80, 0xcc, 0xfd, 0xcc, 0xfe, 0xcc, 0xff, 0xd1, 0x00, 0x00, 0xd1, 0x7f, 0xff, 0xd1, 0xff, 0xff, 0xcd, 0x80, 0x00, 0xcd, 0xff, 0xff, 0xd2, 0x7f, 0xff, 0xff, 0xff, 0xce, 0x7f, 0xff, 0xff, 0xff, 0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff })
|
|
||||||
for _, v := range [](interface{}) {
|
|
||||||
int8(-1), int8(-32), int8(0), int8(1), int8(2), int8(125), int8(126), int8(127), int8(1), int8(-128), int8(-1), uint8(128), uint8(253), uint8(254), uint8(255), int16(0), int16(32767), int16(-1), uint16(32768), uint16(65535), int32(2147483647), uint32(2147483647), int64(9223372036854775807), uint64(18446744073709551615) } {
|
|
||||||
retval, _, e := Unpack(b)
|
|
||||||
if e != nil { t.Error("err != nil") }
|
|
||||||
if retval.Interface() != v { t.Errorf("%u != %u", retval.Interface(), v) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUnpackFloat(t *testing.T) {
|
|
||||||
b := bytes.NewBuffer([]byte { 0xca, 0x3d, 0xcc, 0xcc, 0xcd, 0xca, 0x3e, 0x4c, 0xcc, 0xcd, 0xca, 0xbd, 0xcc, 0xcc, 0xcd, 0xca, 0xbe, 0x4c, 0xcc, 0xcd, 0xca, 0x7f, 0x80, 0x00, 0x00, 0xca, 0xff, 0x80, 0x00, 0x00, 0xca, 0xff, 0xc0, 0x00, 0x0, 0xcb, 0x3f, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0x3f, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0xbf, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0xbf, 0xc9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0xcb, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
|
|
||||||
for _, v := range [](interface{}) { float32(.1), float32(.2), float32(-.1), float32(-.2), float32(math.Inf(1)), float32(math.Inf(-1)), float32(math.NaN()), float64(.1), float64(.2), float64(-.1), float64(-.2) } {
|
|
||||||
retval, _, e := Unpack(b)
|
|
||||||
if e != nil { t.Error("err != nil") }
|
|
||||||
isnan := false
|
|
||||||
if _v, ok := v.(float64); ok {
|
|
||||||
isnan = math.IsNaN(_v)
|
|
||||||
} else if _v, ok := v.(float32); ok {
|
|
||||||
isnan = math.IsNaN(float64(_v))
|
|
||||||
}
|
|
||||||
if isnan {
|
|
||||||
if retval.Interface() == v { t.Errorf("[NaN] %u == %u", retval.Interface(), v) }
|
|
||||||
} else {
|
|
||||||
if retval.Interface() != v { t.Errorf("%u != %u", retval.Interface(), v) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
591
go/pack.go
591
go/pack.go
@@ -1,591 +0,0 @@
|
|||||||
package msgpack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
"reflect"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint8(writer io.Writer, value uint8) (n int, err os.Error) {
|
|
||||||
if value < 128 {
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { 0xcc, byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint16(writer io.Writer, value uint16) (n int, err os.Error) {
|
|
||||||
if value < 128 {
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
} else if value < 256 {
|
|
||||||
return writer.Write([]byte { 0xcc, byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint32(writer io.Writer, value uint32) (n int, err os.Error) {
|
|
||||||
if value < 128 {
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
} else if value < 256 {
|
|
||||||
return writer.Write([]byte { 0xcc, byte(value) })
|
|
||||||
} else if value < 65536 {
|
|
||||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { 0xce, byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint64(writer io.Writer, value uint64) (n int, err os.Error) {
|
|
||||||
if value < 128 {
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
} else if value < 256 {
|
|
||||||
return writer.Write([]byte { 0xcc, byte(value) })
|
|
||||||
} else if value < 65536 {
|
|
||||||
return writer.Write([]byte { 0xcd, byte(value >> 8), byte(value) })
|
|
||||||
} else if value < 4294967296 {
|
|
||||||
return writer.Write([]byte { 0xce, byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { 0xcf, byte(value >> 56), byte(value >> 48), byte(value >> 40), byte(value >> 32), byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
func PackUint(writer io.Writer, value uint) (n int, err os.Error) {
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
switch unsafe.Sizeof(value) {
|
|
||||||
case 4:
|
|
||||||
return PackUint32(writer, *(*uint32)(unsafe.Pointer(&value)))
|
|
||||||
case 8:
|
|
||||||
return PackUint64(writer, *(*uint64)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
return 0, os.ENOENT // never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt8(writer io.Writer, value int8) (n int, err os.Error) {
|
|
||||||
if value < -32 {
|
|
||||||
return writer.Write([]byte { 0xd0, byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt16(writer io.Writer, value int16) (n int, err os.Error) {
|
|
||||||
if value < -128 || value >= 128 {
|
|
||||||
return writer.Write([]byte { 0xd1, byte(uint16(value) >> 8), byte(value) })
|
|
||||||
} else if value < -32 {
|
|
||||||
return writer.Write([]byte { 0xd0, byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt32(writer io.Writer, value int32) (n int, err os.Error) {
|
|
||||||
if value < -32768 || value >= 32768 {
|
|
||||||
return writer.Write([]byte { 0xd2, byte(uint32(value) >> 24), byte(uint32(value) >> 16), byte(uint32(value) >> 8), byte(value) })
|
|
||||||
} else if value < -128 {
|
|
||||||
return writer.Write([]byte { 0xd1, byte(uint32(value) >> 8), byte(value) })
|
|
||||||
} else if value < -32 {
|
|
||||||
return writer.Write([]byte { 0xd0, byte(value) })
|
|
||||||
} else if value >= 128 {
|
|
||||||
return writer.Write([]byte { 0xd1, byte(uint32(value) >> 8), byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt64(writer io.Writer, value int64) (n int, err os.Error) {
|
|
||||||
if value < -2147483648 || value >= 2147483648 {
|
|
||||||
return writer.Write([]byte { 0xd3, byte(uint64(value) >> 56), byte(uint64(value) >> 48), byte(uint64(value) >> 40), byte(uint64(value) >> 32), byte(uint64(value) >> 24), byte(uint64(value) >> 16), byte(uint64(value) >> 8), byte(value) })
|
|
||||||
} else if value < -32768 || value >= 32768 {
|
|
||||||
return writer.Write([]byte { 0xd2, byte(uint64(value) >> 24), byte(uint64(value) >> 16), byte(uint64(value) >> 8), byte(value) })
|
|
||||||
} else if value < -128 || value >= 128 {
|
|
||||||
return writer.Write([]byte { 0xd1, byte(uint64(value) >> 8), byte(value) })
|
|
||||||
} else if value < -32 {
|
|
||||||
return writer.Write([]byte { 0xd0, byte(value) })
|
|
||||||
}
|
|
||||||
return writer.Write([]byte { byte(value) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt(writer io.Writer, value int) (n int, err os.Error) {
|
|
||||||
switch unsafe.Sizeof(value) {
|
|
||||||
case 4:
|
|
||||||
return PackInt32(writer, *(*int32)(unsafe.Pointer(&value)))
|
|
||||||
case 8:
|
|
||||||
return PackInt64(writer, *(*int64)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
return 0, os.ENOENT // never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackNil(writer io.Writer) (n int, err os.Error) {
|
|
||||||
return writer.Write([]byte{ 0xc0 })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackBool(writer io.Writer, value bool) (n int, err os.Error) {
|
|
||||||
var code byte;
|
|
||||||
if value {
|
|
||||||
code = 0xc3
|
|
||||||
} else {
|
|
||||||
code = 0xc2
|
|
||||||
}
|
|
||||||
return writer.Write([]byte{ code })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackFloat32(writer io.Writer, value float32) (n int, err os.Error) {
|
|
||||||
return PackUint32(writer, *(*uint32)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackFloat64(writer io.Writer, value float64) (n int, err os.Error) {
|
|
||||||
return PackUint64(writer, *(*uint64)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackBytes(writer io.Writer, value []byte) (n int, err os.Error) {
|
|
||||||
if len(value) < 32 {
|
|
||||||
n1, err := writer.Write([]byte { 0xa0 | uint8(len(value)) })
|
|
||||||
if err != nil { return n1, err }
|
|
||||||
n2, err := writer.Write(value)
|
|
||||||
return n1 + n2, err
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n1, err := writer.Write([]byte { 0xda, byte(len(value) >> 16), byte(len(value)) })
|
|
||||||
if err != nil { return n1, err }
|
|
||||||
n2, err := writer.Write(value)
|
|
||||||
return n1 + n2, err
|
|
||||||
}
|
|
||||||
n1, err := writer.Write([]byte { 0xdb, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n1, err }
|
|
||||||
n2, err := writer.Write(value)
|
|
||||||
return n1 + n2, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint16Array(writer io.Writer, value []uint16) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint32Array(writer io.Writer, value []uint32) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUint64Array(writer io.Writer, value []uint64) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackUint64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackUintArray(writer io.Writer, value []uint) (n int, err os.Error) {
|
|
||||||
switch unsafe.Sizeof(0) {
|
|
||||||
case 4:
|
|
||||||
return PackUint32Array(writer, *(*[]uint32)(unsafe.Pointer(&value)))
|
|
||||||
case 8:
|
|
||||||
return PackUint64Array(writer, *(*[]uint64)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
return 0, os.ENOENT // never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt8Array(writer io.Writer, value []int8) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt8(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt8(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt8(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt16Array(writer io.Writer, value []int16) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt16(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt32Array(writer io.Writer, value []int32) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackInt64Array(writer io.Writer, value []int64) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackInt64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackIntArray(writer io.Writer, value []int) (n int, err os.Error) {
|
|
||||||
switch unsafe.Sizeof(0) {
|
|
||||||
case 4:
|
|
||||||
return PackInt32Array(writer, *(*[]int32)(unsafe.Pointer(&value)))
|
|
||||||
case 8:
|
|
||||||
return PackInt64Array(writer, *(*[]int64)(unsafe.Pointer(&value)))
|
|
||||||
}
|
|
||||||
return 0, os.ENOENT // never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackFloat32Array(writer io.Writer, value []float32) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat32(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackFloat64Array(writer io.Writer, value []float64) (n int, err os.Error) {
|
|
||||||
if len(value) < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if len(value) < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(len(value) >> 24), byte(len(value) >> 16), byte(len(value) >> 8), byte(len(value)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, i := range value {
|
|
||||||
_n, err := PackFloat64(writer, i)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackArray(writer io.Writer, value reflect.ArrayOrSliceValue) (n int, err os.Error) {
|
|
||||||
{
|
|
||||||
elemType, ok := value.Type().(reflect.ArrayOrSliceType).Elem().(*reflect.UintType)
|
|
||||||
if ok && elemType.Kind() == reflect.Uint8 {
|
|
||||||
return PackBytes(writer, value.Interface().([]byte))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l := value.Len()
|
|
||||||
if l < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x90 | byte(l) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
_n, err := PackValue(writer, value.Elem(i))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if l < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xdc, byte(l >> 8), byte(l) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
_n, err := PackValue(writer, value.Elem(i))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdd, byte(l >> 24), byte(l >> 16), byte(l >> 8), byte(l) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
_n, err := PackValue(writer, value.Elem(i))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackMap(writer io.Writer, value *reflect.MapValue) (n int, err os.Error) {
|
|
||||||
keys := value.Keys()
|
|
||||||
if value.Len() < 16 {
|
|
||||||
n, err := writer.Write([]byte { 0x80 | byte(len(keys)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, k := range keys {
|
|
||||||
_n, err := PackValue(writer, k)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
_n, err = PackValue(writer, value.Elem(k))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else if value.Len() < 65536 {
|
|
||||||
n, err := writer.Write([]byte { 0xde, byte(len(keys) >> 8), byte(len(keys)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, k := range keys {
|
|
||||||
_n, err := PackValue(writer, k)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
_n, err = PackValue(writer, value.Elem(k))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n, err := writer.Write([]byte { 0xdf, byte(len(keys) >> 24), byte(len(keys) >> 16), byte(len(keys) >> 8), byte(len(keys)) })
|
|
||||||
if err != nil { return n, err }
|
|
||||||
for _, k := range keys {
|
|
||||||
_n, err := PackValue(writer, k)
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
_n, err = PackValue(writer, value.Elem(k))
|
|
||||||
if err != nil { return n, err }
|
|
||||||
n += _n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func PackValue(writer io.Writer, value reflect.Value) (n int, err os.Error) {
|
|
||||||
if value == nil || value.Type() == nil { return PackNil(writer) }
|
|
||||||
switch _value := value.(type) {
|
|
||||||
case *reflect.BoolValue: return PackBool(writer, _value.Get())
|
|
||||||
case *reflect.UintValue: return PackUint64(writer, _value.Get())
|
|
||||||
case *reflect.IntValue: return PackInt64(writer, _value.Get())
|
|
||||||
case *reflect.FloatValue: return PackFloat64(writer, _value.Get())
|
|
||||||
case *reflect.ArrayValue: return PackArray(writer, _value)
|
|
||||||
case *reflect.SliceValue: return PackArray(writer, _value)
|
|
||||||
case *reflect.MapValue: return PackMap(writer, _value)
|
|
||||||
case *reflect.InterfaceValue:
|
|
||||||
__value := reflect.NewValue(_value.Interface())
|
|
||||||
_, ok := __value.(*reflect.InterfaceValue)
|
|
||||||
if !ok {
|
|
||||||
return PackValue(writer, __value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic("unsupported type: " + value.Type().String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Packs a given value and writes it into the specified writer.
|
|
||||||
func Pack(writer io.Writer, value interface{}) (n int, err os.Error) {
|
|
||||||
if value == nil { return PackNil(writer) }
|
|
||||||
switch _value := value.(type) {
|
|
||||||
case bool: return PackBool(writer, _value)
|
|
||||||
case uint8: return PackUint8(writer, _value)
|
|
||||||
case uint16: return PackUint16(writer, _value)
|
|
||||||
case uint32: return PackUint32(writer, _value)
|
|
||||||
case uint64: return PackUint64(writer, _value)
|
|
||||||
case uint: return PackUint(writer, _value)
|
|
||||||
case int8: return PackInt8(writer, _value)
|
|
||||||
case int16: return PackInt16(writer, _value)
|
|
||||||
case int32: return PackInt32(writer, _value)
|
|
||||||
case int64: return PackInt64(writer, _value)
|
|
||||||
case int: return PackInt(writer, _value)
|
|
||||||
case float32: return PackFloat32(writer, _value)
|
|
||||||
case float64: return PackFloat64(writer, _value)
|
|
||||||
case []byte: return PackBytes(writer, _value)
|
|
||||||
case []uint16: return PackUint16Array(writer, _value)
|
|
||||||
case []uint32: return PackUint32Array(writer, _value)
|
|
||||||
case []uint64: return PackUint64Array(writer, _value)
|
|
||||||
case []uint: return PackUintArray(writer, _value)
|
|
||||||
case []int8: return PackInt8Array(writer, _value)
|
|
||||||
case []int16: return PackInt16Array(writer, _value)
|
|
||||||
case []int32: return PackInt32Array(writer, _value)
|
|
||||||
case []int64: return PackInt64Array(writer, _value)
|
|
||||||
case []int: return PackIntArray(writer, _value)
|
|
||||||
case []float32: return PackFloat32Array(writer, _value)
|
|
||||||
case []float64: return PackFloat64Array(writer, _value)
|
|
||||||
default:
|
|
||||||
return PackValue(writer, reflect.NewValue(value))
|
|
||||||
}
|
|
||||||
return 0, nil // never get here
|
|
||||||
}
|
|
||||||
288
go/unpack.go
288
go/unpack.go
@@ -1,288 +0,0 @@
|
|||||||
package msgpack
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"unsafe"
|
|
||||||
"strconv"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
func readByte(reader io.Reader) (v uint8, err os.Error) {
|
|
||||||
data := [1]byte{}
|
|
||||||
_, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, e }
|
|
||||||
return data[0], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readUint16(reader io.Reader) (v uint16, n int, err os.Error) {
|
|
||||||
data := [2]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (uint16(data[0]) << 8) | uint16(data[1]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readUint32(reader io.Reader) (v uint32, n int, err os.Error) {
|
|
||||||
data := [4]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (uint32(data[0]) << 24) | (uint32(data[1]) << 16) | (uint32(data[2]) << 8) | uint32(data[3]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readUint64(reader io.Reader) (v uint64, n int, err os.Error) {
|
|
||||||
data := [8]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (uint64(data[0]) << 56) | (uint64(data[1]) << 48) | (uint64(data[2]) << 40) | (uint64(data[3]) << 32) | (uint64(data[4]) << 24) | (uint64(data[5]) << 16) | (uint64(data[6]) << 8) | uint64(data[7]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readInt16(reader io.Reader) (v int16, n int, err os.Error) {
|
|
||||||
data := [2]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (int16(data[0]) << 8) | int16(data[1]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readInt32(reader io.Reader) (v int32, n int, err os.Error) {
|
|
||||||
data := [4]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (int32(data[0]) << 24) | (int32(data[1]) << 16) | (int32(data[2]) << 8) | int32(data[3]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readInt64(reader io.Reader) (v int64, n int, err os.Error) {
|
|
||||||
data := [8]byte{}
|
|
||||||
n, e := reader.Read(data[0:])
|
|
||||||
if e != nil { return 0, n, e }
|
|
||||||
return (int64(data[0]) << 56) | (int64(data[1]) << 48) | (int64(data[2]) << 40) | (int64(data[3]) << 32) | (int64(data[4]) << 24) | (int64(data[5]) << 16) | (int64(data[6]) << 8) | int64(data[7]), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackArray(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
|
||||||
retval := make([]interface{}, nelems)
|
|
||||||
nbytesread := 0
|
|
||||||
var i uint
|
|
||||||
for i = 0; i < nelems; i++ {
|
|
||||||
v, n, e := Unpack(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval[i] = v.Interface()
|
|
||||||
}
|
|
||||||
return reflect.NewValue(retval), nbytesread, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackArrayReflected(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
|
||||||
retval := make([]reflect.Value, nelems)
|
|
||||||
nbytesread := 0
|
|
||||||
var i uint
|
|
||||||
for i = 0; i < nelems; i++ {
|
|
||||||
v, n, e := UnpackReflected(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval[i] = v
|
|
||||||
}
|
|
||||||
return reflect.NewValue(retval), nbytesread, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackMap(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
|
||||||
retval := make(map [interface{}] interface{})
|
|
||||||
nbytesread := 0
|
|
||||||
var i uint
|
|
||||||
for i = 0; i < nelems; i++ {
|
|
||||||
k, n, e := Unpack(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
v, n, e := Unpack(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval[k.Interface()] = v.Interface()
|
|
||||||
}
|
|
||||||
return reflect.NewValue(retval), nbytesread, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpackMapReflected(reader io.Reader, nelems uint) (v reflect.Value, n int, err os.Error) {
|
|
||||||
retval := make(map [reflect.Value] reflect.Value)
|
|
||||||
nbytesread := 0
|
|
||||||
var i uint
|
|
||||||
for i = 0; i < nelems; i++ {
|
|
||||||
k, n, e := UnpackReflected(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
v, n, e := UnpackReflected(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval[k] = v
|
|
||||||
}
|
|
||||||
return reflect.NewValue(retval), nbytesread, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unpack(reader io.Reader, reflected bool) (v reflect.Value, n int, err os.Error) {
|
|
||||||
var retval reflect.Value
|
|
||||||
var nbytesread int = 0
|
|
||||||
|
|
||||||
c, e := readByte(reader)
|
|
||||||
if e != nil { return nil, 0, e }
|
|
||||||
nbytesread += 1
|
|
||||||
if c < 0x80 || c >= 0xe0 {
|
|
||||||
retval = reflect.NewValue(int8(c))
|
|
||||||
} else if c >= 0x80 && c <= 0x8f {
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackMapReflected(reader, uint(c & 0xf))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackMap(reader, uint(c & 0xf))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
nbytesread += n
|
|
||||||
} else if c >= 0x90 && c <= 0x9f {
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackArrayReflected(reader, uint(c & 0xf))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackArray(reader, uint(c & 0xf))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
nbytesread += n
|
|
||||||
} else if c >= 0xa0 && c <= 0xbf {
|
|
||||||
data := make([]byte, c & 0xf);
|
|
||||||
n, e := reader.Read(data)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
} else {
|
|
||||||
switch c {
|
|
||||||
case 0xc0: retval = reflect.NewValue(nil)
|
|
||||||
case 0xc2: retval = reflect.NewValue(false)
|
|
||||||
case 0xc3: retval = reflect.NewValue(true)
|
|
||||||
case 0xca:
|
|
||||||
data, n, e := readUint32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(*(*float32)(unsafe.Pointer(&data)))
|
|
||||||
case 0xcb:
|
|
||||||
data, n, e := readUint64(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(*(*float64)(unsafe.Pointer(&data)))
|
|
||||||
case 0xcc:
|
|
||||||
data, e := readByte(reader)
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(uint8(data))
|
|
||||||
nbytesread += 1
|
|
||||||
case 0xcd:
|
|
||||||
data, n, e := readUint16(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xce:
|
|
||||||
data, n, e := readUint32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xcf:
|
|
||||||
data, n, e := readUint64(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xd0:
|
|
||||||
data, e := readByte(reader)
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(int8(data))
|
|
||||||
nbytesread += 1
|
|
||||||
case 0xd1:
|
|
||||||
data, n, e := readInt16(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xd2:
|
|
||||||
data, n, e := readInt32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xd3:
|
|
||||||
data, n, e := readInt64(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xda:
|
|
||||||
nbytestoread, n, e := readUint16(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
data := make([]byte, nbytestoread)
|
|
||||||
n, e = reader.Read(data)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xdb:
|
|
||||||
nbytestoread, n, e := readUint32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
data := make([]byte, nbytestoread)
|
|
||||||
n, e = reader.Read(data)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
retval = reflect.NewValue(data)
|
|
||||||
case 0xdc:
|
|
||||||
nelemstoread, n, e := readUint16(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackArrayReflected(reader, uint(nelemstoread))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackArray(reader, uint(nelemstoread))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
case 0xdd:
|
|
||||||
nelemstoread, n, e := readUint32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackArrayReflected(reader, uint(nelemstoread))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackArray(reader, uint(nelemstoread))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
case 0xde:
|
|
||||||
nelemstoread, n, e := readUint16(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackMapReflected(reader, uint(nelemstoread))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackMap(reader, uint(nelemstoread))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
case 0xdf:
|
|
||||||
nelemstoread, n, e := readUint32(reader)
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
if reflected {
|
|
||||||
retval, n, e = unpackMapReflected(reader, uint(nelemstoread))
|
|
||||||
} else {
|
|
||||||
retval, n, e = unpackMap(reader, uint(nelemstoread))
|
|
||||||
}
|
|
||||||
nbytesread += n
|
|
||||||
if e != nil { return nil, nbytesread, e }
|
|
||||||
default:
|
|
||||||
panic("unsupported code: " + strconv.Itoa(int(c)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval, nbytesread, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads a value from the reader, unpack and returns it.
|
|
||||||
func Unpack(reader io.Reader) (v reflect.Value, n int, err os.Error) {
|
|
||||||
return unpack(reader, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads unpack a value from the reader, unpack and returns it. When the
|
|
||||||
// value is an array or map, leaves the elements wrapped by corresponding
|
|
||||||
// wrapper objects defined in reflect package.
|
|
||||||
func UnpackReflected(reader io.Reader) (v reflect.Value, n int, err os.Error) {
|
|
||||||
return unpack(reader, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
Copyright (c) 2009-2010, Hideyuki Tanaka
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the Hideyuki Tanaka nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY Hideyuki Tanaka ''AS IS'' AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env runhaskell
|
|
||||||
> import Distribution.Simple
|
|
||||||
> main = defaultMain
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
Name: msgpack
|
|
||||||
Version: 0.6.1.1
|
|
||||||
Synopsis: A Haskell implementation of MessagePack
|
|
||||||
Description:
|
|
||||||
A Haskell implementation of MessagePack <http://msgpack.org/>
|
|
||||||
|
|
||||||
License: BSD3
|
|
||||||
License-File: LICENSE
|
|
||||||
Copyright: Copyright (c) 2009-2011, Hideyuki Tanaka
|
|
||||||
Category: Data
|
|
||||||
Author: Hideyuki Tanaka
|
|
||||||
Maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com>
|
|
||||||
Homepage: http://github.com/msgpack/msgpack
|
|
||||||
Stability: Experimental
|
|
||||||
Cabal-Version: >= 1.6
|
|
||||||
Build-Type: Simple
|
|
||||||
|
|
||||||
Extra-source-files:
|
|
||||||
test/Test.hs
|
|
||||||
test/UserData.hs
|
|
||||||
|
|
||||||
Library
|
|
||||||
Build-depends: base >=4 && <5,
|
|
||||||
transformers >= 0.2 && < 0.3,
|
|
||||||
bytestring >= 0.9 && < 0.10,
|
|
||||||
text >= 0.11 && < 0.12,
|
|
||||||
vector >= 0.7 && < 0.8,
|
|
||||||
attoparsec >= 0.8 && < 0.9,
|
|
||||||
binary >= 0.5.0 && < 0.5.1,
|
|
||||||
data-binary-ieee754 >= 0.4 && < 0.5,
|
|
||||||
deepseq >= 1.1 && <1.2,
|
|
||||||
template-haskell >= 2.4 && < 2.6
|
|
||||||
|
|
||||||
Ghc-options: -Wall
|
|
||||||
Hs-source-dirs: src
|
|
||||||
|
|
||||||
Exposed-modules:
|
|
||||||
Data.MessagePack
|
|
||||||
Data.MessagePack.Assoc
|
|
||||||
Data.MessagePack.Pack
|
|
||||||
Data.MessagePack.Unpack
|
|
||||||
Data.MessagePack.Object
|
|
||||||
Data.MessagePack.Derive
|
|
||||||
|
|
||||||
Other-modules:
|
|
||||||
Data.MessagePack.Internal.Utf8
|
|
||||||
|
|
||||||
Source-repository head
|
|
||||||
Type: git
|
|
||||||
Location: git://github.com/msgpack/msgpack.git
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user