mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-04-23 08:52:32 +02:00
Merge branch 'master' of git://git.sourceforge.jp/gitroot/msgpack/msgpack
This commit is contained in:
commit
519716bbe4
@ -8,5 +8,6 @@ nobase_include_HEADERS = \
|
|||||||
msgpack/pack_define.h \
|
msgpack/pack_define.h \
|
||||||
msgpack/pack_template.h \
|
msgpack/pack_template.h \
|
||||||
msgpack/unpack_define.h \
|
msgpack/unpack_define.h \
|
||||||
msgpack/unpack_template.h
|
msgpack/unpack_template.h \
|
||||||
|
msgpack/sysdep.h
|
||||||
|
|
||||||
|
10
c/object.c
10
c/object.c
@ -18,7 +18,17 @@
|
|||||||
#include "msgpack/object.h"
|
#include "msgpack/object.h"
|
||||||
#include "msgpack/pack.h"
|
#include "msgpack/pack.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#else
|
||||||
|
#ifndef PRIu64
|
||||||
|
#define PRIu64 "I64u"
|
||||||
|
#endif
|
||||||
|
#ifndef PRIi64
|
||||||
|
#define PRIi64 "I64d"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
|
int msgpack_pack_object(msgpack_packer* pk, msgpack_object d)
|
||||||
|
@ -19,9 +19,7 @@
|
|||||||
#define MSGPACK_OBJECT_H__
|
#define MSGPACK_OBJECT_H__
|
||||||
|
|
||||||
#include "msgpack/zone.h"
|
#include "msgpack/zone.h"
|
||||||
#include <stdint.h>
|
#include "msgpack/sysdep.h"
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
4
c/pack.h
4
c/pack.h
@ -18,11 +18,9 @@
|
|||||||
#ifndef MSGPACK_PACK_H__
|
#ifndef MSGPACK_PACK_H__
|
||||||
#define MSGPACK_PACK_H__
|
#define MSGPACK_PACK_H__
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "msgpack/pack_define.h"
|
#include "msgpack/pack_define.h"
|
||||||
#include "msgpack/object.h"
|
#include "msgpack/object.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
18
c/unpack.c
18
c/unpack.c
@ -101,7 +101,7 @@ static inline int template_callback_array(unpack_user* u, unsigned int n, msgpac
|
|||||||
{
|
{
|
||||||
o->type = MSGPACK_OBJECT_ARRAY;
|
o->type = MSGPACK_OBJECT_ARRAY;
|
||||||
o->via.array.size = 0;
|
o->via.array.size = 0;
|
||||||
o->via.array.ptr = msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
|
o->via.array.ptr = (msgpack_object*)msgpack_zone_malloc(u->z, n*sizeof(msgpack_object));
|
||||||
if(o->via.array.ptr == NULL) { return -1; }
|
if(o->via.array.ptr == NULL) { return -1; }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -141,31 +141,31 @@ static inline int template_callback_raw(unpack_user* u, const char* b, const cha
|
|||||||
#define CTX_CAST(m) ((template_context*)(m))
|
#define CTX_CAST(m) ((template_context*)(m))
|
||||||
#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
|
#define CTX_REFERENCED(mpac) CTX_CAST((mpac)->ctx)->user.referenced
|
||||||
|
|
||||||
|
#define COUNTER_SIZE (sizeof(_msgpack_atomic_counter_t))
|
||||||
|
|
||||||
static const size_t COUNTER_SIZE = sizeof(unsigned int);
|
|
||||||
|
|
||||||
static inline void init_count(void* buffer)
|
static inline void init_count(void* buffer)
|
||||||
{
|
{
|
||||||
*(volatile unsigned int*)buffer = 1;
|
*(volatile _msgpack_atomic_counter_t*)buffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void decl_count(void* buffer)
|
static inline void decl_count(void* buffer)
|
||||||
{
|
{
|
||||||
//if(--*(unsigned int*)buffer == 0) {
|
// atomic if(--*(_msgpack_atomic_counter_t*)buffer == 0) { free(buffer); }
|
||||||
if(__sync_sub_and_fetch((unsigned int*)buffer, 1) == 0) {
|
if(_msgpack_sync_decr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer) == 0) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void incr_count(void* buffer)
|
static inline void incr_count(void* buffer)
|
||||||
{
|
{
|
||||||
//++*(unsigned int*)buffer;
|
// atomic ++*(_msgpack_atomic_counter_t*)buffer;
|
||||||
__sync_add_and_fetch((unsigned int*)buffer, 1);
|
_msgpack_sync_incr_and_fetch((volatile _msgpack_atomic_counter_t*)buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int get_count(void* buffer)
|
static inline _msgpack_atomic_counter_t get_count(void* buffer)
|
||||||
{
|
{
|
||||||
return *(volatile unsigned int*)buffer;
|
return *(volatile _msgpack_atomic_counter_t*)buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,13 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef msgpack_unpacker_H__
|
#ifndef MSGPACK_UNPACKER_H__
|
||||||
#define msgpack_unpacker_H__
|
#define MSGPACK_UNPACKER_H__
|
||||||
|
|
||||||
#include "msgpack/zone.h"
|
#include "msgpack/zone.h"
|
||||||
#include "msgpack/object.h"
|
#include "msgpack/object.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -77,7 +77,7 @@ int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
|
|||||||
const char* buf, unsigned int len)
|
const char* buf, unsigned int len)
|
||||||
{
|
{
|
||||||
if(vbuf->tail == vbuf->end) {
|
if(vbuf->tail == vbuf->end) {
|
||||||
const size_t nused = vbuf->end - vbuf->array;
|
const size_t nused = vbuf->tail - vbuf->array;
|
||||||
const size_t nnext = nused * 2;
|
const size_t nnext = nused * 2;
|
||||||
|
|
||||||
struct iovec* nvec = (struct iovec*)realloc(
|
struct iovec* nvec = (struct iovec*)realloc(
|
||||||
@ -133,3 +133,30 @@ int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to)
|
||||||
|
{
|
||||||
|
const size_t tosize = to->tail - to->array;
|
||||||
|
if(vbuf->tail + tosize < vbuf->end) {
|
||||||
|
const size_t nused = vbuf->tail - vbuf->array;
|
||||||
|
const size_t nsize = vbuf->end - vbuf->array;
|
||||||
|
const size_t reqsize = nused + tosize;
|
||||||
|
size_t nnext = nsize * 2;
|
||||||
|
while(nnext < reqsize) {
|
||||||
|
nnext *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iovec* nvec = (struct iovec*)realloc(
|
||||||
|
vbuf->array, sizeof(struct iovec)*nnext);
|
||||||
|
if(nvec == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vbuf->array = nvec;
|
||||||
|
vbuf->end = nvec + nnext;
|
||||||
|
vbuf->tail = nvec + nused;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(vbuf->tail, vbuf->array, sizeof(struct iovec)*tosize);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,16 @@
|
|||||||
#define MSGPACK_VREFBUFFER_H__
|
#define MSGPACK_VREFBUFFER_H__
|
||||||
|
|
||||||
#include "msgpack/zone.h"
|
#include "msgpack/zone.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
#else
|
||||||
|
struct iovec {
|
||||||
|
void *iov_base;
|
||||||
|
size_t iov_len;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -67,6 +76,7 @@ int msgpack_vrefbuffer_append_copy(msgpack_vrefbuffer* vbuf,
|
|||||||
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
|
int msgpack_vrefbuffer_append_ref(msgpack_vrefbuffer* vbuf,
|
||||||
const char* buf, unsigned int len);
|
const char* buf, unsigned int len);
|
||||||
|
|
||||||
|
int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to);
|
||||||
|
|
||||||
int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
|
int msgpack_vrefbuffer_write(void* data, const char* buf, unsigned int len)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
AC_INIT(msgpack/unpack_template.h)
|
AC_INIT(msgpack/unpack_template.h)
|
||||||
AC_CONFIG_AUX_DIR(ac)
|
AC_CONFIG_AUX_DIR(ac)
|
||||||
AM_INIT_AUTOMAKE(msgpack, 0.3.8)
|
AM_INIT_AUTOMAKE(msgpack, 0.3.9)
|
||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
AC_SUBST(CFLAGS)
|
AC_SUBST(CFLAGS)
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "msgpack/object.h"
|
#include "msgpack/object.h"
|
||||||
#include "msgpack/pack.hpp"
|
#include "msgpack/pack.hpp"
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
@ -18,10 +18,9 @@
|
|||||||
#ifndef MSGPACK_PACK_HPP__
|
#ifndef MSGPACK_PACK_HPP__
|
||||||
#define MSGPACK_PACK_HPP__
|
#define MSGPACK_PACK_HPP__
|
||||||
|
|
||||||
#include <arpa/inet.h> // __BYTE_ORDER
|
#include "msgpack/pack_define.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "msgpack/pack_define.h"
|
|
||||||
|
|
||||||
namespace msgpack {
|
namespace msgpack {
|
||||||
|
|
||||||
|
@ -71,6 +71,13 @@ public:
|
|||||||
return msgpack_vrefbuffer_veclen(this);
|
return msgpack_vrefbuffer_veclen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void migrate(vrefbuffer* to)
|
||||||
|
{
|
||||||
|
if(msgpack_vrefbuffer_migrate(this, to) < 0) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef msgpack_vrefbuffer base;
|
typedef msgpack_vrefbuffer base;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "msgpack/object.hpp"
|
#include "msgpack/object.hpp"
|
||||||
#include "msgpack/zone.h"
|
#include "msgpack/zone.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
<% GENERATION_LIMIT = 15 %>
|
<% GENERATION_LIMIT = 15 %>
|
||||||
@ -38,6 +39,9 @@ public:
|
|||||||
|
|
||||||
void push_finalizer(void (*func)(void*), void* data);
|
void push_finalizer(void (*func)(void*), void* data);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void push_finalizer(std::auto_ptr<T> obj);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
<%0.upto(GENERATION_LIMIT) {|i|%>
|
<%0.upto(GENERATION_LIMIT) {|i|%>
|
||||||
@ -94,6 +98,15 @@ inline void zone::push_finalizer(void (*func)(void*), void* data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void zone::push_finalizer(std::auto_ptr<T> obj)
|
||||||
|
{
|
||||||
|
if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, obj.get())) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
obj.release();
|
||||||
|
}
|
||||||
|
|
||||||
inline void zone::clear()
|
inline void zone::clear()
|
||||||
{
|
{
|
||||||
msgpack_zone_clear(this);
|
msgpack_zone_clear(this);
|
||||||
|
37
java-plan1/MessagePack.java
Normal file
37
java-plan1/MessagePack.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessagePack {
|
||||||
|
|
||||||
|
static public Object unpack(InputStream source)
|
||||||
|
{
|
||||||
|
// FIXME not implemented yet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public Object unpack(byte[] source, int len) throws IOException
|
||||||
|
{
|
||||||
|
// FIXME not implemented yet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public Object unpack(ByteBuffer source) throws IOException
|
||||||
|
{
|
||||||
|
// FIXME not implemented yet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public Object unpack(ByteBuffer[] source) throws IOException
|
||||||
|
{
|
||||||
|
// FIXME not implemented yet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public interface MessagePackable {
|
||||||
|
public void toMessagePack(Packer pk);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
266
java-plan1/Packer.java
Normal file
266
java-plan1/Packer.java
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class Packer {
|
||||||
|
protected byte[] castBytes = new byte[9];
|
||||||
|
protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
public Packer(OutputStream out)
|
||||||
|
{
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packByte(byte d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBytes[1] = d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
out.write(d);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packShort(short d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packInt(int d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<15)) {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else if(d < (1<<16)) {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packLong(long d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1L<<5)) {
|
||||||
|
if(d < -(1L<<15)) {
|
||||||
|
if(d < -(1L<<31)) {
|
||||||
|
// signed 64
|
||||||
|
castBytes[0] = (byte)0xd3;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
} else {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<16)) {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
//System.out.println("pack uint 16 "+(short)d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<32)) {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else {
|
||||||
|
// unsigned 64
|
||||||
|
castBytes[0] = (byte)0xcf;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFloat(float d) throws IOException
|
||||||
|
{
|
||||||
|
castBytes[0] = (byte)0xca;
|
||||||
|
castBuffer.putFloat(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packDouble(double d) throws IOException
|
||||||
|
{
|
||||||
|
castBytes[0] = (byte)0xcb;
|
||||||
|
castBuffer.putDouble(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packNil() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packTrue() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc3);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFalse() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packArray(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x90 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xdc;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdd;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packMap(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x80 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xde;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdf;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRaw(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 32) {
|
||||||
|
final int d = 0xa0 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xda;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdb;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b) throws IOException
|
||||||
|
{
|
||||||
|
out.write(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b, int off, int length) throws IOException
|
||||||
|
{
|
||||||
|
out.write(b, off, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public Packer pack(Object o) throws IOException
|
||||||
|
}
|
||||||
|
|
401
java-plan1/Unpacker.java
Normal file
401
java-plan1/Unpacker.java
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class Unpacker {
|
||||||
|
protected static final int CS_HEADER = 0x00;
|
||||||
|
protected static final int CS_FLOAT = 0x0a;
|
||||||
|
protected static final int CS_DOUBLE = 0x0b;
|
||||||
|
protected static final int CS_UINT_8 = 0x0c;
|
||||||
|
protected static final int CS_UINT_16 = 0x0d;
|
||||||
|
protected static final int CS_UINT_32 = 0x0e;
|
||||||
|
protected static final int CS_UINT_64 = 0x0f;
|
||||||
|
protected static final int CS_INT_8 = 0x10;
|
||||||
|
protected static final int CS_INT_16 = 0x11;
|
||||||
|
protected static final int CS_INT_32 = 0x12;
|
||||||
|
protected static final int CS_INT_64 = 0x13;
|
||||||
|
protected static final int CS_RAW_16 = 0x1a;
|
||||||
|
protected static final int CS_RAW_32 = 0x1b;
|
||||||
|
protected static final int CS_ARRAY_16 = 0x1c;
|
||||||
|
protected static final int CS_ARRAY_32 = 0x1d;
|
||||||
|
protected static final int CS_MAP_16 = 0x1e;
|
||||||
|
protected static final int CS_MAP_32 = 0x1f;
|
||||||
|
protected static final int ACS_RAW_VALUE = 0x20;
|
||||||
|
protected static final int CT_ARRAY_ITEM = 0x00;
|
||||||
|
protected static final int CT_MAP_KEY = 0x01;
|
||||||
|
protected static final int CT_MAP_VALUE = 0x02;
|
||||||
|
|
||||||
|
protected static final int MAX_STACK_SIZE = 16;
|
||||||
|
|
||||||
|
protected int cs = CS_HEADER;
|
||||||
|
protected int trail = 0;
|
||||||
|
protected int top = -1;
|
||||||
|
protected boolean finished = false;
|
||||||
|
protected int[] stack_ct = new int[MAX_STACK_SIZE];
|
||||||
|
protected int[] stack_count = new int[MAX_STACK_SIZE];
|
||||||
|
protected Object[] stack_obj = new Object[MAX_STACK_SIZE];
|
||||||
|
protected Object[] stack_map_key = new Object[MAX_STACK_SIZE];
|
||||||
|
//protected Object user;
|
||||||
|
protected ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return stack_obj[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
for(int i=0; i <= top; ++top) {
|
||||||
|
stack_ct[top] = 0;
|
||||||
|
stack_count[top] = 0;
|
||||||
|
stack_obj[top] = null;
|
||||||
|
stack_map_key[top] = null;
|
||||||
|
}
|
||||||
|
cs = CS_HEADER;
|
||||||
|
trail = 0;
|
||||||
|
top = -1;
|
||||||
|
finished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public int execute(byte[] src, int off, int length) throws IOException
|
||||||
|
{
|
||||||
|
if(off >= length) { return off; }
|
||||||
|
|
||||||
|
int limit = length;
|
||||||
|
int i = off;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
Object obj = null;
|
||||||
|
|
||||||
|
_out: do {
|
||||||
|
_header_again: {
|
||||||
|
//System.out.println("while i:"+i+" limit:"+limit);
|
||||||
|
|
||||||
|
int b = src[i];
|
||||||
|
|
||||||
|
_push: {
|
||||||
|
_fixed_trail_again:
|
||||||
|
if(cs == CS_HEADER) {
|
||||||
|
|
||||||
|
if((b & 0x80) == 0) { // Positive Fixnum
|
||||||
|
//System.out.println("positive fixnum "+b);
|
||||||
|
obj = b;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xe0) { // Negative Fixnum
|
||||||
|
//System.out.println("negative fixnum "+b);
|
||||||
|
obj = b;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||||
|
trail = b & 0x1f;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = new byte[0];
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x90) { // FixArray
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
count = b & 0x0f;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new ArrayList(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixarray count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x80) { // FixMap
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
count = b & 0x0f;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new HashMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(b & 0xff) { // FIXME
|
||||||
|
case 0xc0: // nil
|
||||||
|
obj = null;
|
||||||
|
break _push;
|
||||||
|
case 0xc2: // false
|
||||||
|
obj = false;
|
||||||
|
break _push;
|
||||||
|
case 0xc3: // true
|
||||||
|
obj = true;
|
||||||
|
break _push;
|
||||||
|
case 0xca: // float
|
||||||
|
case 0xcb: // double
|
||||||
|
case 0xcc: // unsigned int 8
|
||||||
|
case 0xcd: // unsigned int 16
|
||||||
|
case 0xce: // unsigned int 32
|
||||||
|
case 0xcf: // unsigned int 64
|
||||||
|
case 0xd0: // signed int 8
|
||||||
|
case 0xd1: // signed int 16
|
||||||
|
case 0xd2: // signed int 32
|
||||||
|
case 0xd3: // signed int 64
|
||||||
|
trail = 1 << (b & 0x03);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("a trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case 0xda: // raw 16
|
||||||
|
case 0xdb: // raw 32
|
||||||
|
case 0xdc: // array 16
|
||||||
|
case 0xdd: // array 32
|
||||||
|
case 0xde: // map 16
|
||||||
|
case 0xdf: // map 32
|
||||||
|
trail = 2 << (b & 0x01);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("b trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
default:
|
||||||
|
//System.out.println("unknown b "+(b&0xff));
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
|
||||||
|
do {
|
||||||
|
_fixed_trail_again: {
|
||||||
|
|
||||||
|
if(limit - i <= trail) { break _out; }
|
||||||
|
int n = i + 1;
|
||||||
|
i += trail;
|
||||||
|
|
||||||
|
switch(cs) {
|
||||||
|
case CS_FLOAT:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = castBuffer.getFloat(0);
|
||||||
|
//System.out.println("float "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_DOUBLE:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
obj = castBuffer.getDouble(0);
|
||||||
|
//System.out.println("double "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_8:
|
||||||
|
//System.out.println(n);
|
||||||
|
//System.out.println(src[n]);
|
||||||
|
//System.out.println(src[n+1]);
|
||||||
|
//System.out.println(src[n-1]);
|
||||||
|
obj = ((int)src[n]) & 0xff;
|
||||||
|
//System.out.println("uint8 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_16:
|
||||||
|
//System.out.println(src[n]);
|
||||||
|
//System.out.println(src[n+1]);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
//System.out.println("uint 16 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
{
|
||||||
|
// FIXME always long?
|
||||||
|
int o = castBuffer.getInt(0);
|
||||||
|
if(o < 0) {
|
||||||
|
obj = ((long)o) & 0xffffffffL;
|
||||||
|
} else {
|
||||||
|
obj = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("uint 32 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
{
|
||||||
|
// FIXME always BigInteger?
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(o < 0) {
|
||||||
|
obj = BigInteger.valueOf(o & 0x7fffffffL).setBit(31);
|
||||||
|
} else {
|
||||||
|
obj = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IOException("uint 64 is not supported");
|
||||||
|
case CS_INT_8:
|
||||||
|
obj = (int)src[n];
|
||||||
|
break _push;
|
||||||
|
case CS_INT_16:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = (int)castBuffer.getShort(0);
|
||||||
|
break _push;
|
||||||
|
case CS_INT_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = (int)castBuffer.getInt(0);
|
||||||
|
break _push;
|
||||||
|
case CS_INT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
{
|
||||||
|
// FIXME always long?
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(o <= 0x7fffffffL && o > -0x80000000L) {
|
||||||
|
obj = (int)o;
|
||||||
|
} else {
|
||||||
|
obj = o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//System.out.println("long "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_RAW_16:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
trail = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = new byte[0];
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case CS_RAW_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
trail = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = new byte[0];
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
case ACS_RAW_VALUE:
|
||||||
|
obj = ByteBuffer.wrap(src, n, trail); // FIXME プール? コピー
|
||||||
|
break _push;
|
||||||
|
case CS_ARRAY_16:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new ArrayList(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
break _header_again;
|
||||||
|
case CS_ARRAY_32:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new ArrayList(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
break _header_again;
|
||||||
|
case CS_MAP_16:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new HashMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
case CS_MAP_32:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = new HashMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
default:
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
} while(true);
|
||||||
|
} // _push
|
||||||
|
|
||||||
|
do {
|
||||||
|
_push: {
|
||||||
|
//System.out.println("push top:"+top);
|
||||||
|
if(top == -1) {
|
||||||
|
stack_obj[0] = obj;
|
||||||
|
finished = true;
|
||||||
|
break _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(stack_ct[top]) {
|
||||||
|
case CT_ARRAY_ITEM:
|
||||||
|
//System.out.println("array item "+obj);
|
||||||
|
((ArrayList)(stack_obj[top])).add(obj);
|
||||||
|
if(--stack_count[top] == 0) {
|
||||||
|
obj = stack_obj[top];
|
||||||
|
stack_obj[top] = null;
|
||||||
|
--top;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
break _header_again;
|
||||||
|
case CT_MAP_KEY:
|
||||||
|
//System.out.println("map key:"+top+" "+obj);
|
||||||
|
stack_map_key[top] = obj;
|
||||||
|
stack_ct[top] = CT_MAP_VALUE;
|
||||||
|
break _header_again;
|
||||||
|
case CT_MAP_VALUE:
|
||||||
|
//System.out.println("map value:"+top+" "+obj);
|
||||||
|
((HashMap)(stack_obj[top])).put(stack_map_key[top], obj);
|
||||||
|
if(--stack_count[top] == 0) {
|
||||||
|
obj = stack_obj[top];
|
||||||
|
stack_map_key[top] = null;
|
||||||
|
stack_obj[top] = null;
|
||||||
|
--top;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
break _header_again;
|
||||||
|
default:
|
||||||
|
throw new IOException("parse error");
|
||||||
|
}
|
||||||
|
} // _push
|
||||||
|
} while(true);
|
||||||
|
|
||||||
|
} // _header_again
|
||||||
|
cs = CS_HEADER;
|
||||||
|
++i;
|
||||||
|
} while(i < limit); // _out
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
3
java-plan1/run.sh
Executable file
3
java-plan1/run.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
javac MessagePack.java Packer.java Unpacker.java test.java
|
||||||
|
java test
|
94
java-plan1/test.java
Normal file
94
java-plan1/test.java
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class OpenByteArrayOutputStream extends ByteArrayOutputStream {
|
||||||
|
int getCount() { return count; }
|
||||||
|
byte[] getBuffer() { return buf; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class test {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException
|
||||||
|
{
|
||||||
|
testSimple();
|
||||||
|
testStreaming();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void testSimple() throws IOException
|
||||||
|
{
|
||||||
|
OpenByteArrayOutputStream out = new OpenByteArrayOutputStream();
|
||||||
|
|
||||||
|
Packer pk = new Packer(out);
|
||||||
|
pk.packArray(3)
|
||||||
|
.packInt(1)
|
||||||
|
.packByte((byte)2)
|
||||||
|
.packDouble(0.3);
|
||||||
|
|
||||||
|
Unpacker pac = new Unpacker();
|
||||||
|
int nlen = pac.execute(out.getBuffer(), 0, out.getCount());
|
||||||
|
|
||||||
|
if(pac.isFinished()) {
|
||||||
|
System.out.println("testSimple: "+pac.getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void testStreaming() throws IOException
|
||||||
|
{
|
||||||
|
OpenByteArrayOutputStream out = new OpenByteArrayOutputStream();
|
||||||
|
|
||||||
|
////
|
||||||
|
// sender
|
||||||
|
//
|
||||||
|
// initialize the streaming serializer
|
||||||
|
Packer pk = new Packer(out);
|
||||||
|
|
||||||
|
// serialize 2 objects
|
||||||
|
pk.packArray(3)
|
||||||
|
.packInt(0)
|
||||||
|
.packByte((byte)1)
|
||||||
|
.packDouble(0.2);
|
||||||
|
pk.packArray(3)
|
||||||
|
.packInt(3)
|
||||||
|
.packByte((byte)4)
|
||||||
|
.packDouble(0.5);
|
||||||
|
|
||||||
|
// send it through the network
|
||||||
|
InputStream sock = new ByteArrayInputStream(out.getBuffer(), 0, out.getCount());
|
||||||
|
|
||||||
|
|
||||||
|
////
|
||||||
|
// receiver
|
||||||
|
//
|
||||||
|
// initialize the streaming deserializer
|
||||||
|
Unpacker pac = new Unpacker();
|
||||||
|
int parsed = 0;
|
||||||
|
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int buflen = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
// receive data from the network
|
||||||
|
int c = sock.read();
|
||||||
|
if(c < 0) { return; }
|
||||||
|
|
||||||
|
buf[buflen++] = (byte)c;
|
||||||
|
|
||||||
|
// deserialize
|
||||||
|
parsed = pac.execute(buf, parsed, buflen);
|
||||||
|
if(pac.isFinished()) {
|
||||||
|
// get an object
|
||||||
|
Object msg = pac.getData();
|
||||||
|
System.out.println("testStreaming: "+msg);
|
||||||
|
|
||||||
|
// reset the streaming deserializer
|
||||||
|
pac.reset();
|
||||||
|
buflen = 0;
|
||||||
|
parsed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
java-plan2/build.xml
Normal file
15
java-plan2/build.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<project name="MessagePack for Java">
|
||||||
|
<target name="prepare">
|
||||||
|
<mkdir dir="build" />
|
||||||
|
<mkdir dir="dist" />
|
||||||
|
</target>
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="build"/>
|
||||||
|
<delete dir="dist"/>
|
||||||
|
</target>
|
||||||
|
<target name="compile" depends="prepare">
|
||||||
|
<javac srcdir="src" destdir="build" classpath="lib" source="1.5" target="1.5">
|
||||||
|
<classpath><fileset dir="lib" /> </classpath>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
</project>
|
25
java-plan2/src/org/msgpack/GenericArray.java
Normal file
25
java-plan2/src/org/msgpack/GenericArray.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class GenericArray extends GenericObject {
|
||||||
|
private ArrayList<GenericObject> array;
|
||||||
|
|
||||||
|
public GenericArray(int length)
|
||||||
|
{
|
||||||
|
this.array = new ArrayList<GenericObject>(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(GenericObject element)
|
||||||
|
{
|
||||||
|
array.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GenericObject> asArray()
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
java-plan2/src/org/msgpack/GenericBoolean.java
Normal file
17
java-plan2/src/org/msgpack/GenericBoolean.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class GenericBoolean extends GenericObject {
|
||||||
|
boolean value;
|
||||||
|
|
||||||
|
public GenericBoolean(boolean value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean asBoolean()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
java-plan2/src/org/msgpack/GenericLong.java
Normal file
17
java-plan2/src/org/msgpack/GenericLong.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class GenericLong extends GenericObject {
|
||||||
|
long value;
|
||||||
|
|
||||||
|
public GenericLong(long value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long asLong()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
java-plan2/src/org/msgpack/GenericMap.java
Normal file
25
java-plan2/src/org/msgpack/GenericMap.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class GenericMap extends GenericObject {
|
||||||
|
private HashMap<GenericObject,GenericObject> map;
|
||||||
|
|
||||||
|
public GenericMap(int length)
|
||||||
|
{
|
||||||
|
this.map = new HashMap<GenericObject,GenericObject>(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(GenericObject key, GenericObject value)
|
||||||
|
{
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<GenericObject,GenericObject> asMap()
|
||||||
|
{
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
52
java-plan2/src/org/msgpack/GenericObject.java
Normal file
52
java-plan2/src/org/msgpack/GenericObject.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class GenericObject {
|
||||||
|
public boolean asBoolean()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte asByte()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public short asShort()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int asInt()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public long asLong()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String asString()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] asBytes()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GenericObject> asArray()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<GenericObject,GenericObject> asMap()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
59
java-plan2/src/org/msgpack/GenericRaw.java
Normal file
59
java-plan2/src/org/msgpack/GenericRaw.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public class GenericRaw extends GenericObject {
|
||||||
|
byte[] bytes;
|
||||||
|
String string;
|
||||||
|
|
||||||
|
public GenericRaw()
|
||||||
|
{
|
||||||
|
this.bytes = new byte[0];
|
||||||
|
this.string = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericRaw(byte[] bytes)
|
||||||
|
{
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.string = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericRaw(String string)
|
||||||
|
{
|
||||||
|
this.bytes = null;
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setString(String string)
|
||||||
|
{
|
||||||
|
this.string = string;
|
||||||
|
this.bytes = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.string = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized String asString()
|
||||||
|
{
|
||||||
|
if(string == null) {
|
||||||
|
return string = new String(bytes, UTF8_CHARSET);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized byte[] asBytes()
|
||||||
|
{
|
||||||
|
if(bytes == null) {
|
||||||
|
return bytes = string.getBytes(UTF8_CHARSET);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
55
java-plan2/src/org/msgpack/GenericRawRef.java
Normal file
55
java-plan2/src/org/msgpack/GenericRawRef.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
public class GenericRawRef extends GenericRaw {
|
||||||
|
int offset;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
public GenericRawRef(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.offset = offset;
|
||||||
|
this.length = length;
|
||||||
|
this.string = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericRawRef(String string)
|
||||||
|
{
|
||||||
|
this.bytes = null;
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setString(String string)
|
||||||
|
{
|
||||||
|
this.string = string;
|
||||||
|
this.bytes = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void setBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
this.bytes = bytes;
|
||||||
|
this.string = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized String asString()
|
||||||
|
{
|
||||||
|
if(string == null) {
|
||||||
|
return string = new String(bytes, UTF8_CHARSET);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized byte[] asBytes()
|
||||||
|
{
|
||||||
|
if(bytes == null) {
|
||||||
|
return bytes = string.getBytes(UTF8_CHARSET);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
java-plan2/src/org/msgpack/GenericShort.java
Normal file
29
java-plan2/src/org/msgpack/GenericShort.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class GenericShort extends GenericObject {
|
||||||
|
short value;
|
||||||
|
|
||||||
|
public GenericShort(short value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short asShort()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int asInt()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long asLong()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
7
java-plan2/src/org/msgpack/MessageConvertable.java
Normal file
7
java-plan2/src/org/msgpack/MessageConvertable.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public interface MessageConvertable
|
||||||
|
{
|
||||||
|
public void messageConvert(GenericObject obj);
|
||||||
|
}
|
||||||
|
|
7
java-plan2/src/org/msgpack/MessageMergeable.java
Normal file
7
java-plan2/src/org/msgpack/MessageMergeable.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public interface MessageMergeable {
|
||||||
|
public void setField(int index, Object value);
|
||||||
|
public Object getField(int index);
|
||||||
|
}
|
||||||
|
|
10
java-plan2/src/org/msgpack/MessagePackException.java
Normal file
10
java-plan2/src/org/msgpack/MessagePackException.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class MessagePackException extends RuntimeException
|
||||||
|
{
|
||||||
|
public MessagePackException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
java-plan2/src/org/msgpack/MessagePackable.java
Normal file
9
java-plan2/src/org/msgpack/MessagePackable.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface MessagePackable
|
||||||
|
{
|
||||||
|
public void messagePack(Packer pk) throws IOException;
|
||||||
|
}
|
||||||
|
|
332
java-plan2/src/org/msgpack/Packer.java
Normal file
332
java-plan2/src/org/msgpack/Packer.java
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Packer {
|
||||||
|
protected byte[] castBytes = new byte[9];
|
||||||
|
protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
public Packer(OutputStream out)
|
||||||
|
{
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packByte(byte d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBytes[1] = d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
out.write(d);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packShort(short d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packInt(int d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<15)) {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else if(d < (1<<16)) {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packLong(long d) throws IOException
|
||||||
|
{
|
||||||
|
if(d < -(1L<<5)) {
|
||||||
|
if(d < -(1L<<15)) {
|
||||||
|
if(d < -(1L<<31)) {
|
||||||
|
// signed 64
|
||||||
|
castBytes[0] = (byte)0xd3;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
} else {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<16)) {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
//System.out.println("pack uint 16 "+(short)d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<32)) {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else {
|
||||||
|
// unsigned 64
|
||||||
|
castBytes[0] = (byte)0xcf;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFloat(float d) throws IOException
|
||||||
|
{
|
||||||
|
castBytes[0] = (byte)0xca;
|
||||||
|
castBuffer.putFloat(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packDouble(double d) throws IOException
|
||||||
|
{
|
||||||
|
castBytes[0] = (byte)0xcb;
|
||||||
|
castBuffer.putDouble(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packNil() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packTrue() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc3);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFalse() throws IOException
|
||||||
|
{
|
||||||
|
out.write((byte)0xc2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packArray(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x90 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xdc;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdd;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packMap(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x80 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xde;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdf;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRaw(int n) throws IOException
|
||||||
|
{
|
||||||
|
if(n < 32) {
|
||||||
|
final int d = 0xa0 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xda;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdb;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b) throws IOException
|
||||||
|
{
|
||||||
|
out.write(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b, int off, int length) throws IOException
|
||||||
|
{
|
||||||
|
out.write(b, off, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Charset UTF8_CHARSET = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
public Packer packString(String s) throws IOException
|
||||||
|
{
|
||||||
|
byte[] b = ((String)s).getBytes(UTF8_CHARSET);
|
||||||
|
packRaw(b.length);
|
||||||
|
packRawBody(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(MessagePackable o) throws IOException
|
||||||
|
{
|
||||||
|
o.messagePack(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Object o) throws IOException
|
||||||
|
{
|
||||||
|
if(o == null) {
|
||||||
|
packNil();
|
||||||
|
} else if(o instanceof String) {
|
||||||
|
byte[] b = ((String)o).getBytes(UTF8_CHARSET);
|
||||||
|
packRaw(b.length);
|
||||||
|
packRawBody(b);
|
||||||
|
} else if(o instanceof byte[]) {
|
||||||
|
byte[] b = (byte[])o;
|
||||||
|
packRaw(b.length);
|
||||||
|
packRawBody(b);
|
||||||
|
} else if(o instanceof List) {
|
||||||
|
List<Object> l = (List<Object>)o;
|
||||||
|
packArray(l.size());
|
||||||
|
for(Object i : l) { pack(i); }
|
||||||
|
} else if(o instanceof Map) {
|
||||||
|
Map<Object,Object> m = (Map<Object,Object>)o;
|
||||||
|
packMap(m.size());
|
||||||
|
for(Map.Entry e : m.entrySet()) {
|
||||||
|
pack(e.getKey());
|
||||||
|
pack(e.getValue());
|
||||||
|
}
|
||||||
|
} else if(o instanceof Boolean) {
|
||||||
|
if((Boolean)o) {
|
||||||
|
packTrue();
|
||||||
|
} else {
|
||||||
|
packFalse();
|
||||||
|
}
|
||||||
|
} else if(o instanceof Integer) {
|
||||||
|
packInt((Integer)o);
|
||||||
|
} else if(o instanceof Long) {
|
||||||
|
packLong((Long)o);
|
||||||
|
} else if(o instanceof Short) {
|
||||||
|
packShort((Short)o);
|
||||||
|
} else if(o instanceof Byte) {
|
||||||
|
packByte((Byte)o);
|
||||||
|
} else if(o instanceof Float) {
|
||||||
|
packFloat((Float)o);
|
||||||
|
} else if(o instanceof Double) {
|
||||||
|
packDouble((Double)o);
|
||||||
|
} else if(o instanceof MessagePackable) {
|
||||||
|
((MessagePackable)o).messagePack(this);
|
||||||
|
} else {
|
||||||
|
throw new IOException("unknown object "+o+" ("+o.getClass()+")");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
74
java-plan2/src/org/msgpack/UnbufferedUnpacker.java
Normal file
74
java-plan2/src/org/msgpack/UnbufferedUnpacker.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.lang.Iterable;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import org.msgpack.impl.*;
|
||||||
|
import org.msgpack.schema.Schema;
|
||||||
|
|
||||||
|
public class UnbufferedUnpacker extends UnpackerImpl {
|
||||||
|
private int offset;
|
||||||
|
private boolean finished;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
public UnbufferedUnpacker()
|
||||||
|
{
|
||||||
|
super(new GenericObjectBuilder());
|
||||||
|
this.offset = 0;
|
||||||
|
this.finished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnbufferedUnpacker useSchema(Schema s)
|
||||||
|
{
|
||||||
|
super.setBuilder(new SpecificObjectBuilder(s));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
super.reset();
|
||||||
|
this.offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOffset()
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOffset(int offset)
|
||||||
|
{
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int execute(byte[] buffer) throws UnpackException
|
||||||
|
{
|
||||||
|
return execute(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
public int execute(byte[] buffer, int offset, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
int noffset = super.execute(buffer, offset + this.offset, length);
|
||||||
|
this.offset = noffset - offset;
|
||||||
|
if(super.isFinished()) {
|
||||||
|
this.data = super.getData();
|
||||||
|
this.finished = true;
|
||||||
|
super.reset();
|
||||||
|
} else {
|
||||||
|
this.finished = false;
|
||||||
|
}
|
||||||
|
return noffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
java-plan2/src/org/msgpack/UnpackException.java
Normal file
35
java-plan2/src/org/msgpack/UnpackException.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public class UnpackException extends MessagePackException
|
||||||
|
{
|
||||||
|
public static final int EXTRA_BYTES = 1;
|
||||||
|
public static final int INSUFFICIENT_BYTES = 0;
|
||||||
|
public static final int PARSE_ERROR = -1;
|
||||||
|
|
||||||
|
private int errorCode;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
public UnpackException(String message, int errorCode)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnpackException(String message, int errorCode, Object data)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
this.errorCode = errorCode;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getErrorCode()
|
||||||
|
{
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
53
java-plan2/src/org/msgpack/UnpackIterator.java
Normal file
53
java-plan2/src/org/msgpack/UnpackIterator.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
public class UnpackIterator implements Iterator<Object> {
|
||||||
|
private Unpacker pac;
|
||||||
|
private boolean have;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
UnpackIterator(Unpacker pac)
|
||||||
|
{
|
||||||
|
this.pac = pac;
|
||||||
|
this.have = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext()
|
||||||
|
{
|
||||||
|
if(have) { return true; }
|
||||||
|
try {
|
||||||
|
while(true) {
|
||||||
|
if(pac.execute()) {
|
||||||
|
data = pac.getData();
|
||||||
|
pac.reset();
|
||||||
|
have = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pac.fill()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next()
|
||||||
|
{
|
||||||
|
if(!have) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
have = false;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
269
java-plan2/src/org/msgpack/Unpacker.java
Normal file
269
java-plan2/src/org/msgpack/Unpacker.java
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.lang.Iterable;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import org.msgpack.impl.*;
|
||||||
|
import org.msgpack.schema.Schema;
|
||||||
|
|
||||||
|
public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
||||||
|
|
||||||
|
public static final int DEFAULT_BUFFER_SIZE = 32*1024;
|
||||||
|
|
||||||
|
private int used;
|
||||||
|
private int offset;
|
||||||
|
private int parsed;
|
||||||
|
private byte[] buffer;
|
||||||
|
private int bufferReserveSize;
|
||||||
|
private InputStream stream;
|
||||||
|
|
||||||
|
public Unpacker()
|
||||||
|
{
|
||||||
|
super(new GenericZeroCopyObjectBuilder());
|
||||||
|
this.used = 0;
|
||||||
|
this.offset = 0;
|
||||||
|
this.parsed = 0;
|
||||||
|
this.buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||||
|
this.bufferReserveSize = DEFAULT_BUFFER_SIZE/2;
|
||||||
|
this.stream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(int bufferReserveSize)
|
||||||
|
{
|
||||||
|
super(new GenericZeroCopyObjectBuilder());
|
||||||
|
this.used = 0;
|
||||||
|
this.offset = 0;
|
||||||
|
this.parsed = 0;
|
||||||
|
this.buffer = new byte[bufferReserveSize];
|
||||||
|
this.bufferReserveSize = bufferReserveSize/2;
|
||||||
|
this.stream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(InputStream stream)
|
||||||
|
{
|
||||||
|
super(new GenericZeroCopyObjectBuilder());
|
||||||
|
this.used = 0;
|
||||||
|
this.offset = 0;
|
||||||
|
this.parsed = 0;
|
||||||
|
this.buffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||||
|
this.bufferReserveSize = DEFAULT_BUFFER_SIZE/2;
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(InputStream stream, int bufferReserveSize)
|
||||||
|
{
|
||||||
|
super(new GenericZeroCopyObjectBuilder());
|
||||||
|
this.used = 0;
|
||||||
|
this.offset = 0;
|
||||||
|
this.parsed = 0;
|
||||||
|
this.buffer = new byte[bufferReserveSize];
|
||||||
|
this.bufferReserveSize = bufferReserveSize/2;
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker useSchema(Schema s)
|
||||||
|
{
|
||||||
|
super.setBuilder(new SpecificObjectBuilder(s));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reserveBuffer(int size)
|
||||||
|
{
|
||||||
|
if(buffer.length - used >= size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if(used == parsed && buffer.length >= size) {
|
||||||
|
// rewind buffer
|
||||||
|
used = 0;
|
||||||
|
offset = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int nextSize = buffer.length * 2;
|
||||||
|
while(nextSize < size + used) {
|
||||||
|
nextSize *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] tmp = new byte[nextSize];
|
||||||
|
System.arraycopy(buffer, offset, tmp, 0, used - offset);
|
||||||
|
|
||||||
|
buffer = tmp;
|
||||||
|
used -= offset;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBuffer()
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferOffset()
|
||||||
|
{
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferCapacity()
|
||||||
|
{
|
||||||
|
return buffer.length - used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bufferConsumed(int size)
|
||||||
|
{
|
||||||
|
used += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feed(byte[] buffer)
|
||||||
|
{
|
||||||
|
feed(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feed(byte[] buffer, int offset, int length)
|
||||||
|
{
|
||||||
|
reserveBuffer(length);
|
||||||
|
System.arraycopy(buffer, offset, this.buffer, this.offset, length);
|
||||||
|
bufferConsumed(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fill() throws IOException
|
||||||
|
{
|
||||||
|
if(stream == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reserveBuffer(bufferReserveSize);
|
||||||
|
int rl = stream.read(getBuffer(), getBufferOffset(), getBufferCapacity());
|
||||||
|
if(rl <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bufferConsumed(rl);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Object> iterator()
|
||||||
|
{
|
||||||
|
return new UnpackIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute() throws UnpackException
|
||||||
|
{
|
||||||
|
int noffset = super.execute(buffer, offset, used);
|
||||||
|
if(noffset <= offset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parsed += noffset - offset;
|
||||||
|
offset = noffset;
|
||||||
|
return super.isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return super.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
super.reset();
|
||||||
|
parsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMessageSize()
|
||||||
|
{
|
||||||
|
return parsed - offset + used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParsedSize()
|
||||||
|
{
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNonParsedSize()
|
||||||
|
{
|
||||||
|
return used - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipNonparsedBuffer(int size)
|
||||||
|
{
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeNonparsedBuffer()
|
||||||
|
{
|
||||||
|
used = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static class Context {
|
||||||
|
private boolean finished;
|
||||||
|
private Object data;
|
||||||
|
private int offset;
|
||||||
|
private UnpackerImpl impl;
|
||||||
|
|
||||||
|
public Context()
|
||||||
|
{
|
||||||
|
this.finished = false;
|
||||||
|
this.impl = new UnpackerImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOffset()
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFinished(boolean finished)
|
||||||
|
{
|
||||||
|
this.finished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setData(Object data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOffset(int offset)
|
||||||
|
{
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnpackerImpl getImpl()
|
||||||
|
{
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int unpack(Context ctx, byte[] buffer) throws UnpackException
|
||||||
|
{
|
||||||
|
return unpack(ctx, buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int unpack(Context ctx, byte[] buffer, int offset, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
UnpackerImpl impl = ctx.getImpl();
|
||||||
|
int noffset = impl.execute(buffer, offset + ctx.getOffset(), length);
|
||||||
|
ctx.setOffset(noffset - offset);
|
||||||
|
if(impl.isFinished()) {
|
||||||
|
ctx.setData(impl.getData());
|
||||||
|
ctx.setFinished(false);
|
||||||
|
impl.reset();
|
||||||
|
} else {
|
||||||
|
ctx.setData(null);
|
||||||
|
ctx.setFinished(true);
|
||||||
|
}
|
||||||
|
int parsed = noffset - offset;
|
||||||
|
ctx.setOffset(parsed);
|
||||||
|
return noffset;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
7
java-plan2/src/org/msgpack/impl/ArrayBuilder.java
Normal file
7
java-plan2/src/org/msgpack/impl/ArrayBuilder.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
public interface ArrayBuilder {
|
||||||
|
public void add(Object element);
|
||||||
|
public Object finish();
|
||||||
|
}
|
||||||
|
|
127
java-plan2/src/org/msgpack/impl/GenericObjectBuilder.java
Normal file
127
java-plan2/src/org/msgpack/impl/GenericObjectBuilder.java
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class GenericObjectBuilder implements ObjectBuilder {
|
||||||
|
public Object createNil()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createBoolean(boolean v)
|
||||||
|
{
|
||||||
|
return new GenericBoolean(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
//return new GenericByte(v);
|
||||||
|
return null; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
return new GenericShort(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createInt(int v)
|
||||||
|
{
|
||||||
|
//return new GenericInt(v);
|
||||||
|
return null; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createLong(long v)
|
||||||
|
{
|
||||||
|
return new GenericLong(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFloat(float v)
|
||||||
|
{
|
||||||
|
//return new GenericFloat(v);
|
||||||
|
return null; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createDouble(double v)
|
||||||
|
{
|
||||||
|
//return new GenericDouble(v);
|
||||||
|
return null; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
byte[] copy = new byte[length];
|
||||||
|
System.arraycopy(b, offset, copy, 0, length);
|
||||||
|
return new GenericRaw(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayBuilder createArray(int length)
|
||||||
|
{
|
||||||
|
return new GenericArrayBuilder(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapBuilder createMap(int length)
|
||||||
|
{
|
||||||
|
return new GenericMapBuilder(length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class GenericArrayBuilder implements ArrayBuilder {
|
||||||
|
private GenericArray a;
|
||||||
|
|
||||||
|
GenericArrayBuilder(int length)
|
||||||
|
{
|
||||||
|
this.a = new GenericArray(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(Object element)
|
||||||
|
{
|
||||||
|
a.add((GenericObject)element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object finish()
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class GenericMapBuilder implements MapBuilder {
|
||||||
|
private GenericMap m;
|
||||||
|
private GenericObject key;
|
||||||
|
|
||||||
|
GenericMapBuilder(int length)
|
||||||
|
{
|
||||||
|
this.m = new GenericMap(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putKey(Object key)
|
||||||
|
{
|
||||||
|
this.key = (GenericObject)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putValue(Object value)
|
||||||
|
{
|
||||||
|
m.put(this.key, (GenericObject)value);
|
||||||
|
this.key = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object finish()
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class GenericZeroCopyObjectBuilder extends GenericObjectBuilder {
|
||||||
|
@Override
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
return new GenericRawRef(b, offset, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
8
java-plan2/src/org/msgpack/impl/MapBuilder.java
Normal file
8
java-plan2/src/org/msgpack/impl/MapBuilder.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
public interface MapBuilder {
|
||||||
|
public void putKey(Object key);
|
||||||
|
public void putValue(Object value);
|
||||||
|
public Object finish();
|
||||||
|
}
|
||||||
|
|
16
java-plan2/src/org/msgpack/impl/ObjectBuilder.java
Normal file
16
java-plan2/src/org/msgpack/impl/ObjectBuilder.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
public interface ObjectBuilder {
|
||||||
|
public Object createNil();
|
||||||
|
public Object createBoolean(boolean v);
|
||||||
|
public Object createByte(byte v);
|
||||||
|
public Object createShort(short v);
|
||||||
|
public Object createInt(int v);
|
||||||
|
public Object createLong(long v);
|
||||||
|
public Object createFloat(float v);
|
||||||
|
public Object createDouble(double v);
|
||||||
|
public Object createRaw(byte[] b, int offset, int length);
|
||||||
|
public ArrayBuilder createArray(int length);
|
||||||
|
public MapBuilder createMap(int length);
|
||||||
|
}
|
||||||
|
|
203
java-plan2/src/org/msgpack/impl/SpecificObjectBuilder.java
Normal file
203
java-plan2/src/org/msgpack/impl/SpecificObjectBuilder.java
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import org.msgpack.schema.*;
|
||||||
|
|
||||||
|
public final class SpecificObjectBuilder implements ObjectBuilder {
|
||||||
|
private int top;
|
||||||
|
private Schema schema;
|
||||||
|
|
||||||
|
public SpecificObjectBuilder(Schema schema)
|
||||||
|
{
|
||||||
|
this.top = 0;
|
||||||
|
this.schema = schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSchema(Schema s)
|
||||||
|
{
|
||||||
|
schema = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema swapSchema(Schema s)
|
||||||
|
{
|
||||||
|
Schema old = schema;
|
||||||
|
schema = s;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createNil()
|
||||||
|
{
|
||||||
|
return schema.createNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createBoolean(boolean v)
|
||||||
|
{
|
||||||
|
return schema.createBoolean(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
return schema.createByte(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
return schema.createShort(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createInt(int v)
|
||||||
|
{
|
||||||
|
return schema.createInt(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createLong(long v)
|
||||||
|
{
|
||||||
|
return schema.createLong(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFloat(float v)
|
||||||
|
{
|
||||||
|
return schema.createFloat(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createDouble(double v)
|
||||||
|
{
|
||||||
|
return schema.createDouble(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
return schema.createRaw(b, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayBuilder createArray(int length)
|
||||||
|
{
|
||||||
|
if(schema instanceof ClassSchema) {
|
||||||
|
return new ClassBuilder(length, (ClassSchema)schema, this);
|
||||||
|
}
|
||||||
|
ArraySchema as = (ArraySchema)schema;
|
||||||
|
return new SpecificArrayBuilder(length, as.getElementType(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MapBuilder createMap(int length)
|
||||||
|
{
|
||||||
|
MapSchema ms = (MapSchema)schema;
|
||||||
|
return new SpecificMapBuilder(length, ms.getKeyType(), ms.getValueType(), this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SpecificArrayBuilder implements ArrayBuilder {
|
||||||
|
private ArrayList a;
|
||||||
|
private SpecificObjectBuilder builder;
|
||||||
|
private Schema parentSchema;
|
||||||
|
|
||||||
|
SpecificArrayBuilder(int length, Schema elementSchema, SpecificObjectBuilder builder)
|
||||||
|
{
|
||||||
|
this.a = new ArrayList(length);
|
||||||
|
this.builder = builder;
|
||||||
|
this.parentSchema = builder.swapSchema(elementSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Object element)
|
||||||
|
{
|
||||||
|
a.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object finish()
|
||||||
|
{
|
||||||
|
builder.swapSchema(parentSchema);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class SpecificMapBuilder implements MapBuilder {
|
||||||
|
private HashMap m;
|
||||||
|
private Object key;
|
||||||
|
private Schema keySchema;
|
||||||
|
private Schema valueSchema;
|
||||||
|
private SpecificObjectBuilder builder;
|
||||||
|
private Schema parentSchema;
|
||||||
|
|
||||||
|
SpecificMapBuilder(int length, Schema keySchema, Schema valueSchema, SpecificObjectBuilder builder)
|
||||||
|
{
|
||||||
|
this.m = new HashMap(length);
|
||||||
|
this.keySchema = keySchema;
|
||||||
|
this.valueSchema = valueSchema;
|
||||||
|
this.builder = builder;
|
||||||
|
this.parentSchema = builder.swapSchema(keySchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putKey(Object key)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
this.builder.setSchema(valueSchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putValue(Object value)
|
||||||
|
{
|
||||||
|
m.put(this.key, value);
|
||||||
|
this.key = null;
|
||||||
|
this.builder.setSchema(keySchema);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object finish()
|
||||||
|
{
|
||||||
|
builder.swapSchema(parentSchema);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class ClassBuilder implements ArrayBuilder {
|
||||||
|
private Object object;
|
||||||
|
private int index;
|
||||||
|
private List<? extends FieldSchema> fields;
|
||||||
|
private SpecificObjectBuilder builder;
|
||||||
|
private Schema parentSchema;
|
||||||
|
|
||||||
|
ClassBuilder(int length, ClassSchema schema, SpecificObjectBuilder builder)
|
||||||
|
{
|
||||||
|
this.object = schema.newInstance();
|
||||||
|
this.index = 0;
|
||||||
|
this.fields = schema.getFields();
|
||||||
|
this.builder = builder;
|
||||||
|
this.parentSchema = builder.swapSchema(fields.get(0).getType());
|
||||||
|
// FIXME check length
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(Object element)
|
||||||
|
{
|
||||||
|
FieldSchema f = fields.get(index++); // FIXME check fields.size
|
||||||
|
f.setFieldValue(object, element); // XXX FIXME debug
|
||||||
|
if(fields.size() > index) {
|
||||||
|
builder.setSchema( fields.get(index).getType() );
|
||||||
|
} else {
|
||||||
|
builder.setSchema( null );
|
||||||
|
// FIXME: builder.setSchema(new InvalidFieldSchema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object finish()
|
||||||
|
{
|
||||||
|
builder.swapSchema(parentSchema);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
395
java-plan2/src/org/msgpack/impl/UnpackerImpl.java
Normal file
395
java-plan2/src/org/msgpack/impl/UnpackerImpl.java
Normal file
@ -0,0 +1,395 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
//import java.math.BigInteger;
|
||||||
|
import org.msgpack.UnpackException;
|
||||||
|
|
||||||
|
public class UnpackerImpl {
|
||||||
|
static final int CS_HEADER = 0x00;
|
||||||
|
static final int CS_FLOAT = 0x0a;
|
||||||
|
static final int CS_DOUBLE = 0x0b;
|
||||||
|
static final int CS_UINT_8 = 0x0c;
|
||||||
|
static final int CS_UINT_16 = 0x0d;
|
||||||
|
static final int CS_UINT_32 = 0x0e;
|
||||||
|
static final int CS_UINT_64 = 0x0f;
|
||||||
|
static final int CS_INT_8 = 0x10;
|
||||||
|
static final int CS_INT_16 = 0x11;
|
||||||
|
static final int CS_INT_32 = 0x12;
|
||||||
|
static final int CS_INT_64 = 0x13;
|
||||||
|
static final int CS_RAW_16 = 0x1a;
|
||||||
|
static final int CS_RAW_32 = 0x1b;
|
||||||
|
static final int CS_ARRAY_16 = 0x1c;
|
||||||
|
static final int CS_ARRAY_32 = 0x1d;
|
||||||
|
static final int CS_MAP_16 = 0x1e;
|
||||||
|
static final int CS_MAP_32 = 0x1f;
|
||||||
|
static final int ACS_RAW_VALUE = 0x20;
|
||||||
|
static final int CT_ARRAY_ITEM = 0x00;
|
||||||
|
static final int CT_MAP_KEY = 0x01;
|
||||||
|
static final int CT_MAP_VALUE = 0x02;
|
||||||
|
|
||||||
|
static final int MAX_STACK_SIZE = 16;
|
||||||
|
|
||||||
|
protected int cs = CS_HEADER;
|
||||||
|
protected int trail = 0;
|
||||||
|
protected int top = -1;
|
||||||
|
protected boolean finished = false;
|
||||||
|
protected Object data = null;
|
||||||
|
protected int[] stack_ct = new int[MAX_STACK_SIZE];
|
||||||
|
protected int[] stack_count = new int[MAX_STACK_SIZE];
|
||||||
|
protected Object[] stack_obj = new Object[MAX_STACK_SIZE];
|
||||||
|
protected ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||||
|
protected ObjectBuilder builder;
|
||||||
|
|
||||||
|
protected UnpackerImpl(ObjectBuilder builder)
|
||||||
|
{
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setBuilder(ObjectBuilder builder)
|
||||||
|
{
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reset()
|
||||||
|
{
|
||||||
|
for(int i=0; i <= top; ++top) {
|
||||||
|
stack_ct[top] = 0;
|
||||||
|
stack_count[top] = 0;
|
||||||
|
stack_obj[top] = null;
|
||||||
|
}
|
||||||
|
cs = CS_HEADER;
|
||||||
|
trail = 0;
|
||||||
|
top = -1;
|
||||||
|
finished = false;
|
||||||
|
data = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected int execute(byte[] src, int off, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
if(off >= length) { return off; }
|
||||||
|
|
||||||
|
int limit = length;
|
||||||
|
int i = off;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
Object obj = null;
|
||||||
|
|
||||||
|
_out: do {
|
||||||
|
_header_again: {
|
||||||
|
//System.out.println("while i:"+i+" limit:"+limit);
|
||||||
|
|
||||||
|
int b = src[i];
|
||||||
|
|
||||||
|
_push: {
|
||||||
|
_fixed_trail_again:
|
||||||
|
if(cs == CS_HEADER) {
|
||||||
|
|
||||||
|
if((b & 0x80) == 0) { // Positive Fixnum
|
||||||
|
//System.out.println("positive fixnum "+b);
|
||||||
|
obj = builder.createByte((byte)b);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xe0) { // Negative Fixnum
|
||||||
|
//System.out.println("negative fixnum "+b);
|
||||||
|
obj = builder.createByte((byte)b);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||||
|
trail = b & 0x1f;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = builder.createRaw(new byte[0], 0, 0);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x90) { // FixArray
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
count = b & 0x0f;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createArray(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixarray count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x80) { // FixMap
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
count = b & 0x0f;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(b & 0xff) { // FIXME
|
||||||
|
case 0xc0: // nil
|
||||||
|
obj = builder.createNil();
|
||||||
|
break _push;
|
||||||
|
case 0xc2: // false
|
||||||
|
obj = builder.createBoolean(false);
|
||||||
|
break _push;
|
||||||
|
case 0xc3: // true
|
||||||
|
obj = builder.createBoolean(true);
|
||||||
|
break _push;
|
||||||
|
case 0xca: // float
|
||||||
|
case 0xcb: // double
|
||||||
|
case 0xcc: // unsigned int 8
|
||||||
|
case 0xcd: // unsigned int 16
|
||||||
|
case 0xce: // unsigned int 32
|
||||||
|
case 0xcf: // unsigned int 64
|
||||||
|
case 0xd0: // signed int 8
|
||||||
|
case 0xd1: // signed int 16
|
||||||
|
case 0xd2: // signed int 32
|
||||||
|
case 0xd3: // signed int 64
|
||||||
|
trail = 1 << (b & 0x03);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("a trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case 0xda: // raw 16
|
||||||
|
case 0xdb: // raw 32
|
||||||
|
case 0xdc: // array 16
|
||||||
|
case 0xdd: // array 32
|
||||||
|
case 0xde: // map 16
|
||||||
|
case 0xdf: // map 32
|
||||||
|
trail = 2 << (b & 0x01);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("b trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
default:
|
||||||
|
//System.out.println("unknown b "+(b&0xff));
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
|
||||||
|
do {
|
||||||
|
_fixed_trail_again: {
|
||||||
|
|
||||||
|
if(limit - i <= trail) { break _out; }
|
||||||
|
int n = i + 1;
|
||||||
|
i += trail;
|
||||||
|
|
||||||
|
switch(cs) {
|
||||||
|
case CS_FLOAT:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = builder.createFloat( castBuffer.getFloat(0) );
|
||||||
|
//System.out.println("float "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_DOUBLE:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
obj = builder.createDouble( castBuffer.getDouble(0) );
|
||||||
|
//System.out.println("double "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_8:
|
||||||
|
//System.out.println(n);
|
||||||
|
//System.out.println(src[n]);
|
||||||
|
//System.out.println(src[n+1]);
|
||||||
|
//System.out.println(src[n-1]);
|
||||||
|
obj = builder.createShort( (short)((src[n]) & 0xff) );
|
||||||
|
//System.out.println("uint8 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_16:
|
||||||
|
//System.out.println(src[n]);
|
||||||
|
//System.out.println(src[n+1]);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = builder.createInt( ((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 = builder.createLong( ((long)castBuffer.getInt(0)) & 0xffffffffL );
|
||||||
|
//System.out.println("uint 32 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
{
|
||||||
|
long o = castBuffer.getLong(0);
|
||||||
|
if(o < 0) {
|
||||||
|
// FIXME
|
||||||
|
//obj = GenericBigInteger.valueOf(o & 0x7fffffffL).setBit(31);
|
||||||
|
} else {
|
||||||
|
obj = builder.createLong( o );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new UnpackException("uint 64 bigger than 0x7fffffff is not supported", UnpackException.PARSE_ERROR);
|
||||||
|
case CS_INT_8:
|
||||||
|
obj = builder.createByte( src[n] );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_16:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = builder.createShort( castBuffer.getShort(0) );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = builder.createInt( castBuffer.getInt(0) );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
obj = builder.createLong( 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 = builder.createRaw(new byte[0], 0, 0);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case CS_RAW_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
trail = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = builder.createRaw(new byte[0], 0, 0);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
case ACS_RAW_VALUE:
|
||||||
|
obj = builder.createRaw(src, n, trail);
|
||||||
|
break _push;
|
||||||
|
case CS_ARRAY_16:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createArray(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
break _header_again;
|
||||||
|
case CS_ARRAY_32:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createArray(count);
|
||||||
|
stack_ct[top] = CT_ARRAY_ITEM;
|
||||||
|
stack_count[top] = count;
|
||||||
|
break _header_again;
|
||||||
|
case CS_MAP_16:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
case CS_MAP_32:
|
||||||
|
if(top >= MAX_STACK_SIZE) {
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
++top;
|
||||||
|
stack_obj[top] = builder.createMap(count);
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
stack_count[top] = count;
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
break _header_again;
|
||||||
|
default:
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
} while(true);
|
||||||
|
} // _push
|
||||||
|
|
||||||
|
do {
|
||||||
|
_push: {
|
||||||
|
//System.out.println("push top:"+top);
|
||||||
|
if(top == -1) {
|
||||||
|
++i;
|
||||||
|
data = obj;
|
||||||
|
finished = true;
|
||||||
|
break _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(stack_ct[top]) {
|
||||||
|
case CT_ARRAY_ITEM:
|
||||||
|
//System.out.println("array item "+obj);
|
||||||
|
((ArrayBuilder)stack_obj[top]).add(obj);
|
||||||
|
if(--stack_count[top] == 0) {
|
||||||
|
obj = ((ArrayBuilder)stack_obj[top]).finish();
|
||||||
|
stack_obj[top] = null;
|
||||||
|
--top;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
break _header_again;
|
||||||
|
case CT_MAP_KEY:
|
||||||
|
//System.out.println("map key:"+top+" "+obj);
|
||||||
|
MapBuilder mb = (MapBuilder)stack_obj[top];
|
||||||
|
mb.putKey(obj);
|
||||||
|
stack_ct[top] = CT_MAP_VALUE;
|
||||||
|
break _header_again;
|
||||||
|
case CT_MAP_VALUE:
|
||||||
|
//System.out.println("map value:"+top+" "+obj);
|
||||||
|
((MapBuilder)stack_obj[top]).putValue(obj);
|
||||||
|
if(--stack_count[top] == 0) {
|
||||||
|
obj = ((MapBuilder)stack_obj[top]).finish();
|
||||||
|
stack_obj[top] = null;
|
||||||
|
--top;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
stack_ct[top] = CT_MAP_KEY;
|
||||||
|
break _header_again;
|
||||||
|
default:
|
||||||
|
throw new UnpackException("parse error", UnpackException.PARSE_ERROR);
|
||||||
|
}
|
||||||
|
} // _push
|
||||||
|
} while(true);
|
||||||
|
|
||||||
|
} // _header_again
|
||||||
|
cs = CS_HEADER;
|
||||||
|
++i;
|
||||||
|
} while(i < limit); // _out
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
61
java-plan2/src/org/msgpack/schema/ArraySchema.java
Normal file
61
java-plan2/src/org/msgpack/schema/ArraySchema.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ArraySchema extends Schema {
|
||||||
|
private Schema elementType;
|
||||||
|
|
||||||
|
public ArraySchema(Schema elementType)
|
||||||
|
{
|
||||||
|
super("array");
|
||||||
|
this.elementType = elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Schema getElementType()
|
||||||
|
{
|
||||||
|
return elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "ArrayList<"+elementType.getFullName()+">";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "(array "+elementType.getExpression()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Object> d = (List<Object>)obj;
|
||||||
|
pk.packArray(d.size());
|
||||||
|
for(Object e : d) {
|
||||||
|
elementType.pack(pk, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
List<GenericObject> d = obj.asArray();
|
||||||
|
List<Object> g = new ArrayList<Object>();
|
||||||
|
for(GenericObject o : d) {
|
||||||
|
g.add( elementType.convert(o) );
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
230
java-plan2/src/org/msgpack/schema/ClassGenerator.java
Normal file
230
java-plan2/src/org/msgpack/schema/ClassGenerator.java
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
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.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
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.getType());
|
||||||
|
}
|
||||||
|
} else if(s instanceof ArraySchema) {
|
||||||
|
ArraySchema as = (ArraySchema)s;
|
||||||
|
findSubclassSchema(dst, as.getElementType());
|
||||||
|
} else if(s instanceof MapSchema) {
|
||||||
|
MapSchema as = (MapSchema)s;
|
||||||
|
findSubclassSchema(dst, as.getKeyType());
|
||||||
|
findSubclassSchema(dst, as.getValueType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.*;");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeFooter() throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeClass() throws IOException
|
||||||
|
{
|
||||||
|
line();
|
||||||
|
line("public final class "+schema.getName()+" implements MessagePackable, MessageConvertable");
|
||||||
|
line("{");
|
||||||
|
pushIndent();
|
||||||
|
writeSchema();
|
||||||
|
writeMemberVariables();
|
||||||
|
writeMemberFunctions();
|
||||||
|
popIndent();
|
||||||
|
line("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeSubclass() throws IOException
|
||||||
|
{
|
||||||
|
line();
|
||||||
|
line("final class "+schema.getName()+" 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.getType().getFullName()+" "+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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeConstructors() throws IOException
|
||||||
|
{
|
||||||
|
line();
|
||||||
|
line("public "+schema.getName()+"() { }");
|
||||||
|
}
|
||||||
|
|
||||||
|
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("List<? extends FieldSchema> _f = _SCHEMA.getFields();");
|
||||||
|
line("pk.packArray("+schema.getFields().size()+");");
|
||||||
|
int i = 0;
|
||||||
|
for(FieldSchema f : schema.getFields()) {
|
||||||
|
line("_f.get("+i+").getType().pack(pk, "+f.getName()+");");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
popIndent();
|
||||||
|
line("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeConvertFunction() throws IOException
|
||||||
|
{
|
||||||
|
line();
|
||||||
|
line("@Override");
|
||||||
|
line("@SuppressWarnings(\"unchecked\")");
|
||||||
|
line("public void messageConvert(GenericObject obj)");
|
||||||
|
line("{");
|
||||||
|
pushIndent();
|
||||||
|
line("List<GenericObject> _l = obj.asArray();");
|
||||||
|
line("List<? extends FieldSchema> _f = _SCHEMA.getFields();");
|
||||||
|
int i = 0;
|
||||||
|
for(FieldSchema f : schema.getFields()) {
|
||||||
|
line("if(_l.size() <= "+i+") { return; } "+f.getName()+" = ("+f.getType().getFullName()+")_f.get("+i+").getType().convert(_l.get("+i+"));");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
popIndent();
|
||||||
|
line("}");
|
||||||
|
line();
|
||||||
|
line("public static "+schema.getName()+" convert(GenericObject obj)");
|
||||||
|
line("{");
|
||||||
|
pushIndent();
|
||||||
|
line("return ("+schema.getName()+")_SCHEMA.convert(obj);");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
java-plan2/src/org/msgpack/schema/ClassSchema.java
Normal file
39
java-plan2/src/org/msgpack/schema/ClassSchema.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class ClassSchema extends Schema {
|
||||||
|
protected String namespace;
|
||||||
|
protected List<String> imports;
|
||||||
|
|
||||||
|
public ClassSchema(String name, String namespace, List<String> imports)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
this.namespace = namespace;
|
||||||
|
this.imports = imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace()
|
||||||
|
{
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getImports()
|
||||||
|
{
|
||||||
|
return imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNamespace(String namespace)
|
||||||
|
{
|
||||||
|
this.namespace = namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setImports(List<String> imports)
|
||||||
|
{
|
||||||
|
this.imports = imports;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract List<? extends FieldSchema> getFields();
|
||||||
|
public abstract Object newInstance();
|
||||||
|
}
|
||||||
|
|
31
java-plan2/src/org/msgpack/schema/FieldSchema.java
Normal file
31
java-plan2/src/org/msgpack/schema/FieldSchema.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
public abstract class FieldSchema {
|
||||||
|
private String name;
|
||||||
|
private Schema type;
|
||||||
|
|
||||||
|
public FieldSchema(String name, Schema type)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Schema getType()
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "(field "+name+" "+type.getExpression()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Object getFieldValue(Object obj);
|
||||||
|
public abstract void setFieldValue(Object obj, Object value);
|
||||||
|
}
|
||||||
|
|
89
java-plan2/src/org/msgpack/schema/GenericClassSchema.java
Normal file
89
java-plan2/src/org/msgpack/schema/GenericClassSchema.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class GenericClassSchema extends ClassSchema {
|
||||||
|
private List<GenericFieldSchema> fields;
|
||||||
|
|
||||||
|
private String fqdn;
|
||||||
|
private Constructor constructorCache;
|
||||||
|
|
||||||
|
public GenericClassSchema(String name, List<GenericFieldSchema> fields, String namespace, List<String> imports)
|
||||||
|
{
|
||||||
|
super(name, namespace, imports);
|
||||||
|
this.fields = fields;
|
||||||
|
if(namespace == null) {
|
||||||
|
this.fqdn = name;
|
||||||
|
} else {
|
||||||
|
this.fqdn = namespace+"."+name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
//public String getFullName()
|
||||||
|
//{
|
||||||
|
// if(namespace == null) {
|
||||||
|
// return getName();
|
||||||
|
// } else {
|
||||||
|
// return namespace+"."+getName();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public List<? extends FieldSchema> getFields()
|
||||||
|
{
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNamespace()
|
||||||
|
{
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
StringBuffer b = new StringBuffer();
|
||||||
|
b.append("(class ");
|
||||||
|
b.append(getName());
|
||||||
|
if(namespace != null) {
|
||||||
|
b.append(" (package "+namespace+")");
|
||||||
|
}
|
||||||
|
for(GenericFieldSchema f : fields) {
|
||||||
|
b.append(" "+f.getExpression());
|
||||||
|
}
|
||||||
|
b.append(")");
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object newInstance()
|
||||||
|
{
|
||||||
|
return new HashMap(fields.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
java-plan2/src/org/msgpack/schema/GenericFieldSchema.java
Normal file
25
java-plan2/src/org/msgpack/schema/GenericFieldSchema.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class GenericFieldSchema extends FieldSchema {
|
||||||
|
public GenericFieldSchema(String name, Schema type)
|
||||||
|
{
|
||||||
|
super(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getFieldValue(Object obj)
|
||||||
|
{
|
||||||
|
return ((Map)obj).get(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setFieldValue(Object obj, Object value)
|
||||||
|
{
|
||||||
|
((Map)obj).put(getName(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
58
java-plan2/src/org/msgpack/schema/IntSchema.java
Normal file
58
java-plan2/src/org/msgpack/schema/IntSchema.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class IntSchema extends Schema {
|
||||||
|
public IntSchema()
|
||||||
|
{
|
||||||
|
super("Integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pk.packInt((Integer)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj.asInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createInt(int v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createLong(long v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
58
java-plan2/src/org/msgpack/schema/LongSchema.java
Normal file
58
java-plan2/src/org/msgpack/schema/LongSchema.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class LongSchema extends Schema {
|
||||||
|
public LongSchema()
|
||||||
|
{
|
||||||
|
super("Long");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "long";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pk.packLong((Long)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj.asLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createInt(int v)
|
||||||
|
{
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createLong(long v)
|
||||||
|
{
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
70
java-plan2/src/org/msgpack/schema/MapSchema.java
Normal file
70
java-plan2/src/org/msgpack/schema/MapSchema.java
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class MapSchema extends Schema {
|
||||||
|
private Schema keyType;
|
||||||
|
private Schema valueType;
|
||||||
|
|
||||||
|
public MapSchema(Schema keyType, Schema valueType)
|
||||||
|
{
|
||||||
|
super("map");
|
||||||
|
this.keyType = keyType;
|
||||||
|
this.valueType = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Schema getKeyType()
|
||||||
|
{
|
||||||
|
return keyType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Schema getValueType()
|
||||||
|
{
|
||||||
|
return valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "HashList<"+keyType.getFullName()+", "+valueType.getFullName()+">";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "(map "+keyType.getExpression()+" "+valueType.getExpression()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<Object,Object> d = (Map<Object,Object>)obj;
|
||||||
|
pk.packMap(d.size());
|
||||||
|
for(Map.Entry<Object,Object> e : d.entrySet()) {
|
||||||
|
keyType.pack(pk, e.getKey());
|
||||||
|
valueType.pack(pk, e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
Map<GenericObject,GenericObject> d = obj.asMap();
|
||||||
|
Map<Object,Object> g = new HashMap<Object,Object>();
|
||||||
|
for(Map.Entry<GenericObject,GenericObject> e : d.entrySet()) {
|
||||||
|
g.put(keyType.convert(e.getKey()), valueType.convert(e.getValue()));
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
java-plan2/src/org/msgpack/schema/ObjectSchema.java
Normal file
33
java-plan2/src/org/msgpack/schema/ObjectSchema.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ObjectSchema extends Schema {
|
||||||
|
public ObjectSchema()
|
||||||
|
{
|
||||||
|
super("object");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "GenericObject";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pk.pack(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
java-plan2/src/org/msgpack/schema/PrimitiveSchema.java
Normal file
21
java-plan2/src/org/msgpack/schema/PrimitiveSchema.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
public abstract class PrimitiveSchema extends Schema {
|
||||||
|
public static enum PrimitiveType {
|
||||||
|
BYTE,
|
||||||
|
SHORT,
|
||||||
|
INT,
|
||||||
|
LONG,
|
||||||
|
FLOAT,
|
||||||
|
DOUBLE,
|
||||||
|
}
|
||||||
|
|
||||||
|
public final PrimitiveType type;
|
||||||
|
|
||||||
|
protected PrimitiveSchema(String name, PrimitiveType type)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
44
java-plan2/src/org/msgpack/schema/RawSchema.java
Normal file
44
java-plan2/src/org/msgpack/schema/RawSchema.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class RawSchema extends Schema {
|
||||||
|
public RawSchema()
|
||||||
|
{
|
||||||
|
super("raw");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "byte[]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] d = (byte[])obj;
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj.asBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
byte[] d = new byte[length];
|
||||||
|
System.arraycopy(b, offset, d, 0, length);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
246
java-plan2/src/org/msgpack/schema/SSchemaParser.java
Normal file
246
java-plan2/src/org/msgpack/schema/SSchemaParser.java
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
// FIXME exception class
|
||||||
|
|
||||||
|
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();
|
||||||
|
// FIXME
|
||||||
|
if(type.equals("string")) {
|
||||||
|
return new StringSchema();
|
||||||
|
} else if(type.equals("raw")) {
|
||||||
|
return new RawSchema();
|
||||||
|
} 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("object")) {
|
||||||
|
return new ObjectSchema();
|
||||||
|
} 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 parseArray(exp);
|
||||||
|
} else if(type.equals("map")) {
|
||||||
|
return parseMap(exp);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("class, array 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 fields = new ArrayList();
|
||||||
|
|
||||||
|
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, fields, namespace, imports);
|
||||||
|
} else {
|
||||||
|
return new GenericClassSchema(name, fields, namespace, imports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArraySchema parseArray(SExp exp)
|
||||||
|
{
|
||||||
|
if(exp.size() != 2) {
|
||||||
|
throw new RuntimeException("array is (array ELEMENT_TYPE): "+exp);
|
||||||
|
}
|
||||||
|
Schema elementType = readType(exp.getTuple(1));
|
||||||
|
return new ArraySchema(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));
|
||||||
|
if(specificClass) {
|
||||||
|
return new SpecificFieldSchema(name, type);
|
||||||
|
} else {
|
||||||
|
return new GenericFieldSchema(name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
93
java-plan2/src/org/msgpack/schema/Schema.java
Normal file
93
java-plan2/src/org/msgpack/schema/Schema.java
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.impl.*;
|
||||||
|
import org.msgpack.Packer;
|
||||||
|
import org.msgpack.GenericObject;
|
||||||
|
|
||||||
|
public abstract class Schema {
|
||||||
|
private String expression;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Schema(String name)
|
||||||
|
{
|
||||||
|
this.expression = expression;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(GenericObject obj);
|
||||||
|
//public abstract Object convertGeneric(GenericObject obj);
|
||||||
|
|
||||||
|
|
||||||
|
public Object createNil()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createBoolean(boolean v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createInt(int v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createLong(long v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFloat(float v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createDouble(double v)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
java-plan2/src/org/msgpack/schema/ShortSchema.java
Normal file
46
java-plan2/src/org/msgpack/schema/ShortSchema.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ShortSchema extends Schema {
|
||||||
|
public ShortSchema()
|
||||||
|
{
|
||||||
|
super("Short");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "short";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pk.packShort((Short)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj.asShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createByte(byte v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createShort(short v)
|
||||||
|
{
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
156
java-plan2/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
156
java-plan2/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class SpecificClassSchema extends ClassSchema {
|
||||||
|
private List<SpecificFieldSchema> fields;
|
||||||
|
private String namespace;
|
||||||
|
private List<String> imports;
|
||||||
|
|
||||||
|
private String fqdn;
|
||||||
|
private Constructor constructorCache;
|
||||||
|
|
||||||
|
public SpecificClassSchema(String name, List<SpecificFieldSchema> fields, String namespace, List<String> imports)
|
||||||
|
{
|
||||||
|
super(name, namespace, imports);
|
||||||
|
this.fields = fields;
|
||||||
|
if(namespace == null) {
|
||||||
|
this.fqdn = name;
|
||||||
|
} else {
|
||||||
|
this.fqdn = namespace+"."+name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
//public String getFullName()
|
||||||
|
//{
|
||||||
|
// if(namespace == null) {
|
||||||
|
// return getName();
|
||||||
|
// } else {
|
||||||
|
// return namespace+"."+getName();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
public List<? extends FieldSchema> getFields()
|
||||||
|
{
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
StringBuffer b = new StringBuffer();
|
||||||
|
b.append("(class ");
|
||||||
|
b.append(getName());
|
||||||
|
if(namespace != null) {
|
||||||
|
b.append(" (package "+namespace+")");
|
||||||
|
}
|
||||||
|
for(SpecificFieldSchema f : fields) {
|
||||||
|
b.append(" "+f.getExpression());
|
||||||
|
}
|
||||||
|
b.append(")");
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(constructorCache == null) {
|
||||||
|
cacheConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
pk.packArray(fields.size());
|
||||||
|
for(SpecificFieldSchema f : fields) {
|
||||||
|
f.getType().pack(pk, f.getFieldValue(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
if(constructorCache == null) {
|
||||||
|
cacheConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GenericObject> d = obj.asArray();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object g = constructorCache.newInstance((Object[])null);
|
||||||
|
|
||||||
|
Iterator<GenericObject> vi = d.iterator();
|
||||||
|
Iterator<SpecificFieldSchema> fi = fields.iterator();
|
||||||
|
while(fi.hasNext() && vi.hasNext()) {
|
||||||
|
SpecificFieldSchema f = fi.next();
|
||||||
|
GenericObject v = vi.next();
|
||||||
|
f.setFieldValue(g, f.getType().convert(v));
|
||||||
|
}
|
||||||
|
// leave it as uninitialized
|
||||||
|
//while(fi.hasNext()) {
|
||||||
|
// SpecificFieldSchema f = fi.next();
|
||||||
|
// g.put(f.getName(), null);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return g;
|
||||||
|
|
||||||
|
} 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(SpecificClassSchema o)
|
||||||
|
{
|
||||||
|
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
|
||||||
|
getName().equals(o.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
78
java-plan2/src/org/msgpack/schema/SpecificFieldSchema.java
Normal file
78
java-plan2/src/org/msgpack/schema/SpecificFieldSchema.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class SpecificFieldSchema extends FieldSchema {
|
||||||
|
public Field fieldCache;
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public SpecificFieldSchema(String name, Schema type)
|
||||||
|
{
|
||||||
|
super(name, type);
|
||||||
|
this.index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getFieldValue(Object obj)
|
||||||
|
{
|
||||||
|
if(index >= 0) {
|
||||||
|
return ((MessageMergeable)obj).getField(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return fieldCache.get(obj);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
throw new RuntimeException("can't get value from '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||||
|
} catch(IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("can't get value from '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFieldValue(Object obj, Object value)
|
||||||
|
{
|
||||||
|
if(index >= 0) {
|
||||||
|
((MessageMergeable)obj).setField(index, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fieldCache.set(obj, value);
|
||||||
|
} catch(IllegalArgumentException e) {
|
||||||
|
throw new RuntimeException("can't set value into '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||||
|
} catch(IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("can't set value into '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cacheField(Class c, int index)
|
||||||
|
{
|
||||||
|
for(Class i : c.getInterfaces()) {
|
||||||
|
if(i.equals(MessageMergeable.class)) {
|
||||||
|
this.index = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fieldCache = c.getDeclaredField(getName());
|
||||||
|
if(!fieldCache.isAccessible()) {
|
||||||
|
fieldCache.setAccessible(true);
|
||||||
|
}
|
||||||
|
} catch(NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException("can't get '"+getName()+"' field of '"+c.getName()+"' class: "+e.getMessage());
|
||||||
|
} catch(SecurityException e) {
|
||||||
|
throw new RuntimeException("can't get '"+getName()+"' field of '"+c.getName()+"' class: "+e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//public void setFieldInt(Object obj, int value)
|
||||||
|
//{
|
||||||
|
// if(type instanceof PrimitiveSchema) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
48
java-plan2/src/org/msgpack/schema/StringSchema.java
Normal file
48
java-plan2/src/org/msgpack/schema/StringSchema.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class StringSchema extends Schema {
|
||||||
|
public StringSchema()
|
||||||
|
{
|
||||||
|
super("string");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String s = (String)obj;
|
||||||
|
byte[] d = s.getBytes("UTF-8");
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return obj.asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createRaw(byte[] b, int offset, int length)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return new String(b, offset, length, "UTF-8"); // XXX FIXME debug
|
||||||
|
} catch (Exception e) {
|
||||||
|
// FIXME
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
18
java-plan2/test/Generate.java
Normal file
18
java-plan2/test/Generate.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.msgpack.*;
|
||||||
|
import org.msgpack.schema.*;
|
||||||
|
|
||||||
|
public class Generate {
|
||||||
|
public static void main(String[] args) throws IOException
|
||||||
|
{
|
||||||
|
Writer output = new OutputStreamWriter(System.out);
|
||||||
|
|
||||||
|
Schema s1 = Schema.parse("(class Test (field uri raw) (field width int))");
|
||||||
|
ClassGenerator.write(s1, output);
|
||||||
|
|
||||||
|
Schema s2 = Schema.parse("(class MediaContent (package serializers.msgpack) (field image (array (class Image (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))");
|
||||||
|
ClassGenerator.write(s2, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,277 @@
|
|||||||
|
package serializers.msgpack;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import org.msgpack.*;
|
||||||
|
import org.msgpack.schema.*;
|
||||||
|
|
||||||
|
public final class MediaContent implements MessagePackable, MessageConvertable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class MediaContent (package serializers.msgpack) (field image (array (class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public ArrayList<Image> image;
|
||||||
|
public Media media;
|
||||||
|
|
||||||
|
public MediaContent() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer pk) throws IOException
|
||||||
|
{
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
pk.packArray(2);
|
||||||
|
_f.get(0).getType().pack(pk, image);
|
||||||
|
_f.get(1).getType().pack(pk, media);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageConvert(GenericObject obj)
|
||||||
|
{
|
||||||
|
List<GenericObject> _l = obj.asArray();
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
if(_l.size() <= 0) { return; } image = (ArrayList<Image>)_f.get(0).getType().convert(_l.get(0));
|
||||||
|
if(_l.size() <= 1) { return; } media = (Media)_f.get(1).getType().convert(_l.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MediaContent convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return (MediaContent)_SCHEMA.convert(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(int index, Object value)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
image = (ArrayList<Image>)value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
media = (Media)value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getField(int index)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
return image;
|
||||||
|
case 1:
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Image implements MessagePackable, MessageConvertable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public String uri;
|
||||||
|
public String title;
|
||||||
|
public Integer width;
|
||||||
|
public Integer height;
|
||||||
|
public Integer size;
|
||||||
|
|
||||||
|
public Image() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer pk) throws IOException
|
||||||
|
{
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
pk.packArray(5);
|
||||||
|
_f.get(0).getType().pack(pk, uri);
|
||||||
|
_f.get(1).getType().pack(pk, title);
|
||||||
|
_f.get(2).getType().pack(pk, width);
|
||||||
|
_f.get(3).getType().pack(pk, height);
|
||||||
|
_f.get(4).getType().pack(pk, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageConvert(GenericObject obj)
|
||||||
|
{
|
||||||
|
List<GenericObject> _l = obj.asArray();
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
if(_l.size() <= 0) { return; } uri = (String)_f.get(0).getType().convert(_l.get(0));
|
||||||
|
if(_l.size() <= 1) { return; } title = (String)_f.get(1).getType().convert(_l.get(1));
|
||||||
|
if(_l.size() <= 2) { return; } width = (Integer)_f.get(2).getType().convert(_l.get(2));
|
||||||
|
if(_l.size() <= 3) { return; } height = (Integer)_f.get(3).getType().convert(_l.get(3));
|
||||||
|
if(_l.size() <= 4) { return; } size = (Integer)_f.get(4).getType().convert(_l.get(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Image convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return (Image)_SCHEMA.convert(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(int index, Object value)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
uri = (String)value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
title = (String)value;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
width = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
height = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
size = (Integer)value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getField(int index)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
return uri;
|
||||||
|
case 1:
|
||||||
|
return title;
|
||||||
|
case 2:
|
||||||
|
return width;
|
||||||
|
case 3:
|
||||||
|
return height;
|
||||||
|
case 4:
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Media implements MessagePackable, MessageConvertable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public String uri;
|
||||||
|
public String title;
|
||||||
|
public Integer width;
|
||||||
|
public Integer height;
|
||||||
|
public String format;
|
||||||
|
public Long duration;
|
||||||
|
public Long size;
|
||||||
|
public Integer bitrate;
|
||||||
|
public ArrayList<String> person;
|
||||||
|
public Integer player;
|
||||||
|
public String copyright;
|
||||||
|
|
||||||
|
public Media() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer pk) throws IOException
|
||||||
|
{
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
pk.packArray(11);
|
||||||
|
_f.get(0).getType().pack(pk, uri);
|
||||||
|
_f.get(1).getType().pack(pk, title);
|
||||||
|
_f.get(2).getType().pack(pk, width);
|
||||||
|
_f.get(3).getType().pack(pk, height);
|
||||||
|
_f.get(4).getType().pack(pk, format);
|
||||||
|
_f.get(5).getType().pack(pk, duration);
|
||||||
|
_f.get(6).getType().pack(pk, size);
|
||||||
|
_f.get(7).getType().pack(pk, bitrate);
|
||||||
|
_f.get(8).getType().pack(pk, person);
|
||||||
|
_f.get(9).getType().pack(pk, player);
|
||||||
|
_f.get(10).getType().pack(pk, copyright);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageConvert(GenericObject obj)
|
||||||
|
{
|
||||||
|
List<GenericObject> _l = obj.asArray();
|
||||||
|
List<? extends FieldSchema> _f = _SCHEMA.getFields();
|
||||||
|
if(_l.size() <= 0) { return; } uri = (String)_f.get(0).getType().convert(_l.get(0));
|
||||||
|
if(_l.size() <= 1) { return; } title = (String)_f.get(1).getType().convert(_l.get(1));
|
||||||
|
if(_l.size() <= 2) { return; } width = (Integer)_f.get(2).getType().convert(_l.get(2));
|
||||||
|
if(_l.size() <= 3) { return; } height = (Integer)_f.get(3).getType().convert(_l.get(3));
|
||||||
|
if(_l.size() <= 4) { return; } format = (String)_f.get(4).getType().convert(_l.get(4));
|
||||||
|
if(_l.size() <= 5) { return; } duration = (Long)_f.get(5).getType().convert(_l.get(5));
|
||||||
|
if(_l.size() <= 6) { return; } size = (Long)_f.get(6).getType().convert(_l.get(6));
|
||||||
|
if(_l.size() <= 7) { return; } bitrate = (Integer)_f.get(7).getType().convert(_l.get(7));
|
||||||
|
if(_l.size() <= 8) { return; } person = (ArrayList<String>)_f.get(8).getType().convert(_l.get(8));
|
||||||
|
if(_l.size() <= 9) { return; } player = (Integer)_f.get(9).getType().convert(_l.get(9));
|
||||||
|
if(_l.size() <= 10) { return; } copyright = (String)_f.get(10).getType().convert(_l.get(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Media convert(GenericObject obj)
|
||||||
|
{
|
||||||
|
return (Media)_SCHEMA.convert(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(int index, Object value)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
uri = (String)value;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
title = (String)value;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
width = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
height = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
format = (String)value;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
duration = (Long)value;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
size = (Long)value;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
bitrate = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
person = (ArrayList<String>)value;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
player = (Integer)value;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
copyright = (String)value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getField(int index)
|
||||||
|
{
|
||||||
|
switch(index) {
|
||||||
|
case 0:
|
||||||
|
return uri;
|
||||||
|
case 1:
|
||||||
|
return title;
|
||||||
|
case 2:
|
||||||
|
return width;
|
||||||
|
case 3:
|
||||||
|
return height;
|
||||||
|
case 4:
|
||||||
|
return format;
|
||||||
|
case 5:
|
||||||
|
return duration;
|
||||||
|
case 6:
|
||||||
|
return size;
|
||||||
|
case 7:
|
||||||
|
return bitrate;
|
||||||
|
case 8:
|
||||||
|
return person;
|
||||||
|
case 9:
|
||||||
|
return player;
|
||||||
|
case 10:
|
||||||
|
return copyright;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
(class MediaContent
|
||||||
|
(package serializers.msgpack)
|
||||||
|
(field image (array (class Image
|
||||||
|
(field uri string)
|
||||||
|
(field title string)
|
||||||
|
(field width int)
|
||||||
|
(field height int)
|
||||||
|
(field size int))))
|
||||||
|
(field media (class Media
|
||||||
|
(field uri string)
|
||||||
|
(field title string)
|
||||||
|
(field width int)
|
||||||
|
(field height int)
|
||||||
|
(field format string)
|
||||||
|
(field duration long)
|
||||||
|
(field size long)
|
||||||
|
(field bitrate int)
|
||||||
|
(field person (array string))
|
||||||
|
(field player int)
|
||||||
|
(field copyright string)))
|
||||||
|
)
|
@ -0,0 +1,70 @@
|
|||||||
|
package serializers.msgpack;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
import org.msgpack.*;
|
||||||
|
import org.msgpack.schema.*;
|
||||||
|
import serializers.msgpack.*;
|
||||||
|
|
||||||
|
import serializers.ObjectSerializer;
|
||||||
|
|
||||||
|
public class MessagePackSerializer implements ObjectSerializer<MediaContent>
|
||||||
|
{
|
||||||
|
public String getName() {
|
||||||
|
return "msgpack-specific";
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaContent create() throws Exception {
|
||||||
|
Media media = new Media();
|
||||||
|
media.uri = "http://javaone.com/keynote.mpg";
|
||||||
|
media.format = "video/mpg4";
|
||||||
|
media.title = "Javaone Keynote";
|
||||||
|
media.duration = 1234567L;
|
||||||
|
media.bitrate = 0;
|
||||||
|
media.person = new ArrayList<String>(2);
|
||||||
|
media.person.add("Bill Gates");
|
||||||
|
media.person.add("Steve Jobs");
|
||||||
|
media.player = 0;
|
||||||
|
media.height = 0;
|
||||||
|
media.width = 0;
|
||||||
|
media.size = 123L;
|
||||||
|
media.copyright = "";
|
||||||
|
|
||||||
|
Image image1 = new Image();
|
||||||
|
image1.uri = "http://javaone.com/keynote_large.jpg";
|
||||||
|
image1.width = 0;
|
||||||
|
image1.height = 0;
|
||||||
|
image1.size = 2;
|
||||||
|
image1.title = "Javaone Keynote";
|
||||||
|
|
||||||
|
Image image2 = new Image();
|
||||||
|
image2.uri = "http://javaone.com/keynote_thumbnail.jpg";
|
||||||
|
image2.width = 0;
|
||||||
|
image2.height = 0;
|
||||||
|
image2.size = 1;
|
||||||
|
image2.title = "Javaone Keynote";
|
||||||
|
|
||||||
|
MediaContent content = new MediaContent();
|
||||||
|
content.media = media;
|
||||||
|
content.image = new ArrayList<Image>(2);
|
||||||
|
content.image.add(image1);
|
||||||
|
content.image.add(image2);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaContent deserialize(byte[] array) throws Exception {
|
||||||
|
UnbufferedUnpacker pac = new UnbufferedUnpacker().useSchema(MediaContent.getSchema());
|
||||||
|
pac.execute(array);
|
||||||
|
return (MediaContent)pac.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] serialize(MediaContent content) throws Exception {
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
Packer pk = new Packer(os);
|
||||||
|
pk.pack(content);
|
||||||
|
return os.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
java-plan3/build.xml
Normal file
15
java-plan3/build.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<project name="MessagePack for Java">
|
||||||
|
<target name="prepare">
|
||||||
|
<mkdir dir="build" />
|
||||||
|
<mkdir dir="dist" />
|
||||||
|
</target>
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="build"/>
|
||||||
|
<delete dir="dist"/>
|
||||||
|
</target>
|
||||||
|
<target name="compile" depends="prepare">
|
||||||
|
<javac srcdir="src" destdir="build" source="1.5" target="1.5">
|
||||||
|
<compilerarg value="-Xlint:unchecked" />
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
</project>
|
23
java-plan3/src/org/msgpack/MessageMergeable.java
Normal file
23
java-plan3/src/org/msgpack/MessageMergeable.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
public interface MessageMergeable {
|
||||||
|
public void messageMerge(Object obj) throws MessageTypeException;
|
||||||
|
}
|
||||||
|
|
25
java-plan3/src/org/msgpack/MessagePackable.java
Normal file
25
java-plan3/src/org/msgpack/MessagePackable.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface MessagePackable {
|
||||||
|
public void messagePack(Packer pk) throws IOException;
|
||||||
|
}
|
||||||
|
|
39
java-plan3/src/org/msgpack/MessageTypeException.java
Normal file
39
java-plan3/src/org/msgpack/MessageTypeException.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class MessageTypeException extends IOException {
|
||||||
|
public MessageTypeException() { }
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
409
java-plan3/src/org/msgpack/Packer.java
Normal file
409
java-plan3/src/org/msgpack/Packer.java
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Packer {
|
||||||
|
protected byte[] castBytes = new byte[9];
|
||||||
|
protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
public Packer(OutputStream out) {
|
||||||
|
this.out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packByte(byte d) throws IOException {
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBytes[1] = d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
out.write(d);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packShort(short d) throws IOException {
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packInt(int d) throws IOException {
|
||||||
|
if(d < -(1<<5)) {
|
||||||
|
if(d < -(1<<15)) {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else if(d < (1<<16)) {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packLong(long d) throws IOException {
|
||||||
|
if(d < -(1L<<5)) {
|
||||||
|
if(d < -(1L<<15)) {
|
||||||
|
if(d < -(1L<<31)) {
|
||||||
|
// signed 64
|
||||||
|
castBytes[0] = (byte)0xd3;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
} else {
|
||||||
|
// signed 32
|
||||||
|
castBytes[0] = (byte)0xd2;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < -(1<<7)) {
|
||||||
|
// signed 16
|
||||||
|
castBytes[0] = (byte)0xd1;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
// signed 8
|
||||||
|
castBytes[0] = (byte)0xd0;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(d < (1<<7)) {
|
||||||
|
// fixnum
|
||||||
|
out.write((byte)d);
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<16)) {
|
||||||
|
if(d < (1<<8)) {
|
||||||
|
// unsigned 8
|
||||||
|
castBytes[0] = (byte)0xcc;
|
||||||
|
castBytes[1] = (byte)d;
|
||||||
|
out.write(castBytes, 0, 2);
|
||||||
|
} else {
|
||||||
|
// unsigned 16
|
||||||
|
castBytes[0] = (byte)0xcd;
|
||||||
|
castBuffer.putShort(1, (short)d);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
//System.out.println("pack uint 16 "+(short)d);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(d < (1L<<32)) {
|
||||||
|
// unsigned 32
|
||||||
|
castBytes[0] = (byte)0xce;
|
||||||
|
castBuffer.putInt(1, (int)d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
} else {
|
||||||
|
// unsigned 64
|
||||||
|
castBytes[0] = (byte)0xcf;
|
||||||
|
castBuffer.putLong(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFloat(float d) throws IOException {
|
||||||
|
castBytes[0] = (byte)0xca;
|
||||||
|
castBuffer.putFloat(1, d);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packDouble(double d) throws IOException {
|
||||||
|
castBytes[0] = (byte)0xcb;
|
||||||
|
castBuffer.putDouble(1, d);
|
||||||
|
out.write(castBytes, 0, 9);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packNil() throws IOException {
|
||||||
|
out.write((byte)0xc0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packTrue() throws IOException {
|
||||||
|
out.write((byte)0xc3);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packFalse() throws IOException {
|
||||||
|
out.write((byte)0xc2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packArray(int n) throws IOException {
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x90 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xdc;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdd;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packMap(int n) throws IOException {
|
||||||
|
if(n < 16) {
|
||||||
|
final int d = 0x80 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xde;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdf;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRaw(int n) throws IOException {
|
||||||
|
if(n < 32) {
|
||||||
|
final int d = 0xa0 | n;
|
||||||
|
out.write((byte)d);
|
||||||
|
} else if(n < 65536) {
|
||||||
|
castBytes[0] = (byte)0xda;
|
||||||
|
castBuffer.putShort(1, (short)n);
|
||||||
|
out.write(castBytes, 0, 3);
|
||||||
|
} else {
|
||||||
|
castBytes[0] = (byte)0xdb;
|
||||||
|
castBuffer.putInt(1, n);
|
||||||
|
out.write(castBytes, 0, 5);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b) throws IOException {
|
||||||
|
out.write(b);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer packRawBody(byte[] b, int off, int length) throws IOException {
|
||||||
|
out.write(b, off, length);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
return packRawBody(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Boolean o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
if(o) {
|
||||||
|
return packTrue();
|
||||||
|
} else {
|
||||||
|
return packFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Byte o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packByte(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Short o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packShort(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Integer o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packInt(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Long o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packLong(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Float o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packFloat(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packer pack(Double o) throws IOException {
|
||||||
|
if(o == null) { return packNil(); }
|
||||||
|
return packDouble(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Packer pack(Object o) throws IOException {
|
||||||
|
if(o == null) {
|
||||||
|
return packNil();
|
||||||
|
} else if(o instanceof String) {
|
||||||
|
byte[] b = ((String)o).getBytes("UTF-8");
|
||||||
|
packRaw(b.length);
|
||||||
|
return packRawBody(b);
|
||||||
|
} else if(o instanceof MessagePackable) {
|
||||||
|
((MessagePackable)o).messagePack(this);
|
||||||
|
return this;
|
||||||
|
} else if(o instanceof byte[]) {
|
||||||
|
byte[] b = (byte[])o;
|
||||||
|
packRaw(b.length);
|
||||||
|
return packRawBody(b);
|
||||||
|
} else if(o instanceof List) {
|
||||||
|
List<Object> l = (List<Object>)o;
|
||||||
|
packArray(l.size());
|
||||||
|
for(Object i : l) { pack(i); }
|
||||||
|
return this;
|
||||||
|
} else if(o instanceof Map) {
|
||||||
|
Map<Object,Object> m = (Map<Object,Object>)o;
|
||||||
|
packMap(m.size());
|
||||||
|
for(Map.Entry e : m.entrySet()) {
|
||||||
|
pack(e.getKey());
|
||||||
|
pack(e.getValue());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
} else if(o instanceof Boolean) {
|
||||||
|
if((Boolean)o) {
|
||||||
|
return packTrue();
|
||||||
|
} else {
|
||||||
|
return packFalse();
|
||||||
|
}
|
||||||
|
} else if(o instanceof Integer) {
|
||||||
|
return packInt((Integer)o);
|
||||||
|
} else if(o instanceof Long) {
|
||||||
|
return packLong((Long)o);
|
||||||
|
} else if(o instanceof Short) {
|
||||||
|
return packShort((Short)o);
|
||||||
|
} else if(o instanceof Byte) {
|
||||||
|
return packByte((Byte)o);
|
||||||
|
} else if(o instanceof Float) {
|
||||||
|
return packFloat((Float)o);
|
||||||
|
} else if(o instanceof Double) {
|
||||||
|
return packDouble((Double)o);
|
||||||
|
} else {
|
||||||
|
throw new IOException("unknown object "+o+" ("+o.getClass()+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
133
java-plan3/src/org/msgpack/Schema.java
Normal file
133
java-plan3/src/org/msgpack/Schema.java
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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 {
|
||||||
|
private String expression;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Schema(String name) {
|
||||||
|
this.expression = expression;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpression() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Schema parse(String source) {
|
||||||
|
return SSchemaParser.parse(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Schema load(String source) {
|
||||||
|
return SSchemaParser.load(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(Writer output) throws IOException {
|
||||||
|
ClassGenerator.write(this, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromLong(long v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||||
|
throw new RuntimeException("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME
|
||||||
|
public Object createFromBoolean(boolean v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromLong(long v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||||
|
throw MessageTypeException.schemaMismatch(this);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
82
java-plan3/src/org/msgpack/UnbufferedUnpacker.java
Normal file
82
java-plan3/src/org/msgpack/UnbufferedUnpacker.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.lang.Iterable;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import org.msgpack.impl.UnpackerImpl;
|
||||||
|
|
||||||
|
public class UnbufferedUnpacker extends UnpackerImpl {
|
||||||
|
private int offset;
|
||||||
|
private boolean finished;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
public UnbufferedUnpacker() {
|
||||||
|
super();
|
||||||
|
this.offset = 0;
|
||||||
|
this.finished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnbufferedUnpacker useSchema(Schema s) {
|
||||||
|
super.setSchema(s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
this.offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOffset(int offset) {
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int execute(byte[] buffer) throws UnpackException {
|
||||||
|
return execute(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
public int execute(byte[] buffer, int offset, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
int noffset = super.execute(buffer, offset + this.offset, length);
|
||||||
|
this.offset = noffset - offset;
|
||||||
|
if(super.isFinished()) {
|
||||||
|
this.data = super.getData();
|
||||||
|
this.finished = true;
|
||||||
|
super.reset();
|
||||||
|
} else {
|
||||||
|
this.finished = false;
|
||||||
|
}
|
||||||
|
return noffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
java-plan3/src/org/msgpack/UnpackException.java
Normal file
29
java-plan3/src/org/msgpack/UnpackException.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class UnpackException extends IOException {
|
||||||
|
public UnpackException() { }
|
||||||
|
|
||||||
|
public UnpackException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
66
java-plan3/src/org/msgpack/UnpackIterator.java
Normal file
66
java-plan3/src/org/msgpack/UnpackIterator.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
public class UnpackIterator implements Iterator<Object> {
|
||||||
|
private Unpacker pac;
|
||||||
|
private boolean have;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
UnpackIterator(Unpacker pac) {
|
||||||
|
this.pac = pac;
|
||||||
|
this.have = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
if(have) { return true; }
|
||||||
|
try {
|
||||||
|
while(true) {
|
||||||
|
if(pac.execute()) {
|
||||||
|
data = pac.getData();
|
||||||
|
pac.reset();
|
||||||
|
have = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pac.fill()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next() {
|
||||||
|
if(!have && !hasNext()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
have = false;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
245
java-plan3/src/org/msgpack/Unpacker.java
Normal file
245
java-plan3/src/org/msgpack/Unpacker.java
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack;
|
||||||
|
|
||||||
|
import java.lang.Iterable;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import org.msgpack.impl.UnpackerImpl;
|
||||||
|
|
||||||
|
public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
||||||
|
|
||||||
|
public static final int DEFAULT_BUFFER_SIZE = 32*1024;
|
||||||
|
|
||||||
|
private int used;
|
||||||
|
private int offset;
|
||||||
|
private int parsed;
|
||||||
|
private byte[] buffer;
|
||||||
|
private int bufferReserveSize;
|
||||||
|
private InputStream stream;
|
||||||
|
|
||||||
|
public Unpacker() {
|
||||||
|
this(DEFAULT_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(int bufferReserveSize) {
|
||||||
|
this(null, bufferReserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(InputStream stream) {
|
||||||
|
this(stream, DEFAULT_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker(InputStream stream, int bufferReserveSize) {
|
||||||
|
super();
|
||||||
|
this.used = 0;
|
||||||
|
this.offset = 0;
|
||||||
|
this.parsed = 0;
|
||||||
|
this.buffer = new byte[bufferReserveSize];
|
||||||
|
this.bufferReserveSize = bufferReserveSize/2;
|
||||||
|
this.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unpacker useSchema(Schema s) {
|
||||||
|
super.setSchema(s);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reserveBuffer(int size) {
|
||||||
|
if(buffer.length - used >= size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if(used == parsed && buffer.length >= size) {
|
||||||
|
// rewind buffer
|
||||||
|
used = 0;
|
||||||
|
offset = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int nextSize = buffer.length * 2;
|
||||||
|
while(nextSize < size + used) {
|
||||||
|
nextSize *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] tmp = new byte[nextSize];
|
||||||
|
System.arraycopy(buffer, offset, tmp, 0, used - offset);
|
||||||
|
|
||||||
|
buffer = tmp;
|
||||||
|
used -= offset;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBuffer() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferOffset() {
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferCapacity() {
|
||||||
|
return buffer.length - used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bufferConsumed(int size) {
|
||||||
|
used += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feed(byte[] buffer) {
|
||||||
|
feed(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feed(byte[] buffer, int offset, int length) {
|
||||||
|
reserveBuffer(length);
|
||||||
|
System.arraycopy(buffer, offset, this.buffer, this.offset, length);
|
||||||
|
bufferConsumed(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fill() throws IOException {
|
||||||
|
if(stream == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reserveBuffer(bufferReserveSize);
|
||||||
|
int rl = stream.read(getBuffer(), getBufferOffset(), getBufferCapacity());
|
||||||
|
if(rl <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bufferConsumed(rl);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<Object> iterator() {
|
||||||
|
return new UnpackIterator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean execute() throws UnpackException {
|
||||||
|
int noffset = super.execute(buffer, offset, used);
|
||||||
|
if(noffset <= offset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parsed += noffset - offset;
|
||||||
|
offset = noffset;
|
||||||
|
return super.isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData() {
|
||||||
|
return super.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
parsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMessageSize() {
|
||||||
|
return parsed - offset + used;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParsedSize() {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNonParsedSize() {
|
||||||
|
return used - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void skipNonparsedBuffer(int size) {
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeNonparsedBuffer() {
|
||||||
|
used = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static class Context {
|
||||||
|
private boolean finished;
|
||||||
|
private Object data;
|
||||||
|
private int offset;
|
||||||
|
private UnpackerImpl impl;
|
||||||
|
|
||||||
|
public Context()
|
||||||
|
{
|
||||||
|
this.finished = false;
|
||||||
|
this.impl = new UnpackerImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOffset()
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFinished(boolean finished)
|
||||||
|
{
|
||||||
|
this.finished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setData(Object data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOffset(int offset)
|
||||||
|
{
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnpackerImpl getImpl()
|
||||||
|
{
|
||||||
|
return impl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int unpack(Context ctx, byte[] buffer) throws UnpackException
|
||||||
|
{
|
||||||
|
return unpack(ctx, buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int unpack(Context ctx, byte[] buffer, int offset, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
UnpackerImpl impl = ctx.getImpl();
|
||||||
|
int noffset = impl.execute(buffer, offset + ctx.getOffset(), length);
|
||||||
|
ctx.setOffset(noffset - offset);
|
||||||
|
if(impl.isFinished()) {
|
||||||
|
ctx.setData(impl.getData());
|
||||||
|
ctx.setFinished(false);
|
||||||
|
impl.reset();
|
||||||
|
} else {
|
||||||
|
ctx.setData(null);
|
||||||
|
ctx.setFinished(true);
|
||||||
|
}
|
||||||
|
int parsed = noffset - offset;
|
||||||
|
ctx.setOffset(parsed);
|
||||||
|
return noffset;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
483
java-plan3/src/org/msgpack/impl/UnpackerImpl.java
Normal file
483
java-plan3/src/org/msgpack/impl/UnpackerImpl.java
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
package org.msgpack.impl;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class UnpackerImpl {
|
||||||
|
static final int CS_HEADER = 0x00;
|
||||||
|
static final int CS_FLOAT = 0x0a;
|
||||||
|
static final int CS_DOUBLE = 0x0b;
|
||||||
|
static final int CS_UINT_8 = 0x0c;
|
||||||
|
static final int CS_UINT_16 = 0x0d;
|
||||||
|
static final int CS_UINT_32 = 0x0e;
|
||||||
|
static final int CS_UINT_64 = 0x0f;
|
||||||
|
static final int CS_INT_8 = 0x10;
|
||||||
|
static final int CS_INT_16 = 0x11;
|
||||||
|
static final int CS_INT_32 = 0x12;
|
||||||
|
static final int CS_INT_64 = 0x13;
|
||||||
|
static final int CS_RAW_16 = 0x1a;
|
||||||
|
static final int CS_RAW_32 = 0x1b;
|
||||||
|
static final int CS_ARRAY_16 = 0x1c;
|
||||||
|
static final int CS_ARRAY_32 = 0x1d;
|
||||||
|
static final int CS_MAP_16 = 0x1e;
|
||||||
|
static final int CS_MAP_32 = 0x1f;
|
||||||
|
static final int ACS_RAW_VALUE = 0x20;
|
||||||
|
static final int CT_ARRAY_ITEM = 0x00;
|
||||||
|
static final int CT_MAP_KEY = 0x01;
|
||||||
|
static final int CT_MAP_VALUE = 0x02;
|
||||||
|
|
||||||
|
static final int MAX_STACK_SIZE = 16;
|
||||||
|
|
||||||
|
private int cs;
|
||||||
|
private int trail;
|
||||||
|
private int top;
|
||||||
|
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;
|
||||||
|
|
||||||
|
protected UnpackerImpl()
|
||||||
|
{
|
||||||
|
setSchema(GENERIC_SCHEMA);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setSchema(Schema schema)
|
||||||
|
{
|
||||||
|
this.rootSchema = schema;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isFinished()
|
||||||
|
{
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reset()
|
||||||
|
{
|
||||||
|
cs = CS_HEADER;
|
||||||
|
top = -1;
|
||||||
|
finished = false;
|
||||||
|
data = null;
|
||||||
|
top_ct = 0;
|
||||||
|
top_count = 0;
|
||||||
|
top_obj = null;
|
||||||
|
top_schema = rootSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected int execute(byte[] src, int off, int length) throws UnpackException
|
||||||
|
{
|
||||||
|
if(off >= length) { return off; }
|
||||||
|
|
||||||
|
int limit = length;
|
||||||
|
int i = off;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
Object obj = null;
|
||||||
|
|
||||||
|
_out: do {
|
||||||
|
_header_again: {
|
||||||
|
//System.out.println("while i:"+i+" limit:"+limit);
|
||||||
|
|
||||||
|
int b = src[i];
|
||||||
|
|
||||||
|
_push: {
|
||||||
|
_fixed_trail_again:
|
||||||
|
if(cs == CS_HEADER) {
|
||||||
|
|
||||||
|
if((b & 0x80) == 0) { // Positive Fixnum
|
||||||
|
//System.out.println("positive fixnum "+b);
|
||||||
|
obj = top_schema.createFromByte((byte)b);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xe0) { // Negative Fixnum
|
||||||
|
//System.out.println("negative fixnum "+b);
|
||||||
|
obj = top_schema.createFromByte((byte)b);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||||
|
trail = b & 0x1f;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x90) { // FixArray
|
||||||
|
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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||||
|
++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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((b & 0xf0) == 0x80) { // FixMap
|
||||||
|
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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
++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_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();
|
||||||
|
break _push;
|
||||||
|
case 0xc2: // false
|
||||||
|
obj = top_schema.createFromBoolean(false);
|
||||||
|
break _push;
|
||||||
|
case 0xc3: // true
|
||||||
|
obj = top_schema.createFromBoolean(true);
|
||||||
|
break _push;
|
||||||
|
case 0xca: // float
|
||||||
|
case 0xcb: // double
|
||||||
|
case 0xcc: // unsigned int 8
|
||||||
|
case 0xcd: // unsigned int 16
|
||||||
|
case 0xce: // unsigned int 32
|
||||||
|
case 0xcf: // unsigned int 64
|
||||||
|
case 0xd0: // signed int 8
|
||||||
|
case 0xd1: // signed int 16
|
||||||
|
case 0xd2: // signed int 32
|
||||||
|
case 0xd3: // signed int 64
|
||||||
|
trail = 1 << (b & 0x03);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("a trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case 0xda: // raw 16
|
||||||
|
case 0xdb: // raw 32
|
||||||
|
case 0xdc: // array 16
|
||||||
|
case 0xdd: // array 32
|
||||||
|
case 0xde: // map 16
|
||||||
|
case 0xdf: // map 32
|
||||||
|
trail = 2 << (b & 0x01);
|
||||||
|
cs = b & 0x1f;
|
||||||
|
//System.out.println("b trail "+trail+" cs:"+cs);
|
||||||
|
break _fixed_trail_again;
|
||||||
|
default:
|
||||||
|
//System.out.println("unknown b "+(b&0xff));
|
||||||
|
throw new UnpackException("parse error");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
|
||||||
|
do {
|
||||||
|
_fixed_trail_again: {
|
||||||
|
|
||||||
|
if(limit - i <= trail) { break _out; }
|
||||||
|
int n = i + 1;
|
||||||
|
i += trail;
|
||||||
|
|
||||||
|
switch(cs) {
|
||||||
|
case CS_FLOAT:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = top_schema.createFromFloat( 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) );
|
||||||
|
//System.out.println("double "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_8:
|
||||||
|
//System.out.println(n);
|
||||||
|
//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) );
|
||||||
|
//System.out.println("uint8 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_16:
|
||||||
|
//System.out.println(src[n]);
|
||||||
|
//System.out.println(src[n+1]);
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = top_schema.createFromInt( ((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 );
|
||||||
|
//System.out.println("uint 32 "+obj);
|
||||||
|
break _push;
|
||||||
|
case CS_UINT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
} else {
|
||||||
|
obj = top_schema.createFromLong( o );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break _push;
|
||||||
|
case CS_INT_8:
|
||||||
|
obj = top_schema.createFromByte( src[n] );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_16:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 2);
|
||||||
|
obj = top_schema.createFromShort( castBuffer.getShort(0) );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
obj = top_schema.createFromInt( castBuffer.getInt(0) );
|
||||||
|
break _push;
|
||||||
|
case CS_INT_64:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 8);
|
||||||
|
obj = top_schema.createFromLong( 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);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
break _fixed_trail_again;
|
||||||
|
case CS_RAW_32:
|
||||||
|
castBuffer.rewind();
|
||||||
|
castBuffer.put(src, n, 4);
|
||||||
|
// FIXME overflow check
|
||||||
|
trail = castBuffer.getInt(0) & 0x7fffffff;
|
||||||
|
if(trail == 0) {
|
||||||
|
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
cs = ACS_RAW_VALUE;
|
||||||
|
case ACS_RAW_VALUE:
|
||||||
|
obj = top_schema.createFromRaw(src, n, trail);
|
||||||
|
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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||||
|
++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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||||
|
++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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
stack_obj[top] = top_obj;
|
||||||
|
stack_ct[top] = top_ct;
|
||||||
|
stack_count[top] = top_count;
|
||||||
|
stack_schema[top] = top_schema;
|
||||||
|
++top;
|
||||||
|
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];
|
||||||
|
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||||
|
//System.out.println("fixmap count:"+count);
|
||||||
|
++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_MAP_KEY;
|
||||||
|
top_count = count;
|
||||||
|
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||||
|
break _header_again;
|
||||||
|
default:
|
||||||
|
throw new UnpackException("parse error");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // _fixed_trail_again
|
||||||
|
} while(true);
|
||||||
|
} // _push
|
||||||
|
|
||||||
|
do {
|
||||||
|
_push: {
|
||||||
|
//System.out.println("push top:"+top);
|
||||||
|
if(top == -1) {
|
||||||
|
++i;
|
||||||
|
data = obj;
|
||||||
|
finished = true;
|
||||||
|
break _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(top_ct) {
|
||||||
|
case CT_ARRAY_ITEM: {
|
||||||
|
//System.out.println("array item "+obj);
|
||||||
|
Object[] ar = (Object[])top_obj;
|
||||||
|
ar[ar.length - top_count] = obj;
|
||||||
|
if(--top_count == 0) {
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
case CT_MAP_KEY: {
|
||||||
|
//System.out.println("map key:"+top+" "+obj);
|
||||||
|
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: {
|
||||||
|
//System.out.println("map value:"+top+" "+obj);
|
||||||
|
Object[] mp = (Object[])top_obj;
|
||||||
|
mp[mp.length - top_count*2 + 1] = obj;
|
||||||
|
if(--top_count == 0) {
|
||||||
|
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);
|
||||||
|
stack_obj[top] = null;
|
||||||
|
stack_schema[top] = null;
|
||||||
|
--top;
|
||||||
|
break _push;
|
||||||
|
}
|
||||||
|
top_ct = CT_MAP_KEY;
|
||||||
|
break _header_again;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new UnpackException("parse error");
|
||||||
|
}
|
||||||
|
} // _push
|
||||||
|
} while(true);
|
||||||
|
|
||||||
|
} // _header_again
|
||||||
|
cs = CS_HEADER;
|
||||||
|
++i;
|
||||||
|
} while(i < limit); // _out
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
125
java-plan3/src/org/msgpack/schema/ArraySchema.java
Normal file
125
java-plan3/src/org/msgpack/schema/ArraySchema.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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.RandomAccess;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ArraySchema extends Schema implements IArraySchema {
|
||||||
|
private Schema elementSchema;
|
||||||
|
|
||||||
|
public ArraySchema(Schema elementSchema)
|
||||||
|
{
|
||||||
|
super("array");
|
||||||
|
this.elementSchema = elementSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName()
|
||||||
|
{
|
||||||
|
return "List<"+elementSchema.getFullName()+">";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression()
|
||||||
|
{
|
||||||
|
return "(array "+elementSchema.getExpression()+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException
|
||||||
|
{
|
||||||
|
if(obj instanceof List) {
|
||||||
|
ArrayList<Object> d = (ArrayList<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(Object obj) throws MessageTypeException
|
||||||
|
{
|
||||||
|
if(obj instanceof List) {
|
||||||
|
List d = (List)obj;
|
||||||
|
ArrayList ar = new ArrayList(d.size());
|
||||||
|
if(obj instanceof RandomAccess) {
|
||||||
|
for(int i=0; i < d.size(); ++i) {
|
||||||
|
ar.add( elementSchema.convert(d.get(i)) );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(Object e : d) {
|
||||||
|
ar.add( elementSchema.convert(e) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ar;
|
||||||
|
|
||||||
|
} else if(obj instanceof Collection) {
|
||||||
|
Collection d = (Collection)obj;
|
||||||
|
ArrayList ar = new ArrayList(d.size());
|
||||||
|
for(Object e : (Collection)obj) {
|
||||||
|
ar.add( elementSchema.convert(e) );
|
||||||
|
}
|
||||||
|
return ar;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Schema getElementSchema(int index)
|
||||||
|
{
|
||||||
|
return elementSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromArray(Object[] obj)
|
||||||
|
{
|
||||||
|
return Arrays.asList(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
89
java-plan3/src/org/msgpack/schema/ByteSchema.java
Normal file
89
java-plan3/src/org/msgpack/schema/ByteSchema.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ByteSchema extends Schema {
|
||||||
|
public ByteSchema() {
|
||||||
|
super("Byte");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "byte";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packByte( ((Number)obj).byteValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Byte) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).byteValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromLong(long v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (byte)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
241
java-plan3/src/org/msgpack/schema/ClassGenerator.java
Normal file
241
java-plan3/src/org/msgpack/schema/ClassGenerator.java
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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 ArraySchema) {
|
||||||
|
ArraySchema as = (ArraySchema)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.getName()+" implements MessagePackable, MessageMergeable");
|
||||||
|
line("{");
|
||||||
|
pushIndent();
|
||||||
|
writeSchema();
|
||||||
|
writeMemberVariables();
|
||||||
|
writeMemberFunctions();
|
||||||
|
popIndent();
|
||||||
|
line("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeSubclass() throws IOException {
|
||||||
|
line();
|
||||||
|
line("final class "+schema.getName()+" implements MessagePackable, MessageMergeable");
|
||||||
|
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().getFullName()+" "+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();
|
||||||
|
writeMergeFunction();
|
||||||
|
writeFactoryFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeConstructors() throws IOException {
|
||||||
|
line();
|
||||||
|
line("public "+schema.getName()+"() { }");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 writeMergeFunction() throws IOException {
|
||||||
|
line();
|
||||||
|
line("@Override");
|
||||||
|
line("@SuppressWarnings(\"unchecked\")");
|
||||||
|
line("public void messageMerge(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().getFullName()+")_fields["+i+"].getSchema().convert(_source["+i+"]);");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
popIndent();
|
||||||
|
line("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeFactoryFunction() throws IOException {
|
||||||
|
line();
|
||||||
|
line("@SuppressWarnings(\"unchecked\")");
|
||||||
|
line("public static "+schema.getName()+" createFromMessage(Object[] _message)");
|
||||||
|
line("{");
|
||||||
|
pushIndent();
|
||||||
|
line(schema.getName()+" _self = new "+schema.getName()+"();");
|
||||||
|
int i = 0;
|
||||||
|
for(FieldSchema f : schema.getFields()) {
|
||||||
|
line("if(_message.length <= "+i+") { return _self; } _self."+f.getName()+" = ("+f.getSchema().getFullName()+")_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
95
java-plan3/src/org/msgpack/schema/ClassSchema.java
Normal file
95
java-plan3/src/org/msgpack/schema/ClassSchema.java
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public abstract class ClassSchema extends Schema implements IArraySchema {
|
||||||
|
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) {
|
||||||
|
super(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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?
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Override
|
||||||
|
//public String getFullName()
|
||||||
|
//{
|
||||||
|
// if(namespace == null) {
|
||||||
|
// return getName();
|
||||||
|
// } else {
|
||||||
|
// return namespace+"."+getName();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
StringBuffer b = new StringBuffer();
|
||||||
|
b.append("(class ");
|
||||||
|
b.append(getName());
|
||||||
|
if(namespace != null) {
|
||||||
|
b.append(" (package "+namespace+")");
|
||||||
|
}
|
||||||
|
for(FieldSchema f : fields) {
|
||||||
|
b.append(" "+f.getExpression());
|
||||||
|
}
|
||||||
|
b.append(")");
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(SpecificClassSchema o) {
|
||||||
|
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
|
||||||
|
getName().equals(o.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
84
java-plan3/src/org/msgpack/schema/DoubleSchema.java
Normal file
84
java-plan3/src/org/msgpack/schema/DoubleSchema.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class DoubleSchema extends Schema {
|
||||||
|
public DoubleSchema() {
|
||||||
|
super("Double");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "double";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packDouble( ((Number)obj).doubleValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Double) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).doubleValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
return (double)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
return (double)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
return (double)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (double)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (double)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
43
java-plan3/src/org/msgpack/schema/FieldSchema.java
Normal file
43
java-plan3/src/org/msgpack/schema/FieldSchema.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import org.msgpack.Schema;
|
||||||
|
|
||||||
|
public class FieldSchema {
|
||||||
|
private String name;
|
||||||
|
private Schema schema;
|
||||||
|
|
||||||
|
public FieldSchema(String name, Schema schema) {
|
||||||
|
this.name = name;
|
||||||
|
this.schema = schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Schema getSchema() {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpression() {
|
||||||
|
return "(field "+name+" "+schema.getExpression()+")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
84
java-plan3/src/org/msgpack/schema/FloatSchema.java
Normal file
84
java-plan3/src/org/msgpack/schema/FloatSchema.java
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class FloatSchema extends Schema {
|
||||||
|
public FloatSchema() {
|
||||||
|
super("Float");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "float";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packFloat( ((Number)obj).floatValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Float) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).floatValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
return (float)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
return (float)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
return (float)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (float)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (float)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
91
java-plan3/src/org/msgpack/schema/GenericClassSchema.java
Normal file
91
java-plan3/src/org/msgpack/schema/GenericClassSchema.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
192
java-plan3/src/org/msgpack/schema/GenericSchema.java
Normal file
192
java-plan3/src/org/msgpack/schema/GenericSchema.java
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
//import org.msgpack.generic.*;
|
||||||
|
|
||||||
|
public class GenericSchema extends Schema implements IArraySchema, IMapSchema {
|
||||||
|
public GenericSchema() {
|
||||||
|
super("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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@Override
|
||||||
|
public Object createFromNil() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromBoolean(boolean v) {
|
||||||
|
return new GenericBoolean(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFromByte(byte v) {
|
||||||
|
return new GenericByte(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
return new GenericShort(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
return new GenericInt(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromLong(long v) {
|
||||||
|
return new GenericLong(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return new GenericFloat(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return new GenericDouble(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||||
|
return new GenericRaw(b, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromArray(Object[] obj) {
|
||||||
|
// FIXME GenericArray
|
||||||
|
return Arrays.asList(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromMap(Object[] obj) {
|
||||||
|
GenericMap m = new GenericMap(obj.length / 2);
|
||||||
|
int i = 0;
|
||||||
|
while(i < obj.length) {
|
||||||
|
Object k = obj[i++];
|
||||||
|
Object v = obj[i++];
|
||||||
|
m.put(k, v);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
26
java-plan3/src/org/msgpack/schema/IArraySchema.java
Normal file
26
java-plan3/src/org/msgpack/schema/IArraySchema.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import org.msgpack.Schema;
|
||||||
|
|
||||||
|
public interface IArraySchema {
|
||||||
|
public Schema getElementSchema(int index);
|
||||||
|
public Object createFromArray(Object[] obj);
|
||||||
|
}
|
||||||
|
|
27
java-plan3/src/org/msgpack/schema/IMapSchema.java
Normal file
27
java-plan3/src/org/msgpack/schema/IMapSchema.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import org.msgpack.Schema;
|
||||||
|
|
||||||
|
public interface IMapSchema {
|
||||||
|
public Schema getKeySchema();
|
||||||
|
public Schema getValueSchema();
|
||||||
|
public Object createFromMap(Object[] obj);
|
||||||
|
}
|
||||||
|
|
89
java-plan3/src/org/msgpack/schema/IntSchema.java
Normal file
89
java-plan3/src/org/msgpack/schema/IntSchema.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class IntSchema extends Schema {
|
||||||
|
public IntSchema() {
|
||||||
|
super("Integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "int";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packInt( ((Number)obj).intValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Integer) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).intValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (int)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
89
java-plan3/src/org/msgpack/schema/LongSchema.java
Normal file
89
java-plan3/src/org/msgpack/schema/LongSchema.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class LongSchema extends Schema {
|
||||||
|
public LongSchema() {
|
||||||
|
super("Long");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "long";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packLong( ((Number)obj).longValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Long) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).longValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (long)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
102
java-plan3/src/org/msgpack/schema/MapSchema.java
Normal file
102
java-plan3/src/org/msgpack/schema/MapSchema.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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) {
|
||||||
|
super("map");
|
||||||
|
this.keySchema = keySchema;
|
||||||
|
this.valueSchema = valueSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName() {
|
||||||
|
return "HashList<"+keySchema.getFullName()+", "+valueSchema.getFullName()+">";
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Map) {
|
||||||
|
Map<Object,Object> d = (Map<Object,Object>)obj;
|
||||||
|
Map<Object,Object> m = new HashMap<Object,Object>();
|
||||||
|
for(Map.Entry<Object,Object> e : d.entrySet()) {
|
||||||
|
m.put(keySchema.convert(e.getKey()), valueSchema.convert(e.getValue()));
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Schema getKeySchema() {
|
||||||
|
return keySchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Schema getValueSchema() {
|
||||||
|
return valueSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
105
java-plan3/src/org/msgpack/schema/RawSchema.java
Normal file
105
java-plan3/src/org/msgpack/schema/RawSchema.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class RawSchema extends Schema {
|
||||||
|
public RawSchema() {
|
||||||
|
super("raw");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFullName() {
|
||||||
|
return "byte[]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
// FIXME instanceof GenericObject
|
||||||
|
if(obj instanceof byte[]) {
|
||||||
|
byte[] d = (byte[])obj;
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
|
||||||
|
} else if(obj instanceof ByteBuffer) {
|
||||||
|
ByteBuffer d = (ByteBuffer)obj;
|
||||||
|
if(!d.hasArray()) {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
pk.packRaw(d.capacity());
|
||||||
|
pk.packRawBody(d.array(), d.position(), d.capacity());
|
||||||
|
|
||||||
|
} else if(obj instanceof String) {
|
||||||
|
try {
|
||||||
|
byte[] d = ((String)obj).getBytes("UTF-8");
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
// FIXME instanceof GenericObject
|
||||||
|
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 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 MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||||
|
byte[] d = new byte[length];
|
||||||
|
System.arraycopy(b, offset, d, 0, length);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
64
java-plan3/src/org/msgpack/schema/ReflectionClassSchema.java
Normal file
64
java-plan3/src/org/msgpack/schema/ReflectionClassSchema.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
254
java-plan3/src/org/msgpack/schema/SSchemaParser.java
Normal file
254
java-plan3/src/org/msgpack/schema/SSchemaParser.java
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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 RawSchema();
|
||||||
|
} 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 parseArray(exp);
|
||||||
|
} else if(type.equals("map")) {
|
||||||
|
return parseMap(exp);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("class, array 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 ArraySchema parseArray(SExp exp) {
|
||||||
|
if(exp.size() != 2) {
|
||||||
|
throw new RuntimeException("array is (array ELEMENT_TYPE): "+exp);
|
||||||
|
}
|
||||||
|
Schema elementType = readType(exp.getTuple(1));
|
||||||
|
return new ArraySchema(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
89
java-plan3/src/org/msgpack/schema/ShortSchema.java
Normal file
89
java-plan3/src/org/msgpack/schema/ShortSchema.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
package org.msgpack.schema;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.msgpack.*;
|
||||||
|
|
||||||
|
public class ShortSchema extends Schema {
|
||||||
|
public ShortSchema() {
|
||||||
|
super("Short");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getExpression() {
|
||||||
|
return "short";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
if(obj instanceof Number) {
|
||||||
|
pk.packShort( ((Number)obj).shortValue() );
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
if(obj instanceof Short) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof Number) {
|
||||||
|
return ((Number)obj).shortValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromByte(byte v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromShort(short v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromInt(int v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromLong(long v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromFloat(float v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createFromDouble(double v) {
|
||||||
|
return (short)v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
122
java-plan3/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
122
java-plan3/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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 {
|
||||||
|
MessageMergeable o = (MessageMergeable)constructorCache.newInstance((Object[])null);
|
||||||
|
o.messageMerge(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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
111
java-plan3/src/org/msgpack/schema/StringSchema.java
Normal file
111
java-plan3/src/org/msgpack/schema/StringSchema.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// MessagePack for Java
|
||||||
|
//
|
||||||
|
// Copyright (C) 2009 FURUHASHI Sadayuki
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
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() {
|
||||||
|
super("string");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullName() {
|
||||||
|
return "String";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pack(Packer pk, Object obj) throws IOException {
|
||||||
|
// FIXME instanceof GenericObject
|
||||||
|
if(obj instanceof String) {
|
||||||
|
try {
|
||||||
|
byte[] d = ((String)obj).getBytes("UTF-8");
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(obj instanceof byte[]) {
|
||||||
|
byte[] d = (byte[])obj;
|
||||||
|
pk.packRaw(d.length);
|
||||||
|
pk.packRawBody(d);
|
||||||
|
|
||||||
|
} else if(obj instanceof ByteBuffer) {
|
||||||
|
ByteBuffer d = (ByteBuffer)obj;
|
||||||
|
if(!d.hasArray()) {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
pk.packRaw(d.capacity());
|
||||||
|
pk.packRawBody(d.array(), d.position(), d.capacity());
|
||||||
|
|
||||||
|
} else if(obj == null) {
|
||||||
|
pk.packNil();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object convert(Object obj) throws MessageTypeException {
|
||||||
|
// FIXME instanceof GenericObject
|
||||||
|
if(obj instanceof String) {
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
} else if(obj instanceof byte[]) {
|
||||||
|
try {
|
||||||
|
return new String((byte[])obj, "UTF-8");
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} 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 MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw MessageTypeException.invalidConvert(obj, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
java-plan3/test/Generate.java
Normal file
38
java-plan3/test/Generate.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.msgpack.*;
|
||||||
|
import org.msgpack.schema.*;
|
||||||
|
|
||||||
|
public class Generate {
|
||||||
|
public static void main(String[] args) throws IOException
|
||||||
|
{
|
||||||
|
String source =
|
||||||
|
"(class MediaContent"+
|
||||||
|
" (package serializers.msgpack)"+
|
||||||
|
" (field image (array (class Image"+
|
||||||
|
" (field uri string)"+
|
||||||
|
" (field title string)"+
|
||||||
|
" (field width int)"+
|
||||||
|
" (field height int)"+
|
||||||
|
" (field size int))))"+
|
||||||
|
" (field media (class Media"+
|
||||||
|
" (field uri string)"+
|
||||||
|
" (field title string)"+
|
||||||
|
" (field width int)"+
|
||||||
|
" (field height int)"+
|
||||||
|
" (field format string)"+
|
||||||
|
" (field duration long)"+
|
||||||
|
" (field size long)"+
|
||||||
|
" (field bitrate int)"+
|
||||||
|
" (field person (array string))"+
|
||||||
|
" (field player int)"+
|
||||||
|
" (field copyright string)))"+
|
||||||
|
" )";
|
||||||
|
|
||||||
|
Schema schema = Schema.parse(source);
|
||||||
|
|
||||||
|
Writer output = new OutputStreamWriter(System.out);
|
||||||
|
ClassGenerator.write(schema, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,173 @@
|
|||||||
|
package serializers.msgpack;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import org.msgpack.*;
|
||||||
|
import org.msgpack.schema.ClassSchema;
|
||||||
|
import org.msgpack.schema.FieldSchema;
|
||||||
|
|
||||||
|
public final class MediaContent implements MessagePackable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class MediaContent (package serializers.msgpack) (field image (array (class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int)))) (field media (class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public List<Image> image;
|
||||||
|
public Media media;
|
||||||
|
|
||||||
|
public MediaContent() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer _pk) throws IOException
|
||||||
|
{
|
||||||
|
_pk.packArray(2);
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
_fields[0].getSchema().pack(_pk, image);
|
||||||
|
_fields[1].getSchema().pack(_pk, media);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageMerge(Object obj) throws MessageTypeException
|
||||||
|
{
|
||||||
|
Object[] _source = ((List)obj).toArray();
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
if(_source.length <= 0) { return; } this.image = (List<Image>)_fields[0].getSchema().convert(_source[0]);
|
||||||
|
if(_source.length <= 1) { return; } this.media = (Media)_fields[1].getSchema().convert(_source[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static MediaContent createFromMessage(Object[] _message)
|
||||||
|
{
|
||||||
|
MediaContent _self = new MediaContent();
|
||||||
|
if(_message.length <= 0) { return _self; } _self.image = (List<Image>)_message[0];
|
||||||
|
if(_message.length <= 1) { return _self; } _self.media = (Media)_message[1];
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Image implements MessagePackable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Image (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field size int))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public String uri;
|
||||||
|
public String title;
|
||||||
|
public Integer width;
|
||||||
|
public Integer height;
|
||||||
|
public Integer size;
|
||||||
|
|
||||||
|
public Image() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer _pk) throws IOException
|
||||||
|
{
|
||||||
|
_pk.packArray(5);
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
_fields[0].getSchema().pack(_pk, uri);
|
||||||
|
_fields[1].getSchema().pack(_pk, title);
|
||||||
|
_fields[2].getSchema().pack(_pk, width);
|
||||||
|
_fields[3].getSchema().pack(_pk, height);
|
||||||
|
_fields[4].getSchema().pack(_pk, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageMerge(Object obj) throws MessageTypeException
|
||||||
|
{
|
||||||
|
Object[] _source = ((List)obj).toArray();
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
if(_source.length <= 0) { return; } this.uri = (String)_fields[0].getSchema().convert(_source[0]);
|
||||||
|
if(_source.length <= 1) { return; } this.title = (String)_fields[1].getSchema().convert(_source[1]);
|
||||||
|
if(_source.length <= 2) { return; } this.width = (Integer)_fields[2].getSchema().convert(_source[2]);
|
||||||
|
if(_source.length <= 3) { return; } this.height = (Integer)_fields[3].getSchema().convert(_source[3]);
|
||||||
|
if(_source.length <= 4) { return; } this.size = (Integer)_fields[4].getSchema().convert(_source[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Image createFromMessage(Object[] _message)
|
||||||
|
{
|
||||||
|
Image _self = new Image();
|
||||||
|
if(_message.length <= 0) { return _self; } _self.uri = (String)_message[0];
|
||||||
|
if(_message.length <= 1) { return _self; } _self.title = (String)_message[1];
|
||||||
|
if(_message.length <= 2) { return _self; } _self.width = (Integer)_message[2];
|
||||||
|
if(_message.length <= 3) { return _self; } _self.height = (Integer)_message[3];
|
||||||
|
if(_message.length <= 4) { return _self; } _self.size = (Integer)_message[4];
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Media implements MessagePackable, MessageMergeable
|
||||||
|
{
|
||||||
|
private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load("(class Media (package serializers.msgpack) (field uri string) (field title string) (field width int) (field height int) (field format string) (field duration long) (field size long) (field bitrate int) (field person (array string)) (field player int) (field copyright string))");
|
||||||
|
public static ClassSchema getSchema() { return _SCHEMA; }
|
||||||
|
|
||||||
|
public String uri;
|
||||||
|
public String title;
|
||||||
|
public Integer width;
|
||||||
|
public Integer height;
|
||||||
|
public String format;
|
||||||
|
public Long duration;
|
||||||
|
public Long size;
|
||||||
|
public Integer bitrate;
|
||||||
|
public List<String> person;
|
||||||
|
public Integer player;
|
||||||
|
public String copyright;
|
||||||
|
|
||||||
|
public Media() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messagePack(Packer _pk) throws IOException
|
||||||
|
{
|
||||||
|
_pk.packArray(11);
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
_fields[0].getSchema().pack(_pk, uri);
|
||||||
|
_fields[1].getSchema().pack(_pk, title);
|
||||||
|
_fields[2].getSchema().pack(_pk, width);
|
||||||
|
_fields[3].getSchema().pack(_pk, height);
|
||||||
|
_fields[4].getSchema().pack(_pk, format);
|
||||||
|
_fields[5].getSchema().pack(_pk, duration);
|
||||||
|
_fields[6].getSchema().pack(_pk, size);
|
||||||
|
_fields[7].getSchema().pack(_pk, bitrate);
|
||||||
|
_fields[8].getSchema().pack(_pk, person);
|
||||||
|
_fields[9].getSchema().pack(_pk, player);
|
||||||
|
_fields[10].getSchema().pack(_pk, copyright);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void messageMerge(Object obj) throws MessageTypeException
|
||||||
|
{
|
||||||
|
Object[] _source = ((List)obj).toArray();
|
||||||
|
FieldSchema[] _fields = _SCHEMA.getFields();
|
||||||
|
if(_source.length <= 0) { return; } this.uri = (String)_fields[0].getSchema().convert(_source[0]);
|
||||||
|
if(_source.length <= 1) { return; } this.title = (String)_fields[1].getSchema().convert(_source[1]);
|
||||||
|
if(_source.length <= 2) { return; } this.width = (Integer)_fields[2].getSchema().convert(_source[2]);
|
||||||
|
if(_source.length <= 3) { return; } this.height = (Integer)_fields[3].getSchema().convert(_source[3]);
|
||||||
|
if(_source.length <= 4) { return; } this.format = (String)_fields[4].getSchema().convert(_source[4]);
|
||||||
|
if(_source.length <= 5) { return; } this.duration = (Long)_fields[5].getSchema().convert(_source[5]);
|
||||||
|
if(_source.length <= 6) { return; } this.size = (Long)_fields[6].getSchema().convert(_source[6]);
|
||||||
|
if(_source.length <= 7) { return; } this.bitrate = (Integer)_fields[7].getSchema().convert(_source[7]);
|
||||||
|
if(_source.length <= 8) { return; } this.person = (List<String>)_fields[8].getSchema().convert(_source[8]);
|
||||||
|
if(_source.length <= 9) { return; } this.player = (Integer)_fields[9].getSchema().convert(_source[9]);
|
||||||
|
if(_source.length <= 10) { return; } this.copyright = (String)_fields[10].getSchema().convert(_source[10]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Media createFromMessage(Object[] _message)
|
||||||
|
{
|
||||||
|
Media _self = new Media();
|
||||||
|
if(_message.length <= 0) { return _self; } _self.uri = (String)_message[0];
|
||||||
|
if(_message.length <= 1) { return _self; } _self.title = (String)_message[1];
|
||||||
|
if(_message.length <= 2) { return _self; } _self.width = (Integer)_message[2];
|
||||||
|
if(_message.length <= 3) { return _self; } _self.height = (Integer)_message[3];
|
||||||
|
if(_message.length <= 4) { return _self; } _self.format = (String)_message[4];
|
||||||
|
if(_message.length <= 5) { return _self; } _self.duration = (Long)_message[5];
|
||||||
|
if(_message.length <= 6) { return _self; } _self.size = (Long)_message[6];
|
||||||
|
if(_message.length <= 7) { return _self; } _self.bitrate = (Integer)_message[7];
|
||||||
|
if(_message.length <= 8) { return _self; } _self.person = (List<String>)_message[8];
|
||||||
|
if(_message.length <= 9) { return _self; } _self.player = (Integer)_message[9];
|
||||||
|
if(_message.length <= 10) { return _self; } _self.copyright = (String)_message[10];
|
||||||
|
return _self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
(class MediaContent
|
||||||
|
(package serializers.msgpack)
|
||||||
|
(field image (array (class Image
|
||||||
|
(field uri string)
|
||||||
|
(field title string)
|
||||||
|
(field width int)
|
||||||
|
(field height int)
|
||||||
|
(field size int))))
|
||||||
|
(field media (class Media
|
||||||
|
(field uri string)
|
||||||
|
(field title string)
|
||||||
|
(field width int)
|
||||||
|
(field height int)
|
||||||
|
(field format string)
|
||||||
|
(field duration long)
|
||||||
|
(field size long)
|
||||||
|
(field bitrate int)
|
||||||
|
(field person (array string))
|
||||||
|
(field player int)
|
||||||
|
(field copyright string)))
|
||||||
|
)
|
@ -0,0 +1,68 @@
|
|||||||
|
package serializers.msgpack;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.msgpack.*;
|
||||||
|
import serializers.ObjectSerializer;
|
||||||
|
|
||||||
|
public class MessagePackDynamicSerializer implements ObjectSerializer<Object>
|
||||||
|
{
|
||||||
|
public String getName() {
|
||||||
|
return "msgpack-dynamic";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object create() throws Exception {
|
||||||
|
ArrayList media = new ArrayList(11);
|
||||||
|
media.add("http://javaone.com/keynote.mpg");
|
||||||
|
media.add("video/mpg4");
|
||||||
|
media.add("Javaone Keynote");
|
||||||
|
media.add(1234567L);
|
||||||
|
media.add(0);
|
||||||
|
ArrayList<String> person = new ArrayList<String>(2);
|
||||||
|
person.add("Bill Gates");
|
||||||
|
person.add("Steve Jobs");
|
||||||
|
media.add(person);
|
||||||
|
media.add(0);
|
||||||
|
media.add(0);
|
||||||
|
media.add(0);
|
||||||
|
media.add(123L);
|
||||||
|
media.add("");
|
||||||
|
|
||||||
|
ArrayList image1 = new ArrayList(5);
|
||||||
|
image1.add("http://javaone.com/keynote_large.jpg");
|
||||||
|
image1.add(0);
|
||||||
|
image1.add(0);
|
||||||
|
image1.add(2);
|
||||||
|
image1.add("Javaone Keynote");
|
||||||
|
|
||||||
|
ArrayList image2 = new ArrayList(5);
|
||||||
|
image2.add("http://javaone.com/keynote_thumbnail.jpg");
|
||||||
|
image2.add(0);
|
||||||
|
image2.add(0);
|
||||||
|
image2.add(1);
|
||||||
|
image2.add("Javaone Keynote");
|
||||||
|
|
||||||
|
ArrayList content = new ArrayList(2);
|
||||||
|
content.add(media);
|
||||||
|
ArrayList<Object> images = new ArrayList<Object>(2);
|
||||||
|
images.add(image1);
|
||||||
|
images.add(image2);
|
||||||
|
content.add(images);
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] serialize(Object content) throws Exception {
|
||||||
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
Packer pk = new Packer(os);
|
||||||
|
pk.pack(content);
|
||||||
|
return os.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object deserialize(byte[] array) throws Exception {
|
||||||
|
UnbufferedUnpacker pac = new UnbufferedUnpacker();
|
||||||
|
pac.execute(array);
|
||||||
|
return (Object)pac.getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user