java: uses MessagePackObject instead of Object for type of deserialized objects

This commit is contained in:
frsyuki
2010-08-18 18:10:30 +09:00
parent 8c67087a15
commit 8b79e6d3c7
31 changed files with 270 additions and 2644 deletions

View File

@@ -47,7 +47,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
offset = noffset;
} while(!super.isFinished());
Object obj = super.getData();
MessagePackObject obj = super.getData();
super.reset();
result.done(obj);
@@ -198,7 +198,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
{
long o = castBuffer.getLong(0);
if(o < 0) {
// FIXME
// FIXME unpackBigInteger
throw new MessageTypeException("uint 64 bigger than 0x7fffffff is not supported");
}
advance(9);
@@ -231,6 +231,8 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
}
}
// FIXME unpackBigInteger
final float unpackFloat() throws IOException, MessageTypeException {
more(1);
int b = buffer[offset];
@@ -414,7 +416,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
return s;
}
final Object unpackObject() throws IOException {
final MessagePackObject unpackObject() throws IOException {
UnpackResult result = new UnpackResult();
if(!next(result)) {
super.reset();

View File

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

View File

@@ -308,12 +308,6 @@ public class Packer {
}
public Packer packWithSchema(Object o, Schema s) throws IOException {
s.pack(this, o);
return this;
}
public Packer packString(String s) throws IOException {
byte[] b = ((String)s).getBytes("UTF-8");
packRaw(b.length);

View File

@@ -1,78 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack;
import java.io.Writer;
import java.io.IOException;
import org.msgpack.schema.SSchemaParser;
//import org.msgpack.schema.ClassGenerator;
public abstract class Schema {
public Schema() { }
public abstract String getClassName();
public abstract String getExpression();
public static Schema parse(String source) {
return SSchemaParser.parse(source);
}
public static Schema load(String source) {
return SSchemaParser.load(source);
}
public abstract void pack(Packer pk, Object obj) throws IOException;
public abstract Object convert(Object obj) throws MessageTypeException;
public Object createFromNil() {
return null;
}
public Object createFromBoolean(boolean v) {
throw new MessageTypeException("type error");
}
public Object createFromByte(byte v) {
throw new MessageTypeException("type error");
}
public Object createFromShort(short v) {
throw new MessageTypeException("type error");
}
public Object createFromInt(int v) {
throw new MessageTypeException("type error");
}
public Object createFromLong(long v) {
throw new MessageTypeException("type error");
}
public Object createFromFloat(float v) {
throw new MessageTypeException("type error");
}
public Object createFromDouble(double v) {
throw new MessageTypeException("type error");
}
public Object createFromRaw(byte[] b, int offset, int length) {
throw new MessageTypeException("type error");
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,64 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class BooleanSchema extends Schema {
public BooleanSchema() { }
@Override
public String getClassName() {
return "Boolean";
}
@Override
public String getExpression() {
return "boolean";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Boolean) {
pk.packBoolean((Boolean)obj);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final boolean convertBoolean(Object obj) throws MessageTypeException {
if(obj instanceof Boolean) {
return (Boolean)obj;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertBoolean(obj);
}
@Override
public Object createFromBoolean(boolean v) {
return v;
}
}

View File

@@ -1,97 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.msgpack.*;
public class ByteArraySchema extends Schema {
public ByteArraySchema() { }
@Override
public String getClassName() {
return "byte[]";
}
@Override
public String getExpression() {
return "raw";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof byte[]) {
byte[] b = (byte[])obj;
pk.packRaw(b.length);
pk.packRawBody(b);
} else if(obj instanceof String) {
try {
byte[] b = ((String)obj).getBytes("UTF-8");
pk.packRaw(b.length);
pk.packRawBody(b);
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final byte[] convertByteArray(Object obj) throws MessageTypeException {
if(obj instanceof byte[]) {
// FIXME copy?
//byte[] d = (byte[])obj;
//byte[] v = new byte[d.length];
//System.arraycopy(d, 0, v, 0, d.length);
//return v;
return (byte[])obj;
} else if(obj instanceof ByteBuffer) {
ByteBuffer d = (ByteBuffer)obj;
byte[] v = new byte[d.capacity()];
int pos = d.position();
d.get(v);
d.position(pos);
return v;
} else if(obj instanceof String) {
try {
return ((String)obj).getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertByteArray(obj);
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
byte[] d = new byte[length];
System.arraycopy(b, offset, d, 0, length);
return d;
}
}

View File

@@ -1,96 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class ByteSchema extends Schema {
public ByteSchema() { }
@Override
public String getClassName() {
return "Byte";
}
@Override
public String getExpression() {
return "byte";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
short value = ((Number)obj).shortValue();
if(value > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
pk.packByte((byte)value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final byte convertByte(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
short value = ((Number)obj).shortValue();
if(value > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertByte(obj);
}
@Override
public Object createFromByte(byte v) {
return (byte)v;
}
@Override
public Object createFromShort(short v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
@Override
public Object createFromInt(int v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
@Override
public Object createFromLong(long v) {
if(v > Byte.MAX_VALUE) {
throw new MessageTypeException();
}
return (byte)v;
}
}

View File

@@ -1,244 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.io.File;
import java.io.Writer;
import org.msgpack.*;
public class ClassGenerator {
private ClassSchema schema;
private Writer writer;
private int indent;
private ClassGenerator(Writer writer) {
this.writer = writer;
this.indent = 0;
}
public static void write(Schema schema, Writer dest) throws IOException {
if(!(schema instanceof ClassSchema)) {
throw new RuntimeException("schema is not class schema");
}
ClassSchema cs = (ClassSchema)schema;
new ClassGenerator(dest).run(cs);
}
private void run(ClassSchema cs) throws IOException {
List<ClassSchema> subclasses = new ArrayList<ClassSchema>();
for(FieldSchema f : cs.getFields()) {
findSubclassSchema(subclasses, f.getSchema());
}
for(ClassSchema sub : subclasses) {
sub.setNamespace(cs.getNamespace());
sub.setImports(cs.getImports());
}
this.schema = cs;
writeHeader();
writeClass();
for(ClassSchema sub : subclasses) {
this.schema = sub;
writeSubclass();
}
writeFooter();
this.schema = null;
writer.flush();
}
private void findSubclassSchema(List<ClassSchema> dst, Schema s) {
if(s instanceof ClassSchema) {
ClassSchema cs = (ClassSchema)s;
if(!dst.contains(cs)) { dst.add(cs); }
for(FieldSchema f : cs.getFields()) {
findSubclassSchema(dst, f.getSchema());
}
} else if(s instanceof ListSchema) {
ListSchema as = (ListSchema)s;
findSubclassSchema(dst, as.getElementSchema(0));
} else if(s instanceof SetSchema) {
SetSchema as = (SetSchema)s;
findSubclassSchema(dst, as.getElementSchema(0));
} else if(s instanceof MapSchema) {
MapSchema as = (MapSchema)s;
findSubclassSchema(dst, as.getKeySchema());
findSubclassSchema(dst, as.getValueSchema());
}
}
private void writeHeader() throws IOException {
if(schema.getNamespace() != null) {
line("package "+schema.getNamespace()+";");
line();
}
line("import java.util.*;");
line("import java.io.*;");
line("import org.msgpack.*;");
line("import org.msgpack.schema.ClassSchema;");
line("import org.msgpack.schema.FieldSchema;");
}
private void writeFooter() throws IOException {
line();
}
private void writeClass() throws IOException {
line();
line("public final class "+schema.getClassName()+" implements MessagePackable, MessageConvertable");
line("{");
pushIndent();
writeSchema();
writeMemberVariables();
writeMemberFunctions();
popIndent();
line("}");
}
private void writeSubclass() throws IOException {
line();
line("final class "+schema.getClassName()+" implements MessagePackable, MessageConvertable");
line("{");
pushIndent();
writeSchema();
writeMemberVariables();
writeMemberFunctions();
popIndent();
line("}");
}
private void writeSchema() throws IOException {
line("private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load(\""+schema.getExpression()+"\");");
line("public static ClassSchema getSchema() { return _SCHEMA; }");
}
private void writeMemberVariables() throws IOException {
line();
for(FieldSchema f : schema.getFields()) {
line("public "+f.getSchema().getClassName()+" "+f.getName()+";");
}
}
private void writeMemberFunctions() throws IOException {
// void messagePack(Packer pk)
// boolean equals(Object obj)
// int hashCode()
// void set(int _index, Object _value)
// Object get(int _index);
// getXxx()
// setXxx(Xxx xxx)
writeConstructors();
writeAccessors();
writePackFunction();
writeConvertFunction();
writeFactoryFunction();
}
private void writeConstructors() throws IOException {
line();
line("public "+schema.getClassName()+"() { }");
}
private void writeAccessors() throws IOException {
// FIXME
//line();
//for(FieldSchema f : schema.getFields()) {
// line("");
//}
}
private void writePackFunction() throws IOException {
line();
line("@Override");
line("public void messagePack(Packer _pk) throws IOException");
line("{");
pushIndent();
line("_pk.packArray("+schema.getFields().length+");");
line("FieldSchema[] _fields = _SCHEMA.getFields();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("_fields["+i+"].getSchema().pack(_pk, "+f.getName()+");");
++i;
}
popIndent();
line("}");
}
private void writeConvertFunction() throws IOException {
line();
line("@Override");
line("@SuppressWarnings(\"unchecked\")");
line("public void messageConvert(Object obj) throws MessageTypeException");
line("{");
pushIndent();
line("Object[] _source = ((List)obj).toArray();");
line("FieldSchema[] _fields = _SCHEMA.getFields();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("if(_source.length <= "+i+") { return; } this."+f.getName()+" = ("+f.getSchema().getClassName()+")_fields["+i+"].getSchema().convert(_source["+i+"]);");
++i;
}
popIndent();
line("}");
}
private void writeFactoryFunction() throws IOException {
line();
line("@SuppressWarnings(\"unchecked\")");
line("public static "+schema.getClassName()+" createFromMessage(Object[] _message)");
line("{");
pushIndent();
line(schema.getClassName()+" _self = new "+schema.getClassName()+"();");
int i = 0;
for(FieldSchema f : schema.getFields()) {
line("if(_message.length <= "+i+") { return _self; } _self."+f.getName()+" = ("+f.getSchema().getClassName()+")_message["+i+"];");
++i;
}
line("return _self;");
popIndent();
line("}");
}
private void line(String str) throws IOException {
for(int i=0; i < indent; ++i) {
writer.write("\t");
}
writer.write(str+"\n");
}
private void line() throws IOException {
writer.write("\n");
}
private void pushIndent() {
indent += 1;
}
private void popIndent() {
indent -= 1;
}
}

View File

@@ -1,91 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.List;
import org.msgpack.*;
public abstract class ClassSchema extends Schema implements IArraySchema {
protected String name;
protected FieldSchema[] fields;
protected List<String> imports;
protected String namespace;
protected String fqdn;
public ClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
this.name = name;
this.namespace = namespace;
this.imports = imports; // FIXME clone?
this.fields = new FieldSchema[fields.size()];
System.arraycopy(fields.toArray(), 0, this.fields, 0, fields.size());
if(namespace == null) {
this.fqdn = name;
} else {
this.fqdn = namespace+"."+name;
}
}
@Override
public String getClassName() {
return name;
}
@Override
public String getExpression() {
StringBuffer b = new StringBuffer();
b.append("(class ");
b.append(name);
if(namespace != null) {
b.append(" (package "+namespace+")");
}
for(FieldSchema f : fields) {
b.append(" "+f.getExpression());
}
b.append(")");
return b.toString();
}
public boolean equals(ClassSchema o) {
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
name.equals(o.name);
}
public final FieldSchema[] getFields() {
return fields;
}
String getNamespace() {
return namespace;
}
List<String> getImports() {
return imports;
}
void setNamespace(String namespace) {
this.namespace = namespace;
}
void setImports(List<String> imports) {
this.imports = imports; // FIXME clone?
}
}

View File

@@ -1,74 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class DoubleSchema extends Schema {
public DoubleSchema() { }
@Override
public String getClassName() {
return "Double";
}
@Override
public String getExpression() {
return "double";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Double) {
pk.packDouble((Double)obj);
} else if(obj instanceof Float) {
pk.packFloat((Float)obj);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final double convertDouble(Object obj) throws MessageTypeException {
if(obj instanceof Double) {
return (Double)obj;
} else if(obj instanceof Float) {
return ((Float)obj).doubleValue();
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertDouble(obj);
}
@Override
public Object createFromFloat(float v) {
return (double)v;
}
@Override
public Object createFromDouble(double v) {
return (double)v;
}
}

View File

@@ -1,43 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import org.msgpack.Schema;
public 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()+")";
}
}

View File

@@ -1,74 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class FloatSchema extends Schema {
public FloatSchema() { }
@Override
public String getClassName() {
return "Float";
}
@Override
public String getExpression() {
return "float";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Double) {
pk.packDouble((Double)obj);
} else if(obj instanceof Float) {
pk.packFloat((Float)obj);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final float convertFloat(Object obj) throws MessageTypeException {
if(obj instanceof Double) {
return ((Double)obj).floatValue();
} else if(obj instanceof Float) {
return (Float)obj;
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertFloat(obj);
}
@Override
public Object createFromFloat(float v) {
return (float)v;
}
@Override
public Object createFromDouble(double v) {
return (float)v;
}
}

View File

@@ -1,87 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class GenericClassSchema extends ClassSchema {
public GenericClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
super(name, namespace, imports, fields);
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Map) {
Map d = (Map)obj;
pk.packArray(fields.length);
for(int i=0; i < fields.length; ++i) {
FieldSchema f = fields[i];
f.getSchema().pack(pk, d.get(f.getName()));
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
if(obj instanceof Collection) {
// FIXME optimize
return createFromArray( ((Collection)obj).toArray() );
} else if(obj instanceof Map) {
HashMap<String,Object> m = new HashMap<String,Object>(fields.length);
Map d = (Map)obj;
for(int i=0; i < fields.length; ++i) {
FieldSchema f = fields[i];
String fieldName = f.getName();
m.put(fieldName, f.getSchema().convert(d.get(fieldName)));
}
return m;
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public Schema getElementSchema(int index) {
// FIXME check index < fields.length
return fields[index].getSchema();
}
public Object createFromArray(Object[] obj) {
HashMap<String,Object> m = new HashMap<String,Object>(fields.length);
int i=0;
for(; i < obj.length; ++i) {
m.put(fields[i].getName(), obj[i]);
}
for(; i < fields.length; ++i) {
m.put(fields[i].getName(), null);
}
return m;
}
}

View File

@@ -1,129 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class GenericSchema extends Schema implements IArraySchema, IMapSchema {
public GenericSchema() { }
@Override
public String getClassName() {
return "Object";
}
@Override
public String getExpression() {
return "object";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
pk.pack(obj);
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return obj;
}
@Override
public Schema getElementSchema(int index) {
return this;
}
@Override
public Schema getKeySchema() {
return this;
}
@Override
public Schema getValueSchema() {
return this;
}
@Override
public Object createFromNil() {
return null;
}
@Override
public Object createFromBoolean(boolean v) {
return v;
}
@Override
public Object createFromByte(byte v) {
return v;
}
@Override
public Object createFromShort(short v) {
return v;
}
@Override
public Object createFromInt(int v) {
return v;
}
@Override
public Object createFromLong(long v) {
return v;
}
@Override
public Object createFromFloat(float v) {
return v;
}
@Override
public Object createFromDouble(double v) {
return v;
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
byte[] bytes = new byte[length];
System.arraycopy(b, offset, bytes, 0, length);
return bytes;
}
@Override
public Object createFromArray(Object[] obj) {
return Arrays.asList(obj);
}
@Override
@SuppressWarnings("unchecked")
public Object createFromMap(Object[] obj) {
HashMap m = new HashMap(obj.length / 2);
int i = 0;
while(i < obj.length) {
Object k = obj[i++];
Object v = obj[i++];
m.put(k, v);
}
return m;
}
}

View File

@@ -1,26 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import org.msgpack.Schema;
public interface IArraySchema {
public Schema getElementSchema(int index);
public Object createFromArray(Object[] obj);
}

View File

@@ -1,27 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import org.msgpack.Schema;
public interface IMapSchema {
public Schema getKeySchema();
public Schema getValueSchema();
public Object createFromMap(Object[] obj);
}

View File

@@ -1,96 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class IntSchema extends Schema {
public IntSchema() { }
@Override
public String getClassName() {
return "Integer";
}
@Override
public String getExpression() {
return "int";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value >= Short.MAX_VALUE) {
long lvalue = ((Number)obj).longValue();
if(lvalue > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
}
pk.packInt(value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final int convertInt(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value >= Integer.MAX_VALUE) {
long lvalue = ((Number)obj).longValue();
if(lvalue > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
}
return value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertInt(obj);
}
@Override
public Object createFromByte(byte v) {
return (int)v;
}
@Override
public Object createFromShort(short v) {
return (int)v;
}
@Override
public Object createFromInt(int v) {
return (int)v;
}
@Override
public Object createFromLong(long v) {
if(v > Integer.MAX_VALUE) {
throw new MessageTypeException();
}
return (int)v;
}
}

View File

@@ -1,111 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.RandomAccess;
import java.io.IOException;
import org.msgpack.*;
public class ListSchema extends Schema implements IArraySchema {
private Schema elementSchema;
public ListSchema(Schema elementSchema) {
this.elementSchema = elementSchema;
}
@Override
public String getClassName() {
return "List<"+elementSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(array "+elementSchema.getExpression()+")";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof List) {
List<Object> d = (List<Object>)obj;
pk.packArray(d.size());
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
elementSchema.pack(pk, d.get(i));
}
} else {
for(Object e : d) {
elementSchema.pack(pk, e);
}
}
} else if(obj instanceof Set) {
Set<Object> d = (Set<Object>)obj;
pk.packArray(d.size());
for(Object e : d) {
elementSchema.pack(pk, e);
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <T> List<T> convertList(Object obj,
Schema elementSchema, List<T> dest) throws MessageTypeException {
if(!(obj instanceof List)) {
throw new MessageTypeException();
}
List<Object> d = (List<Object>)obj;
if(dest == null) {
dest = new ArrayList<T>(d.size());
}
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
dest.add( (T)elementSchema.convert(d.get(i)) );
}
} else {
for(Object e : d) {
dest.add( (T)elementSchema.convert(e) );
}
}
return dest;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertList(obj, elementSchema, null);
}
@Override
public Schema getElementSchema(int index) {
return elementSchema;
}
@Override
public Object createFromArray(Object[] obj) {
return Arrays.asList(obj);
}
}

View File

@@ -1,80 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class LongSchema extends Schema {
public LongSchema() { }
@Override
public String getClassName() {
return "Long";
}
@Override
public String getExpression() {
return "long";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
long value = ((Number)obj).longValue();
pk.packLong(value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final long convertLong(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
return ((Number)obj).longValue();
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertLong(obj);
}
@Override
public Object createFromByte(byte v) {
return (long)v;
}
@Override
public Object createFromShort(short v) {
return (long)v;
}
@Override
public Object createFromInt(int v) {
return (long)v;
}
@Override
public Object createFromLong(long v) {
return (long)v;
}
}

View File

@@ -1,106 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import org.msgpack.*;
public class MapSchema extends Schema implements IMapSchema {
private Schema keySchema;
private Schema valueSchema;
public MapSchema(Schema keySchema, Schema valueSchema) {
this.keySchema = keySchema;
this.valueSchema = valueSchema;
}
@Override
public String getClassName() {
return "Map<"+keySchema.getClassName()+", "+valueSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(map "+keySchema.getExpression()+" "+valueSchema.getExpression()+")";
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Map) {
Map<Object,Object> d = (Map<Object,Object>)obj;
pk.packMap(d.size());
for(Map.Entry<Object,Object> e : d.entrySet()) {
keySchema.pack(pk, e.getKey());
valueSchema.pack(pk, e.getValue());
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <K,V> Map<K,V> convertMap(Object obj,
Schema keySchema, Schema valueSchema, Map<K,V> dest) throws MessageTypeException {
if(!(obj instanceof Map)) {
throw new MessageTypeException();
}
Map<Object,Object> d = (Map<Object,Object>)obj;
if(dest == null) {
dest = new HashMap<K,V>(d.size());
}
for(Map.Entry<Object,Object> e : d.entrySet()) {
dest.put((K)keySchema.convert(e.getKey()),
(V)valueSchema.convert(e.getValue()));
}
return dest;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertMap(obj, keySchema, valueSchema, null);
}
@Override
public Schema getKeySchema() {
return keySchema;
}
@Override
public Schema getValueSchema() {
return valueSchema;
}
@Override
@SuppressWarnings("unchecked")
public Object createFromMap(Object[] obj) {
HashMap dest = new HashMap(obj.length / 2);
int i = 0;
while(i < obj.length) {
Object k = obj[i++];
Object v = obj[i++];
dest.put(k, v);
}
return dest;
}
}

View File

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

View File

@@ -1,264 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import org.msgpack.*;
// FIXME exception class
public class SSchemaParser {
public static Schema parse(String source) {
return new SSchemaParser(false).run(source);
}
public static Schema load(String source) {
return new SSchemaParser(true).run(source);
}
private static abstract class SExp {
boolean isAtom() { return false; }
public String getAtom() { return null; }
boolean isTuple() { return false; }
public SExp getTuple(int i) { return null; }
public int size() { return 0; }
public boolean empty() { return size() == 0; }
Iterator<SExp> iterator(int offset) { return null; }
}
private static class SAtom extends SExp {
private String atom;
SAtom(String atom) { this.atom = atom; }
boolean isAtom() { return true; }
public String getAtom() { return atom; }
public String toString() { return atom; }
}
private static class STuple extends SExp {
private List<SExp> tuple;
STuple() { this.tuple = new ArrayList<SExp>(); }
public void add(SExp e) { tuple.add(e); }
boolean isTuple() { return true; }
public SExp getTuple(int i) { return tuple.get(i); }
public int size() { return tuple.size(); }
Iterator<SExp> iterator(int skip) {
Iterator<SExp> i = tuple.iterator();
for(int s=0; s < skip; ++s) { i.next(); }
return i;
}
public String toString() {
if(tuple.isEmpty()) { return "()"; }
Iterator<SExp> i = tuple.iterator();
StringBuffer o = new StringBuffer();
o.append("(").append(i.next());
while(i.hasNext()) { o.append(" ").append(i.next()); }
o.append(")");
return o.toString();
}
}
boolean specificClass;
private SSchemaParser(boolean specificClass) {
this.specificClass = specificClass;
}
private static Pattern pattern = Pattern.compile(
"(?:\\s+)|([\\(\\)]|[\\d\\w\\.]+)");
private Schema run(String source) {
Matcher m = pattern.matcher(source);
Stack<STuple> stack = new Stack<STuple>();
String token;
while(true) {
while(true) {
if(!m.find()) { throw new RuntimeException("unexpected end of file"); }
token = m.group(1);
if(token != null) { break; }
}
if(token.equals("(")) {
stack.push(new STuple());
} else if(token.equals(")")) {
STuple top = stack.pop();
if(stack.empty()) {
stack.push(top);
break;
}
stack.peek().add(top);
} else {
if(stack.empty()) {
throw new RuntimeException("unexpected token '"+token+"'");
}
stack.peek().add(new SAtom(token));
}
}
while(true) {
if(!m.find()) { break; }
token = m.group(1);
if(token != null) { throw new RuntimeException("unexpected token '"+token+"'"); }
}
return readType( stack.pop() );
}
private Schema readType(SExp exp) {
if(exp.isAtom()) {
String type = exp.getAtom();
if(type.equals("string")) {
return new StringSchema();
} else if(type.equals("raw")) {
return new ByteArraySchema();
} else if(type.equals("byte")) {
return new ByteSchema();
} else if(type.equals("short")) {
return new ShortSchema();
} else if(type.equals("int")) {
return new IntSchema();
} else if(type.equals("long")) {
return new LongSchema();
} else if(type.equals("float")) {
return new FloatSchema();
} else if(type.equals("double")) {
return new DoubleSchema();
} else if(type.equals("object")) {
return new GenericSchema();
} else {
throw new RuntimeException("byte, short, int, long, float, double, raw, string or object is expected but got '"+type+"': "+exp);
}
} else {
String type = exp.getTuple(0).getAtom();
if(type.equals("class")) {
return parseClass(exp);
} else if(type.equals("array")) {
return parseList(exp);
} else if(type.equals("set")) {
return parseSet(exp);
} else if(type.equals("map")) {
return parseMap(exp);
} else {
throw new RuntimeException("class, list, set or map is expected but got '"+type+"': "+exp);
}
}
}
private ClassSchema parseClass(SExp exp) {
if(exp.size() < 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("class is (class NAME CLASS_BODY): "+exp);
}
String namespace = null;
List<String> imports = new ArrayList<String>();
String name = exp.getTuple(1).getAtom();
List<FieldSchema> fields = new ArrayList<FieldSchema>();
for(Iterator<SExp> i=exp.iterator(2); i.hasNext();) {
SExp subexp = i.next();
if(!subexp.isTuple() || subexp.empty() || !subexp.getTuple(0).isAtom()) {
throw new RuntimeException("field, package or import is expected: "+subexp);
}
String type = subexp.getTuple(0).getAtom();
if(type.equals("field")) {
fields.add( parseField(subexp) );
} else if(type.equals("package")) {
if(namespace != null) {
throw new RuntimeException("duplicated package definition: "+subexp);
}
namespace = parseNamespace(subexp);
} else if(type.equals("import")) {
imports.add( parseImport(subexp) );
} else {
throw new RuntimeException("field, package or import is expected but got '"+type+"': "+subexp);
}
}
if(specificClass) {
return new SpecificClassSchema(name, namespace, imports, fields);
} else {
return new GenericClassSchema(name, namespace, imports, fields);
}
}
private ListSchema parseList(SExp exp) {
if(exp.size() != 2) {
throw new RuntimeException("list is (list ELEMENT_TYPE): "+exp);
}
Schema elementType = readType(exp.getTuple(1));
return new ListSchema(elementType);
}
private SetSchema parseSet(SExp exp) {
if(exp.size() != 2) {
throw new RuntimeException("list is (list ELEMENT_TYPE): "+exp);
}
Schema elementType = readType(exp.getTuple(1));
return new SetSchema(elementType);
}
private MapSchema parseMap(SExp exp) {
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("map is (map KEY_TYPE VALUE_TYPE): "+exp);
}
Schema keyType = readType(exp.getTuple(1));
Schema valueType = readType(exp.getTuple(2));
return new MapSchema(keyType, valueType);
}
private String parseNamespace(SExp exp) {
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("package is (package NAME): "+exp);
}
String name = exp.getTuple(1).getAtom();
return name;
}
private String parseImport(SExp exp) {
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("import is (import NAME): "+exp);
}
String name = exp.getTuple(1).getAtom();
return name;
}
private FieldSchema parseField(SExp exp) {
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
throw new RuntimeException("field is (field NAME TYPE): "+exp);
}
String name = exp.getTuple(1).getAtom();
Schema type = readType(exp.getTuple(2));
return new FieldSchema(name, type);
}
}

View File

@@ -1,115 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.RandomAccess;
import java.io.IOException;
import org.msgpack.*;
public class SetSchema extends Schema implements IArraySchema {
private Schema elementSchema;
public SetSchema(Schema elementSchema) {
this.elementSchema = elementSchema;
}
@Override
public String getClassName() {
return "Set<"+elementSchema.getClassName()+">";
}
@Override
public String getExpression() {
return "(set "+elementSchema.getExpression()+")";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof List) {
List<Object> d = (List<Object>)obj;
pk.packArray(d.size());
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
elementSchema.pack(pk, d.get(i));
}
} else {
for(Object e : d) {
elementSchema.pack(pk, e);
}
}
} else if(obj instanceof Set) {
Set<Object> d = (Set<Object>)obj;
pk.packArray(d.size());
for(Object e : d) {
elementSchema.pack(pk, e);
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
@SuppressWarnings("unchecked")
public static final <T> Set<T> convertSet(Object obj,
Schema elementSchema, Set<T> dest) throws MessageTypeException {
if(!(obj instanceof List)) {
throw new MessageTypeException();
}
List<Object> d = (List<Object>)obj;
if(dest == null) {
dest = new HashSet<T>(d.size());
}
if(obj instanceof RandomAccess) {
for(int i=0; i < d.size(); ++i) {
dest.add( (T)elementSchema.convert(d.get(i)) );
}
} else {
for(Object e : d) {
dest.add( (T)elementSchema.convert(e) );
}
}
return dest;
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertSet(obj, elementSchema, null);
}
@Override
public Schema getElementSchema(int index) {
return elementSchema;
}
@Override
public Object createFromArray(Object[] obj) {
Set m = new HashSet(obj.length);
for(int i=0; i < obj.length; i++) {
m.add(obj[i]);
}
return m;
}
}

View File

@@ -1,93 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.io.IOException;
import org.msgpack.*;
public class ShortSchema extends Schema {
public ShortSchema() { }
@Override
public String getClassName() {
return "Short";
}
@Override
public String getExpression() {
return "short";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value > Short.MAX_VALUE) {
throw new MessageTypeException();
}
pk.packShort((short)value);
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final short convertShort(Object obj) throws MessageTypeException {
if(obj instanceof Number) {
int value = ((Number)obj).intValue();
if(value > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)value;
}
throw new MessageTypeException();
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertShort(obj);
}
@Override
public Object createFromByte(byte v) {
return (short)v;
}
@Override
public Object createFromShort(short v) {
return (short)v;
}
@Override
public Object createFromInt(int v) {
if(v > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)v;
}
@Override
public Object createFromLong(long v) {
if(v > Short.MAX_VALUE) {
throw new MessageTypeException();
}
return (short)v;
}
}

View File

@@ -1,122 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.util.Collection;
import java.util.List;
import java.lang.reflect.*;
import java.io.IOException;
import org.msgpack.*;
public class SpecificClassSchema extends ClassSchema {
private Class classCache;
private Method factoryCache;
private Constructor constructorCache;
public SpecificClassSchema(
String name, String namespace,
List<String> imports, List<FieldSchema> fields) {
super(name, namespace, imports, fields);
}
@Override
@SuppressWarnings("unchecked")
public void pack(Packer pk, Object obj) throws IOException {
if(obj == null) {
pk.packNil();
return;
}
if(classCache == null) {
cacheFactory();
}
if(classCache.isInstance(obj)) {
((MessagePackable)obj).messagePack(pk);
} else {
// FIXME Map<String,Object>
throw MessageTypeException.invalidConvert(obj, this);
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
if(obj instanceof Collection) {
if(constructorCache == null) {
cacheConstructor();
}
try {
MessageConvertable o = (MessageConvertable)constructorCache.newInstance((Object[])null);
o.messageConvert(obj);
return o;
} catch (InvocationTargetException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (InstantiationException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
} catch (IllegalAccessException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
}
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public Schema getElementSchema(int index) {
// FIXME check index < fields.length
return fields[index].getSchema();
}
public Object createFromArray(Object[] obj) {
if(factoryCache == null) {
cacheFactory();
}
try {
return factoryCache.invoke(null, new Object[]{obj});
} catch (InvocationTargetException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getCause());
} catch (IllegalAccessException e) {
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
}
}
@SuppressWarnings("unchecked")
private void cacheFactory() {
try {
classCache = Class.forName(fqdn);
factoryCache = classCache.getDeclaredMethod("createFromMessage", new Class[]{Object[].class});
factoryCache.setAccessible(true);
} catch(ClassNotFoundException e) {
throw new RuntimeException("class not found: "+fqdn);
} catch (NoSuchMethodException e) {
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
}
}
@SuppressWarnings("unchecked")
private void cacheConstructor() {
try {
classCache = Class.forName(fqdn);
constructorCache = classCache.getDeclaredConstructor((Class[])null);
constructorCache.setAccessible(true);
} catch(ClassNotFoundException e) {
throw new RuntimeException("class not found: "+fqdn);
} catch (NoSuchMethodException e) {
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
}
}
}

View File

@@ -1,102 +0,0 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.schema;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.msgpack.*;
public class StringSchema extends Schema {
public StringSchema() { }
@Override
public String getClassName() {
return "String";
}
@Override
public String getExpression() {
return "string";
}
@Override
public void pack(Packer pk, Object obj) throws IOException {
if(obj instanceof byte[]) {
byte[] b = (byte[])obj;
pk.packRaw(b.length);
pk.packRawBody(b);
} else if(obj instanceof String) {
try {
byte[] b = ((String)obj).getBytes("UTF-8");
pk.packRaw(b.length);
pk.packRawBody(b);
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj == null) {
pk.packNil();
} else {
throw MessageTypeException.invalidConvert(obj, this);
}
}
public static final String convertString(Object obj) throws MessageTypeException {
if(obj instanceof byte[]) {
try {
return new String((byte[])obj, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else if(obj instanceof String) {
return (String)obj;
} else if(obj instanceof ByteBuffer) {
ByteBuffer d = (ByteBuffer)obj;
try {
if(d.hasArray()) {
return new String(d.array(), d.position(), d.capacity(), "UTF-8");
} else {
byte[] v = new byte[d.capacity()];
int pos = d.position();
d.get(v);
d.position(pos);
return new String(v, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
throw new MessageTypeException();
}
} else {
throw new MessageTypeException();
}
}
@Override
public Object convert(Object obj) throws MessageTypeException {
return convertString(obj);
}
@Override
public Object createFromRaw(byte[] b, int offset, int length) {
try {
return new String(b, offset, length, "UTF-8");
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}

View File

@@ -8,240 +8,223 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class TestPackUnpack {
protected Object unpackOne(ByteArrayOutputStream out) {
return unpackOne(out, null);
}
protected Object unpackOne(ByteArrayOutputStream out, Schema schema) {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
if (schema != null)
upk = upk.useSchema(schema);
Iterator<Object> it = upk.iterator();
assertEquals(true, it.hasNext());
Object obj = it.next();
assertEquals(false, it.hasNext());
return obj;
}
public MessagePackObject unpackOne(ByteArrayOutputStream out) {
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker upk = new Unpacker(in);
Iterator<MessagePackObject> it = upk.iterator();
assertEquals(true, it.hasNext());
MessagePackObject obj = it.next();
assertEquals(false, it.hasNext());
return obj;
}
@Test
public void testInt() throws Exception {
testInt(0);
testInt(-1);
testInt(1);
testInt(Integer.MIN_VALUE);
testInt(Integer.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testInt(rand.nextInt());
}
public void testInt(int val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Byte)
assertEquals(val, ((Byte)obj).intValue());
else if (obj instanceof Integer)
assertEquals(val, ((Integer)obj).intValue());
else if (obj instanceof Short)
assertEquals(val, ((Short)obj).intValue());
else if (obj instanceof Long)
assertEquals(val, ((Long)obj).intValue());
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
public void testInt(int val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asInt());
}
@Test
public void testInt() throws Exception {
testInt(0);
testInt(-1);
testInt(1);
testInt(Integer.MIN_VALUE);
testInt(Integer.MAX_VALUE);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testInt(rand.nextInt());
}
@Test
public void testFloat() throws Exception {
testFloat((float)0.0);
testFloat((float)-0.0);
testFloat((float)1.0);
testFloat((float)-1.0);
testFloat((float)Float.MAX_VALUE);
testFloat((float)Float.MIN_VALUE);
testFloat((float)Float.NaN);
testFloat((float)Float.NEGATIVE_INFINITY);
testFloat((float)Float.POSITIVE_INFINITY);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testFloat(rand.nextFloat());
}
public void testFloat(float val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Float)
assertEquals(val, ((Float)obj).floatValue(), 10e-10);
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
public void testFloat(float val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asFloat(), 10e-10);
}
@Test
public void testFloat() throws Exception {
testFloat((float)0.0);
testFloat((float)-0.0);
testFloat((float)1.0);
testFloat((float)-1.0);
testFloat((float)Float.MAX_VALUE);
testFloat((float)Float.MIN_VALUE);
testFloat((float)Float.NaN);
testFloat((float)Float.NEGATIVE_INFINITY);
testFloat((float)Float.POSITIVE_INFINITY);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testFloat(rand.nextFloat());
}
@Test
public void testDouble() throws Exception {
testDouble((double)0.0);
testDouble((double)-0.0);
testDouble((double)1.0);
testDouble((double)-1.0);
testDouble((double)Double.MAX_VALUE);
testDouble((double)Double.MIN_VALUE);
testDouble((double)Double.NaN);
testDouble((double)Double.NEGATIVE_INFINITY);
testDouble((double)Double.POSITIVE_INFINITY);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testDouble(rand.nextDouble());
}
public void testDouble(double val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Double)
assertEquals(val, ((Double)obj).doubleValue(), 10e-10);
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
public void testDouble(double val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asDouble(), 10e-10);
}
@Test
public void testDouble() throws Exception {
testDouble((double)0.0);
testDouble((double)-0.0);
testDouble((double)1.0);
testDouble((double)-1.0);
testDouble((double)Double.MAX_VALUE);
testDouble((double)Double.MIN_VALUE);
testDouble((double)Double.NaN);
testDouble((double)Double.NEGATIVE_INFINITY);
testDouble((double)Double.POSITIVE_INFINITY);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testDouble(rand.nextDouble());
}
@Test
public void testNil() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).packNil();
Object obj = unpackOne(out);
assertEquals(null, obj);
}
@Test
public void testNil() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).packNil();
MessagePackObject obj = unpackOne(out);
assertTrue(obj.isNull());
}
@Test
public void testBoolean() throws Exception {
testBoolean(false);
testBoolean(true);
}
public void testBoolean(boolean val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof Boolean)
assertEquals(val, ((Boolean)obj).booleanValue());
else {
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
@Test
public void testBoolean() throws Exception {
testBoolean(false);
testBoolean(true);
}
public void testBoolean(boolean val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asBoolean());
}
@Test
public void testString() throws Exception {
testString("");
testString("a");
testString("ab");
testString("abc");
// small size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 31 + 1;
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// medium size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 100 + (1 << 15);
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
// large size string
for (int i = 0; i < 10; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 100 + (1 << 31);
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
}
public void testString(String val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out);
if (obj instanceof byte[])
assertEquals(val, new String((byte[])obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
public void testString(String val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
MessagePackObject obj = unpackOne(out);
assertEquals(val, obj.asString());
}
@Test
public void testString() throws Exception {
testString("");
testString("a");
testString("ab");
testString("abc");
@Test
public void testArray() throws Exception {
List<Integer> emptyList = new ArrayList<Integer>();
testArray(emptyList, Schema.parse("(array int)"));
// small size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 31 + 1;
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(array int)");
List<Integer> l = new ArrayList<Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(j);
testArray(l, schema);
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(array string)");
List<String> l = new ArrayList<String>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(Integer.toString(j));
testArray(l, schema);
}
}
public void testArray(List val, Schema schema) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out, schema);
if (obj instanceof List)
assertTrue(val.equals(obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
// medium size string
for (int i = 0; i < 100; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 100 + (1 << 15);
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
@Test
public void testMap() throws Exception {
Map<Integer, Integer> emptyMap = new HashMap<Integer, Integer>();
testMap(emptyMap, Schema.parse("(map int int)"));
// large size string
for (int i = 0; i < 10; i++) {
StringBuilder sb = new StringBuilder();
int len = (int)Math.random() % 100 + (1 << 31);
for (int j = 0; j < len; j++)
sb.append('a' + ((int)Math.random()) & 26);
testString(sb.toString());
}
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(map int int)");
Map<Integer, Integer> m = new HashMap<Integer, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(j, j);
testMap(m, schema);
}
for (int i = 0; i < 1000; i++) {
Schema schema = Schema.parse("(map string int)");
Map<String, Integer> m = new HashMap<String, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(Integer.toString(j), j);
testMap(m, schema);
}
}
public void testMap(Map val, Schema schema) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
Object obj = unpackOne(out, schema);
if (obj instanceof Map)
assertTrue(val.equals(obj));
else {
System.out.println("obj=" + obj);
System.out.println("Got unexpected class: " + obj.getClass());
assertTrue(false);
}
}
@Test
public void testArray() throws Exception {
List<Integer> emptyList = new ArrayList<Integer>();
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyList);
MessagePackObject obj = unpackOne(out);
assertEquals(emptyList, obj.asList());
}
for (int i = 0; i < 1000; i++) {
List<Integer> l = new ArrayList<Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(l);
MessagePackObject obj = unpackOne(out);
List<MessagePackObject> list = obj.asList();
assertEquals(l.size(), list.size());
for (int j = 0; j < len; j++) {
assertEquals(l.get(j).intValue(), list.get(j).asInt());
}
}
for (int i = 0; i < 1000; i++) {
List<String> l = new ArrayList<String>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
l.add(Integer.toString(j));
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(l);
MessagePackObject obj = unpackOne(out);
List<MessagePackObject> list = obj.asList();
assertEquals(l.size(), list.size());
for (int j = 0; j < len; j++) {
assertEquals(l.get(j), list.get(j).asString());
}
}
}
@Test
public void testMap() throws Exception {
Map<Integer, Integer> emptyMap = new HashMap<Integer, Integer>();
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(emptyMap);
MessagePackObject obj = unpackOne(out);
assertEquals(emptyMap, obj.asMap());
}
for (int i = 0; i < 1000; i++) {
Map<Integer, Integer> m = new HashMap<Integer, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(j, j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(m);
MessagePackObject obj = unpackOne(out);
Map<MessagePackObject, MessagePackObject> map = obj.asMap();
assertEquals(m.size(), map.size());
for (Map.Entry<MessagePackObject, MessagePackObject> pair : map.entrySet()) {
Integer val = m.get(pair.getKey().asInt());
assertNotNull(val);
assertEquals(val.intValue(), pair.getValue().asInt());
}
}
for (int i = 0; i < 1000; i++) {
Map<String, Integer> m = new HashMap<String, Integer>();
int len = (int)Math.random() % 1000 + 1;
for (int j = 0; j < len; j++)
m.put(Integer.toString(j), j);
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(m);
MessagePackObject obj = unpackOne(out);
Map<MessagePackObject, MessagePackObject> map = obj.asMap();
assertEquals(m.size(), map.size());
for (Map.Entry<MessagePackObject, MessagePackObject> pair : map.entrySet()) {
Integer val = m.get(pair.getKey().asString());
assertNotNull(val);
assertEquals(val.intValue(), pair.getValue().asInt());
}
}
}
};