Merge branch 'master' of ssh://github.com/msgpack/msgpack

This commit is contained in:
UENISHI Kota 2010-08-28 00:36:54 +09:00
commit 31d211cded
56 changed files with 2087 additions and 2759 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,136 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.math.BigInteger;
public abstract class MessagePackObject implements Cloneable, MessagePackable {
public boolean isNil() {
return false;
}
public boolean isBooleanType() {
return false;
}
public boolean isIntegerType() {
return false;
}
public boolean isFloatType() {
return false;
}
public boolean isArrayType() {
return false;
}
public boolean isMapType() {
return false;
}
public boolean isRawType() {
return false;
}
public boolean asBoolean() {
throw new MessageTypeException("type error");
}
public byte asByte() {
throw new MessageTypeException("type error");
}
public short asShort() {
throw new MessageTypeException("type error");
}
public int asInt() {
throw new MessageTypeException("type error");
}
public long asLong() {
throw new MessageTypeException("type error");
}
public BigInteger asBigInteger() {
throw new MessageTypeException("type error");
}
public float asFloat() {
throw new MessageTypeException("type error");
}
public double asDouble() {
throw new MessageTypeException("type error");
}
public byte[] asByteArray() {
throw new MessageTypeException("type error");
}
public String asString() {
throw new MessageTypeException("type error");
}
public MessagePackObject[] asArray() {
throw new MessageTypeException("type error");
}
public List<MessagePackObject> asList() {
throw new MessageTypeException("type error");
}
public Map<MessagePackObject, MessagePackObject> asMap() {
throw new MessageTypeException("type error");
}
public byte byteValue() {
throw new MessageTypeException("type error");
}
public short shortValue() {
throw new MessageTypeException("type error");
}
public int intValue() {
throw new MessageTypeException("type error");
}
public long longValue() {
throw new MessageTypeException("type error");
}
public BigInteger bigIntegerValue() {
throw new MessageTypeException("type error");
}
public float floatValue() {
throw new MessageTypeException("type error");
}
public double doubleValue() {
throw new MessageTypeException("type error");
}
abstract public Object clone();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,81 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.util.List;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class ArrayType extends MessagePackObject {
private MessagePackObject[] array;
ArrayType(MessagePackObject[] array) {
this.array = array;
}
public static ArrayType create(MessagePackObject[] array) {
return new ArrayType(array);
}
@Override
public boolean isArrayType() {
return true;
}
@Override
public MessagePackObject[] asArray() {
return array;
}
@Override
public List<MessagePackObject> asList() {
return Arrays.asList(array);
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packArray(array.length);
for(int i=0; i < array.length; i++) {
array[i].messagePack(pk);
}
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((ArrayType)obj).array, array);
}
@Override
public int hashCode() {
return array.hashCode();
}
@Override
public Object clone() {
MessagePackObject[] copy = new MessagePackObject[array.length];
for(int i=0; i < array.length; i++) {
copy[i] = (MessagePackObject)array[i].clone();
}
return copy;
}
}

View File

@ -0,0 +1,131 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class BigIntegerTypeIMPL extends IntegerType {
private BigInteger value;
BigIntegerTypeIMPL(BigInteger value) {
this.value = value;
}
@Override
public byte asByte() {
if(value.compareTo(BigInteger.valueOf((long)Byte.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.byteValue();
}
@Override
public short asShort() {
if(value.compareTo(BigInteger.valueOf((long)Short.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.shortValue();
}
@Override
public int asInt() {
if(value.compareTo(BigInteger.valueOf((long)Integer.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.intValue();
}
@Override
public long asLong() {
if(value.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
throw new MessageTypeException("type error");
}
return value.longValue();
}
@Override
public BigInteger asBigInteger() {
return value;
}
@Override
public byte byteValue() {
return value.byteValue();
}
@Override
public short shortValue() {
return value.shortValue();
}
@Override
public int intValue() {
return value.intValue();
}
@Override
public long longValue() {
return value.longValue();
}
@Override
public BigInteger bigIntegerValue() {
return value;
}
@Override
public float floatValue() {
return value.floatValue();
}
@Override
public double doubleValue() {
return value.doubleValue();
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packBigInteger(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == ShortIntegerTypeIMPL.class) {
return BigInteger.valueOf(((ShortIntegerTypeIMPL)obj).longValue()).equals(value);
} else if(obj.getClass() == LongIntegerTypeIMPL.class) {
return BigInteger.valueOf(((LongIntegerTypeIMPL)obj).longValue()).equals(value);
}
return false;
}
return ((BigIntegerTypeIMPL)obj).value.equals(value);
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public Object clone() {
return new BigIntegerTypeIMPL(value);
}
}

View File

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

View File

@ -0,0 +1,101 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class DoubleTypeIMPL extends FloatType {
private double value;
public DoubleTypeIMPL(double value) {
this.value = value;
}
@Override
public float asFloat() {
// FIXME check overflow, underflow?
return (float)value;
}
@Override
public double asDouble() {
return value;
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf((long)value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packDouble(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return ((DoubleTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
long v = Double.doubleToLongBits(value);
return (int)(v^(v>>>32));
}
@Override
public Object clone() {
return new DoubleTypeIMPL(value);
}
}

View File

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

View File

@ -0,0 +1,94 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class FloatTypeIMPL extends FloatType {
private float value;
public FloatTypeIMPL(float value) {
this.value = value;
}
@Override
public float asFloat() {
return value;
}
@Override
public double asDouble() {
return (double)value;
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packFloat(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return ((FloatTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return Float.floatToIntBits(value);
}
@Override
public Object clone() {
return new FloatTypeIMPL(value);
}
}

View File

@ -0,0 +1,49 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import org.msgpack.*;
public abstract class IntegerType extends MessagePackObject {
@Override
public boolean isIntegerType() {
return true;
}
public static IntegerType create(byte value) {
return new ShortIntegerTypeIMPL((int)value);
}
public static IntegerType create(short value) {
return new ShortIntegerTypeIMPL((int)value);
}
public static IntegerType create(int value) {
return new ShortIntegerTypeIMPL(value);
}
public static IntegerType create(long value) {
return new LongIntegerTypeIMPL(value);
}
public static IntegerType create(BigInteger value) {
return new BigIntegerTypeIMPL(value);
}
}

View File

@ -0,0 +1,128 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class LongIntegerTypeIMPL extends IntegerType {
private long value;
LongIntegerTypeIMPL(long value) {
this.value = value;
}
@Override
public byte asByte() {
if(value > (long)Byte.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (byte)value;
}
@Override
public short asShort() {
if(value > (long)Short.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (short)value;
}
@Override
public int asInt() {
if(value > (long)Integer.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (int)value;
}
@Override
public long asLong() {
return value;
}
@Override
public BigInteger asBigInteger() {
return BigInteger.valueOf(value);
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf(value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packLong(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == ShortIntegerTypeIMPL.class) {
return value == ((ShortIntegerTypeIMPL)obj).longValue();
} else if(obj.getClass() == BigIntegerTypeIMPL.class) {
return BigInteger.valueOf(value).equals(((BigIntegerTypeIMPL)obj).bigIntegerValue());
}
return false;
}
return ((LongIntegerTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return (int)(value^(value>>>32));
}
@Override
public Object clone() {
return new LongIntegerTypeIMPL(value);
}
}

View File

@ -0,0 +1,84 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class MapType extends MessagePackObject {
private MessagePackObject[] map;
MapType(MessagePackObject[] map) {
this.map = map;
}
public static MapType create(MessagePackObject[] map) {
return new MapType(map);
}
@Override
public boolean isMapType() {
return true;
}
@Override
public Map<MessagePackObject, MessagePackObject> asMap() {
HashMap<MessagePackObject, MessagePackObject> m = new HashMap(map.length / 2);
int i = 0;
while(i < map.length) {
MessagePackObject k = map[i++];
MessagePackObject v = map[i++];
m.put(k, v);
}
return m;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packMap(map.length / 2);
for(int i=0; i < map.length; i++) {
map[i].messagePack(pk);
}
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((MapType)obj).map, map);
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public Object clone() {
MessagePackObject[] copy = new MessagePackObject[map.length];
for(int i=0; i < map.length; i++) {
copy[i] = (MessagePackObject)map[i].clone();
}
return copy;
}
}

View File

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

View File

@ -0,0 +1,90 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.util.Arrays;
import java.io.IOException;
import org.msgpack.*;
public class RawType extends MessagePackObject {
private byte[] bytes;
RawType(byte[] bytes) {
this.bytes = bytes;
}
RawType(String str) {
try {
this.bytes = str.getBytes("UTF-8");
} catch (Exception e) {
throw new MessageTypeException("type error");
}
}
public static RawType create(byte[] bytes) {
return new RawType(bytes);
}
public static RawType create(String str) {
return new RawType(str);
}
@Override
public boolean isRawType() {
return true;
}
@Override
public byte[] asByteArray() {
return bytes;
}
@Override
public String asString() {
try {
return new String(bytes, "UTF-8");
} catch (Exception e) {
throw new MessageTypeException("type error");
}
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packRaw(bytes.length);
pk.packRawBody(bytes);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
return false;
}
return Arrays.equals(((RawType)obj).bytes, bytes);
}
@Override
public int hashCode() {
return bytes.hashCode();
}
@Override
public Object clone() {
return new RawType((byte[])bytes.clone());
}
}

View File

@ -0,0 +1,125 @@
//
// MessagePack for Java
//
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.msgpack.object;
import java.math.BigInteger;
import java.io.IOException;
import org.msgpack.*;
class ShortIntegerTypeIMPL extends IntegerType {
private int value;
ShortIntegerTypeIMPL(int value) {
this.value = value;
}
@Override
public byte asByte() {
if(value > (int)Byte.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (byte)value;
}
@Override
public short asShort() {
if(value > (int)Short.MAX_VALUE) {
throw new MessageTypeException("type error");
}
return (short)value;
}
@Override
public int asInt() {
return value;
}
@Override
public long asLong() {
return value;
}
@Override
public BigInteger asBigInteger() {
return BigInteger.valueOf((long)value);
}
@Override
public byte byteValue() {
return (byte)value;
}
@Override
public short shortValue() {
return (short)value;
}
@Override
public int intValue() {
return (int)value;
}
@Override
public long longValue() {
return (long)value;
}
@Override
public BigInteger bigIntegerValue() {
return BigInteger.valueOf((long)value);
}
@Override
public float floatValue() {
return (float)value;
}
@Override
public double doubleValue() {
return (double)value;
}
@Override
public void messagePack(Packer pk) throws IOException {
pk.packInt(value);
}
@Override
public boolean equals(Object obj) {
if(obj.getClass() != getClass()) {
if(obj.getClass() == LongIntegerTypeIMPL.class) {
return (long)value == ((LongIntegerTypeIMPL)obj).longValue();
} else if(obj.getClass() == BigIntegerTypeIMPL.class) {
return ((BigIntegerTypeIMPL)obj).bigIntegerValue().equals(BigInteger.valueOf((long)value));
}
return false;
}
return ((ShortIntegerTypeIMPL)obj).value == value;
}
@Override
public int hashCode() {
return value;
}
@Override
public Object clone() {
return new ShortIntegerTypeIMPL(value);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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

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

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