Compare commits

..

9 Commits

Author SHA1 Message Date
frsyuki
9684c8664f cpp: version 0.5.4 2010-08-29 18:27:10 +09:00
frsyuki
3c75361e5a cpp: updates README.md 2010-08-29 18:24:32 +09:00
frsyuki
c44c9ab74d cpp: adds msgpack_vc2008.vcproj file in source package 2010-08-29 18:23:16 +09:00
frsyuki
8cc9c871b7 Merge branch 'master' of github.com:msgpack/msgpack 2010-08-28 11:40:45 +09:00
UENISHI Kota
31d211cded Merge branch 'master' of ssh://github.com/msgpack/msgpack 2010-08-28 00:36:54 +09:00
UENISHI Kota
c42cba1d54 erlang: fixed bug around error case when serializing atom. 2010-08-27 23:02:16 +09:00
frsyuki
c87f7cb9ac cpp: fixes fix_int; updates test/fixint.cc 2010-08-27 20:52:40 +09:00
tokuhirom
8de1f764fd Perl: bump up version to 0.14 2010-08-21 16:09:30 +09:00
tokuhirom
a91c1ec6d9 fixed segv on cyclic reference(patch by dankogai) 2010-08-21 16:02:23 +09:00
16 changed files with 215 additions and 57 deletions

View File

@@ -1,5 +1,10 @@
2010-07-27 version 0.5.3: 2010-08-29 version 0.5.4:
* includes msgpack_vc2008.vcproj file in source package
* fixes type::fix_int types
2010-08-27 version 0.5.3:
* adds type::fix_{u,}int{8,16,32,64} types * adds type::fix_{u,}int{8,16,32,64} types
* adds msgpack_pack_fix_{u,}int{8,16,32,64} functions * adds msgpack_pack_fix_{u,}int{8,16,32,64} functions

View File

@@ -6,7 +6,9 @@ DOC_FILES = \
NOTICE \ NOTICE \
msgpack_vc8.vcproj \ msgpack_vc8.vcproj \
msgpack_vc8.sln \ msgpack_vc8.sln \
msgpack_vc8.postbuild.bat msgpack_vc2008.vcproj \
msgpack_vc2008.sln \
msgpack_vc.postbuild.bat
EXTRA_DIST = \ EXTRA_DIST = \
$(DOC_FILES) $(DOC_FILES)

View File

@@ -13,9 +13,10 @@ On UNIX-like platform, run ./configure && make && sudo make install:
$ make $ make
$ sudo make install $ sudo make install
On Windows, open msgpack_vc8.vcproj file and build it using batch build. DLLs are built on lib folder, and the headers are built on include folder. 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 and msgpackc library. To use the library in your program, include msgpack.hpp header and link "msgpack" library.
## Example ## Example
@@ -34,15 +35,9 @@ To use the library in your program, include msgpack.hpp header and link msgpack
msgpack::pack(&buffer, target); msgpack::pack(&buffer, target);
// Deserialize the serialized data. // Deserialize the serialized data.
msgpack::zone mempool; // this manages the life of deserialized object msgpack::unpacked msg; // includes memory pool and deserialized object
msgpack::object obj; msgpack::unpack(&msg, sbuf.data(), sbuf.size());
msgpack::unpack_return ret = msgpack::object obj = msg.get();
msgpack::unpack(buffer.data, buffer.size, NULL, &mempool, &obj);
if(ret != msgapck::UNPACK_SUCCESS) {
// error check
exit(1);
}
// Print the deserialized object to stdout. // Print the deserialized object to stdout.
std::cout << obj << std::endl; // ["Hello," "World!"] std::cout << obj << std::endl; // ["Hello," "World!"]
@@ -55,7 +50,7 @@ To use the library in your program, include msgpack.hpp header and link msgpack
obj.as<int>(); // type is mismatched, msgpack::type_error is thrown obj.as<int>(); // type is mismatched, msgpack::type_error is thrown
} }
API document and other example codes are available at the [wiki.](http://msgpack.sourceforge.net/start) API documents and other example codes are available at the [wiki.](http://redmine.msgpack.org/projects/msgpack/wiki)
## License ## License

View File

@@ -1,6 +1,6 @@
AC_INIT(src/object.cpp) AC_INIT(src/object.cpp)
AC_CONFIG_AUX_DIR(ac) AC_CONFIG_AUX_DIR(ac)
AM_INIT_AUTOMAKE(msgpack, 0.5.3) AM_INIT_AUTOMAKE(msgpack, 0.5.4)
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
AC_SUBST(CFLAGS) AC_SUBST(CFLAGS)

View File

@@ -28,7 +28,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Gathering header files" Description="Gathering header files"
CommandLine="msgpack_vc8.postbuild.bat" CommandLine="msgpack_vc.postbuild.bat"
Outputs="include" Outputs="include"
/> />
<Tool <Tool
@@ -96,7 +96,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Gathering header files" Description="Gathering header files"
CommandLine="msgpack_vc8.postbuild.bat" CommandLine="msgpack_vc.postbuild.bat"
Outputs="include" Outputs="include"
/> />
<Tool <Tool

View File

@@ -29,3 +29,6 @@ cp -f ../msgpack/unpack_template.h src/msgpack/
cp -f ../test/cases.mpac test/ cp -f ../test/cases.mpac test/
cp -f ../test/cases_compact.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

View File

@@ -19,6 +19,7 @@
#define MSGPACK_TYPE_FIXINT_HPP__ #define MSGPACK_TYPE_FIXINT_HPP__
#include "msgpack/object.hpp" #include "msgpack/object.hpp"
#include "msgpack/type/int.hpp"
namespace msgpack { namespace msgpack {
@@ -29,10 +30,13 @@ template <typename T>
struct fix_int { struct fix_int {
fix_int() : value(0) { } fix_int() : value(0) { }
fix_int(T value) : value(value) { } fix_int(T value) : value(value) { }
operator T() const { return value; } operator T() const { return value; }
T get() const { return value; } T get() const { return value; }
private: private:
const T value; T value;
}; };
@@ -50,6 +54,32 @@ typedef fix_int<int64_t> fix_int64;
} // namespace type } // 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> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int8& v)
{ o.pack_fix_int8(v); return o; } { o.pack_fix_int8(v); return o; }
@@ -66,6 +96,7 @@ template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_int64& v)
{ o.pack_fix_int64(v); return o; } { o.pack_fix_int64(v); return o; }
template <typename Stream> template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v) inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint8& v)
{ o.pack_fix_uint8(v); return o; } { o.pack_fix_uint8(v); return o; }
@@ -83,6 +114,58 @@ inline packer<Stream>& operator<< (packer<Stream>& o, const type::fix_uint64& v)
{ o.pack_fix_uint64(v); return o; } { 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 } // namespace msgpack
#endif /* msgpack/type/fixint.hpp */ #endif /* msgpack/type/fixint.hpp */

View File

@@ -22,3 +22,34 @@ TEST(fixint, size)
check_size<msgpack::type::fix_uint64>(9); 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>();
}

View File

@@ -126,7 +126,7 @@ pack_(List) when is_list(List) ->
pack_({Map}) when is_list(Map) -> pack_({Map}) when is_list(Map) ->
pack_map(Map); pack_map(Map);
pack_(Other) -> pack_(Other) ->
throw({error, {badarg, Other}}). throw({badarg, Other}).
-spec pack_uint_(non_neg_integer()) -> binary(). -spec pack_uint_(non_neg_integer()) -> binary().
@@ -387,4 +387,9 @@ benchmark_test()->
{Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)), {Data,<<>>}=?debugTime("deserialize", msgpack:unpack(S)),
?debugFmt("for ~p KB test data.", [byte_size(S) div 1024]). ?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. -endif.

View File

@@ -24,9 +24,7 @@ public class TestMessageUnpackable {
Image dst = new Image(); Image dst = new Image();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in); dst.messageUnpack(new Unpacker(in));
dst.messageUnpack(pac);
assertEquals(src, dst); assertEquals(src, dst);
} }

View File

@@ -272,63 +272,63 @@ do { \
} while(0) } while(0)
#ifdef msgpack_pack_inline_func_fastint #ifdef msgpack_pack_inline_func_fixint
msgpack_pack_inline_func_fastint(_uint8)(msgpack_pack_user x, uint8_t d) msgpack_pack_inline_func_fixint(_uint8)(msgpack_pack_user x, uint8_t d)
{ {
unsigned char buf[2] = {0xcc, TAKE8_8(d)}; unsigned char buf[2] = {0xcc, TAKE8_8(d)};
msgpack_pack_append_buffer(x, buf, 2); msgpack_pack_append_buffer(x, buf, 2);
} }
msgpack_pack_inline_func_fastint(_uint16)(msgpack_pack_user x, uint16_t d) msgpack_pack_inline_func_fixint(_uint16)(msgpack_pack_user x, uint16_t d)
{ {
unsigned char buf[3]; unsigned char buf[3];
buf[0] = 0xcd; _msgpack_store16(&buf[1], d); buf[0] = 0xcd; _msgpack_store16(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 3); msgpack_pack_append_buffer(x, buf, 3);
} }
msgpack_pack_inline_func_fastint(_uint32)(msgpack_pack_user x, uint32_t d) msgpack_pack_inline_func_fixint(_uint32)(msgpack_pack_user x, uint32_t d)
{ {
unsigned char buf[5]; unsigned char buf[5];
buf[0] = 0xce; _msgpack_store32(&buf[1], d); buf[0] = 0xce; _msgpack_store32(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 5); msgpack_pack_append_buffer(x, buf, 5);
} }
msgpack_pack_inline_func_fastint(_uint64)(msgpack_pack_user x, uint64_t d) msgpack_pack_inline_func_fixint(_uint64)(msgpack_pack_user x, uint64_t d)
{ {
unsigned char buf[9]; unsigned char buf[9];
buf[0] = 0xcf; _msgpack_store64(&buf[1], d); buf[0] = 0xcf; _msgpack_store64(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 9); msgpack_pack_append_buffer(x, buf, 9);
} }
msgpack_pack_inline_func_fastint(_int8)(msgpack_pack_user x, int8_t d) msgpack_pack_inline_func_fixint(_int8)(msgpack_pack_user x, int8_t d)
{ {
unsigned char buf[2] = {0xd0, TAKE8_8(d)}; unsigned char buf[2] = {0xd0, TAKE8_8(d)};
msgpack_pack_append_buffer(x, buf, 2); msgpack_pack_append_buffer(x, buf, 2);
} }
msgpack_pack_inline_func_fastint(_int16)(msgpack_pack_user x, int16_t d) msgpack_pack_inline_func_fixint(_int16)(msgpack_pack_user x, int16_t d)
{ {
unsigned char buf[3]; unsigned char buf[3];
buf[0] = 0xd1; _msgpack_store16(&buf[1], d); buf[0] = 0xd1; _msgpack_store16(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 3); msgpack_pack_append_buffer(x, buf, 3);
} }
msgpack_pack_inline_func_fastint(_int32)(msgpack_pack_user x, int32_t d) msgpack_pack_inline_func_fixint(_int32)(msgpack_pack_user x, int32_t d)
{ {
unsigned char buf[5]; unsigned char buf[5];
buf[0] = 0xd2; _msgpack_store32(&buf[1], d); buf[0] = 0xd2; _msgpack_store32(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 5); msgpack_pack_append_buffer(x, buf, 5);
} }
msgpack_pack_inline_func_fastint(_int64)(msgpack_pack_user x, int64_t d) msgpack_pack_inline_func_fixint(_int64)(msgpack_pack_user x, int64_t d)
{ {
unsigned char buf[9]; unsigned char buf[9];
buf[0] = 0xd3; _msgpack_store64(&buf[1], d); buf[0] = 0xd3; _msgpack_store64(&buf[1], d);
msgpack_pack_append_buffer(x, buf, 9); msgpack_pack_append_buffer(x, buf, 9);
} }
#undef msgpack_pack_inline_func_fastint #undef msgpack_pack_inline_func_fixint
#endif #endif

View File

@@ -1,3 +1,8 @@
0.14
- fixed segv on serializing cyclic reference
(Dan Kogai)
0.13 0.13
- clearly specify requires_c99(), because msgpack C header requires C99. - clearly specify requires_c99(), because msgpack C header requires C99.

View File

@@ -4,7 +4,7 @@ use warnings;
use XSLoader; use XSLoader;
use 5.008001; use 5.008001;
our $VERSION = '0.13'; our $VERSION = '0.14';
our $PreferInteger = 0; our $PreferInteger = 0;
our $true = do { bless \(my $dummy = 1), "Data::MessagePack::Boolean" }; our $true = do { bless \(my $dummy = 1), "Data::MessagePack::Boolean" };

View File

@@ -49,6 +49,8 @@ static void need(enc_t *enc, STRLEN len);
# error "msgpack only supports IVSIZE = 8,4,2 environment." # error "msgpack only supports IVSIZE = 8,4,2 environment."
#endif #endif
#define ERR_NESTING_EXCEEDED "perl structure exceeds maximum nesting level (max_depth set too low?)"
static void need(enc_t *enc, STRLEN len) static void need(enc_t *enc, STRLEN len)
{ {
@@ -146,9 +148,10 @@ static int try_int(enc_t* enc, const char *p, size_t len) {
} }
static void _msgpack_pack_rv(enc_t *enc, SV* sv); static void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth);
static void _msgpack_pack_sv(enc_t *enc, SV* sv) { static void _msgpack_pack_sv(enc_t *enc, SV* sv, int depth) {
if (!depth) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED);
SvGETMAGIC(sv); SvGETMAGIC(sv);
if (sv==NULL) { if (sv==NULL) {
@@ -171,7 +174,7 @@ static void _msgpack_pack_sv(enc_t *enc, SV* sv) {
} else if (SvIOKp(sv)) { } else if (SvIOKp(sv)) {
PACK_IV(enc, SvIV(sv)); PACK_IV(enc, SvIV(sv));
} else if (SvROK(sv)) { } else if (SvROK(sv)) {
_msgpack_pack_rv(enc, SvRV(sv)); _msgpack_pack_rv(enc, SvRV(sv), depth-1);
} else if (!SvOK(sv)) { } else if (!SvOK(sv)) {
msgpack_pack_nil(enc); msgpack_pack_nil(enc);
} else if (isGV(sv)) { } else if (isGV(sv)) {
@@ -182,8 +185,9 @@ static void _msgpack_pack_sv(enc_t *enc, SV* sv) {
} }
} }
static void _msgpack_pack_rv(enc_t *enc, SV* sv) { static void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) {
svtype svt; svtype svt;
if (!depth) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED);
SvGETMAGIC(sv); SvGETMAGIC(sv);
svt = SvTYPE(sv); svt = SvTYPE(sv);
@@ -207,8 +211,8 @@ static void _msgpack_pack_rv(enc_t *enc, SV* sv) {
msgpack_pack_map(enc, count); msgpack_pack_map(enc, count);
while (he = hv_iternext(hval)) { while (he = hv_iternext(hval)) {
_msgpack_pack_sv(enc, hv_iterkeysv(he)); _msgpack_pack_sv(enc, hv_iterkeysv(he), depth);
_msgpack_pack_sv(enc, HeVAL(he)); _msgpack_pack_sv(enc, HeVAL(he), depth);
} }
} else if (svt == SVt_PVAV) { } else if (svt == SVt_PVAV) {
AV* ary = (AV*)sv; AV* ary = (AV*)sv;
@@ -218,7 +222,7 @@ static void _msgpack_pack_rv(enc_t *enc, SV* sv) {
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
SV** svp = av_fetch(ary, i, 0); SV** svp = av_fetch(ary, i, 0);
if (svp) { if (svp) {
_msgpack_pack_sv(enc, *svp); _msgpack_pack_sv(enc, *svp, depth);
} else { } else {
msgpack_pack_nil(enc); msgpack_pack_nil(enc);
} }
@@ -244,11 +248,13 @@ static void _msgpack_pack_rv(enc_t *enc, SV* sv) {
XS(xs_pack) { XS(xs_pack) {
dXSARGS; dXSARGS;
if (items != 2) { if (items < 2) {
Perl_croak(aTHX_ "Usage: Data::MessagePack->pack($dat)"); Perl_croak(aTHX_ "Usage: Data::MessagePack->pack($dat [,$max_depth])");
} }
SV* val = ST(1); SV* val = ST(1);
int depth = 512;
if (items >= 3) depth = SvIV(ST(2));
enc_t enc; enc_t enc;
enc.sv = sv_2mortal(NEWSV(0, INIT_SIZE)); enc.sv = sv_2mortal(NEWSV(0, INIT_SIZE));
@@ -256,7 +262,7 @@ XS(xs_pack) {
enc.end = SvEND(enc.sv); enc.end = SvEND(enc.sv);
SvPOK_only(enc.sv); SvPOK_only(enc.sv);
_msgpack_pack_sv(&enc, val); _msgpack_pack_sv(&enc, val, depth);
SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv)); SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv));
*SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */ *SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */

25
perl/t/08_cycle.t Normal file
View File

@@ -0,0 +1,25 @@
use t::Util;
use Test::More;
use Data::MessagePack;
plan tests => 5;
my $aref = [0];
$aref->[1] = $aref;
eval { Data::MessagePack->pack($aref) };
ok $@, $@;
my $href = {};
$href->{cycle} = $href;
eval { Data::MessagePack->pack($aref) };
ok $@, $@;
$aref = [0,[1,2]];
eval { Data::MessagePack->pack($aref) };
ok !$@;
eval { Data::MessagePack->pack($aref, 3) };
ok !$@;
eval { Data::MessagePack->pack($aref, 2) };
ok $@, $@;