Compare commits

...

54 Commits

Author SHA1 Message Date
frsyuki
421bee3871 cpp: version 0.5.3 2010-08-27 17:53:19 +09:00
frsyuki
2c7573a032 cpp: updates msgpack_vc8.postbuild.bat 2010-08-27 17:53:02 +09:00
frsyuki
fe2a0f5089 cpp: adds fixed length serialization for integers 2010-08-27 17:42:05 +09:00
frsyuki
59ba8dec4e cpp: fixes include paths 2010-08-27 16:45:48 +09:00
frsyuki
c8e351b31e java: adds TestMessageUnpackable test 2010-08-21 03:36:44 +09:00
frsyuki
b4c98584db java: adds Unpacker.unpackBigInteger() 2010-08-19 01:19:34 +09:00
frsyuki
1d17836b7d java: NilType::create() returns NilType's one and only instance 2010-08-19 00:54:23 +09:00
frsyuki
193a739749 java: updates TestDirectConversion 2010-08-19 00:05:48 +09:00
frsyuki
48da2b8353 java: adds Packer.pack(<primitive types>) 2010-08-18 23:47:31 +09:00
frsyuki
40dc9de6c9 java: supports packing/unpacking of BigInteger less than 0xffffffffffffffff 2010-08-18 23:37:47 +09:00
frsyuki
d7469e4694 java: fixes cross-language test case 2010-08-18 22:55:50 +09:00
frsyuki
fdfabc9f88 java: adds cross-language test case 2010-08-18 22:51:23 +09:00
frsyuki
5658ca5b90 java: adds ObjectEquals test 2010-08-18 22:24:51 +09:00
frsyuki
8b79e6d3c7 java: uses MessagePackObject instead of Object for type of deserialized objects 2010-08-18 18:10:30 +09:00
frsyuki
8c67087a15 java: adds MessagePackObject.bigIntegerValue(), asBigInteger() and equals() 2010-08-18 16:32:42 +09:00
frsyuki
057f73a73e java: implements MessagePackObject::hashCode() 2010-08-10 14:11:44 +09:00
frsyuki
d3bb37d113 java: fixes MapSchema 2010-08-10 14:11:25 +09:00
frsyuki
6c91b862c9 java: MessagePackObject implements Cloneable and MessagePackable interfaces 2010-07-28 01:17:20 +09:00
frsyuki
cba47b635a java: changed deploy path to ./target/website/maven2 directory. 2010-07-27 09:50:57 +09:00
Kazuki Ohta
cd83388f8b java: fixed repository location. msgpack.sourceforge.net => msgpack.org 2010-07-27 08:59:09 +09:00
frsyuki
02ae247536 java: adds MessagePackObject class 2 2010-07-24 18:20:00 +09:00
frsyuki
1621a68191 Merge branch 'master' of github.com:msgpack/msgpack 2010-07-24 18:08:19 +09:00
frsyuki
2aef495d62 java: adds MessagePackObject class 2010-07-24 18:08:00 +09:00
frsyuki
227c168b65 java: fixes fatal offset calculation bugs on BufferedUnpackerIMPL.unpackInt() 2010-07-24 18:07:22 +09:00
UENISHI Kota
dcbcf5842f erlang: msgpack:unpack_all/1 doc. 2010-07-18 23:55:07 +09:00
UENISHI Kota
8a3ac6d9bd erlang: omake menus added. 2010-07-18 23:50:29 +09:00
UENISHI Kota
6cabad19d5 erlang: unpack_all/1 improve, error handling added. 2010-07-18 23:48:20 +09:00
UENISHI Kota
dad7a03d19 erlang: stopped support for dict() type. 2010-07-18 23:42:23 +09:00
UENISHI Kota
7b152640d9 erlang: 'edoc' document generation 2010-07-18 23:40:25 +09:00
UENISHI Kota
78fddff34e erlang: merged vincent's contribution 2010-07-18 23:01:43 +09:00
frsyuki
f8a016edb5 Merge branch 'master' of github.com:msgpack/msgpack 2010-07-14 17:09:34 +09:00
frsyuki
f5453d38ec cpp: version 0.5.2 2010-07-14 17:06:16 +09:00
frsyuki
331bf0af21 cpp: type::raw_ref::str(), operator==, operator!=, operator< and operator> are now const 2010-07-14 17:04:41 +09:00
tokuhirom
9ac69337e8 perl: bump up version to 0.13! 2010-07-14 09:58:41 +09:00
tokuhirom
ca0c844f32 clearly specified this distribution requires requires C99. 2010-07-14 09:58:05 +09:00
Vincent de Phily
e629e8784f erlang: Improve documentation
The doc is in edoc format, generated from the source as an html file.
The makefile's default action now also generates the documentation.

I ignored unpack_all/1 and pack(dict()) for now because their future is still uncertain.
2010-07-12 14:08:22 +02:00
Vincent de Phily
e944c1ee93 erlang: Only handle throw() in pack/1 and unpack/1
Rationale: We only use throw/1 for error handling, never erlang:error/1.
           Caller bugs will get a nice {error,...} return while library bugs will
           bubble up in all their uglyness; that's the proper way to do things
           in erlang.
2010-07-09 20:37:06 +02:00
Vincent de Phily
02c882bda3 erlang: Make pack_map/1 api private 2010-07-09 20:34:38 +02:00
Vincent de Phily
2c29377abf erlang: s/short/incomplete/ and s/badarg/{badarg,Term}/
Nicer error returns.
2010-07-09 20:30:17 +02:00
Vincent de Phily
21992f1b9e erlang: fix receiving from port_command in unit tests
Ports can send data bit by bit; make sure we read all the port has to offer in one go.
This should fix the "broken pipe" error we sometime got during testing.
We did not previously check the return of compare_all/2, which is why the bug was not noticed.
Incidentally, this change fixes dialyzer warnings too.
2010-07-09 18:53:24 +02:00
Vincent de Phily
8a3f090684 erlang: Fix some existing specs and add a few other.
dialyzer still complains about dict() and ?assert(false), but I don't think they're real issues.
2010-07-09 17:36:36 +02:00
UENISHI Kota
a4258505a9 erlang: modified wrong testcase. 2010-07-09 23:23:00 +09:00
Vincent de Phily
ba4a971bfa erlang: Remove unecessary 'throw(short)' clause for unpack_{array,map}_/1
Unecessary because unpack_/1 will throw it anyway.
This does mean that we go a tiny bit deeper to find that we don't have enough data,
but that should be a rare code path. Keep the main code path fast and the code clean.

While at it, rename vars to match its sibling function and to avoid thinking that
RestLen is a byte count (it's an item count).
2010-07-09 13:44:02 +02:00
Vincent de Phily
6abc120279 erlang: Fix incomplete/invalid cases of unpack_/1
* fix list of invalid bytes was missing 3 possibilities (see type chart section of msgpack format spec)
* fix matching of invalid bytes to look at 1 byte instead of 2
* simplify 'incomplete' case : anything that's not complete or invalid is by definition incomplete
2010-07-09 13:29:47 +02:00
Vincent de Phily
64c36b7a8f Remove a couple of superfluous 'when' clauses.
The when clause for unpack_/1 has been moved to unpack/1 so that it is performed only once.
2010-07-09 13:06:57 +02:00
Vincent de Phily
64b9f0762c Merge branch 'master' of git://github.com/msgpack/msgpack
Reseting msgpack.erl to upstream version.
2010-07-09 12:35:22 +02:00
UENISHI Kota
e799082e5c erlang: better test cases, except 'Broken pipe' 2010-07-09 01:21:35 +09:00
UENISHI Kota
eab66a022e erlang: added try-catch clause for easy error handling 2010-07-09 01:04:09 +09:00
UENISHI Kota
485915c27a erlang: added simple performance test description. 2010-07-08 23:39:47 +09:00
UENISHI Kota
45fb482ab4 erlang: added simple performance test. 2010-07-08 23:36:18 +09:00
frsyuki
167e2475d8 cpp: generate version.h using AC_OUTPUT macro in ./configure 2010-07-06 23:30:15 +09:00
frsyuki
fe77251242 cpp: fixes missing dependency to generate version.h 2010-07-06 19:16:49 +09:00
Vincent de Phily
33a7d56042 * Return {more,undefined} instead of {more,integer()}, as we can only know the "minimum bytes needed to continue" instead of the actually usefull "total packet size".
* Merge all {more,...} clauses of unpack_/1 into one.
* Reformat unpack_/1 for readability.
* Fix some specs, error values, and documentation.
2010-06-29 11:59:56 +02:00
Vincent de Phily
8f7f23a0e5 Rewrite unpack_/1 using pattern matching to get a 30-40% speedup.
Simplify pack_* and unpack_{array,map} function clauses to get more readability and a minor speedup.
2010-06-28 18:11:52 +02:00
83 changed files with 2538 additions and 2963 deletions

View File

@@ -1,4 +1,16 @@
2010-07-27 version 0.5.3:
* adds type::fix_{u,}int{8,16,32,64} types
* adds msgpack_pack_fix_{u,}int{8,16,32,64} functions
* adds packer<Stream>::pack_fix_{u,}int{8,16,32,64} functions
* fixes include paths
2010-07-14 version 0.5.2:
* type::raw::str(), operator==, operator!=, operator< and operator> are now const
* generates version.h using AC_OUTPUT macro in ./configure
2010-07-06 version 0.5.1:
* Add msgpack_vrefbuffer_new and msgpack_vrefbuffer_free

View File

@@ -1,6 +1,6 @@
AC_INIT(src/object.cpp)
AC_CONFIG_AUX_DIR(ac)
AM_INIT_AUTOMAKE(msgpack, 0.5.1)
AM_INIT_AUTOMAKE(msgpack, 0.5.3)
AC_CONFIG_HEADER(config.h)
AC_SUBST(CFLAGS)
@@ -68,5 +68,8 @@ AC_SUBST(VERSION_MAJOR, $major)
AC_SUBST(VERSION_MINOR, $minor)
AC_OUTPUT([Makefile src/Makefile test/Makefile])
AC_OUTPUT([Makefile
src/Makefile
src/msgpack/version.h
test/Makefile])

View File

@@ -26,10 +26,11 @@ copy src\msgpack\object.hpp include\msgpack\
copy src\msgpack\zone.hpp include\msgpack\
copy src\msgpack\type.hpp include\msgpack\type\
copy src\msgpack\type\bool.hpp include\msgpack\type\
copy src\msgpack\type\deque.hpp include\msgpack\type\
copy src\msgpack\type\fixint.hpp include\msgpack\type\
copy src\msgpack\type\float.hpp include\msgpack\type\
copy src\msgpack\type\int.hpp include\msgpack\type\
copy src\msgpack\type\list.hpp include\msgpack\type\
copy src\msgpack\type\deque.hpp include\msgpack\type\
copy src\msgpack\type\map.hpp include\msgpack\type\
copy src\msgpack\type\nil.hpp include\msgpack\type\
copy src\msgpack\type\pair.hpp include\msgpack\type\

View File

@@ -58,10 +58,11 @@ nobase_include_HEADERS += \
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/deque.hpp \
msgpack/type/map.hpp \
msgpack/type/nil.hpp \
msgpack/type/pair.hpp \
@@ -82,13 +83,6 @@ EXTRA_DIST = \
msgpack/type/tuple.hpp.erb
msgpack/version.h: msgpack/version.h.in Makefile.in
sed -e s/VERSION_UNDEFINED/$(VERSION)/ \
-e s/VERSION_MAJOR_UNDEFINED/$(VERSION_MAJOR)/ \
-e s/VERSION_MINOR_UNDEFINED/$(VERSION_MINOR)/ \
$< > $@
doxygen_c:
cat ../Doxyfile > Doxyfile_c
echo "FILE_PATTERNS = *.h" >> Doxyfile_c

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_OBJECT_H__
#define MSGPACK_OBJECT_H__
#include "msgpack/zone.h"
#include "zone.h"
#include <stdio.h>
#ifdef __cplusplus

View File

@@ -18,9 +18,9 @@
#ifndef MSGPACK_OBJECT_HPP__
#define MSGPACK_OBJECT_HPP__
#include "msgpack/object.h"
#include "msgpack/pack.hpp"
#include "msgpack/zone.hpp"
#include "object.h"
#include "pack.hpp"
#include "zone.hpp"
#include <string.h>
#include <stdexcept>
#include <typeinfo>

View File

@@ -18,8 +18,8 @@
#ifndef MSGPACK_PACK_H__
#define MSGPACK_PACK_H__
#include "msgpack/pack_define.h"
#include "msgpack/object.h"
#include "pack_define.h"
#include "object.h"
#include <stdlib.h>
#ifdef __cplusplus
@@ -70,6 +70,15 @@ static int msgpack_pack_int16(msgpack_packer* pk, int16_t d);
static int msgpack_pack_int32(msgpack_packer* pk, int32_t d);
static int msgpack_pack_int64(msgpack_packer* pk, int64_t d);
static int msgpack_pack_fix_uint8(msgpack_packer* pk, uint8_t d);
static int msgpack_pack_fix_uint16(msgpack_packer* pk, uint16_t d);
static int msgpack_pack_fix_uint32(msgpack_packer* pk, uint32_t d);
static int msgpack_pack_fix_uint64(msgpack_packer* pk, uint64_t d);
static int msgpack_pack_fix_int8(msgpack_packer* pk, int8_t d);
static int msgpack_pack_fix_int16(msgpack_packer* pk, int16_t d);
static int msgpack_pack_fix_int32(msgpack_packer* pk, int32_t d);
static int msgpack_pack_fix_int64(msgpack_packer* pk, int64_t d);
static int msgpack_pack_float(msgpack_packer* pk, float d);
static int msgpack_pack_double(msgpack_packer* pk, double d);
@@ -96,12 +105,18 @@ int msgpack_pack_object(msgpack_packer* pk, msgpack_object d);
#define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_cint(name) \
inline int msgpack_pack ## name
#define msgpack_pack_inline_func_fixint(name) \
inline int msgpack_pack_fix ## name
#define msgpack_pack_user msgpack_packer*
#define msgpack_pack_append_buffer(user, buf, len) \
return (*(user)->callback)((user)->data, (const char*)buf, len)
#include "msgpack/pack_template.h"
#include "pack_template.h"
inline void msgpack_packer_init(msgpack_packer* pk, void* data, msgpack_packer_write callback)
{

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_PACK_HPP__
#define MSGPACK_PACK_HPP__
#include "msgpack/pack_define.h"
#include "pack_define.h"
#include <stdexcept>
#include <limits.h>
@@ -45,6 +45,15 @@ public:
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);
@@ -78,6 +87,15 @@ private:
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);
@@ -133,11 +151,15 @@ inline void pack(Stream& s, const T& v)
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 "msgpack/pack_template.h"
#include "pack_template.h"
template <typename Stream>
@@ -149,6 +171,7 @@ 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; }
@@ -182,6 +205,39 @@ 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; }

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_SBUFFER_HPP__
#define MSGPACK_SBUFFER_HPP__
#include "msgpack/sbuffer.h"
#include "sbuffer.h"
#include <stdexcept>
namespace msgpack {

View File

@@ -1,15 +1,16 @@
#include "msgpack/type/bool.hpp"
#include "msgpack/type/float.hpp"
#include "msgpack/type/int.hpp"
#include "msgpack/type/list.hpp"
#include "msgpack/type/deque.hpp"
#include "msgpack/type/map.hpp"
#include "msgpack/type/nil.hpp"
#include "msgpack/type/pair.hpp"
#include "msgpack/type/raw.hpp"
#include "msgpack/type/set.hpp"
#include "msgpack/type/string.hpp"
#include "msgpack/type/vector.hpp"
#include "msgpack/type/tuple.hpp"
#include "msgpack/type/define.hpp"
#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"

View File

@@ -0,0 +1,89 @@
//
// 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"
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:
const 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
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; }
} // namespace msgpack
#endif /* msgpack/type/fixint.hpp */

View File

@@ -33,25 +33,25 @@ struct raw_ref {
uint32_t size;
const char* ptr;
std::string str() { return std::string(ptr, size); }
std::string str() const { return std::string(ptr, size); }
bool operator== (const raw_ref& x)
bool operator== (const raw_ref& x) const
{
return size == x.size && memcmp(ptr, x.ptr, size) == 0;
}
bool operator!= (const raw_ref& x)
bool operator!= (const raw_ref& x) const
{
return !(*this != x);
}
bool operator< (const raw_ref& 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)
bool operator> (const raw_ref& x) const
{
if(size == x.size) { return memcmp(ptr, x.ptr, size) > 0; }
else { return size > x.size; }

View File

@@ -18,8 +18,8 @@
#ifndef MSGPACK_UNPACKER_H__
#define MSGPACK_UNPACKER_H__
#include "msgpack/zone.h"
#include "msgpack/object.h"
#include "zone.h"
#include "object.h"
#include <string.h>
#ifdef __cplusplus

View File

@@ -18,9 +18,9 @@
#ifndef MSGPACK_UNPACK_HPP__
#define MSGPACK_UNPACK_HPP__
#include "msgpack/unpack.h"
#include "msgpack/object.hpp"
#include "msgpack/zone.hpp"
#include "unpack.h"
#include "object.hpp"
#include "zone.hpp"
#include <memory>
#include <stdexcept>

View File

@@ -27,9 +27,9 @@ const char* msgpack_version(void);
int msgpack_version_major(void);
int msgpack_version_minor(void);
#define MSGPACK_VERSION "VERSION_UNDEFINED"
#define MSGPACK_VERSION_MAJOR VERSION_MAJOR_UNDEFINED
#define MSGPACK_VERSION_MINOR VERSION_MINOR_UNDEFINED
#define MSGPACK_VERSION "@VERSION@"
#define MSGPACK_VERSION_MAJOR @VERSION_MAJOR@
#define MSGPACK_VERSION_MINOR @VERSION_MINOR@
#ifdef __cplusplus

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_VREFBUFFER_H__
#define MSGPACK_VREFBUFFER_H__
#include "msgpack/zone.h"
#include "zone.h"
#include <stdlib.h>
#ifndef _WIN32

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_VREFBUFFER_HPP__
#define MSGPACK_VREFBUFFER_HPP__
#include "msgpack/vrefbuffer.h"
#include "vrefbuffer.h"
#include <stdexcept>
namespace msgpack {

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_ZBUFFER_H__
#define MSGPACK_ZBUFFER_H__
#include "msgpack/sysdep.h"
#include "sysdep.h"
#include <stdlib.h>
#include <string.h>
#include <zlib.h>

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_ZBUFFER_HPP__
#define MSGPACK_ZBUFFER_HPP__
#include "msgpack/zbuffer.h"
#include "zbuffer.h"
#include <stdexcept>
namespace msgpack {

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_ZONE_H__
#define MSGPACK_ZONE_H__
#include "msgpack/sysdep.h"
#include "sysdep.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -18,7 +18,7 @@
#ifndef MSGPACK_ZONE_HPP__
#define MSGPACK_ZONE_HPP__
#include "msgpack/zone.h"
#include "zone.h"
#include <cstdlib>
#include <memory>
#include <vector>

View File

@@ -13,6 +13,8 @@ check_PROGRAMS = \
convert \
buffer \
cases \
fixint \
fixint_c \
version \
msgpackc_test \
msgpack_test
@@ -38,6 +40,10 @@ 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

View File

@@ -32,5 +32,7 @@ TEST(cases, format)
EXPECT_TRUE( pac_compact.next(&result_compact) );
EXPECT_EQ(result_compact.get(), result.get());
}
EXPECT_FALSE( pac_compact.next(&result) );
}

24
cpp/test/fixint.cc Normal file
View File

@@ -0,0 +1,24 @@
#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);
}

32
cpp/test/fixint_c.cc Normal file
View File

@@ -0,0 +1,32 @@
#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
erlang/.gitignore vendored
View File

@@ -2,3 +2,4 @@ MANIFEST
*.beam
.omakedb*
*.omc
*~

View File

@@ -22,7 +22,7 @@
# Phony targets are scoped, so you probably want to declare them first.
#
.PHONY: all clean test #install
.PHONY: all clean test edoc dialyzer #install
########################################################################
# Subdirectories.
@@ -33,10 +33,19 @@
.DEFAULT: msgpack.beam
msgpack.beam: msgpack.erl
erlc $<
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 *.beam
-rm -f *.beam *.html

4
erlang/edoc/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.html
*.css
*.png
edoc-info

View File

@@ -15,89 +15,121 @@
%% 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').
%% tuples, atoms are not supported. lists, integers, double, and so on.
%% see http://msgpack.sourceforge.jp/spec for
%% supported formats. APIs are almost compatible
%% for C API (http://msgpack.sourceforge.jp/c:doc)
%% except buffering functions (both copying and zero-copying).
-export([pack/1, unpack/1, unpack_all/1]).
-export([pack_map/1]).
% compile:
% erl> c(msgpack).
% erl> S = <some term>.
% erl> {S, <<>>} = msgpack:unpack( msgpack:pack(S) ).
-type reason() :: enomem | badarg | no_code_matches.
% @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 ===== %
-spec pack(Term::msgpack_term()) -> binary().
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(Map) when is_tuple(Map), element(1,Map)=:=dict ->
pack_map(dict:to_list(Map));
pack(_Other) ->
{error, undefined}.
% unpacking.
% if failed in decoding and not end, get more data
% and feed more Bin into this function.
% TODO: error case for imcomplete format when short for any type formats.
-spec unpack( Bin::binary() )-> {msgpack_term(), binary()} |
{more, non_neg_integer()} | {more, undefined} |
{error, reason()}.
unpack(Bin) when not is_binary(Bin)->
{error, badarg};
unpack(Bin) when bit_size(Bin) >= 8 ->
unpack_(Bin);
unpack(<<>>)->
{more, 1};
unpack(_) ->
{more, undefined}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% external APIs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec unpack_all( binary() ) -> [msgpack_term()].
% @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)->
case unpack(Data) of
{ Term, Binary } when bit_size(Binary) =:= 0 ->
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)]
[Term|unpack_all_(Binary)]
end.
-spec pack_map(M::[{msgpack_term(),msgpack_term()}])-> binary().
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.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% internal APIs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ===== 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({error, {badarg, Other}}).
-spec pack_uint_(non_neg_integer()) -> binary().
% positive fixnum
pack_uint_(N) when N < 128 ->
<< 2#0:1, N:7 >>;
@@ -114,8 +146,9 @@ pack_uint_(N) when N < 16#FFFFFFFF->
pack_uint_(N) ->
<< 16#CF:8, N:64/big-unsigned-integer-unit:1 >>.
-spec pack_int_(integer()) -> binary().
% negative fixnum
pack_int_(N) when is_integer(N) , N >= -32->
pack_int_(N) when N >= -32->
<< 2#111:3, N:5 >>;
% int 8
pack_int_(N) when N > -128 ->
@@ -130,6 +163,8 @@ pack_int_(N) when N > -16#FFFFFFFF ->
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 >>.
@@ -138,6 +173,8 @@ pack_int_(N) ->
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
@@ -149,7 +186,9 @@ pack_raw(Bin) ->
<< 16#DB:8, Len:32/big-unsigned-integer-unit:1, Bin/binary >>
end.
% list / tuple
-spec pack_array([msgpack_term()]) -> binary() | no_return().
% list
pack_array(L) ->
case length(L) of
Len when Len < 16 ->
@@ -159,43 +198,47 @@ pack_array(L) ->
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>>).
pack_array_(Tail, <<Acc/binary, (pack_(Head))/binary>>).
% FIXME! this should be without lists:reverse/1
unpack_array_(<<>>, 0, RetList) -> {lists:reverse(RetList), <<>>};
unpack_array_(Remain, 0, RetList) when is_binary(Remain)-> {lists:reverse(RetList), Remain};
unpack_array_(<<>>, RestLen, _RetList) when RestLen > 0 -> {more, undefined};
unpack_array_(Bin, RestLen, RetList) when is_binary(Bin)->
case unpack(Bin) of
{more, _} -> {more, undefined};
{Term, Rest}-> unpack_array_(Rest, RestLen-1, [Term|RetList])
% 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>>).
pack_map_(Tail, << Acc/binary, (pack_(Key))/binary, (pack_(Value))/binary>>).
% FIXME! this should be without lists:reverse/1
-spec unpack_map_(binary(), non_neg_integer(), [{term(), msgpack_term()}])->
{more, non_neg_integer()} | { any(), 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) ->
case unpack(Bin) of
{more, _} -> {more, undefined};
{Key, Rest} ->
case unpack(Rest) of
{more, _} -> {more, undefined};
{Value, Rest2} ->
unpack_map_(Rest2,Len-1,[{Key,Value}|Acc])
end
end.
{Key, Rest} = unpack_(Bin),
{Value, Rest2} = unpack_(Rest),
unpack_map_(Rest2, Len-1, [{Key,Value}|Acc]).
-spec unpack_(Payload::binary()) ->
{more, pos_integer()} | {msgpack_term(), binary()} | {error, reason()}.
unpack_(Binary)->
case Binary of
% 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};
@@ -230,37 +273,20 @@ unpack_(Binary)->
<<2#1001:4, L:4, Rest/binary>> -> unpack_array_(Rest, L, []); % array
<<2#1000:4, L:4, Rest/binary>> -> unpack_map_(Rest, L, []); % map
% Incomplete / invalid data
<<16#CA, Rest/binary>> -> {more, 4-byte_size(Rest)};
<<16#CB, Rest/binary>> -> {more, 8-byte_size(Rest)};
<<16#CC>> -> {more, 1};
<<16#CD, Rest/binary>> -> {more, 2-byte_size(Rest)};
<<16#CE, Rest/binary>> -> {more, 4-byte_size(Rest)};
<<16#CF, Rest/binary>> -> {more, 8-byte_size(Rest)};
<<16#D0>> -> {more, 1};
<<16#D1, Rest/binary>> -> {more, 2-byte_size(Rest)};
<<16#D2, Rest/binary>> -> {more, 4-byte_size(Rest)};
<<16#D3, Rest/binary>> -> {more, 8-byte_size(Rest)};
<<16#DA, Rest/binary>> -> {more, 16-byte_size(Rest)};
<<16#DB, Rest/binary>> -> {more, 32-byte_size(Rest)};
<<16#DC, Rest/binary>> -> {more, 2-byte_size(Rest)};
<<16#DD, Rest/binary>> -> {more, 4-byte_size(Rest)};
<<16#DE, Rest/binary>> -> {more, 2-byte_size(Rest)};
<<16#DF, Rest/binary>> -> {more, 4-byte_size(Rest)};
<<2#101:3, L:5, Rest/binary>> -> {more, L-byte_size(Rest)};
<<>> -> {more, 1};
<<2#101:3, _/binary>> -> {more, undefined};
<<F:8, Rest/binary>> when F==16#C1;
F==16#C7; F==16#C8; F==16#C9; F==16#D5;
F==16#D6; F==16#D7; F==16#D8; F==16#D9->
{error, {badarg, <<F, Rest/binary>>}};
Other ->
{error, {badarg, Other}}
% 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.
% ===== test codes ===== %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% unit tests
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-include_lib("eunit/include/eunit.hrl").
-ifdef(EUNIT).
@@ -268,9 +294,24 @@ compare_all([], [])-> ok;
compare_all([], R)-> {toomuchrhs, R};
compare_all(L, [])-> {toomuchlhs, L};
compare_all([LH|LTL], [RH|RTL]) ->
LH=RH,
?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,
@@ -291,24 +332,18 @@ basic_test()->
port_test()->
Tests = test_data(),
{[Tests],<<>>} = msgpack:unpack(msgpack:pack([Tests])),
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary]),
?assertEqual({[Tests],<<>>}, msgpack:unpack(msgpack:pack([Tests]))),
Port = open_port({spawn, "ruby ../test/crosslang.rb"}, [binary, eof]),
true = port_command(Port, msgpack:pack(Tests)),
receive
{Port, {data, Data}}-> {Tests, <<>>}=msgpack:unpack(Data)
after 1024-> ?assert(false) end,
?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,
case msgpack:unpack(Bin) of
{more, N} when not is_integer(N) ->
?assertEqual(undefined, N);
{more, N} ->
?assert( N < Len )
end.
?assertEqual({error,incomplete}, msgpack:unpack(Bin)).
partial_test()-> % error handling test.
Term = lists:seq(0, 45),
@@ -318,10 +353,7 @@ partial_test()-> % error handling test.
long_test()->
Longer = lists:seq(0, 655),
% Longest = lists:seq(0,12345),
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)),
% {Longest, <<>>} = msgpack:unpack(msgpack:pack(Longest)).
ok.
{Longer, <<>>} = msgpack:unpack(msgpack:pack(Longer)).
map_test()->
Ints = lists:seq(0, 65),
@@ -331,6 +363,7 @@ map_test()->
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">>,
@@ -338,25 +371,20 @@ unknown_test()->
-234.4355, 1.0e-34, 1.0e64,
[23, 234, 0.23],
[0,42,<<"sum">>, [1,2]], [1,42, nil, [3]],
{[{1,2},{<<"hoge">>,nil}]},
{[{1,2},{<<"hoge">>,nil}]}, % map
-234, -50000,
42
],
Port = open_port({spawn, "ruby testcase_generator.rb"}, [binary]),
receive
{Port, {data, Data}}->
compare_all(Tests, msgpack:unpack_all(Data))
after 1024-> ?assert(false) end,
?assertEqual(ok, compare_all(Tests, msgpack:unpack_all(port_receive(Port)))),
port_close(Port).
test_([]) -> 0;
test_([Before|Rest])->
Pack = msgpack:pack(Before),
{After, <<>>} = msgpack:unpack( Pack ),
?assertEqual(Before, After),
1+test_(Rest).
other_test()->
{more,1}=msgpack:unpack(<<>>).
?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]).
-endif.

View File

@@ -7,7 +7,7 @@
<description>MessagePack for Java</description>
<name>MessagePack for Java</name>
<url>http://msgpack.sourceforge.net/</url>
<url>http://msgpack.org/</url>
<licenses>
<license>
@@ -97,29 +97,24 @@
<repositories>
<repository>
<id>msgpack.sourceforge.net</id>
<id>msgpack.org</id>
<name>MessagePack Maven2 Repository</name>
<url>http://msgpack.sourceforge.net/maven2</url>
</repository>
<repository>
<id>msgpack.sourceforge.net</id>
<name>MessagePack Maven2 Snapshot Repository</name>
<url>http://msgpack.sourceforge.net/maven2-snapshot</url>
<url>http://msgpack.org/maven2</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<uniqueVersion>false</uniqueVersion>
<id>shell.sourceforge.net</id>
<name>Repository at sourceforge.net</name>
<url>scp://shell.sourceforge.net/home/groups/m/ms/msgpack/htdocs/maven2/</url>
<id>msgpack.org</id>
<name>Repository at msgpack.org</name>
<url>file://${project.build.directory}/website/maven2/</url>
</repository>
<snapshotRepository>
<uniqueVersion>true</uniqueVersion>
<id>shell.sourceforge.net</id>
<name>Repository Name</name>
<url>scp://shell.sourceforge.net/home/groups/m/ms/msgpack/htdocs/maven2-snapshot/</url>
<id>msgpack.org</id>
<name>Repository at msgpack.org</name>
<url>file://${project.build.directory}/website/maven2/</url>
</snapshotRepository>
</distributionManagement>

View File

@@ -19,7 +19,7 @@ package org.msgpack;
import java.io.IOException;
import java.nio.ByteBuffer;
//import java.math.BigInteger;
import java.math.BigInteger;
abstract class BufferedUnpackerImpl extends UnpackerImpl {
int offset = 0;
@@ -47,7 +47,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
offset = noffset;
} while(!super.isFinished());
Object obj = super.getData();
MessagePackObject obj = super.getData();
super.reset();
result.done(obj);
@@ -103,7 +103,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
case 0xcc: // unsigned int 8
more(2);
advance(2);
return (int)((short)buffer[offset+1] & 0xff);
return (int)((short)(buffer[offset-1]) & 0xff);
case 0xcd: // unsigned int 16
more(3);
castBuffer.rewind();
@@ -137,7 +137,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
case 0xd0: // signed int 8
more(2);
advance(2);
return (int)buffer[offset+1];
return (int)buffer[offset-1];
case 0xd1: // signed int 16
more(3);
castBuffer.rewind();
@@ -178,7 +178,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
case 0xcc: // unsigned int 8
more(2);
advance(2);
return (long)((short)buffer[offset+1] & 0xff);
return (long)((short)(buffer[offset-1]) & 0xff);
case 0xcd: // unsigned int 16
more(3);
castBuffer.rewind();
@@ -198,8 +198,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
{
long o = castBuffer.getLong(0);
if(o < 0) {
// FIXME
throw new MessageTypeException("uint 64 bigger than 0x7fffffff is not supported");
throw new MessageTypeException();
}
advance(9);
return o;
@@ -207,7 +206,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
case 0xd0: // signed int 8
more(2);
advance(2);
return (long)buffer[offset+1];
return (long)buffer[offset-1];
case 0xd1: // signed int 16
more(3);
castBuffer.rewind();
@@ -231,6 +230,26 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
}
}
final BigInteger unpackBigInteger() throws IOException, MessageTypeException {
more(1);
int b = buffer[offset];
if((b & 0xff) != 0xcf) {
return BigInteger.valueOf(unpackLong());
}
// unsigned int 64
more(9);
castBuffer.rewind();
castBuffer.put(buffer, offset+1, 8);
advance(9);
long o = castBuffer.getLong(0);
if(o < 0) {
return new BigInteger(1, castBuffer.array());
} else {
return BigInteger.valueOf(o);
}
}
final float unpackFloat() throws IOException, MessageTypeException {
more(1);
int b = buffer[offset];
@@ -414,7 +433,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
return s;
}
final Object unpackObject() throws IOException {
final MessagePackObject unpackObject() throws IOException {
UnpackResult result = new UnpackResult();
if(!next(result)) {
super.reset();

View File

@@ -18,6 +18,6 @@
package org.msgpack;
public interface MessageConvertable {
public void messageConvert(Object obj) throws MessageTypeException;
public void messageConvert(MessagePackObject obj) throws MessageTypeException;
}

View File

@@ -0,0 +1,136 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.math.BigInteger;
public abstract class MessagePackObject implements Cloneable, MessagePackable {
public boolean isNil() {
return false;
}
public boolean isBooleanType() {
return false;
}
public boolean isIntegerType() {
return false;
}
public boolean isFloatType() {
return false;
}
public boolean isArrayType() {
return false;
}
public boolean isMapType() {
return false;
}
public boolean isRawType() {
return false;
}
public boolean asBoolean() {
throw new MessageTypeException("type error");
}
public byte asByte() {
throw new MessageTypeException("type error");
}
public short asShort() {
throw new MessageTypeException("type error");
}
public int asInt() {
throw new MessageTypeException("type error");
}
public long asLong() {
throw new MessageTypeException("type error");
}
public BigInteger asBigInteger() {
throw new MessageTypeException("type error");
}
public float asFloat() {
throw new MessageTypeException("type error");
}
public double asDouble() {
throw new MessageTypeException("type error");
}
public byte[] asByteArray() {
throw new MessageTypeException("type error");
}
public String asString() {
throw new MessageTypeException("type error");
}
public MessagePackObject[] asArray() {
throw new MessageTypeException("type error");
}
public List<MessagePackObject> asList() {
throw new MessageTypeException("type error");
}
public Map<MessagePackObject, MessagePackObject> asMap() {
throw new MessageTypeException("type error");
}
public byte byteValue() {
throw new MessageTypeException("type error");
}
public short shortValue() {
throw new MessageTypeException("type error");
}
public int intValue() {
throw new MessageTypeException("type error");
}
public long longValue() {
throw new MessageTypeException("type error");
}
public BigInteger bigIntegerValue() {
throw new MessageTypeException("type error");
}
public float floatValue() {
throw new MessageTypeException("type error");
}
public double doubleValue() {
throw new MessageTypeException("type error");
}
abstract public Object clone();
}

View File

@@ -23,15 +23,5 @@ public class MessageTypeException extends RuntimeException {
public MessageTypeException(String s) {
super(s);
}
public static MessageTypeException invalidConvert(Object from, Schema to) {
return new MessageTypeException(from.getClass().getName()+" cannot be convert to "+to.getExpression());
}
/* FIXME
public static MessageTypeException schemaMismatch(Schema to) {
return new MessageTypeException("schema mismatch "+to.getExpression());
}
*/
}

View File

@@ -22,6 +22,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.math.BigInteger;
/**
* Packer enables you to serialize objects into OutputStream.
@@ -194,6 +195,27 @@ public class Packer {
return this;
}
public Packer packBigInteger(BigInteger d) throws IOException {
if(d.bitLength() <= 63) {
return packLong(d.longValue());
} else if(d.bitLength() <= 64 && d.signum() >= 0) {
castBytes[0] = (byte)0xcf;
byte[] barray = d.toByteArray();
castBytes[1] = barray[barray.length-8];
castBytes[2] = barray[barray.length-7];
castBytes[3] = barray[barray.length-6];
castBytes[4] = barray[barray.length-5];
castBytes[5] = barray[barray.length-4];
castBytes[6] = barray[barray.length-3];
castBytes[7] = barray[barray.length-2];
castBytes[8] = barray[barray.length-1];
out.write(castBytes);
return this;
} else {
throw new MessageTypeException("can't pack BigInteger larger than 0xffffffffffffffff");
}
}
public Packer packFloat(float d) throws IOException {
castBytes[0] = (byte)0xca;
castBuffer.putFloat(1, d);
@@ -286,12 +308,6 @@ public class Packer {
}
public Packer packWithSchema(Object o, Schema s) throws IOException {
s.pack(this, o);
return this;
}
public Packer packString(String s) throws IOException {
byte[] b = ((String)s).getBytes("UTF-8");
packRaw(b.length);
@@ -299,39 +315,36 @@ public class Packer {
}
public Packer pack(String o) throws IOException {
if(o == null) { return packNil(); }
return packString(o);
public Packer pack(boolean o) throws IOException {
if(o) {
return packTrue();
} else {
return packFalse();
}
}
public Packer pack(MessagePackable o) throws IOException {
if(o == null) { return packNil(); }
o.messagePack(this);
return this;
public Packer pack(byte o) throws IOException {
return packByte(o);
}
public Packer pack(byte[] o) throws IOException {
if(o == null) { return packNil(); }
packRaw(o.length);
return packRawBody(o);
public Packer pack(short o) throws IOException {
return packShort(o);
}
public Packer pack(List o) throws IOException {
if(o == null) { return packNil(); }
packArray(o.size());
for(Object i : o) { pack(i); }
return this;
public Packer pack(int o) throws IOException {
return packInt(o);
}
@SuppressWarnings("unchecked")
public Packer pack(Map o) throws IOException {
if(o == null) { return packNil(); }
packMap(o.size());
for(Map.Entry e : ((Map<Object,Object>)o).entrySet()) {
pack(e.getKey());
pack(e.getValue());
public Packer pack(long o) throws IOException {
return packLong(o);
}
return this;
public Packer pack(float o) throws IOException {
return packFloat(o);
}
public Packer pack(double o) throws IOException {
return packDouble(o);
}
public Packer pack(Boolean o) throws IOException {
@@ -363,6 +376,11 @@ public class Packer {
return packLong(o);
}
public Packer pack(BigInteger o) throws IOException {
if(o == null) { return packNil(); }
return packBigInteger(o);
}
public Packer pack(Float o) throws IOException {
if(o == null) { return packNil(); }
return packFloat(o);
@@ -373,8 +391,41 @@ public class Packer {
return packDouble(o);
}
public Packer pack(String o) throws IOException {
if(o == null) { return packNil(); }
return packString(o);
}
public Packer pack(MessagePackable o) throws IOException {
if(o == null) { return packNil(); }
o.messagePack(this);
return this;
}
public Packer pack(byte[] o) throws IOException {
if(o == null) { return packNil(); }
packRaw(o.length);
return packRawBody(o);
}
public Packer pack(List o) throws IOException {
if(o == null) { return packNil(); }
packArray(o.size());
for(Object i : o) { pack(i); }
return this;
}
public Packer pack(Map o) throws IOException {
if(o == null) { return packNil(); }
packMap(o.size());
for(Map.Entry<Object,Object> e : ((Map<Object,Object>)o).entrySet()) {
pack(e.getKey());
pack(e.getValue());
}
return this;
}
@SuppressWarnings("unchecked")
public Packer pack(Object o) throws IOException {
if(o == null) {
return packNil();
@@ -397,7 +448,7 @@ public class Packer {
} else if(o instanceof Map) {
Map<Object,Object> m = (Map<Object,Object>)o;
packMap(m.size());
for(Map.Entry e : m.entrySet()) {
for(Map.Entry<Object,Object> e : m.entrySet()) {
pack(e.getKey());
pack(e.getValue());
}
@@ -420,6 +471,8 @@ public class Packer {
return packFloat((Float)o);
} else if(o instanceof Double) {
return packDouble((Double)o);
} else if(o instanceof BigInteger) {
return packBigInteger((BigInteger)o);
} else {
throw new MessageTypeException("unknown object "+o+" ("+o.getClass()+")");
}

View File

@@ -1,78 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack;
import java.io.Writer;
import java.io.IOException;
import org.msgpack.schema.SSchemaParser;
//import org.msgpack.schema.ClassGenerator;
public abstract class Schema {
public Schema() { }
public abstract String getClassName();
public abstract String getExpression();
public static Schema parse(String source) {
return SSchemaParser.parse(source);
}
public static Schema load(String source) {
return SSchemaParser.load(source);
}
public abstract void pack(Packer pk, Object obj) throws IOException;
public abstract Object convert(Object obj) throws MessageTypeException;
public Object createFromNil() {
return null;
}
public Object createFromBoolean(boolean v) {
throw new MessageTypeException("type error");
}
public Object createFromByte(byte v) {
throw new MessageTypeException("type error");
}
public Object createFromShort(short v) {
throw new MessageTypeException("type error");
}
public Object createFromInt(int v) {
throw new MessageTypeException("type error");
}
public Object createFromLong(long v) {
throw new MessageTypeException("type error");
}
public Object createFromFloat(float v) {
throw new MessageTypeException("type error");
}
public Object createFromDouble(double v) {
throw new MessageTypeException("type error");
}
public Object createFromRaw(byte[] b, int offset, int length) {
throw new MessageTypeException("type error");
}
}

View File

@@ -21,7 +21,7 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class UnpackIterator extends UnpackResult implements Iterator<Object> {
public class UnpackIterator extends UnpackResult implements Iterator<MessagePackObject> {
private Unpacker pac;
UnpackIterator(Unpacker pac) {
@@ -38,7 +38,7 @@ public class UnpackIterator extends UnpackResult implements Iterator<Object> {
}
}
public Object next() {
public MessagePackObject next() {
if(!finished && !hasNext()) {
throw new NoSuchElementException();
}

View File

@@ -19,13 +19,13 @@ package org.msgpack;
public class UnpackResult {
protected boolean finished = false;
protected Object data = null;
protected MessagePackObject data = null;
public boolean isFinished() {
return finished;
}
public Object getData() {
public MessagePackObject getData() {
return data;
}
@@ -34,7 +34,7 @@ public class UnpackResult {
data = null;
}
void done(Object obj) {
void done(MessagePackObject obj) {
finished = true;
data = obj;
}

View File

@@ -22,12 +22,13 @@ import java.io.InputStream;
import java.io.IOException;
import java.util.Iterator;
import java.nio.ByteBuffer;
import java.math.BigInteger;
/**
* Unpacker enables you to deserialize objects from stream.
*
* Unpacker provides Buffered API, Unbuffered API, Schema API
* and Direct Conversion API.
* Unpacker provides Buffered API, Unbuffered API and
* Direct Conversion API.
*
* Buffered API uses the internal buffer of the Unpacker.
* Following code uses Buffered API with an InputStream:
@@ -39,7 +40,7 @@ import java.nio.ByteBuffer;
* UnpackResult result = pac.next();
*
* // use an iterator.
* for(Object obj : pac) {
* for(MessagePackObject obj : pac) {
* // use MessageConvertable interface to convert the
* // the generic object to the specific type.
* }
@@ -56,7 +57,7 @@ import java.nio.ByteBuffer;
* pac.feed(input_bytes);
*
* // use next() method or iterators.
* for(Object obj : pac) {
* for(MessagePackObject obj : pac) {
* // ...
* }
* </pre>
@@ -75,7 +76,7 @@ import java.nio.ByteBuffer;
* System.in.read(pac.getBuffer(), pac.getBufferOffset(), pac.getBufferCapacity());
*
* // use next() method or iterators.
* for(Object obj : pac) {
* for(MessagePackObject obj : pac) {
* // ...
* }
* </pre>
@@ -96,12 +97,12 @@ import java.nio.ByteBuffer;
*
* // take out object if deserialized object is ready.
* if(pac.isFinished()) {
* Object obj = pac.getData();
* MessagePackObject obj = pac.getData();
* // ...
* }
* </pre>
*/
public class Unpacker implements Iterable<Object> {
public class Unpacker implements Iterable<MessagePackObject> {
// buffer:
// +---------------------------------------------+
@@ -170,16 +171,6 @@ public class Unpacker implements Iterable<Object> {
this.stream = stream;
}
/**
* Sets schema to convert deserialized object into specific type.
* Default schema is {@link GenericSchema} that leaves objects for generic type. Use {@link MessageConvertable#messageConvert(Object)} method to convert the generic object.
* @param s schem to use
*/
public Unpacker useSchema(Schema s) {
impl.setSchema(s);
return this;
}
/**
* Gets the input stream.
@@ -255,7 +246,7 @@ public class Unpacker implements Iterable<Object> {
/**
* Returns the iterator that calls {@link next()} method repeatedly.
*/
public Iterator<Object> iterator() {
public Iterator<MessagePackObject> iterator() {
return new UnpackIterator(this);
}
@@ -387,7 +378,7 @@ public class Unpacker implements Iterable<Object> {
/**
* Gets the object deserialized by {@link execute(byte[])} method.
*/
public Object getData() {
public MessagePackObject getData() {
return impl.getData();
}
@@ -462,6 +453,15 @@ public class Unpacker implements Iterable<Object> {
return impl.unpackLong();
}
/**
* Gets one {@code BigInteger} value from the buffer.
* This method calls {@link fill()} method if needed.
* @throws MessageTypeException the first value of the buffer is not a {@code BigInteger}.
*/
public BigInteger unpackBigInteger() throws IOException, MessageTypeException {
return impl.unpackBigInteger();
}
/**
* Gets one {@code float} value from the buffer.
* This method calls {@link fill()} method if needed.
@@ -557,7 +557,7 @@ public class Unpacker implements Iterable<Object> {
* Gets one {@code Object} value from the buffer.
* This method calls {@link fill()} method if needed.
*/
final public Object unpackObject() throws IOException {
final public MessagePackObject unpackObject() throws IOException {
return impl.unpackObject();
}

View File

@@ -18,11 +18,8 @@
package org.msgpack;
import java.nio.ByteBuffer;
//import java.math.BigInteger;
import org.msgpack.*;
import org.msgpack.schema.GenericSchema;
import org.msgpack.schema.IMapSchema;
import org.msgpack.schema.IArraySchema;
import java.math.BigInteger;
import org.msgpack.object.*;
public class UnpackerImpl {
static final int CS_HEADER = 0x00;
@@ -55,30 +52,19 @@ public class UnpackerImpl {
private int[] stack_ct = new int[MAX_STACK_SIZE];
private int[] stack_count = new int[MAX_STACK_SIZE];
private Object[] stack_obj = new Object[MAX_STACK_SIZE];
private Schema[] stack_schema = new Schema[MAX_STACK_SIZE];
private int top_ct;
private int top_count;
private Object top_obj;
private Schema top_schema;
private ByteBuffer castBuffer = ByteBuffer.allocate(8);
private boolean finished = false;
private Object data = null;
private static final Schema GENERIC_SCHEMA = new GenericSchema();
private Schema rootSchema;
private MessagePackObject data = null;
public UnpackerImpl()
{
setSchema(GENERIC_SCHEMA);
}
public void setSchema(Schema schema)
{
this.rootSchema = schema;
reset();
}
public final Object getData()
public final MessagePackObject getData()
{
return data;
}
@@ -94,7 +80,6 @@ public class UnpackerImpl {
top_ct = 0;
top_count = 0;
top_obj = null;
top_schema = rootSchema;
}
public final void reset()
@@ -127,20 +112,20 @@ public class UnpackerImpl {
if((b & 0x80) == 0) { // Positive Fixnum
//System.out.println("positive fixnum "+b);
obj = top_schema.createFromByte((byte)b);
obj = IntegerType.create((byte)b);
break _push;
}
if((b & 0xe0) == 0xe0) { // Negative Fixnum
//System.out.println("negative fixnum "+b);
obj = top_schema.createFromByte((byte)b);
obj = IntegerType.create((byte)b);
break _push;
}
if((b & 0xe0) == 0xa0) { // FixRaw
trail = b & 0x1f;
if(trail == 0) {
obj = top_schema.createFromRaw(new byte[0], 0, 0);
obj = RawType.create(new byte[0]);
break _push;
}
cs = ACS_RAW_VALUE;
@@ -151,25 +136,20 @@ public class UnpackerImpl {
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IArraySchema)) {
throw new RuntimeException("type error");
}
count = b & 0x0f;
//System.out.println("fixarray count:"+count);
obj = new Object[count];
obj = new MessagePackObject[count];
if(count == 0) {
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
obj = ArrayType.create((MessagePackObject[])obj);
break _push;
}
++top;
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_ARRAY_ITEM;
top_count = count;
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
break _header_again;
}
@@ -177,13 +157,10 @@ public class UnpackerImpl {
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IMapSchema)) {
throw new RuntimeException("type error");
}
count = b & 0x0f;
obj = new Object[count*2];
obj = new MessagePackObject[count*2];
if(count == 0) {
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
obj = MapType.create((MessagePackObject[])obj);
break _push;
}
//System.out.println("fixmap count:"+count);
@@ -191,23 +168,21 @@ public class UnpackerImpl {
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_MAP_KEY;
top_count = count;
top_schema = ((IMapSchema)top_schema).getKeySchema();
break _header_again;
}
switch(b & 0xff) { // FIXME
case 0xc0: // nil
obj = top_schema.createFromNil();
obj = NilType.create();
break _push;
case 0xc2: // false
obj = top_schema.createFromBoolean(false);
obj = BooleanType.create(false);
break _push;
case 0xc3: // true
obj = top_schema.createFromBoolean(true);
obj = BooleanType.create(true);
break _push;
case 0xca: // float
case 0xcb: // double
@@ -251,13 +226,13 @@ public class UnpackerImpl {
case CS_FLOAT:
castBuffer.rewind();
castBuffer.put(src, n, 4);
obj = top_schema.createFromFloat( castBuffer.getFloat(0) );
obj = FloatType.create( castBuffer.getFloat(0) );
//System.out.println("float "+obj);
break _push;
case CS_DOUBLE:
castBuffer.rewind();
castBuffer.put(src, n, 8);
obj = top_schema.createFromDouble( castBuffer.getDouble(0) );
obj = FloatType.create( castBuffer.getDouble(0) );
//System.out.println("double "+obj);
break _push;
case CS_UINT_8:
@@ -265,7 +240,7 @@ public class UnpackerImpl {
//System.out.println(src[n]);
//System.out.println(src[n+1]);
//System.out.println(src[n-1]);
obj = top_schema.createFromShort( (short)((src[n]) & 0xff) );
obj = IntegerType.create( (short)((src[n]) & 0xff) );
//System.out.println("uint8 "+obj);
break _push;
case CS_UINT_16:
@@ -273,13 +248,13 @@ public class UnpackerImpl {
//System.out.println(src[n+1]);
castBuffer.rewind();
castBuffer.put(src, n, 2);
obj = top_schema.createFromInt( ((int)castBuffer.getShort(0)) & 0xffff );
obj = IntegerType.create( ((int)castBuffer.getShort(0)) & 0xffff );
//System.out.println("uint 16 "+obj);
break _push;
case CS_UINT_32:
castBuffer.rewind();
castBuffer.put(src, n, 4);
obj = top_schema.createFromLong( ((long)castBuffer.getInt(0)) & 0xffffffffL );
obj = IntegerType.create( ((long)castBuffer.getInt(0)) & 0xffffffffL );
//System.out.println("uint 32 "+obj);
break _push;
case CS_UINT_64:
@@ -288,38 +263,36 @@ public class UnpackerImpl {
{
long o = castBuffer.getLong(0);
if(o < 0) {
// FIXME
//obj = GenericBigInteger.valueOf(o & 0x7fffffffL).setBit(31);
throw new UnpackException("uint 64 bigger than 0x7fffffff is not supported");
obj = IntegerType.create(new BigInteger(1, castBuffer.array()));
} else {
obj = top_schema.createFromLong( o );
obj = IntegerType.create(o);
}
}
break _push;
case CS_INT_8:
obj = top_schema.createFromByte( src[n] );
obj = IntegerType.create( src[n] );
break _push;
case CS_INT_16:
castBuffer.rewind();
castBuffer.put(src, n, 2);
obj = top_schema.createFromShort( castBuffer.getShort(0) );
obj = IntegerType.create( castBuffer.getShort(0) );
break _push;
case CS_INT_32:
castBuffer.rewind();
castBuffer.put(src, n, 4);
obj = top_schema.createFromInt( castBuffer.getInt(0) );
obj = IntegerType.create( castBuffer.getInt(0) );
break _push;
case CS_INT_64:
castBuffer.rewind();
castBuffer.put(src, n, 8);
obj = top_schema.createFromLong( castBuffer.getLong(0) );
obj = IntegerType.create( castBuffer.getLong(0) );
break _push;
case CS_RAW_16:
castBuffer.rewind();
castBuffer.put(src, n, 2);
trail = ((int)castBuffer.getShort(0)) & 0xffff;
if(trail == 0) {
obj = top_schema.createFromRaw(new byte[0], 0, 0);
obj = RawType.create(new byte[0]);
break _push;
}
cs = ACS_RAW_VALUE;
@@ -330,77 +303,68 @@ public class UnpackerImpl {
// FIXME overflow check
trail = castBuffer.getInt(0) & 0x7fffffff;
if(trail == 0) {
obj = top_schema.createFromRaw(new byte[0], 0, 0);
obj = RawType.create(new byte[0]);
break _push;
}
cs = ACS_RAW_VALUE;
case ACS_RAW_VALUE:
obj = top_schema.createFromRaw(src, n, trail);
break _fixed_trail_again;
case ACS_RAW_VALUE: {
byte[] raw = new byte[trail];
System.arraycopy(src, n, raw, 0, trail);
obj = RawType.create(raw);
}
break _push;
case CS_ARRAY_16:
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IArraySchema)) {
throw new RuntimeException("type error");
}
castBuffer.rewind();
castBuffer.put(src, n, 2);
count = ((int)castBuffer.getShort(0)) & 0xffff;
obj = new Object[count];
obj = new MessagePackObject[count];
if(count == 0) {
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
obj = ArrayType.create((MessagePackObject[])obj);
break _push;
}
++top;
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_ARRAY_ITEM;
top_count = count;
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
break _header_again;
case CS_ARRAY_32:
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IArraySchema)) {
throw new RuntimeException("type error");
}
castBuffer.rewind();
castBuffer.put(src, n, 4);
// FIXME overflow check
count = castBuffer.getInt(0) & 0x7fffffff;
obj = new Object[count];
obj = new MessagePackObject[count];
if(count == 0) {
obj = ((IArraySchema)top_schema).createFromArray((Object[])obj);
obj = ArrayType.create((MessagePackObject[])obj);
break _push;
}
++top;
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_ARRAY_ITEM;
top_count = count;
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
break _header_again;
case CS_MAP_16:
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IMapSchema)) {
throw new RuntimeException("type error");
}
castBuffer.rewind();
castBuffer.put(src, n, 2);
count = ((int)castBuffer.getShort(0)) & 0xffff;
obj = new Object[count*2];
obj = new MessagePackObject[count*2];
if(count == 0) {
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
obj = MapType.create((MessagePackObject[])obj);
break _push;
}
//System.out.println("fixmap count:"+count);
@@ -408,26 +372,21 @@ public class UnpackerImpl {
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_MAP_KEY;
top_count = count;
top_schema = ((IMapSchema)top_schema).getKeySchema();
break _header_again;
case CS_MAP_32:
if(top >= MAX_STACK_SIZE) {
throw new UnpackException("parse error");
}
if(!(top_schema instanceof IMapSchema)) {
throw new RuntimeException("type error");
}
castBuffer.rewind();
castBuffer.put(src, n, 4);
// FIXME overflow check
count = castBuffer.getInt(0) & 0x7fffffff;
obj = new Object[count*2];
obj = new MessagePackObject[count*2];
if(count == 0) {
obj = ((IMapSchema)top_schema).createFromMap((Object[])obj);
obj = MapType.create((MessagePackObject[])obj);
break _push;
}
//System.out.println("fixmap count:"+count);
@@ -435,11 +394,9 @@ public class UnpackerImpl {
stack_obj[top] = top_obj;
stack_ct[top] = top_ct;
stack_count[top] = top_count;
stack_schema[top] = top_schema;
top_obj = obj;
top_ct = CT_MAP_KEY;
top_count = count;
top_schema = ((IMapSchema)top_schema).getKeySchema();
break _header_again;
default:
throw new UnpackException("parse error");
@@ -454,7 +411,7 @@ public class UnpackerImpl {
//System.out.println("push top:"+top);
if(top == -1) {
++i;
data = obj;
data = (MessagePackObject)obj;
finished = true;
break _out;
}
@@ -468,14 +425,10 @@ public class UnpackerImpl {
top_obj = stack_obj[top];
top_ct = stack_ct[top];
top_count = stack_count[top];
top_schema = stack_schema[top];
obj = ((IArraySchema)top_schema).createFromArray(ar);
obj = ArrayType.create((MessagePackObject[])ar);
stack_obj[top] = null;
stack_schema[top] = null;
--top;
break _push;
} else {
top_schema = ((IArraySchema)stack_schema[top]).getElementSchema(ar.length - top_count);
}
break _header_again;
}
@@ -484,7 +437,6 @@ public class UnpackerImpl {
Object[] mp = (Object[])top_obj;
mp[mp.length - top_count*2] = obj;
top_ct = CT_MAP_VALUE;
top_schema = ((IMapSchema)stack_schema[top]).getValueSchema();
break _header_again;
}
case CT_MAP_VALUE: {
@@ -495,10 +447,8 @@ public class UnpackerImpl {
top_obj = stack_obj[top];
top_ct = stack_ct[top];
top_count = stack_count[top];
top_schema = stack_schema[top];
obj = ((IMapSchema)top_schema).createFromMap(mp);
obj = MapType.create((MessagePackObject[])mp);
stack_obj[top] = null;
stack_schema[top] = null;
--top;
break _push;
}

View File

@@ -0,0 +1,81 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.util.List;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class ArrayType extends MessagePackObject {
private MessagePackObject[] array;
ArrayType(MessagePackObject[] array) {
this.array = array;
}
public static ArrayType create(MessagePackObject[] array) {
return new ArrayType(array);
}
@Override
public boolean isArrayType() {
return true;
}
@Override
public MessagePackObject[] asArray() {
return array;
}
@Override
public List<MessagePackObject> asList() {
return Arrays.asList(array);
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packArray(array.length);
for(int i=0; i < array.length; i++) {
array[i].messagePack(pk);
}
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((ArrayType)obj).array, array);
}
@Override
public int hashCode() {
return array.hashCode();
}
@Override
public Object clone() {
MessagePackObject[] copy = new MessagePackObject[array.length];
for(int i=0; i < array.length; i++) {
copy[i] = (MessagePackObject)array[i].clone();
}
return copy;
}
}

View File

@@ -0,0 +1,131 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class BigIntegerTypeIMPL extends IntegerType {
private BigInteger value;
BigIntegerTypeIMPL(BigInteger value) {
this.value = value;
}
@Override
public byte asByte() {
if(value.compareTo(BigInteger.valueOf((long)Byte.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.byteValue();
}
@Override
public short asShort() {
if(value.compareTo(BigInteger.valueOf((long)Short.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.shortValue();
}
@Override
public int asInt() {
if(value.compareTo(BigInteger.valueOf((long)Integer.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.intValue();
}
@Override
public long asLong() {
if(value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.longValue();
}
@Override
public BigInteger asBigInteger() {
return value;
}
@Override
public byte byteValue() {
return value.byteValue();
}
@Override
public short shortValue() {
return value.shortValue();
}
@Override
public int intValue() {
return value.intValue();
}
@Override
public long longValue() {
return value.longValue();
}
@Override
public BigInteger bigIntegerValue() {
return value;
}
@Override
public float floatValue() {
return value.floatValue();
}
@Override
public double doubleValue() {
return value.doubleValue();
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packBigInteger(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == ShortIntegerTypeIMPL.class) {
return BigInteger.valueOf(((ShortIntegerTypeIMPL)obj).longValue()).equals(value);
} else if(obj.getClass() == LongIntegerTypeIMPL.class) {
return BigInteger.valueOf(((LongIntegerTypeIMPL)obj).longValue()).equals(value);
}
return false;
}
return ((BigIntegerTypeIMPL)obj).value.equals(value);
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public Object clone() {
return new BigIntegerTypeIMPL(value);
}
}

View File

@@ -15,50 +15,57 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
package org.msgpack.object;
import java.io.IOException;
import org.msgpack.*;
public class BooleanSchema extends Schema {
public BooleanSchema() { }
public class BooleanType extends MessagePackObject {
private boolean value;
@Override
public String getClassName() {
return "Boolean";
BooleanType(boolean value) {
this.value = value;
}
public static BooleanType create(boolean value) {
return new BooleanType(value);
}
@Override
public String getExpression() {
return "boolean";
public boolean isBooleanType() {
return true;
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Boolean) {
pk.packBoolean((Boolean)obj);
} else if(obj == null) {
pk.packNil();
public boolean asBoolean() {
return value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packBoolean(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return ((BooleanType)obj).value == value;
}
@Override
public int hashCode() {
if(value) {
return 1231;
} else {
throw MessageTypeException.invalidConvert(obj, this);
return 1237;
}
}
public static final boolean convertBoolean(Object obj) throws MessageTypeException {
if(obj instanceof Boolean) {
return (Boolean)obj;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertBoolean(obj);
}
@Override
public Object createFromBoolean(boolean v) {
return v;
public Object clone() {
return new BooleanType(value);
}
}

View File

@@ -0,0 +1,101 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class DoubleTypeIMPL extends FloatType {
private double value;
public DoubleTypeIMPL(double value) {
this.value = value;
}
@Override
public float asFloat() {
// FIXME check overflow, underflow?
return (float)value;
}
@Override
public double asDouble() {
return value;
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf((long)value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packDouble(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return ((DoubleTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
long v = Double.doubleToLongBits(value);
return (int)(v^(v>>>32));
}
@Override
public Object clone() {
return new DoubleTypeIMPL(value);
}
}

View File

@@ -15,12 +15,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
package org.msgpack.object;
import org.msgpack.Schema;
import org.msgpack.*;
public interface IArraySchema {
public Schema getElementSchema(int index);
public Object createFromArray(Object[] obj);
public abstract class FloatType extends MessagePackObject {
@Override
public boolean isFloatType() {
return true;
}
public static FloatType create(float value) {
return new FloatTypeIMPL(value);
}
public static FloatType create(double value) {
return new DoubleTypeIMPL(value);
}
}

View File

@@ -0,0 +1,94 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class FloatTypeIMPL extends FloatType {
private float value;
public FloatTypeIMPL(float value) {
this.value = value;
}
@Override
public float asFloat() {
return value;
}
@Override
public double asDouble() {
return (double)value;
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packFloat(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return ((FloatTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return Float.floatToIntBits(value);
}
@Override
public Object clone() {
return new FloatTypeIMPL(value);
}
}

View File

@@ -0,0 +1,49 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import org.msgpack.*;
public abstract class IntegerType extends MessagePackObject {
@Override
public boolean isIntegerType() {
return true;
}
public static IntegerType create(byte value) {
return new ShortIntegerTypeIMPL((int)value);
}
public static IntegerType create(short value) {
return new ShortIntegerTypeIMPL((int)value);
}
public static IntegerType create(int value) {
return new ShortIntegerTypeIMPL(value);
}
public static IntegerType create(long value) {
return new LongIntegerTypeIMPL(value);
}
public static IntegerType create(BigInteger value) {
return new BigIntegerTypeIMPL(value);
}
}

View File

@@ -0,0 +1,128 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class LongIntegerTypeIMPL extends IntegerType {
private long value;
LongIntegerTypeIMPL(long value) {
this.value = value;
}
@Override
public byte asByte() {
if(value > (long)Byte.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (byte)value;
}
@Override
public short asShort() {
if(value > (long)Short.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (short)value;
}
@Override
public int asInt() {
if(value > (long)Integer.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (int)value;
}
@Override
public long asLong() {
return value;
}
@Override
public BigInteger asBigInteger() {
return BigInteger.valueOf(value);
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf(value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packLong(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == ShortIntegerTypeIMPL.class) {
return value == ((ShortIntegerTypeIMPL)obj).longValue();
} else if(obj.getClass() == BigIntegerTypeIMPL.class) {
return BigInteger.valueOf(value).equals(((BigIntegerTypeIMPL)obj).bigIntegerValue());
}
return false;
}
return ((LongIntegerTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return (int)(value^(value>>>32));
}
@Override
public Object clone() {
return new LongIntegerTypeIMPL(value);
}
}

View File

@@ -0,0 +1,84 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class MapType extends MessagePackObject {
private MessagePackObject[] map;
MapType(MessagePackObject[] map) {
this.map = map;
}
public static MapType create(MessagePackObject[] map) {
return new MapType(map);
}
@Override
public boolean isMapType() {
return true;
}
@Override
public Map<MessagePackObject, MessagePackObject> asMap() {
HashMap<MessagePackObject, MessagePackObject> m = new HashMap(map.length / 2);
int i = 0;
while(i < map.length) {
MessagePackObject k = map[i++];
MessagePackObject v = map[i++];
m.put(k, v);
}
return m;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packMap(map.length / 2);
for(int i=0; i < map.length; i++) {
map[i].messagePack(pk);
}
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((MapType)obj).map, map);
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public Object clone() {
MessagePackObject[] copy = new MessagePackObject[map.length];
for(int i=0; i < map.length; i++) {
copy[i] = (MessagePackObject)map[i].clone();
}
return copy;
}
}

View File

@@ -15,29 +15,46 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
package org.msgpack.object;
import org.msgpack.Schema;
import java.io.IOException;
import org.msgpack.*;
public class FieldSchema {
private String name;
private Schema schema;
public class NilType extends MessagePackObject {
private final static NilType INSTANCE = new NilType();
public FieldSchema(String name, Schema schema) {
this.name = name;
this.schema = schema;
public static NilType create() {
return INSTANCE;
}
public final String getName() {
return name;
private NilType() { }
@Override
public boolean isNil() {
return true;
}
public final Schema getSchema() {
return schema;
@Override
public void messagePack(Packer pk) throws IOException {
pk.packNil();
}
public String getExpression() {
return "(field "+name+" "+schema.getExpression()+")";
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return true;
}
@Override
public int hashCode() {
return 0;
}
@Override
public Object clone() {
return INSTANCE;
}
}

View File

@@ -0,0 +1,90 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class RawType extends MessagePackObject {
private byte[] bytes;
RawType(byte[] bytes) {
this.bytes = bytes;
}
RawType(String str) {
try {
this.bytes = str.getBytes("UTF-8");
} catch (Exception e) {
throw new MessageTypeException("type error");
}
}
public static RawType create(byte[] bytes) {
return new RawType(bytes);
}
public static RawType create(String str) {
return new RawType(str);
}
@Override
public boolean isRawType() {
return true;
}
@Override
public byte[] asByteArray() {
return bytes;
}
@Override
public String asString() {
try {
return new String(bytes, "UTF-8");
} catch (Exception e) {
throw new MessageTypeException("type error");
}
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packRaw(bytes.length);
pk.packRawBody(bytes);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((RawType)obj).bytes, bytes);
}
@Override
public int hashCode() {
return bytes.hashCode();
}
@Override
public Object clone() {
return new RawType((byte[])bytes.clone());
}
}

View File

@@ -0,0 +1,125 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class ShortIntegerTypeIMPL extends IntegerType {
private int value;
ShortIntegerTypeIMPL(int value) {
this.value = value;
}
@Override
public byte asByte() {
if(value > (int)Byte.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (byte)value;
}
@Override
public short asShort() {
if(value > (int)Short.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (short)value;
}
@Override
public int asInt() {
return value;
}
@Override
public long asLong() {
return value;
}
@Override
public BigInteger asBigInteger() {
return BigInteger.valueOf((long)value);
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf((long)value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packInt(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == LongIntegerTypeIMPL.class) {
return (long)value == ((LongIntegerTypeIMPL)obj).longValue();
} else if(obj.getClass() == BigIntegerTypeIMPL.class) {
return ((BigIntegerTypeIMPL)obj).bigIntegerValue().equals(BigInteger.valueOf((long)value));
}
return false;
}
return ((ShortIntegerTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return value;
}
@Override
public Object clone() {
return new ShortIntegerTypeIMPL(value);
}
}

View File

@@ -1,97 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.msgpack.*;
public class ByteArraySchema extends Schema {
public ByteArraySchema() { }
@Override
public String getClassName() {
return "byte[]";
}
@Override
public String getExpression() {
return "raw";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof byte[]) {
byte[] b = (byte[])obj;
pk.packRaw(b.length);
pk.packRawBody(b);
} else if(obj instanceof String) {
try {
byte[] b = ((String)obj).getBytes("UTF-8");
pk.packRaw(b.length);
pk.packRawBody(b);
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final byte[] convertByteArray(Object obj) throws MessageTypeException {
if(obj instanceof byte[]) {
// FIXME copy?
//byte[] d = (byte[])obj;
//byte[] v = new byte[d.length];
//System.arraycopy(d, 0, v, 0, d.length);
//return v;
return (byte[])obj;
} else if(obj instanceof ByteBuffer) {
ByteBuffer d = (ByteBuffer)obj;
byte[] v = new byte[d.capacity()];
int pos = d.position();
d.get(v);
d.position(pos);
return v;
} else if(obj instanceof String) {
try {
return ((String)obj).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertByteArray(obj);
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
byte[] d = new byte[length];
System.arraycopy(b, offset, d, 0, length);
return d;
}
}

View File

@@ -1,96 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class ByteSchema extends Schema {
public ByteSchema() { }
@Override
public String getClassName() {
return "Byte";
}
@Override
public String getExpression() {
return "byte";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
short value = ((Number)obj).shortValue();
if(value > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
pk.packByte((byte)value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final byte convertByte(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
short value = ((Number)obj).shortValue();
if(value > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertByte(obj);
}
@Override
public Object createFromByte(byte v) {
return (byte)v;
}
@Override
public Object createFromShort(short v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
@Override
public Object createFromInt(int v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
@Override
public Object createFromLong(long v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
}

View File

@@ -1,244 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.io.File;
import java.io.Writer;
import org.msgpack.*;
public class ClassGenerator {
private ClassSchema schema;
private Writer writer;
private int indent;
private ClassGenerator(Writer writer) {
this.writer = writer;
this.indent = 0;
}
public static void write(Schema schema, Writer dest) throws IOException {
if(!(schema instanceof ClassSchema)) {
throw new RuntimeException("schema is not class schema");
}
ClassSchema cs = (ClassSchema)schema;
new ClassGenerator(dest).run(cs);
}
private void run(ClassSchema cs) throws IOException {
List<ClassSchema> subclasses = new ArrayList<ClassSchema>();
for(FieldSchema f : cs.getFields()) {
findSubclassSchema(subclasses, f.getSchema());
}
for(ClassSchema sub : subclasses) {
sub.setNamespace(cs.getNamespace());
sub.setImports(cs.getImports());
}
this.schema = cs;
writeHeader();
writeClass();
for(ClassSchema sub : subclasses) {
this.schema = sub;
writeSubclass();
}
writeFooter();
this.schema = null;
writer.flush();
}
private void findSubclassSchema(List<ClassSchema> dst, Schema s) {
if(s instanceof ClassSchema) {
ClassSchema cs = (ClassSchema)s;
if(!dst.contains(cs)) { dst.add(cs); }
for(FieldSchema f : cs.getFields()) {
findSubclassSchema(dst, f.getSchema());
}
} else if(s instanceof ListSchema) {
ListSchema as = (ListSchema)s;
findSubclassSchema(dst, as.getElementSchema(0));
} else if(s instanceof SetSchema) {
SetSchema as = (SetSchema)s;
findSubclassSchema(dst, as.getElementSchema(0));
} else if(s instanceof MapSchema) {
MapSchema as = (MapSchema)s;
findSubclassSchema(dst, as.getKeySchema());
findSubclassSchema(dst, as.getValueSchema());
}
}
private void writeHeader() throws IOException {
if(schema.getNamespace() != null) {
line("package "+schema.getNamespace()+";");
line();
}
line("import java.util.*;");
line("import java.io.*;");
line("import org.msgpack.*;");
line("import org.msgpack.schema.ClassSchema;");
line("import org.msgpack.schema.FieldSchema;");
}
private void writeFooter() throws IOException {
line();
}
private void writeClass() throws IOException {
line();
line("public final class "+schema.getClassName()+" implements MessagePackable, MessageConvertable");
line("{");
pushIndent();
writeSchema();
writeMemberVariables();
writeMemberFunctions();
popIndent();
line("}");
}
private void writeSubclass() throws IOException {
line();
line("final class "+schema.getClassName()+" implements MessagePackable, MessageConvertable");
line("{");
pushIndent();
writeSchema();
writeMemberVariables();
writeMemberFunctions();
popIndent();
line("}");
}
private void writeSchema() throws IOException {
line("private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load(\""+schema.getExpression()+"\");");
line("public static ClassSchema getSchema() { return _SCHEMA; }");
}
private void writeMemberVariables() throws IOException {
line();
for(FieldSchema f : schema.getFields()) {
line("public "+f.getSchema().getClassName()+" "+f.getName()+";");
}
}
private void writeMemberFunctions() throws IOException {
// void messagePack(Packer pk)
// boolean equals(Object obj)
// int hashCode()
// void set(int _index, Object _value)
// Object get(int _index);
// getXxx()
// setXxx(Xxx xxx)
writeConstructors();
writeAccessors();
writePackFunction();
writeConvertFunction();
writeFactoryFunction();
}
private void writeConstructors() throws IOException {
line();
line("public "+schema.getClassName()+"() { }");
}
private void writeAccessors() throws IOException {
// FIXME
//line();
//for(FieldSchema f : schema.getFields()) {
// line("");
//}
}
private void writePackFunction() throws IOException {
line();
line("@Override");
line("public void messagePack(Packer _pk) throws IOException");
line("{");
pushIndent();
line("_pk.packArray("+schema.getFields().length+");");
line("FieldSchema[] _fields = _SCHEMA.getFields();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("_fields["+i+"].getSchema().pack(_pk, "+f.getName()+");");
++i;
}
popIndent();
line("}");
}
private void writeConvertFunction() throws IOException {
line();
line("@Override");
line("@SuppressWarnings(\"unchecked\")");
line("public void messageConvert(Object obj) throws MessageTypeException");
line("{");
pushIndent();
line("Object[] _source = ((List)obj).toArray();");
line("FieldSchema[] _fields = _SCHEMA.getFields();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("if(_source.length <= "+i+") { return; } this."+f.getName()+" = ("+f.getSchema().getClassName()+")_fields["+i+"].getSchema().convert(_source["+i+"]);");
++i;
}
popIndent();
line("}");
}
private void writeFactoryFunction() throws IOException {
line();
line("@SuppressWarnings(\"unchecked\")");
line("public static "+schema.getClassName()+" createFromMessage(Object[] _message)");
line("{");
pushIndent();
line(schema.getClassName()+" _self = new "+schema.getClassName()+"();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("if(_message.length <= "+i+") { return _self; } _self."+f.getName()+" = ("+f.getSchema().getClassName()+")_message["+i+"];");
++i;
}
line("return _self;");
popIndent();
line("}");
}
private void line(String str) throws IOException {
for(int i=0; i < indent; ++i) {
writer.write("\t");
}
writer.write(str+"\n");
}
private void line() throws IOException {
writer.write("\n");
}
private void pushIndent() {
indent += 1;
}
private void popIndent() {
indent -= 1;
}
}

View File

@@ -1,91 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.List;
import org.msgpack.*;
public abstract class ClassSchema extends Schema implements IArraySchema {
protected String name;
protected FieldSchema[] fields;
protected List<String> imports;
protected String namespace;
protected String fqdn;
public ClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
this.name = name;
this.namespace = namespace;
this.imports = imports; // FIXME clone?
this.fields = new FieldSchema[fields.size()];
System.arraycopy(fields.toArray(), 0, this.fields, 0, fields.size());
if(namespace == null) {
this.fqdn = name;
} else {
this.fqdn = namespace+"."+name;
}
}
@Override
public String getClassName() {
return name;
}
@Override
public String getExpression() {
StringBuffer b = new StringBuffer();
b.append("(class ");
b.append(name);
if(namespace != null) {
b.append(" (package "+namespace+")");
}
for(FieldSchema f : fields) {
b.append(" "+f.getExpression());
}
b.append(")");
return b.toString();
}
public boolean equals(ClassSchema o) {
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
name.equals(o.name);
}
public final FieldSchema[] getFields() {
return fields;
}
String getNamespace() {
return namespace;
}
List<String> getImports() {
return imports;
}
void setNamespace(String namespace) {
this.namespace = namespace;
}
void setImports(List<String> imports) {
this.imports = imports; // FIXME clone?
}
}

View File

@@ -1,74 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class DoubleSchema extends Schema {
public DoubleSchema() { }
@Override
public String getClassName() {
return "Double";
}
@Override
public String getExpression() {
return "double";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Double) {
pk.packDouble((Double)obj);
} else if(obj instanceof Float) {
pk.packFloat((Float)obj);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final double convertDouble(Object obj) throws MessageTypeException {
if(obj instanceof Double) {
return (Double)obj;
} else if(obj instanceof Float) {
return ((Float)obj).doubleValue();
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertDouble(obj);
}
@Override
public Object createFromFloat(float v) {
return (double)v;
}
@Override
public Object createFromDouble(double v) {
return (double)v;
}
}

View File

@@ -1,74 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class FloatSchema extends Schema {
public FloatSchema() { }
@Override
public String getClassName() {
return "Float";
}
@Override
public String getExpression() {
return "float";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Double) {
pk.packDouble((Double)obj);
} else if(obj instanceof Float) {
pk.packFloat((Float)obj);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final float convertFloat(Object obj) throws MessageTypeException {
if(obj instanceof Double) {
return ((Double)obj).floatValue();
} else if(obj instanceof Float) {
return (Float)obj;
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertFloat(obj);
}
@Override
public Object createFromFloat(float v) {
return (float)v;
}
@Override
public Object createFromDouble(double v) {
return (float)v;
}
}

View File

@@ -1,87 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class GenericClassSchema extends ClassSchema {
public GenericClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
super(name, namespace, imports, fields);
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Map) {
Map d = (Map)obj;
pk.packArray(fields.length);
for(int i=0; i < fields.length; ++i) {
FieldSchema f = fields[i];
f.getSchema().pack(pk, d.get(f.getName()));
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
if(obj instanceof Collection) {
// FIXME optimize
return createFromArray( ((Collection)obj).toArray() );
} else if(obj instanceof Map) {
HashMap<String,Object> m = new HashMap<String,Object>(fields.length);
Map d = (Map)obj;
for(int i=0; i < fields.length; ++i) {
FieldSchema f = fields[i];
String fieldName = f.getName();
m.put(fieldName, f.getSchema().convert(d.get(fieldName)));
}
return m;
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public Schema getElementSchema(int index) {
// FIXME check index < fields.length
return fields[index].getSchema();
}
public Object createFromArray(Object[] obj) {
HashMap<String,Object> m = new HashMap<String,Object>(fields.length);
int i=0;
for(; i < obj.length; ++i) {
m.put(fields[i].getName(), obj[i]);
}
for(; i < fields.length; ++i) {
m.put(fields[i].getName(), null);
}
return m;
}
}

View File

@@ -1,129 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class GenericSchema extends Schema implements IArraySchema, IMapSchema {
public GenericSchema() { }
@Override
public String getClassName() {
return "Object";
}
@Override
public String getExpression() {
return "object";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
pk.pack(obj);
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return obj;
}
@Override
public Schema getElementSchema(int index) {
return this;
}
@Override
public Schema getKeySchema() {
return this;
}
@Override
public Schema getValueSchema() {
return this;
}
@Override
public Object createFromNil() {
return null;
}
@Override
public Object createFromBoolean(boolean v) {
return v;
}
@Override
public Object createFromByte(byte v) {
return v;
}
@Override
public Object createFromShort(short v) {
return v;
}
@Override
public Object createFromInt(int v) {
return v;
}
@Override
public Object createFromLong(long v) {
return v;
}
@Override
public Object createFromFloat(float v) {
return v;
}
@Override
public Object createFromDouble(double v) {
return v;
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
byte[] bytes = new byte[length];
System.arraycopy(b, offset, bytes, 0, length);
return bytes;
}
@Override
public Object createFromArray(Object[] obj) {
return Arrays.asList(obj);
}
@Override
@SuppressWarnings("unchecked")
public Object createFromMap(Object[] obj) {
HashMap m = new HashMap(obj.length / 2);
int i = 0;
while(i < obj.length) {
Object k = obj[i++];
Object v = obj[i++];
m.put(k, v);
}
return m;
}
}

View File

@@ -1,27 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import org.msgpack.Schema;
public interface IMapSchema {
public Schema getKeySchema();
public Schema getValueSchema();
public Object createFromMap(Object[] obj);
}

View File

@@ -1,96 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class IntSchema extends Schema {
public IntSchema() { }
@Override
public String getClassName() {
return "Integer";
}
@Override
public String getExpression() {
return "int";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value >= Short.MAX_VALUE) {
long lvalue = ((Number)obj).longValue();
if(lvalue > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
}
pk.packInt(value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final int convertInt(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value >= Integer.MAX_VALUE) {
long lvalue = ((Number)obj).longValue();
if(lvalue > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
}
return value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertInt(obj);
}
@Override
public Object createFromByte(byte v) {
return (int)v;
}
@Override
public Object createFromShort(short v) {
return (int)v;
}
@Override
public Object createFromInt(int v) {
return (int)v;
}
@Override
public Object createFromLong(long v) {
if(v > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
return (int)v;
}
}

View File

@@ -1,111 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.RandomAccess;
import java.io.IOException;
import org.msgpack.*;
public class ListSchema extends Schema implements IArraySchema {
private Schema elementSchema;
public ListSchema(Schema elementSchema) {
this.elementSchema = elementSchema;
}
@Override
public String getClassName() {
return "List<"+elementSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(array "+elementSchema.getExpression()+")";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof List) {
List<Object> d = (List<Object>)obj;
pk.packArray(d.size());
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
elementSchema.pack(pk, d.get(i));
}
} else {
for(Object e : d) {
elementSchema.pack(pk, e);
}
}
} else if(obj instanceof Set) {
Set<Object> d = (Set<Object>)obj;
pk.packArray(d.size());
for(Object e : d) {
elementSchema.pack(pk, e);
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <T> List<T> convertList(Object obj,
Schema elementSchema, List<T> dest) throws MessageTypeException {
if(!(obj instanceof List)) {
throw new MessageTypeException();
}
List<Object> d = (List<Object>)obj;
if(dest == null) {
dest = new ArrayList<T>(d.size());
}
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
dest.add( (T)elementSchema.convert(d.get(i)) );
}
} else {
for(Object e : d) {
dest.add( (T)elementSchema.convert(e) );
}
}
return dest;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertList(obj, elementSchema, null);
}
@Override
public Schema getElementSchema(int index) {
return elementSchema;
}
@Override
public Object createFromArray(Object[] obj) {
return Arrays.asList(obj);
}
}

View File

@@ -1,80 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class LongSchema extends Schema {
public LongSchema() { }
@Override
public String getClassName() {
return "Long";
}
@Override
public String getExpression() {
return "long";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
long value = ((Number)obj).longValue();
pk.packLong(value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final long convertLong(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
return ((Number)obj).longValue();
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertLong(obj);
}
@Override
public Object createFromByte(byte v) {
return (long)v;
}
@Override
public Object createFromShort(short v) {
return (long)v;
}
@Override
public Object createFromInt(int v) {
return (long)v;
}
@Override
public Object createFromLong(long v) {
return (long)v;
}
}

View File

@@ -1,106 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class MapSchema extends Schema implements IMapSchema {
private Schema keySchema;
private Schema valueSchema;
public MapSchema(Schema keySchema, Schema valueSchema) {
this.keySchema = keySchema;
this.valueSchema = valueSchema;
}
@Override
public String getClassName() {
return "Map<"+keySchema.getClassName()+", "+valueSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(map "+keySchema.getExpression()+" "+valueSchema.getExpression()+")";
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Map) {
Map<Object,Object> d = (Map<Object,Object>)obj;
pk.packMap(d.size());
for(Map.Entry<Object,Object> e : d.entrySet()) {
keySchema.pack(pk, e.getKey());
valueSchema.pack(pk, e.getValue());
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <K,V> Map<K,V> convertMap(Object obj,
Schema keySchema, Schema valueSchema, Map<K,V> dest) throws MessageTypeException {
if(!(obj instanceof Map)) {
throw new MessageTypeException();
}
Map<Object,Object> d = (Map<Object,Object>)obj;
if(dest == null) {
dest = new HashMap<K,V>(d.size());
}
for(Map.Entry<Object,Object> e : d.entrySet()) {
dest.put((K)keySchema.convert(e.getKey()),
(V)valueSchema.convert(e.getValue()));
}
return (Map<K,V>)d;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertMap(obj, keySchema, valueSchema, null);
}
@Override
public Schema getKeySchema() {
return keySchema;
}
@Override
public Schema getValueSchema() {
return valueSchema;
}
@Override
@SuppressWarnings("unchecked")
public Object createFromMap(Object[] obj) {
HashMap dest = new HashMap(obj.length / 2);
int i = 0;
while(i < obj.length) {
Object k = obj[i++];
Object v = obj[i++];
dest.put(k, v);
}
return dest;
}
}

View File

@@ -1,64 +0,0 @@
package org.msgpack.schema;
import java.util.Arrays;
import java.util.List;
import java.lang.reflect.*;
import org.msgpack.*;
// FIXME
public abstract class ReflectionClassSchema extends ClassSchema {
private Constructor constructorCache;
public ReflectionClassSchema(String name, List<FieldSchema> fields, String namespace, List<String> imports) {
super(name, namespace, imports, fields);
}
/*
Schema getElementSchema(int index)
{
// FIXME check index < fields.length
fields[index].getSchema();
}
Object createFromArray(Object[] obj)
{
Object o = newInstance();
((MessageConvertable)o).messageConvert(obj);
return o;
}
Object newInstance()
{
if(constructorCache == null) {
cacheConstructor();
}
try {
return constructorCache.newInstance((Object[])null);
} catch (InvocationTargetException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (InstantiationException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
}
}
private void cacheConstructor()
{
try {
Class c = Class.forName(fqdn);
int index = 0;
for(SpecificFieldSchema f : fields) {
f.cacheField(c, index++);
}
constructorCache = c.getDeclaredConstructor((Class[])null);
constructorCache.setAccessible(true);
} catch(ClassNotFoundException e) {
throw new RuntimeException("class not found: "+fqdn);
} catch (NoSuchMethodException e) {
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
}
}
*/
}

View File

@@ -1,264 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.msgpack.*;
// FIXME exception class
public class SSchemaParser {
public static Schema parse(String source) {
return new SSchemaParser(false).run(source);
}
public static Schema load(String source) {
return new SSchemaParser(true).run(source);
}
private static abstract class SExp {
boolean isAtom() { return false; }
public String getAtom() { return null; }
boolean isTuple() { return false; }
public SExp getTuple(int i) { return null; }
public int size() { return 0; }
public boolean empty() { return size() == 0; }
Iterator<SExp> iterator(int offset) { return null; }
}
private static class SAtom extends SExp {
private String atom;
SAtom(String atom) { this.atom = atom; }
boolean isAtom() { return true; }
public String getAtom() { return atom; }
public String toString() { return atom; }
}
private static class STuple extends SExp {
private List<SExp> tuple;
STuple() { this.tuple = new ArrayList<SExp>(); }
public void add(SExp e) { tuple.add(e); }
boolean isTuple() { return true; }
public SExp getTuple(int i) { return tuple.get(i); }
public int size() { return tuple.size(); }
Iterator<SExp> iterator(int skip) {
Iterator<SExp> i = tuple.iterator();
for(int s=0; s < skip; ++s) { i.next(); }
return i;
}
public String toString() {
if(tuple.isEmpty()) { return "()"; }
Iterator<SExp> i = tuple.iterator();
StringBuffer o = new StringBuffer();
o.append("(").append(i.next());
while(i.hasNext()) { o.append(" ").append(i.next()); }
o.append(")");
return o.toString();
}
}
boolean specificClass;
private SSchemaParser(boolean specificClass) {
this.specificClass = specificClass;
}
private static Pattern pattern = Pattern.compile(
"(?:\\s+)|([\\(\\)]|[\\d\\w\\.]+)");
private Schema run(String source) {
Matcher m = pattern.matcher(source);
Stack<STuple> stack = new Stack<STuple>();
String token;
while(true) {
while(true) {
if(!m.find()) { throw new RuntimeException("unexpected end of file"); }
token = m.group(1);
if(token != null) { break; }
}
if(token.equals("(")) {
stack.push(new STuple());
} else if(token.equals(")")) {
STuple top = stack.pop();
if(stack.empty()) {
stack.push(top);
break;
}
stack.peek().add(top);
} else {
if(stack.empty()) {
throw new RuntimeException("unexpected token '"+token+"'");
}
stack.peek().add(new SAtom(token));
}
}
while(true) {
if(!m.find()) { break; }
token = m.group(1);
if(token != null) { throw new RuntimeException("unexpected token '"+token+"'"); }
}
return readType( stack.pop() );
}
private Schema readType(SExp exp) {
if(exp.isAtom()) {
String type = exp.getAtom();
if(type.equals("string")) {
return new StringSchema();
} else if(type.equals("raw")) {
return new ByteArraySchema();
} else if(type.equals("byte")) {
return new ByteSchema();
} else if(type.equals("short")) {
return new ShortSchema();
} else if(type.equals("int")) {
return new IntSchema();
} else if(type.equals("long")) {
return new LongSchema();
} else if(type.equals("float")) {
return new FloatSchema();
} else if(type.equals("double")) {
return new DoubleSchema();
} else if(type.equals("object")) {
return new GenericSchema();
} else {
throw new RuntimeException("byte, short, int, long, float, double, raw, string or object is expected but got '"+type+"': "+exp);
}
} else {
String type = exp.getTuple(0).getAtom();
if(type.equals("class")) {
return parseClass(exp);
} else if(type.equals("array")) {
return parseList(exp);
} else if(type.equals("set")) {
return parseSet(exp);
} else if(type.equals("map")) {
return parseMap(exp);
} else {
throw new RuntimeException("class, list, set or map is expected but got '"+type+"': "+exp);
}
}
}
private ClassSchema parseClass(SExp exp) {
if(exp.size() < 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("class is (class NAME CLASS_BODY): "+exp);
}
String namespace = null;
List<String> imports = new ArrayList<String>();
String name = exp.getTuple(1).getAtom();
List<FieldSchema> fields = new ArrayList<FieldSchema>();
for(Iterator<SExp> i=exp.iterator(2); i.hasNext();) {
SExp subexp = i.next();
if(!subexp.isTuple() || subexp.empty() || !subexp.getTuple(0).isAtom()) {
throw new RuntimeException("field, package or import is expected: "+subexp);
}
String type = subexp.getTuple(0).getAtom();
if(type.equals("field")) {
fields.add( parseField(subexp) );
} else if(type.equals("package")) {
if(namespace != null) {
throw new RuntimeException("duplicated package definition: "+subexp);
}
namespace = parseNamespace(subexp);
} else if(type.equals("import")) {
imports.add( parseImport(subexp) );
} else {
throw new RuntimeException("field, package or import is expected but got '"+type+"': "+subexp);
}
}
if(specificClass) {
return new SpecificClassSchema(name, namespace, imports, fields);
} else {
return new GenericClassSchema(name, namespace, imports, fields);
}
}
private ListSchema parseList(SExp exp) {
if(exp.size() != 2) {
throw new RuntimeException("list is (list ELEMENT_TYPE): "+exp);
}
Schema elementType = readType(exp.getTuple(1));
return new ListSchema(elementType);
}
private SetSchema parseSet(SExp exp) {
if(exp.size() != 2) {
throw new RuntimeException("list is (list ELEMENT_TYPE): "+exp);
}
Schema elementType = readType(exp.getTuple(1));
return new SetSchema(elementType);
}
private MapSchema parseMap(SExp exp) {
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("map is (map KEY_TYPE VALUE_TYPE): "+exp);
}
Schema keyType = readType(exp.getTuple(1));
Schema valueType = readType(exp.getTuple(2));
return new MapSchema(keyType, valueType);
}
private String parseNamespace(SExp exp) {
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("package is (package NAME): "+exp);
}
String name = exp.getTuple(1).getAtom();
return name;
}
private String parseImport(SExp exp) {
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("import is (import NAME): "+exp);
}
String name = exp.getTuple(1).getAtom();
return name;
}
private FieldSchema parseField(SExp exp) {
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("field is (field NAME TYPE): "+exp);
}
String name = exp.getTuple(1).getAtom();
Schema type = readType(exp.getTuple(2));
return new FieldSchema(name, type);
}
}

View File

@@ -1,115 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.RandomAccess;
import java.io.IOException;
import org.msgpack.*;
public class SetSchema extends Schema implements IArraySchema {
private Schema elementSchema;
public SetSchema(Schema elementSchema) {
this.elementSchema = elementSchema;
}
@Override
public String getClassName() {
return "Set<"+elementSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(set "+elementSchema.getExpression()+")";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof List) {
List<Object> d = (List<Object>)obj;
pk.packArray(d.size());
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
elementSchema.pack(pk, d.get(i));
}
} else {
for(Object e : d) {
elementSchema.pack(pk, e);
}
}
} else if(obj instanceof Set) {
Set<Object> d = (Set<Object>)obj;
pk.packArray(d.size());
for(Object e : d) {
elementSchema.pack(pk, e);
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <T> Set<T> convertSet(Object obj,
Schema elementSchema, Set<T> dest) throws MessageTypeException {
if(!(obj instanceof List)) {
throw new MessageTypeException();
}
List<Object> d = (List<Object>)obj;
if(dest == null) {
dest = new HashSet<T>(d.size());
}
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
dest.add( (T)elementSchema.convert(d.get(i)) );
}
} else {
for(Object e : d) {
dest.add( (T)elementSchema.convert(e) );
}
}
return dest;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertSet(obj, elementSchema, null);
}
@Override
public Schema getElementSchema(int index) {
return elementSchema;
}
@Override
public Object createFromArray(Object[] obj) {
Set m = new HashSet(obj.length);
for(int i=0; i < obj.length; i++) {
m.add(obj[i]);
}
return m;
}
}

View File

@@ -1,93 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class ShortSchema extends Schema {
public ShortSchema() { }
@Override
public String getClassName() {
return "Short";
}
@Override
public String getExpression() {
return "short";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value > Short.MAX_VALUE) {
throw new MessageTypeException();
}
pk.packShort((short)value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final short convertShort(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertShort(obj);
}
@Override
public Object createFromByte(byte v) {
return (short)v;
}
@Override
public Object createFromShort(short v) {
return (short)v;
}
@Override
public Object createFromInt(int v) {
if(v > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)v;
}
@Override
public Object createFromLong(long v) {
if(v > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)v;
}
}

View File

@@ -1,122 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.util.Collection;
import java.util.List;
import java.lang.reflect.*;
import java.io.IOException;
import org.msgpack.*;
public class SpecificClassSchema extends ClassSchema {
private Class classCache;
private Method factoryCache;
private Constructor constructorCache;
public SpecificClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
super(name, namespace, imports, fields);
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj == null) {
pk.packNil();
return;
}
if(classCache == null) {
cacheFactory();
}
if(classCache.isInstance(obj)) {
((MessagePackable)obj).messagePack(pk);
} else {
// FIXME Map<String,Object>
throw MessageTypeException.invalidConvert(obj, this);
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
if(obj instanceof Collection) {
if(constructorCache == null) {
cacheConstructor();
}
try {
MessageConvertable o = (MessageConvertable)constructorCache.newInstance((Object[])null);
o.messageConvert(obj);
return o;
} catch (InvocationTargetException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (InstantiationException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
}
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public Schema getElementSchema(int index) {
// FIXME check index < fields.length
return fields[index].getSchema();
}
public Object createFromArray(Object[] obj) {
if(factoryCache == null) {
cacheFactory();
}
try {
return factoryCache.invoke(null, new Object[]{obj});
} catch (InvocationTargetException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getCause());
} catch (IllegalAccessException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
}
}
@SuppressWarnings("unchecked")
private void cacheFactory() {
try {
classCache = Class.forName(fqdn);
factoryCache = classCache.getDeclaredMethod("createFromMessage", new Class[]{Object[].class});
factoryCache.setAccessible(true);
} catch(ClassNotFoundException e) {
throw new RuntimeException("class not found: "+fqdn);
} catch (NoSuchMethodException e) {
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
}
}
@SuppressWarnings("unchecked")
private void cacheConstructor() {
try {
classCache = Class.forName(fqdn);
constructorCache = classCache.getDeclaredConstructor((Class[])null);
constructorCache.setAccessible(true);
} catch(ClassNotFoundException e) {
throw new RuntimeException("class not found: "+fqdn);
} catch (NoSuchMethodException e) {
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
}
}
}

View File

@@ -1,102 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-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.
//
package org.msgpack.schema;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.msgpack.*;
public class StringSchema extends Schema {
public StringSchema() { }
@Override
public String getClassName() {
return "String";
}
@Override
public String getExpression() {
return "string";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof byte[]) {
byte[] b = (byte[])obj;
pk.packRaw(b.length);
pk.packRawBody(b);
} else if(obj instanceof String) {
try {
byte[] b = ((String)obj).getBytes("UTF-8");
pk.packRaw(b.length);
pk.packRawBody(b);
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final String convertString(Object obj) throws MessageTypeException {
if(obj instanceof byte[]) {
try {
return new String((byte[])obj, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj instanceof String) {
return (String)obj;
} else if(obj instanceof ByteBuffer) {
ByteBuffer d = (ByteBuffer)obj;
try {
if(d.hasArray()) {
return new String(d.array(), d.position(), d.capacity(), "UTF-8");
} else {
byte[] v = new byte[d.capacity()];
int pos = d.position();
d.get(v);
d.position(pos);
return new String(v, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertString(obj);
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
try {
return new String(b, offset, length, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,50 @@
package org.msgpack;
import org.msgpack.*;
import java.io.*;
import java.util.*;
public class Image implements MessagePackable, MessageUnpackable {
public String uri = "";
public String title = "";
public int width = 0;
public int height = 0;
public int size = 0;
public void messagePack(Packer pk) throws IOException {
pk.packArray(5);
pk.pack(uri);
pk.pack(title);
pk.pack(width);
pk.pack(height);
pk.pack(size);
}
public void messageUnpack(Unpacker pac) throws IOException, MessageTypeException {
int length = pac.unpackArray();
if(length != 5) {
throw new MessageTypeException();
}
uri = pac.unpackString();
title = pac.unpackString();
width = pac.unpackInt();
height = pac.unpackInt();
size = pac.unpackInt();
}
public boolean equals(Image obj) {
return uri.equals(obj.uri) &&
title.equals(obj.title) &&
width == obj.width &&
height == obj.height &&
size == obj.size;
}
public boolean equals(Object obj) {
if(obj.getClass() != Image.class) {
return false;
}
return equals((Image)obj);
}
}

View File

@@ -0,0 +1,40 @@
package org.msgpack;
import java.io.*;
import java.util.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestCases {
public void feedFile(Unpacker pac, String path) throws Exception {
FileInputStream input = new FileInputStream(path);
byte[] buffer = new byte[32*1024];
while(true) {
int count = input.read(buffer);
if(count < 0) {
break;
}
pac.feed(buffer, 0, count);
}
}
@Test
public void testCases() throws Exception {
Unpacker pac = new Unpacker();
Unpacker pac_compact = new Unpacker();
feedFile(pac, "src/test/resources/cases.mpac");
feedFile(pac_compact, "src/test/resources/cases_compact.mpac");
UnpackResult result = new UnpackResult();
while(pac.next(result)) {
UnpackResult result_compact = new UnpackResult();
assertTrue( pac_compact.next(result_compact) );
assertTrue( result.getData().equals(result_compact.getData()) );
}
assertFalse( pac_compact.next(result) );
}
};

View File

@@ -3,6 +3,7 @@ package org.msgpack;
import org.msgpack.*;
import java.io.*;
import java.util.*;
import java.math.BigInteger;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -23,8 +24,52 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
assertEquals(val, upk.unpackInt());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackInt());
}
@Test
public void testLong() throws Exception {
testLong(0);
testLong(-1);
testLong(1);
testLong(Integer.MIN_VALUE);
testLong(Integer.MAX_VALUE);
testLong(Long.MIN_VALUE);
testLong(Long.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testLong(rand.nextLong());
}
public void testLong(long val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackLong());
}
@Test
public void testBigInteger() throws Exception {
testBigInteger(BigInteger.valueOf(0));
testBigInteger(BigInteger.valueOf(-1));
testBigInteger(BigInteger.valueOf(1));
testBigInteger(BigInteger.valueOf(Integer.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Integer.MAX_VALUE));
testBigInteger(BigInteger.valueOf(Long.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Long.MAX_VALUE));
BigInteger max = BigInteger.valueOf(Long.MAX_VALUE).setBit(63);
testBigInteger(max);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testBigInteger( max.subtract(BigInteger.valueOf( Math.abs(rand.nextLong()) )) );
}
public void testBigInteger(BigInteger val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackBigInteger());
}
@Test
@@ -46,13 +91,8 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
float f = upk.unpackFloat();
if(Float.isNaN(val)) {
assertTrue(Float.isNaN(f));
} else {
assertEquals(val, f, 10e-10);
}
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackFloat(), 10e-10);
}
@Test
@@ -74,13 +114,8 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
double f = upk.unpackDouble();
if(Double.isNaN(val)) {
assertTrue(Double.isNaN(f));
} else {
assertEquals(val, f, 10e-10);
}
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackDouble(), 10e-10);
}
@Test
@@ -88,8 +123,8 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).packNil();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
assertEquals(null, upk.unpackNull());
Unpacker pac = new Unpacker(in);
assertEquals(null, pac.unpackNull());
}
@Test
@@ -101,8 +136,8 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
assertEquals(val, upk.unpackBoolean());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackBoolean());
}
@Test
@@ -111,6 +146,7 @@ public class TestDirectConversion {
testString("a");
testString("ab");
testString("abc");
// small size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
@@ -119,6 +155,7 @@ public class TestDirectConversion {
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// medium size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
@@ -127,6 +164,7 @@ public class TestDirectConversion {
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// large size string
for (int i = 0; i < 10; i++) {
StringBuilder sb = new StringBuilder();
@@ -140,9 +178,102 @@ public class TestDirectConversion {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
assertEquals(val, upk.unpackString());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackString());
}
// FIXME container types
@Test
public void testArray() throws Exception {
List<Integer> emptyList = new ArrayList<Integer>();
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyList);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackArray();
assertEquals(0, ulen);
}
for (int i = 0; i < 1000; i++) {
List<Integer> l = new ArrayList<Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(l);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackArray();
assertEquals(len, ulen);
for (int j = 0; j < len; j++) {
assertEquals(l.get(j).intValue(), pac.unpackInt());
}
}
for (int i = 0; i < 1000; i++) {
List<String> l = new ArrayList<String>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(Integer.toString(j));
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(l);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackArray();
assertEquals(len, ulen);
for (int j = 0; j < len; j++) {
assertEquals(l.get(j), pac.unpackString());
}
}
}
@Test
public void testMap() throws Exception {
Map<Integer, Integer> emptyMap = new HashMap<Integer, Integer>();
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyMap);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackMap();
assertEquals(0, ulen);
}
for (int i = 0; i < 1000; i++) {
Map<Integer, Integer> m = new HashMap<Integer, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(j, j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(m);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackMap();
assertEquals(len, ulen);
for (int j = 0; j < len; j++) {
Integer val = m.get(pac.unpackInt());
assertNotNull(val);
assertEquals(val.intValue(), pac.unpackInt());
}
}
for (int i = 0; i < 1000; i++) {
Map<String, Integer> m = new HashMap<String, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(Integer.toString(j), j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(m);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
int ulen = pac.unpackMap();
assertEquals(len, ulen);
for (int j = 0; j < len; j++) {
Integer val = m.get(pac.unpackString());
assertNotNull(val);
assertEquals(val.intValue(), pac.unpackInt());
}
}
}
};

View File

@@ -0,0 +1,34 @@
package org.msgpack;
import org.msgpack.*;
import java.io.*;
import java.util.*;
import java.math.BigInteger;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestMessageUnpackable {
@Test
public void testImage() throws Exception {
Image src = new Image();
src.title = "msgpack";
src.uri = "http://msgpack.org/";
src.width = 2560;
src.height = 1600;
src.size = 4096000;
ByteArrayOutputStream out = new ByteArrayOutputStream();
src.messagePack(new Packer(out));
Image dst = new Image();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
dst.messageUnpack(pac);
assertEquals(src, dst);
}
}

View File

@@ -0,0 +1,96 @@
package org.msgpack;
import org.msgpack.*;
import org.msgpack.object.*;
import java.math.BigInteger;
import java.util.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestObjectEquals {
@Test
public void testInt() throws Exception {
testInt(0);
testInt(-1);
testInt(1);
testInt(Integer.MIN_VALUE);
testInt(Integer.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testInt(rand.nextInt());
}
public void testInt(int val) throws Exception {
MessagePackObject objInt = IntegerType.create(val);
MessagePackObject objLong = IntegerType.create((long)val);
MessagePackObject objBigInt = IntegerType.create(BigInteger.valueOf((long)val));
assertTrue(objInt.equals(objInt));
assertTrue(objInt.equals(objLong));
assertTrue(objInt.equals(objBigInt));
assertTrue(objLong.equals(objInt));
assertTrue(objLong.equals(objLong));
assertTrue(objLong.equals(objBigInt));
assertTrue(objBigInt.equals(objInt));
assertTrue(objBigInt.equals(objLong));
assertTrue(objBigInt.equals(objBigInt));
}
@Test
public void testLong() throws Exception {
testLong(0);
testLong(-1);
testLong(1);
testLong(Integer.MIN_VALUE);
testLong(Integer.MAX_VALUE);
testLong(Long.MIN_VALUE);
testLong(Long.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testLong(rand.nextLong());
}
public void testLong(long val) throws Exception {
MessagePackObject objInt = IntegerType.create((int)val);
MessagePackObject objLong = IntegerType.create(val);
MessagePackObject objBigInt = IntegerType.create(BigInteger.valueOf(val));
if(val > (long)Integer.MAX_VALUE || val < (long)Integer.MIN_VALUE) {
assertTrue(objInt.equals(objInt));
assertFalse(objInt.equals(objLong));
assertFalse(objInt.equals(objBigInt));
assertFalse(objLong.equals(objInt));
assertTrue(objLong.equals(objLong));
assertTrue(objLong.equals(objBigInt));
assertFalse(objBigInt.equals(objInt));
assertTrue(objBigInt.equals(objLong));
assertTrue(objBigInt.equals(objBigInt));
} else {
assertTrue(objInt.equals(objInt));
assertTrue(objInt.equals(objLong));
assertTrue(objInt.equals(objBigInt));
assertTrue(objLong.equals(objInt));
assertTrue(objLong.equals(objLong));
assertTrue(objLong.equals(objBigInt));
assertTrue(objBigInt.equals(objInt));
assertTrue(objBigInt.equals(objLong));
assertTrue(objBigInt.equals(objBigInt));
}
}
@Test
public void testNil() throws Exception {
assertTrue(NilType.create().equals(NilType.create()));
assertFalse(NilType.create().equals(IntegerType.create(0)));
assertFalse(NilType.create().equals(BooleanType.create(false)));
}
@Test
public void testString() throws Exception {
testString("");
testString("a");
testString("ab");
testString("abc");
}
public void testString(String str) throws Exception {
assertTrue(RawType.create(str).equals(RawType.create(str)));
}
}

View File

@@ -3,22 +3,18 @@ package org.msgpack;
import org.msgpack.*;
import java.io.*;
import java.util.*;
import java.math.BigInteger;
import org.junit.Test;
import static org.junit.Assert.*;
public class TestPackUnpack {
protected Object unpackOne(ByteArrayOutputStream out) {
return unpackOne(out, null);
}
protected Object unpackOne(ByteArrayOutputStream out, Schema schema) {
public MessagePackObject unpackOne(ByteArrayOutputStream out) {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
if (schema != null)
upk = upk.useSchema(schema);
Iterator<Object> it = upk.iterator();
Unpacker pac = new Unpacker(in);
Iterator<MessagePackObject> it = pac.iterator();
assertEquals(true, it.hasNext());
Object obj = it.next();
MessagePackObject obj = it.next();
assertEquals(false, it.hasNext());
return obj;
}
@@ -37,19 +33,50 @@ public class TestPackUnpack {
public void testInt(int val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Byte)
assertEquals(val, ((Byte)obj).intValue());
else if (obj instanceof Integer)
assertEquals(val, ((Integer)obj).intValue());
else if (obj instanceof Short)
assertEquals(val, ((Short)obj).intValue());
else if (obj instanceof Long)
assertEquals(val, ((Long)obj).intValue());
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asInt());
}
@Test
public void testLong() throws Exception {
testLong(0);
testLong(-1);
testLong(1);
testLong(Integer.MIN_VALUE);
testLong(Integer.MAX_VALUE);
testLong(Long.MIN_VALUE);
testLong(Long.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testLong(rand.nextLong());
}
public void testLong(long val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asLong());
}
@Test
public void testBigInteger() throws Exception {
testBigInteger(BigInteger.valueOf(0));
testBigInteger(BigInteger.valueOf(-1));
testBigInteger(BigInteger.valueOf(1));
testBigInteger(BigInteger.valueOf(Integer.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Integer.MAX_VALUE));
testBigInteger(BigInteger.valueOf(Long.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Long.MAX_VALUE));
BigInteger max = BigInteger.valueOf(Long.MAX_VALUE).setBit(63);
testBigInteger(max);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testBigInteger( max.subtract(BigInteger.valueOf( Math.abs(rand.nextLong()) )) );
}
public void testBigInteger(BigInteger val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asBigInteger());
}
@Test
@@ -70,13 +97,9 @@ public class TestPackUnpack {
public void testFloat(float val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Float)
assertEquals(val, ((Float)obj).floatValue(), 10e-10);
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
MessagePackObject obj = unpackOne(out);
float f = obj.asFloat();
assertEquals(val, f, 10e-10);
}
@Test
@@ -97,21 +120,17 @@ public class TestPackUnpack {
public void testDouble(double val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Double)
assertEquals(val, ((Double)obj).doubleValue(), 10e-10);
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
MessagePackObject obj = unpackOne(out);
double f = obj.asDouble();
assertEquals(val, f, 10e-10);
}
@Test
public void testNil() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).packNil();
Object obj = unpackOne(out);
assertEquals(null, obj);
MessagePackObject obj = unpackOne(out);
assertTrue(obj.isNil());
}
@Test
@@ -122,13 +141,8 @@ public class TestPackUnpack {
public void testBoolean(boolean val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Boolean)
assertEquals(val, ((Boolean)obj).booleanValue());
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asBoolean());
}
@Test
@@ -137,6 +151,7 @@ public class TestPackUnpack {
testString("a");
testString("ab");
testString("abc");
// small size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
@@ -145,6 +160,7 @@ public class TestPackUnpack {
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// medium size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
@@ -153,6 +169,7 @@ public class TestPackUnpack {
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// large size string
for (int i = 0; i < 10; i++) {
StringBuilder sb = new StringBuilder();
@@ -165,83 +182,94 @@ public class TestPackUnpack {
public void testString(String val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof byte[])
assertEquals(val, new String((byte[])obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asString());
}
@Test
public void testArray() throws Exception {
List<Integer> emptyList = new ArrayList<Integer>();
testArray(emptyList, Schema.parse("(array int)"));
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyList);
MessagePackObject obj = unpackOne(out);
assertEquals(emptyList, obj.asList());
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(array int)");
List<Integer> l = new ArrayList<Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(j);
testArray(l, schema);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(l);
MessagePackObject obj = unpackOne(out);
List<MessagePackObject> list = obj.asList();
assertEquals(l.size(), list.size());
for (int j = 0; j < len; j++) {
assertEquals(l.get(j).intValue(), list.get(j).asInt());
}
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(array string)");
List<String> l = new ArrayList<String>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(Integer.toString(j));
testArray(l, schema);
}
}
public void testArray(List val, Schema schema) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out, schema);
if (obj instanceof List)
assertTrue(val.equals(obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
new Packer(out).pack(l);
MessagePackObject obj = unpackOne(out);
List<MessagePackObject> list = obj.asList();
assertEquals(l.size(), list.size());
for (int j = 0; j < len; j++) {
assertEquals(l.get(j), list.get(j).asString());
}
}
}
@Test
public void testMap() throws Exception {
Map<Integer, Integer> emptyMap = new HashMap<Integer, Integer>();
testMap(emptyMap, Schema.parse("(map int int)"));
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyMap);
MessagePackObject obj = unpackOne(out);
assertEquals(emptyMap, obj.asMap());
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(map int int)");
Map<Integer, Integer> m = new HashMap<Integer, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(j, j);
testMap(m, schema);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(m);
MessagePackObject obj = unpackOne(out);
Map<MessagePackObject, MessagePackObject> map = obj.asMap();
assertEquals(m.size(), map.size());
for (Map.Entry<MessagePackObject, MessagePackObject> pair : map.entrySet()) {
Integer val = m.get(pair.getKey().asInt());
assertNotNull(val);
assertEquals(val.intValue(), pair.getValue().asInt());
}
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(map string int)");
Map<String, Integer> m = new HashMap<String, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(Integer.toString(j), j);
testMap(m, schema);
}
}
public void testMap(Map val, Schema schema) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out, schema);
if (obj instanceof Map)
assertTrue(val.equals(obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
new Packer(out).pack(m);
MessagePackObject obj = unpackOne(out);
Map<MessagePackObject, MessagePackObject> map = obj.asMap();
assertEquals(m.size(), map.size());
for (Map.Entry<MessagePackObject, MessagePackObject> pair : map.entrySet()) {
Integer val = m.get(pair.getKey().asString());
assertNotNull(val);
assertEquals(val.intValue(), pair.getValue().asInt());
}
}
}
};

View File

@@ -0,0 +1 @@
[false,true,null,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,127,127,255,65535,4294967295,-32,-32,-128,-32768,-2147483648,0.0,-0.0,1.0,-1.0,"a","a","a","","","",[0],[0],[0],[],[],[],{},{},{},{"a":97},{"a":97},{"a":97},[[]],[["a"]]]

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,7 @@
0.13
- clearly specify requires_c99(), because msgpack C header requires C99.
0.12
- PERL_NO_GET_CONTEXT makes horrible dTHXs. remove it.

View File

@@ -1,4 +1,6 @@
use inc::Module::Install;
use Config;
name 'Data-MessagePack';
all_from 'lib/Data/MessagePack.pm';
readme_from('lib/Data/MessagePack.pm');
@@ -11,6 +13,8 @@ tests 't/*.t';
recursive_author_tests('xt');
use_ppport 3.19;
requires_c99(); # msgpack C library requires C99.
clean_files qw{
*.stackdump
*.gcov *.gcda *.gcno

View File

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