Compare commits

...

17 Commits

Author SHA1 Message Date
frsyuki
bf3cb63d46 cpp: version 0.3.8 2009-09-10 13:53:12 +09:00
frsyuki
8da7b692f6 cpp: define, type::tuple: GENERATION_LIMIT = 31 2009-09-10 13:50:19 +09:00
Kazuki Ohta
320c79db49 c++: add vrefbuffer test 2009-09-04 16:20:29 +09:00
frsyuki
ebf64d9892 cpp: test.cpp: fixes EXPECT_EQ rule 2009-08-26 12:28:08 +09:00
frsyuki
c12d5b8461 c: test.cpp: add msgpack_sbuffer_destroy and msgpack_zone_destroy 2009-08-26 12:27:28 +09:00
Kazuki Ohta
7186edc45e C: more strict tests for float, double
C++: more strict tests for float, double & enum, union member
2009-08-26 11:52:12 +09:00
Kazuki Ohta
c94772104d C: add test for map
C++: add tests for primitive types, stl types, user-defined type
2009-08-26 11:28:54 +09:00
Kazuki Ohta
9374571056 C: add more tests (float, double, nil, true, false, array, raw) 2009-08-26 09:24:07 +09:00
Kazuki Ohta
c232e91f83 c: fix bugs in c/test.cpp and add more tests 2009-08-25 19:26:54 +09:00
Kazuki Ohta
5b8777026a c: add sometests for serialization 2009-08-25 19:04:21 +09:00
Kazuki Ohta
51e435d46c fix build 2009-08-25 18:40:06 +09:00
frsyuki
d3f9ab7dec add c/test.cpp cpp/test.cpp 2009-08-25 18:35:26 +09:00
frsyuki
1ba330c473 fix cpp/preprocess.sh 2009-08-25 18:25:58 +09:00
frsyuki
dba7f480ed cpp: add missing preprocess.sh file 2009-08-19 17:50:15 +09:00
frsyuki
3a39accb0b cpp: preprocess eruby templates on ./bootstrap; released package doesn't require erb 2009-08-19 17:47:22 +09:00
frsyuki
387eca6fbf cpp-0.3.7 2009-08-19 17:36:05 +09:00
frsyuki
b2381d0513 cpp: fix overflow check for minimum number of signed integer type 2009-08-19 15:10:10 +09:00
13 changed files with 1120 additions and 235 deletions

View File

@@ -1,5 +1,4 @@
if ENABLE_CXX
export ERB
SUBDIRS = c cpp
else
SUBDIRS = c

4
README
View File

@@ -8,9 +8,7 @@ Binary-based efficient data interchange format.
MessagePack is only tested on Linux and Mac OS X, but it may run on other
UNIX-like platforms.
Following programs are required to build:
- gcc >= 4.1 with C++ support
- ruby >= 1.8 (ruby is used as a preprocessor)
gcc >= 4.1 is required to build.
*Installation

View File

@@ -31,11 +31,8 @@ if test x"$1" = x"--help"; then
fi
#if [ -z "$NO_NEST" ];then
# cd c && ./bootstrap $@; cd ..
# cd cpp && ./bootstrap $@; cd ..
#fi
mkdir -p ac
(cd cpp && ./preprocess.sh $@; cd ..)
ACLOCAL="aclocal"

View File

@@ -18,3 +18,11 @@ nobase_include_HEADERS = \
# -version-info CURRENT:REVISION:AGE
libmsgpackc_la_LDFLAGS = -version-info 1:0:0
check_PROGRAMS = \
msgpackc_test
msgpackc_test_SOURCES = test.cpp
msgpackc_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c
msgpackc_test_LDFLAGS = libmsgpackc.la -lgtest_main
TESTS = $(check_PROGRAMS)

424
c/test.cpp Normal file
View File

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

View File

@@ -1,6 +1,6 @@
AC_INIT(msgpack/unpack_template.h)
AC_CONFIG_AUX_DIR(ac)
AM_INIT_AUTOMAKE(msgpack, 0.3.6)
AM_INIT_AUTOMAKE(msgpack, 0.3.8)
AC_CONFIG_HEADER(config.h)
AC_SUBST(CFLAGS)
@@ -23,11 +23,6 @@ if test "$enable_cxx" != "no"; then
if test "" = "$CXXFLAGS"; then
CXXFLAGS="-g -O4"
fi
AC_CHECK_PROG(ERB, erb, erb)
if test "x$ERB" = x; then
AC_MSG_ERROR([cannot find erb. Ruby is needed to build.])
fi
fi
# FIXME

View File

@@ -27,33 +27,16 @@ nobase_include_HEADERS = \
msgpack/type/tuple.hpp \
msgpack/type/define.hpp
# FIXME
object.lo: msgpack/type/tuple.hpp msgpack/type/define.hpp msgpack/zone.hpp
msgpack/type/tuple.hpp: msgpack/type/tuple.hpp.erb
$(ERB) $< > $@.tmp
mv $@.tmp $@
msgpack/type/define.hpp: msgpack/type/define.hpp.erb
$(ERB) $< > $@.tmp
mv $@.tmp $@
msgpack/zone.hpp: msgpack/zone.hpp.erb
$(ERB) $< > $@.tmp
mv $@.tmp $@
MOSTLYCLEANFILES = \
msgpack/type/tuple.hpp \
msgpack/type/define.hpp \
msgpack/zone.hpp
EXTRA_DIST = \
msgpack/type/tuple.hpp.erb \
msgpack/type/define.hpp.erb \
msgpack/zone.hpp.erb
libmsgpack_la_LIBADD = -L../c -lmsgpackc
# -version-info CURRENT:REVISION:AGE
libmsgpack_la_LDFLAGS = -version-info 1:0:0
check_PROGRAMS = \
msgpack_test
msgpack_test_SOURCES = test.cpp
msgpack_test_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/c -I$(top_srcdir)/cpp
msgpack_test_LDFLAGS = libmsgpack.la -lgtest_main
TESTS = $(check_PROGRAMS)

View File

@@ -16,7 +16,6 @@
// limitations under the License.
//
#include "msgpack/object.hpp"
#include <string.h>
namespace msgpack {

11
cpp/preprocess.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
preprocess() {
erb $1.erb > $1.tmp
mv $1.tmp $1
}
preprocess msgpack/type/tuple.hpp
preprocess msgpack/type/define.hpp
preprocess msgpack/zone.hpp

View File

@@ -1,201 +1,672 @@
#include <iostream>
#include "msgpack.hpp"
#include <math.h>
#include <string>
#include <msgpack.hpp>
#include <sstream>
#include <memory>
#include <vector>
#include <map>
#include <deque>
#include <set>
#include <list>
using namespace msgpack;
#include <gtest/gtest.h>
class checker {
public:
template <typename T>
void check(const char* d, size_t len, T should) {
try {
std::cout << "----" << std::endl;
using namespace std;
object o;
try {
o = unpack(d, len, m_zone);
} catch (std::runtime_error& e) {
std::cout << o << std::endl;
std::cout << "**" << e.what() << "**" << std::endl;
return;
}
const unsigned int kLoop = 10000;
const unsigned int kElements = 100;
const double kEPS = 1e-10;
std::cout << o << std::endl;
#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)
try {
std::stringstream s;
pack(s, should);
std::string str(s.str());
object ro = unpack(str.data(), str.size(), m_zone);
std::cout << ro << std::endl;
if(ro != o) { throw std::runtime_error("NOT MATCH"); }
} catch (std::runtime_error& e) {
std::cout << "** REUNPACK FAILED **" << std::endl;
std::cout << e.what() << std::endl;
} catch (...) {
std::cout << "** REUNPACK FAILED **" << std::endl;
std::cout << "unknown error" << std::endl;
}
} catch (...) { m_zone.clear(); throw; }
m_zone.clear();
}
private:
zone m_zone;
};
int main(void)
TEST(MSGPACK, simple_buffer_short)
{
checker c;
#if 0
{ // SimpleValue
const char d[] = {
0x93, 0xc0, 0xc2, 0xc3,
};
c.check(d, sizeof(d),
type::make_tuple(
type::nil(), false, true
)
);
}
{ // Fixnum
const char d[] = {
0x92,
0x93, 0x00, 0x40, 0x7f,
0x93, 0xe0, 0xf0, 0xff,
};
c.check(d, sizeof(d),
type::make_tuple(
type::make_tuple(
0, 64, 127
),
type::make_tuple(
-32, -16, -1
)
)
);
}
{ // FixArray
const char d[] = {
0x92,
0x90,
0x91,
0x91, 0xc0,
};
std::vector<int> empty;
c.check(d, sizeof(d),
type::make_tuple(
empty,
type::make_tuple(
type::make_tuple(
type::nil()
)
)
)
);
}
{ // FixRaw
const char d[] = {
0x94,
0xa0,
0xa1, 'a',
0xa2, 'b', 'c',
0xa3, 'd', 'e', 'f',
};
c.check(d, sizeof(d),
type::make_tuple(
std::string(""),
std::string("a"),
std::string("bc"),
type::raw_ref("def", 3)
)
);
}
#endif
static const unsigned TASK_ARRAY = 1000;
static const unsigned TASK_REPEAT = 10;
std::vector<std::string> task;
// create task
{
static char traw[64];
memset(traw, 'a', sizeof(traw));
task.resize(TASK_ARRAY);
for(unsigned i=0; i < TASK_ARRAY; ++i) {
task[i] = std::string(traw, sizeof(traw));
}
}
std::stringstream stream;
// send message
{
for(unsigned i=0; i < TASK_REPEAT; ++i) {
pack(stream, task);
}
std::cout << "send " << stream.str().size() << " bytes" << std::endl;
}
ssize_t total_bytes = stream.str().size();
stream.seekg(0);
// reserive message
{
unsigned num_msg = 0;
static const size_t RESERVE_SIZE = 32;//*1024;
unpacker pac;
while(stream.good() && total_bytes > 0) {
// 1. reserve buffer
pac.reserve_buffer(RESERVE_SIZE);
// 2. read data to buffer() up to buffer_capacity() bytes
size_t sz = stream.readsome(
pac.buffer(),
pac.buffer_capacity());
total_bytes -= sz;
std::cout << "read " << sz << " bytes to capacity "
<< pac.buffer_capacity() << " bytes"
<< std::endl;
// 3. specify the number of bytes actually copied
pac.buffer_consumed(sz);
// 4. repeat execute() until it returns false
while( pac.execute() ) {
// 5.1. take out the parsed object
object o = pac.data();
// 5.2 release the zone
std::auto_ptr<zone> olife( pac.release_zone() );
// 5.3 re-initialize the unpacker */
pac.reset();
// do some with the o and olife
std::cout << "message parsed: " << o << std::endl;
++num_msg;
}
}
std::cout << "stream finished" << std::endl;
std::cout << num_msg << " messages reached" << std::endl;
}
return 0;
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);
}
//-----------------------------------------------------------------------------
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);
}
}
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);
}

View File

@@ -33,7 +33,7 @@ namespace msgpack {
namespace type {
<% GENERATION_LIMIT = 15 %>
<% GENERATION_LIMIT = 31 %>
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
struct define;

View File

@@ -37,7 +37,7 @@ namespace detail {
{ throw type_error(); }
return o.via.u64;
} else if(o.type == type::NEGATIVE_INTEGER) {
if(o.via.i64 < (int64_t)-std::numeric_limits<T>::max())
if(o.via.i64 < (int64_t)std::numeric_limits<T>::min())
{ throw type_error(); }
return o.via.i64;
}

View File

@@ -26,7 +26,7 @@ namespace type {
// FIXME operator==
// FIXME operator!=
<% GENERATION_LIMIT = 15 %>
<% GENERATION_LIMIT = 31 %>
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
struct tuple;