mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-21 23:56:55 +02:00
import MessagePack for Java
This commit is contained in:
23
java/src/org/msgpack/MessageMergeable.java
Normal file
23
java/src/org/msgpack/MessageMergeable.java
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// 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;
|
||||
|
||||
public interface MessageMergeable {
|
||||
public void messageMerge(Object obj) throws MessageTypeException;
|
||||
}
|
||||
|
25
java/src/org/msgpack/MessagePackable.java
Normal file
25
java/src/org/msgpack/MessagePackable.java
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public interface MessagePackable {
|
||||
public void messagePack(Packer pk) throws IOException;
|
||||
}
|
||||
|
39
java/src/org/msgpack/MessageTypeException.java
Normal file
39
java/src/org/msgpack/MessageTypeException.java
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public class MessageTypeException extends IOException {
|
||||
public MessageTypeException() { }
|
||||
|
||||
public MessageTypeException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public static MessageTypeException invalidConvert(Object from, Schema to) {
|
||||
return new MessageTypeException(from.getClass().getName()+" cannot be convert to "+to.getExpression());
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
public static MessageTypeException schemaMismatch(Schema to) {
|
||||
return new MessageTypeException("schema mismatch "+to.getExpression());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
409
java/src/org/msgpack/Packer.java
Normal file
409
java/src/org/msgpack/Packer.java
Normal file
@@ -0,0 +1,409 @@
|
||||
//
|
||||
// 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.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Packer {
|
||||
protected byte[] castBytes = new byte[9];
|
||||
protected ByteBuffer castBuffer = ByteBuffer.wrap(castBytes);
|
||||
protected OutputStream out;
|
||||
|
||||
public Packer(OutputStream out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public Packer packByte(byte d) throws IOException {
|
||||
if(d < -(1<<5)) {
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBytes[1] = d;
|
||||
out.write(castBytes, 0, 2);
|
||||
} else {
|
||||
out.write(d);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packShort(short d) throws IOException {
|
||||
if(d < -(1<<5)) {
|
||||
if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, d);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
castBytes[0] = (byte)0xd0;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
}
|
||||
} else if(d < (1<<7)) {
|
||||
// fixnum
|
||||
out.write((byte)d);
|
||||
} else {
|
||||
if(d < (1<<8)) {
|
||||
// unsigned 8
|
||||
castBytes[0] = (byte)0xcc;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
} else {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, d);
|
||||
out.write(castBytes, 0, 3);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packInt(int d) throws IOException {
|
||||
if(d < -(1<<5)) {
|
||||
if(d < -(1<<15)) {
|
||||
// signed 32
|
||||
castBytes[0] = (byte)0xd2;
|
||||
castBuffer.putInt(1, d);
|
||||
out.write(castBytes, 0, 5);
|
||||
} else if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
castBytes[0] = (byte)0xd0;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
}
|
||||
} else if(d < (1<<7)) {
|
||||
// fixnum
|
||||
out.write((byte)d);
|
||||
} else {
|
||||
if(d < (1<<8)) {
|
||||
// unsigned 8
|
||||
castBytes[0] = (byte)0xcc;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
} else if(d < (1<<16)) {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// unsigned 32
|
||||
castBytes[0] = (byte)0xce;
|
||||
castBuffer.putInt(1, d);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packLong(long d) throws IOException {
|
||||
if(d < -(1L<<5)) {
|
||||
if(d < -(1L<<15)) {
|
||||
if(d < -(1L<<31)) {
|
||||
// signed 64
|
||||
castBytes[0] = (byte)0xd3;
|
||||
castBuffer.putLong(1, d);
|
||||
out.write(castBytes, 0, 9);
|
||||
} else {
|
||||
// signed 32
|
||||
castBytes[0] = (byte)0xd2;
|
||||
castBuffer.putInt(1, (int)d);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
} else {
|
||||
if(d < -(1<<7)) {
|
||||
// signed 16
|
||||
castBytes[0] = (byte)0xd1;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
// signed 8
|
||||
castBytes[0] = (byte)0xd0;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
}
|
||||
}
|
||||
} else if(d < (1<<7)) {
|
||||
// fixnum
|
||||
out.write((byte)d);
|
||||
} else {
|
||||
if(d < (1L<<16)) {
|
||||
if(d < (1<<8)) {
|
||||
// unsigned 8
|
||||
castBytes[0] = (byte)0xcc;
|
||||
castBytes[1] = (byte)d;
|
||||
out.write(castBytes, 0, 2);
|
||||
} else {
|
||||
// unsigned 16
|
||||
castBytes[0] = (byte)0xcd;
|
||||
castBuffer.putShort(1, (short)d);
|
||||
out.write(castBytes, 0, 3);
|
||||
//System.out.println("pack uint 16 "+(short)d);
|
||||
}
|
||||
} else {
|
||||
if(d < (1L<<32)) {
|
||||
// unsigned 32
|
||||
castBytes[0] = (byte)0xce;
|
||||
castBuffer.putInt(1, (int)d);
|
||||
out.write(castBytes, 0, 5);
|
||||
} else {
|
||||
// unsigned 64
|
||||
castBytes[0] = (byte)0xcf;
|
||||
castBuffer.putLong(1, d);
|
||||
out.write(castBytes, 0, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packFloat(float d) throws IOException {
|
||||
castBytes[0] = (byte)0xca;
|
||||
castBuffer.putFloat(1, d);
|
||||
out.write(castBytes, 0, 5);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packDouble(double d) throws IOException {
|
||||
castBytes[0] = (byte)0xcb;
|
||||
castBuffer.putDouble(1, d);
|
||||
out.write(castBytes, 0, 9);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packNil() throws IOException {
|
||||
out.write((byte)0xc0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packTrue() throws IOException {
|
||||
out.write((byte)0xc3);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packFalse() throws IOException {
|
||||
out.write((byte)0xc2);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packArray(int n) throws IOException {
|
||||
if(n < 16) {
|
||||
final int d = 0x90 | n;
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xdc;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdd;
|
||||
castBuffer.putInt(1, n);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packMap(int n) throws IOException {
|
||||
if(n < 16) {
|
||||
final int d = 0x80 | n;
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xde;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdf;
|
||||
castBuffer.putInt(1, n);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packRaw(int n) throws IOException {
|
||||
if(n < 32) {
|
||||
final int d = 0xa0 | n;
|
||||
out.write((byte)d);
|
||||
} else if(n < 65536) {
|
||||
castBytes[0] = (byte)0xda;
|
||||
castBuffer.putShort(1, (short)n);
|
||||
out.write(castBytes, 0, 3);
|
||||
} else {
|
||||
castBytes[0] = (byte)0xdb;
|
||||
castBuffer.putInt(1, n);
|
||||
out.write(castBytes, 0, 5);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packRawBody(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer packRawBody(byte[] b, int off, int length) throws IOException {
|
||||
out.write(b, off, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Packer packWithSchema(Object o, Schema s) throws IOException {
|
||||
s.pack(this, o);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Packer packString(String s) throws IOException {
|
||||
byte[] b = ((String)s).getBytes("UTF-8");
|
||||
packRaw(b.length);
|
||||
return packRawBody(b);
|
||||
}
|
||||
|
||||
|
||||
public Packer pack(String o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packString(o);
|
||||
}
|
||||
|
||||
public Packer pack(MessagePackable o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
o.messagePack(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(byte[] o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packRaw(o.length);
|
||||
return packRawBody(o);
|
||||
}
|
||||
|
||||
public Packer pack(List o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packArray(o.size());
|
||||
for(Object i : o) { pack(i); }
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Packer pack(Map o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
packMap(o.size());
|
||||
for(Map.Entry e : ((Map<Object,Object>)o).entrySet()) {
|
||||
pack(e.getKey());
|
||||
pack(e.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packer pack(Boolean o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
if(o) {
|
||||
return packTrue();
|
||||
} else {
|
||||
return packFalse();
|
||||
}
|
||||
}
|
||||
|
||||
public Packer pack(Byte o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packByte(o);
|
||||
}
|
||||
|
||||
public Packer pack(Short o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packShort(o);
|
||||
}
|
||||
|
||||
public Packer pack(Integer o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packInt(o);
|
||||
}
|
||||
|
||||
public Packer pack(Long o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packLong(o);
|
||||
}
|
||||
|
||||
public Packer pack(Float o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packFloat(o);
|
||||
}
|
||||
|
||||
public Packer pack(Double o) throws IOException {
|
||||
if(o == null) { return packNil(); }
|
||||
return packDouble(o);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Packer pack(Object o) throws IOException {
|
||||
if(o == null) {
|
||||
return packNil();
|
||||
} else if(o instanceof String) {
|
||||
byte[] b = ((String)o).getBytes("UTF-8");
|
||||
packRaw(b.length);
|
||||
return packRawBody(b);
|
||||
} else if(o instanceof MessagePackable) {
|
||||
((MessagePackable)o).messagePack(this);
|
||||
return this;
|
||||
} else if(o instanceof byte[]) {
|
||||
byte[] b = (byte[])o;
|
||||
packRaw(b.length);
|
||||
return packRawBody(b);
|
||||
} else if(o instanceof List) {
|
||||
List<Object> l = (List<Object>)o;
|
||||
packArray(l.size());
|
||||
for(Object i : l) { pack(i); }
|
||||
return this;
|
||||
} else if(o instanceof Map) {
|
||||
Map<Object,Object> m = (Map<Object,Object>)o;
|
||||
packMap(m.size());
|
||||
for(Map.Entry e : m.entrySet()) {
|
||||
pack(e.getKey());
|
||||
pack(e.getValue());
|
||||
}
|
||||
return this;
|
||||
} else if(o instanceof Boolean) {
|
||||
if((Boolean)o) {
|
||||
return packTrue();
|
||||
} else {
|
||||
return packFalse();
|
||||
}
|
||||
} else if(o instanceof Integer) {
|
||||
return packInt((Integer)o);
|
||||
} else if(o instanceof Long) {
|
||||
return packLong((Long)o);
|
||||
} else if(o instanceof Short) {
|
||||
return packShort((Short)o);
|
||||
} else if(o instanceof Byte) {
|
||||
return packByte((Byte)o);
|
||||
} else if(o instanceof Float) {
|
||||
return packFloat((Float)o);
|
||||
} else if(o instanceof Double) {
|
||||
return packDouble((Double)o);
|
||||
} else {
|
||||
throw new IOException("unknown object "+o+" ("+o.getClass()+")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
133
java/src/org/msgpack/Schema.java
Normal file
133
java/src/org/msgpack/Schema.java
Normal file
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// 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 {
|
||||
private String expression;
|
||||
private String name;
|
||||
|
||||
public Schema(String name) {
|
||||
this.expression = expression;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Schema parse(String source) {
|
||||
return SSchemaParser.parse(source);
|
||||
}
|
||||
|
||||
public static Schema load(String source) {
|
||||
return SSchemaParser.load(source);
|
||||
}
|
||||
|
||||
public void write(Writer output) throws IOException {
|
||||
ClassGenerator.write(this, output);
|
||||
}
|
||||
|
||||
public abstract void pack(Packer pk, Object obj) throws IOException;
|
||||
|
||||
public abstract Object convert(Object obj) throws MessageTypeException;
|
||||
|
||||
|
||||
public Object createFromNil() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object createFromBoolean(boolean v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromByte(byte v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromShort(short v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromInt(int v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromLong(long v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromFloat(float v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromDouble(double v) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
/* FIXME
|
||||
public Object createFromBoolean(boolean v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromByte(byte v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromShort(short v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromInt(int v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromLong(long v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromFloat(float v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromDouble(double v) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
throw MessageTypeException.schemaMismatch(this);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
82
java/src/org/msgpack/UnbufferedUnpacker.java
Normal file
82
java/src/org/msgpack/UnbufferedUnpacker.java
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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.lang.Iterable;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import org.msgpack.impl.UnpackerImpl;
|
||||
|
||||
public class UnbufferedUnpacker extends UnpackerImpl {
|
||||
private int offset;
|
||||
private boolean finished;
|
||||
private Object data;
|
||||
|
||||
public UnbufferedUnpacker() {
|
||||
super();
|
||||
this.offset = 0;
|
||||
this.finished = false;
|
||||
}
|
||||
|
||||
public UnbufferedUnpacker useSchema(Schema s) {
|
||||
super.setSchema(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int execute(byte[] buffer) throws UnpackException {
|
||||
return execute(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
public int execute(byte[] buffer, int offset, int length) throws UnpackException
|
||||
{
|
||||
int noffset = super.execute(buffer, offset + this.offset, length);
|
||||
this.offset = noffset - offset;
|
||||
if(super.isFinished()) {
|
||||
this.data = super.getData();
|
||||
this.finished = true;
|
||||
super.reset();
|
||||
} else {
|
||||
this.finished = false;
|
||||
}
|
||||
return noffset;
|
||||
}
|
||||
}
|
||||
|
29
java/src/org/msgpack/UnpackException.java
Normal file
29
java/src/org/msgpack/UnpackException.java
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
|
||||
public class UnpackException extends IOException {
|
||||
public UnpackException() { }
|
||||
|
||||
public UnpackException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
66
java/src/org/msgpack/UnpackIterator.java
Normal file
66
java/src/org/msgpack/UnpackIterator.java
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class UnpackIterator implements Iterator<Object> {
|
||||
private Unpacker pac;
|
||||
private boolean have;
|
||||
private Object data;
|
||||
|
||||
UnpackIterator(Unpacker pac) {
|
||||
this.pac = pac;
|
||||
this.have = false;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if(have) { return true; }
|
||||
try {
|
||||
while(true) {
|
||||
if(pac.execute()) {
|
||||
data = pac.getData();
|
||||
pac.reset();
|
||||
have = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!pac.fill()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
if(!have && !hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
have = false;
|
||||
return data;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
245
java/src/org/msgpack/Unpacker.java
Normal file
245
java/src/org/msgpack/Unpacker.java
Normal file
@@ -0,0 +1,245 @@
|
||||
//
|
||||
// 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.lang.Iterable;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import org.msgpack.impl.UnpackerImpl;
|
||||
|
||||
public class Unpacker extends UnpackerImpl implements Iterable<Object> {
|
||||
|
||||
public static final int DEFAULT_BUFFER_SIZE = 32*1024;
|
||||
|
||||
private int used;
|
||||
private int offset;
|
||||
private int parsed;
|
||||
private byte[] buffer;
|
||||
private int bufferReserveSize;
|
||||
private InputStream stream;
|
||||
|
||||
public Unpacker() {
|
||||
this(DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public Unpacker(int bufferReserveSize) {
|
||||
this(null, bufferReserveSize);
|
||||
}
|
||||
|
||||
public Unpacker(InputStream stream) {
|
||||
this(stream, DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public Unpacker(InputStream stream, int bufferReserveSize) {
|
||||
super();
|
||||
this.used = 0;
|
||||
this.offset = 0;
|
||||
this.parsed = 0;
|
||||
this.buffer = new byte[bufferReserveSize];
|
||||
this.bufferReserveSize = bufferReserveSize/2;
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public Unpacker useSchema(Schema s) {
|
||||
super.setSchema(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void reserveBuffer(int size) {
|
||||
if(buffer.length - used >= size) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(used == parsed && buffer.length >= size) {
|
||||
// rewind buffer
|
||||
used = 0;
|
||||
offset = 0;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
int nextSize = buffer.length * 2;
|
||||
while(nextSize < size + used) {
|
||||
nextSize *= 2;
|
||||
}
|
||||
|
||||
byte[] tmp = new byte[nextSize];
|
||||
System.arraycopy(buffer, offset, tmp, 0, used - offset);
|
||||
|
||||
buffer = tmp;
|
||||
used -= offset;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
public byte[] getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public int getBufferOffset() {
|
||||
return used;
|
||||
}
|
||||
|
||||
public int getBufferCapacity() {
|
||||
return buffer.length - used;
|
||||
}
|
||||
|
||||
public void bufferConsumed(int size) {
|
||||
used += size;
|
||||
}
|
||||
|
||||
public void feed(byte[] buffer) {
|
||||
feed(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public void feed(byte[] buffer, int offset, int length) {
|
||||
reserveBuffer(length);
|
||||
System.arraycopy(buffer, offset, this.buffer, this.offset, length);
|
||||
bufferConsumed(length);
|
||||
}
|
||||
|
||||
public boolean fill() throws IOException {
|
||||
if(stream == null) {
|
||||
return false;
|
||||
}
|
||||
reserveBuffer(bufferReserveSize);
|
||||
int rl = stream.read(getBuffer(), getBufferOffset(), getBufferCapacity());
|
||||
if(rl <= 0) {
|
||||
return false;
|
||||
}
|
||||
bufferConsumed(rl);
|
||||
return true;
|
||||
}
|
||||
|
||||
public Iterator<Object> iterator() {
|
||||
return new UnpackIterator(this);
|
||||
}
|
||||
|
||||
public boolean execute() throws UnpackException {
|
||||
int noffset = super.execute(buffer, offset, used);
|
||||
if(noffset <= offset) {
|
||||
return false;
|
||||
}
|
||||
parsed += noffset - offset;
|
||||
offset = noffset;
|
||||
return super.isFinished();
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return super.getData();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset();
|
||||
parsed = 0;
|
||||
}
|
||||
|
||||
public int getMessageSize() {
|
||||
return parsed - offset + used;
|
||||
}
|
||||
|
||||
public int getParsedSize() {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public int getNonParsedSize() {
|
||||
return used - offset;
|
||||
}
|
||||
|
||||
public void skipNonparsedBuffer(int size) {
|
||||
offset += size;
|
||||
}
|
||||
|
||||
public void removeNonparsedBuffer() {
|
||||
used = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
public static class Context {
|
||||
private boolean finished;
|
||||
private Object data;
|
||||
private int offset;
|
||||
private UnpackerImpl impl;
|
||||
|
||||
public Context()
|
||||
{
|
||||
this.finished = false;
|
||||
this.impl = new UnpackerImpl();
|
||||
}
|
||||
|
||||
public boolean isFinished()
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
|
||||
public Object getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
int getOffset()
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
void setFinished(boolean finished)
|
||||
{
|
||||
this.finished = finished;
|
||||
}
|
||||
|
||||
void setData(Object data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
void setOffset(int offset)
|
||||
{
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
UnpackerImpl getImpl()
|
||||
{
|
||||
return impl;
|
||||
}
|
||||
}
|
||||
|
||||
public static int unpack(Context ctx, byte[] buffer) throws UnpackException
|
||||
{
|
||||
return unpack(ctx, buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public static int unpack(Context ctx, byte[] buffer, int offset, int length) throws UnpackException
|
||||
{
|
||||
UnpackerImpl impl = ctx.getImpl();
|
||||
int noffset = impl.execute(buffer, offset + ctx.getOffset(), length);
|
||||
ctx.setOffset(noffset - offset);
|
||||
if(impl.isFinished()) {
|
||||
ctx.setData(impl.getData());
|
||||
ctx.setFinished(false);
|
||||
impl.reset();
|
||||
} else {
|
||||
ctx.setData(null);
|
||||
ctx.setFinished(true);
|
||||
}
|
||||
int parsed = noffset - offset;
|
||||
ctx.setOffset(parsed);
|
||||
return noffset;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
500
java/src/org/msgpack/impl/UnpackerImpl.java
Normal file
500
java/src/org/msgpack/impl/UnpackerImpl.java
Normal file
@@ -0,0 +1,500 @@
|
||||
//
|
||||
// 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.impl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
//import java.math.BigInteger;
|
||||
import org.msgpack.*;
|
||||
import org.msgpack.schema.GenericSchema;
|
||||
import org.msgpack.schema.IMapSchema;
|
||||
import org.msgpack.schema.IArraySchema;
|
||||
|
||||
public class UnpackerImpl {
|
||||
static final int CS_HEADER = 0x00;
|
||||
static final int CS_FLOAT = 0x0a;
|
||||
static final int CS_DOUBLE = 0x0b;
|
||||
static final int CS_UINT_8 = 0x0c;
|
||||
static final int CS_UINT_16 = 0x0d;
|
||||
static final int CS_UINT_32 = 0x0e;
|
||||
static final int CS_UINT_64 = 0x0f;
|
||||
static final int CS_INT_8 = 0x10;
|
||||
static final int CS_INT_16 = 0x11;
|
||||
static final int CS_INT_32 = 0x12;
|
||||
static final int CS_INT_64 = 0x13;
|
||||
static final int CS_RAW_16 = 0x1a;
|
||||
static final int CS_RAW_32 = 0x1b;
|
||||
static final int CS_ARRAY_16 = 0x1c;
|
||||
static final int CS_ARRAY_32 = 0x1d;
|
||||
static final int CS_MAP_16 = 0x1e;
|
||||
static final int CS_MAP_32 = 0x1f;
|
||||
static final int ACS_RAW_VALUE = 0x20;
|
||||
static final int CT_ARRAY_ITEM = 0x00;
|
||||
static final int CT_MAP_KEY = 0x01;
|
||||
static final int CT_MAP_VALUE = 0x02;
|
||||
|
||||
static final int MAX_STACK_SIZE = 16;
|
||||
|
||||
private int cs;
|
||||
private int trail;
|
||||
private int top;
|
||||
private int[] stack_ct = new int[MAX_STACK_SIZE];
|
||||
private int[] stack_count = new int[MAX_STACK_SIZE];
|
||||
private Object[] stack_obj = new Object[MAX_STACK_SIZE];
|
||||
private Schema[] stack_schema = new Schema[MAX_STACK_SIZE];
|
||||
private int top_ct;
|
||||
private int top_count;
|
||||
private Object top_obj;
|
||||
private Schema top_schema;
|
||||
private ByteBuffer castBuffer = ByteBuffer.allocate(8);
|
||||
private boolean finished = false;
|
||||
private Object data = null;
|
||||
|
||||
private static final Schema GENERIC_SCHEMA = new GenericSchema();
|
||||
private Schema rootSchema;
|
||||
|
||||
protected UnpackerImpl()
|
||||
{
|
||||
setSchema(GENERIC_SCHEMA);
|
||||
}
|
||||
|
||||
protected void setSchema(Schema schema)
|
||||
{
|
||||
this.rootSchema = schema;
|
||||
reset();
|
||||
}
|
||||
|
||||
protected Object getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
protected boolean isFinished()
|
||||
{
|
||||
return finished;
|
||||
}
|
||||
|
||||
protected void reset()
|
||||
{
|
||||
cs = CS_HEADER;
|
||||
top = -1;
|
||||
finished = false;
|
||||
data = null;
|
||||
top_ct = 0;
|
||||
top_count = 0;
|
||||
top_obj = null;
|
||||
top_schema = rootSchema;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected int execute(byte[] src, int off, int length) throws UnpackException
|
||||
{
|
||||
if(off >= length) { return off; }
|
||||
|
||||
int limit = length;
|
||||
int i = off;
|
||||
int count;
|
||||
|
||||
Object obj = null;
|
||||
|
||||
_out: do {
|
||||
_header_again: {
|
||||
//System.out.println("while i:"+i+" limit:"+limit);
|
||||
|
||||
int b = src[i];
|
||||
|
||||
_push: {
|
||||
_fixed_trail_again:
|
||||
if(cs == CS_HEADER) {
|
||||
|
||||
if((b & 0x80) == 0) { // Positive Fixnum
|
||||
//System.out.println("positive fixnum "+b);
|
||||
obj = top_schema.createFromByte((byte)b);
|
||||
break _push;
|
||||
}
|
||||
|
||||
if((b & 0xe0) == 0xe0) { // Negative Fixnum
|
||||
//System.out.println("negative fixnum "+b);
|
||||
obj = top_schema.createFromByte((byte)b);
|
||||
break _push;
|
||||
}
|
||||
|
||||
if((b & 0xe0) == 0xa0) { // FixRaw
|
||||
trail = b & 0x1f;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
break _fixed_trail_again;
|
||||
}
|
||||
|
||||
if((b & 0xf0) == 0x90) { // FixArray
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
count = b & 0x0f;
|
||||
//System.out.println("fixarray count:"+count);
|
||||
obj = new Object[count];
|
||||
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
}
|
||||
|
||||
if((b & 0xf0) == 0x80) { // FixMap
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
count = b & 0x0f;
|
||||
obj = new Object[count*2];
|
||||
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||
//System.out.println("fixmap count:"+count);
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
}
|
||||
|
||||
switch(b & 0xff) { // FIXME
|
||||
case 0xc0: // nil
|
||||
obj = top_schema.createFromNil();
|
||||
break _push;
|
||||
case 0xc2: // false
|
||||
obj = top_schema.createFromBoolean(false);
|
||||
break _push;
|
||||
case 0xc3: // true
|
||||
obj = top_schema.createFromBoolean(true);
|
||||
break _push;
|
||||
case 0xca: // float
|
||||
case 0xcb: // double
|
||||
case 0xcc: // unsigned int 8
|
||||
case 0xcd: // unsigned int 16
|
||||
case 0xce: // unsigned int 32
|
||||
case 0xcf: // unsigned int 64
|
||||
case 0xd0: // signed int 8
|
||||
case 0xd1: // signed int 16
|
||||
case 0xd2: // signed int 32
|
||||
case 0xd3: // signed int 64
|
||||
trail = 1 << (b & 0x03);
|
||||
cs = b & 0x1f;
|
||||
//System.out.println("a trail "+trail+" cs:"+cs);
|
||||
break _fixed_trail_again;
|
||||
case 0xda: // raw 16
|
||||
case 0xdb: // raw 32
|
||||
case 0xdc: // array 16
|
||||
case 0xdd: // array 32
|
||||
case 0xde: // map 16
|
||||
case 0xdf: // map 32
|
||||
trail = 2 << (b & 0x01);
|
||||
cs = b & 0x1f;
|
||||
//System.out.println("b trail "+trail+" cs:"+cs);
|
||||
break _fixed_trail_again;
|
||||
default:
|
||||
//System.out.println("unknown b "+(b&0xff));
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
|
||||
} // _fixed_trail_again
|
||||
|
||||
do {
|
||||
_fixed_trail_again: {
|
||||
|
||||
if(limit - i <= trail) { break _out; }
|
||||
int n = i + 1;
|
||||
i += trail;
|
||||
|
||||
switch(cs) {
|
||||
case CS_FLOAT:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromFloat( castBuffer.getFloat(0) );
|
||||
//System.out.println("float "+obj);
|
||||
break _push;
|
||||
case CS_DOUBLE:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 8);
|
||||
obj = top_schema.createFromDouble( castBuffer.getDouble(0) );
|
||||
//System.out.println("double "+obj);
|
||||
break _push;
|
||||
case CS_UINT_8:
|
||||
//System.out.println(n);
|
||||
//System.out.println(src[n]);
|
||||
//System.out.println(src[n+1]);
|
||||
//System.out.println(src[n-1]);
|
||||
obj = top_schema.createFromShort( (short)((src[n]) & 0xff) );
|
||||
//System.out.println("uint8 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_16:
|
||||
//System.out.println(src[n]);
|
||||
//System.out.println(src[n+1]);
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
obj = top_schema.createFromInt( ((int)castBuffer.getShort(0)) & 0xffff );
|
||||
//System.out.println("uint 16 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_32:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromLong( ((long)castBuffer.getInt(0)) & 0xffffffffL );
|
||||
//System.out.println("uint 32 "+obj);
|
||||
break _push;
|
||||
case CS_UINT_64:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 8);
|
||||
{
|
||||
long o = castBuffer.getLong(0);
|
||||
if(o < 0) {
|
||||
// FIXME
|
||||
//obj = GenericBigInteger.valueOf(o & 0x7fffffffL).setBit(31);
|
||||
throw new UnpackException("uint 64 bigger than 0x7fffffff is not supported");
|
||||
} else {
|
||||
obj = top_schema.createFromLong( o );
|
||||
}
|
||||
}
|
||||
break _push;
|
||||
case CS_INT_8:
|
||||
obj = top_schema.createFromByte( src[n] );
|
||||
break _push;
|
||||
case CS_INT_16:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
obj = top_schema.createFromShort( castBuffer.getShort(0) );
|
||||
break _push;
|
||||
case CS_INT_32:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
obj = top_schema.createFromInt( castBuffer.getInt(0) );
|
||||
break _push;
|
||||
case CS_INT_64:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 8);
|
||||
obj = top_schema.createFromLong( castBuffer.getLong(0) );
|
||||
break _push;
|
||||
case CS_RAW_16:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
trail = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
break _fixed_trail_again;
|
||||
case CS_RAW_32:
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
// FIXME overflow check
|
||||
trail = castBuffer.getInt(0) & 0x7fffffff;
|
||||
if(trail == 0) {
|
||||
obj = top_schema.createFromRaw(new byte[0], 0, 0);
|
||||
break _push;
|
||||
}
|
||||
cs = ACS_RAW_VALUE;
|
||||
case ACS_RAW_VALUE:
|
||||
obj = top_schema.createFromRaw(src, n, trail);
|
||||
break _push;
|
||||
case CS_ARRAY_16:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
obj = new Object[count];
|
||||
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
case CS_ARRAY_32:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IArraySchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
// FIXME overflow check
|
||||
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||
obj = new Object[count];
|
||||
if(count == 0) { break _push; } // FIXME check IArraySchema
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_ARRAY_ITEM;
|
||||
top_count = count;
|
||||
top_schema = ((IArraySchema)top_schema).getElementSchema(0);
|
||||
break _header_again;
|
||||
case CS_MAP_16:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 2);
|
||||
count = ((int)castBuffer.getShort(0)) & 0xffff;
|
||||
obj = new Object[count*2];
|
||||
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||
//System.out.println("fixmap count:"+count);
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
++top;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
case CS_MAP_32:
|
||||
if(top >= MAX_STACK_SIZE) {
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
if(!(top_schema instanceof IMapSchema)) {
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
castBuffer.rewind();
|
||||
castBuffer.put(src, n, 4);
|
||||
// FIXME overflow check
|
||||
count = castBuffer.getInt(0) & 0x7fffffff;
|
||||
obj = new Object[count*2];
|
||||
if(count == 0) { break _push; } // FIXME check IMapSchema
|
||||
//System.out.println("fixmap count:"+count);
|
||||
++top;
|
||||
stack_obj[top] = top_obj;
|
||||
stack_ct[top] = top_ct;
|
||||
stack_count[top] = top_count;
|
||||
stack_schema[top] = top_schema;
|
||||
top_obj = obj;
|
||||
top_ct = CT_MAP_KEY;
|
||||
top_count = count;
|
||||
top_schema = ((IMapSchema)top_schema).getKeySchema();
|
||||
break _header_again;
|
||||
default:
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
|
||||
} // _fixed_trail_again
|
||||
} while(true);
|
||||
} // _push
|
||||
|
||||
do {
|
||||
_push: {
|
||||
//System.out.println("push top:"+top);
|
||||
if(top == -1) {
|
||||
++i;
|
||||
data = obj;
|
||||
finished = true;
|
||||
break _out;
|
||||
}
|
||||
|
||||
switch(top_ct) {
|
||||
case CT_ARRAY_ITEM: {
|
||||
//System.out.println("array item "+obj);
|
||||
Object[] ar = (Object[])top_obj;
|
||||
ar[ar.length - top_count] = obj;
|
||||
if(--top_count == 0) {
|
||||
top_obj = stack_obj[top];
|
||||
top_ct = stack_ct[top];
|
||||
top_count = stack_count[top];
|
||||
top_schema = stack_schema[top];
|
||||
obj = ((IArraySchema)top_schema).createFromArray(ar);
|
||||
stack_obj[top] = null;
|
||||
stack_schema[top] = null;
|
||||
--top;
|
||||
break _push;
|
||||
} else {
|
||||
top_schema = ((IArraySchema)stack_schema[top]).getElementSchema(ar.length - top_count);
|
||||
}
|
||||
break _header_again;
|
||||
}
|
||||
case CT_MAP_KEY: {
|
||||
//System.out.println("map key:"+top+" "+obj);
|
||||
Object[] mp = (Object[])top_obj;
|
||||
mp[mp.length - top_count*2] = obj;
|
||||
top_ct = CT_MAP_VALUE;
|
||||
top_schema = ((IMapSchema)stack_schema[top]).getValueSchema();
|
||||
break _header_again;
|
||||
}
|
||||
case CT_MAP_VALUE: {
|
||||
//System.out.println("map value:"+top+" "+obj);
|
||||
Object[] mp = (Object[])top_obj;
|
||||
mp[mp.length - top_count*2 + 1] = obj;
|
||||
if(--top_count == 0) {
|
||||
top_obj = stack_obj[top];
|
||||
top_ct = stack_ct[top];
|
||||
top_count = stack_count[top];
|
||||
top_schema = stack_schema[top];
|
||||
obj = ((IMapSchema)top_schema).createFromMap(mp);
|
||||
stack_obj[top] = null;
|
||||
stack_schema[top] = null;
|
||||
--top;
|
||||
break _push;
|
||||
}
|
||||
top_ct = CT_MAP_KEY;
|
||||
break _header_again;
|
||||
}
|
||||
default:
|
||||
throw new UnpackException("parse error");
|
||||
}
|
||||
} // _push
|
||||
} while(true);
|
||||
|
||||
} // _header_again
|
||||
cs = CS_HEADER;
|
||||
++i;
|
||||
} while(i < limit); // _out
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
125
java/src/org/msgpack/schema/ArraySchema.java
Normal file
125
java/src/org/msgpack/schema/ArraySchema.java
Normal 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.schema;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.RandomAccess;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ArraySchema extends Schema implements IArraySchema {
|
||||
private Schema elementSchema;
|
||||
|
||||
public ArraySchema(Schema elementSchema)
|
||||
{
|
||||
super("array");
|
||||
this.elementSchema = elementSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName()
|
||||
{
|
||||
return "List<"+elementSchema.getFullName()+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "(array "+elementSchema.getExpression()+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj instanceof List) {
|
||||
ArrayList<Object> d = (ArrayList<Object>)obj;
|
||||
pk.packArray(d.size());
|
||||
if(obj instanceof RandomAccess) {
|
||||
for(int i=0; i < d.size(); ++i) {
|
||||
elementSchema.pack(pk, d.get(i));
|
||||
}
|
||||
} else {
|
||||
for(Object e : d) {
|
||||
elementSchema.pack(pk, e);
|
||||
}
|
||||
}
|
||||
|
||||
} else if(obj instanceof Set) {
|
||||
Set<Object> d = (Set<Object>)obj;
|
||||
pk.packArray(d.size());
|
||||
for(Object e : d) {
|
||||
elementSchema.pack(pk, e);
|
||||
}
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(Object obj) throws MessageTypeException
|
||||
{
|
||||
if(obj instanceof List) {
|
||||
List d = (List)obj;
|
||||
ArrayList ar = new ArrayList(d.size());
|
||||
if(obj instanceof RandomAccess) {
|
||||
for(int i=0; i < d.size(); ++i) {
|
||||
ar.add( elementSchema.convert(d.get(i)) );
|
||||
}
|
||||
} else {
|
||||
for(Object e : d) {
|
||||
ar.add( elementSchema.convert(e) );
|
||||
}
|
||||
}
|
||||
return ar;
|
||||
|
||||
} else if(obj instanceof Collection) {
|
||||
Collection d = (Collection)obj;
|
||||
ArrayList ar = new ArrayList(d.size());
|
||||
for(Object e : (Collection)obj) {
|
||||
ar.add( elementSchema.convert(e) );
|
||||
}
|
||||
return ar;
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getElementSchema(int index)
|
||||
{
|
||||
return elementSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromArray(Object[] obj)
|
||||
{
|
||||
return Arrays.asList(obj);
|
||||
}
|
||||
}
|
||||
|
89
java/src/org/msgpack/schema/ByteSchema.java
Normal file
89
java/src/org/msgpack/schema/ByteSchema.java
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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() {
|
||||
super("Byte");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "byte";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packByte( ((Number)obj).byteValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Byte) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).byteValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (byte)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (byte)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (byte)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return (byte)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (byte)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (byte)v;
|
||||
}
|
||||
}
|
||||
|
241
java/src/org/msgpack/schema/ClassGenerator.java
Normal file
241
java/src/org/msgpack/schema/ClassGenerator.java
Normal file
@@ -0,0 +1,241 @@
|
||||
//
|
||||
// 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 ArraySchema) {
|
||||
ArraySchema as = (ArraySchema)s;
|
||||
findSubclassSchema(dst, as.getElementSchema(0));
|
||||
} else if(s instanceof MapSchema) {
|
||||
MapSchema as = (MapSchema)s;
|
||||
findSubclassSchema(dst, as.getKeySchema());
|
||||
findSubclassSchema(dst, as.getValueSchema());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeHeader() throws IOException {
|
||||
if(schema.getNamespace() != null) {
|
||||
line("package "+schema.getNamespace()+";");
|
||||
line();
|
||||
}
|
||||
line("import java.util.*;");
|
||||
line("import java.io.*;");
|
||||
line("import org.msgpack.*;");
|
||||
line("import org.msgpack.schema.ClassSchema;");
|
||||
line("import org.msgpack.schema.FieldSchema;");
|
||||
}
|
||||
|
||||
private void writeFooter() throws IOException {
|
||||
line();
|
||||
}
|
||||
|
||||
private void writeClass() throws IOException {
|
||||
line();
|
||||
line("public final class "+schema.getName()+" implements MessagePackable, MessageMergeable");
|
||||
line("{");
|
||||
pushIndent();
|
||||
writeSchema();
|
||||
writeMemberVariables();
|
||||
writeMemberFunctions();
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeSubclass() throws IOException {
|
||||
line();
|
||||
line("final class "+schema.getName()+" implements MessagePackable, MessageMergeable");
|
||||
line("{");
|
||||
pushIndent();
|
||||
writeSchema();
|
||||
writeMemberVariables();
|
||||
writeMemberFunctions();
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeSchema() throws IOException {
|
||||
line("private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load(\""+schema.getExpression()+"\");");
|
||||
line("public static ClassSchema getSchema() { return _SCHEMA; }");
|
||||
}
|
||||
|
||||
private void writeMemberVariables() throws IOException {
|
||||
line();
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("public "+f.getSchema().getFullName()+" "+f.getName()+";");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMemberFunctions() throws IOException {
|
||||
// void messagePack(Packer pk)
|
||||
// boolean equals(Object obj)
|
||||
// int hashCode()
|
||||
// void set(int _index, Object _value)
|
||||
// Object get(int _index);
|
||||
// getXxx()
|
||||
// setXxx(Xxx xxx)
|
||||
writeConstructors();
|
||||
writeAccessors();
|
||||
writePackFunction();
|
||||
writeMergeFunction();
|
||||
writeFactoryFunction();
|
||||
}
|
||||
|
||||
private void writeConstructors() throws IOException {
|
||||
line();
|
||||
line("public "+schema.getName()+"() { }");
|
||||
}
|
||||
|
||||
private void writeAccessors() throws IOException {
|
||||
// FIXME
|
||||
//line();
|
||||
//for(FieldSchema f : schema.getFields()) {
|
||||
// line("");
|
||||
//}
|
||||
}
|
||||
|
||||
private void writePackFunction() throws IOException {
|
||||
line();
|
||||
line("@Override");
|
||||
line("public void messagePack(Packer _pk) throws IOException");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line("_pk.packArray("+schema.getFields().length+");");
|
||||
line("FieldSchema[] _fields = _SCHEMA.getFields();");
|
||||
int i = 0;
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("_fields["+i+"].getSchema().pack(_pk, "+f.getName()+");");
|
||||
++i;
|
||||
}
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeMergeFunction() throws IOException {
|
||||
line();
|
||||
line("@Override");
|
||||
line("@SuppressWarnings(\"unchecked\")");
|
||||
line("public void messageMerge(Object obj) throws MessageTypeException");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line("Object[] _source = ((List)obj).toArray();");
|
||||
line("FieldSchema[] _fields = _SCHEMA.getFields();");
|
||||
int i = 0;
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("if(_source.length <= "+i+") { return; } this."+f.getName()+" = ("+f.getSchema().getFullName()+")_fields["+i+"].getSchema().convert(_source["+i+"]);");
|
||||
++i;
|
||||
}
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeFactoryFunction() throws IOException {
|
||||
line();
|
||||
line("@SuppressWarnings(\"unchecked\")");
|
||||
line("public static "+schema.getName()+" createFromMessage(Object[] _message)");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line(schema.getName()+" _self = new "+schema.getName()+"();");
|
||||
int i = 0;
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("if(_message.length <= "+i+") { return _self; } _self."+f.getName()+" = ("+f.getSchema().getFullName()+")_message["+i+"];");
|
||||
++i;
|
||||
}
|
||||
line("return _self;");
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void line(String str) throws IOException {
|
||||
for(int i=0; i < indent; ++i) {
|
||||
writer.write("\t");
|
||||
}
|
||||
writer.write(str+"\n");
|
||||
}
|
||||
|
||||
private void line() throws IOException {
|
||||
writer.write("\n");
|
||||
}
|
||||
|
||||
private void pushIndent() {
|
||||
indent += 1;
|
||||
}
|
||||
|
||||
private void popIndent() {
|
||||
indent -= 1;
|
||||
}
|
||||
}
|
||||
|
95
java/src/org/msgpack/schema/ClassSchema.java
Normal file
95
java/src/org/msgpack/schema/ClassSchema.java
Normal file
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// 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 FieldSchema[] fields;
|
||||
protected List<String> imports;
|
||||
protected String namespace;
|
||||
protected String fqdn;
|
||||
|
||||
public ClassSchema(
|
||||
String name, String namespace,
|
||||
List<String> imports, List<FieldSchema> fields) {
|
||||
super(name);
|
||||
this.namespace = namespace;
|
||||
this.imports = imports; // FIXME clone?
|
||||
this.fields = new FieldSchema[fields.size()];
|
||||
System.arraycopy(fields.toArray(), 0, this.fields, 0, fields.size());
|
||||
if(namespace == null) {
|
||||
this.fqdn = name;
|
||||
} else {
|
||||
this.fqdn = namespace+"."+name;
|
||||
}
|
||||
}
|
||||
|
||||
public final FieldSchema[] getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
List<String> getImports() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
void setImports(List<String> imports) {
|
||||
this.imports = imports; // FIXME clone?
|
||||
}
|
||||
|
||||
//@Override
|
||||
//public String getFullName()
|
||||
//{
|
||||
// if(namespace == null) {
|
||||
// return getName();
|
||||
// } else {
|
||||
// return namespace+"."+getName();
|
||||
// }
|
||||
//}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("(class ");
|
||||
b.append(getName());
|
||||
if(namespace != null) {
|
||||
b.append(" (package "+namespace+")");
|
||||
}
|
||||
for(FieldSchema f : fields) {
|
||||
b.append(" "+f.getExpression());
|
||||
}
|
||||
b.append(")");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public boolean equals(SpecificClassSchema o) {
|
||||
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
|
||||
getName().equals(o.getName());
|
||||
}
|
||||
}
|
||||
|
84
java/src/org/msgpack/schema/DoubleSchema.java
Normal file
84
java/src/org/msgpack/schema/DoubleSchema.java
Normal 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.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class DoubleSchema extends Schema {
|
||||
public DoubleSchema() {
|
||||
super("Double");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "double";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packDouble( ((Number)obj).doubleValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Double) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).doubleValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (double)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (double)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (double)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (double)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (double)v;
|
||||
}
|
||||
}
|
||||
|
43
java/src/org/msgpack/schema/FieldSchema.java
Normal file
43
java/src/org/msgpack/schema/FieldSchema.java
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
package org.msgpack.schema;
|
||||
|
||||
import org.msgpack.Schema;
|
||||
|
||||
public class FieldSchema {
|
||||
private String name;
|
||||
private Schema schema;
|
||||
|
||||
public FieldSchema(String name, Schema schema) {
|
||||
this.name = name;
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public final Schema getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
public String getExpression() {
|
||||
return "(field "+name+" "+schema.getExpression()+")";
|
||||
}
|
||||
}
|
||||
|
84
java/src/org/msgpack/schema/FloatSchema.java
Normal file
84
java/src/org/msgpack/schema/FloatSchema.java
Normal 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.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class FloatSchema extends Schema {
|
||||
public FloatSchema() {
|
||||
super("Float");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "float";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packFloat( ((Number)obj).floatValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Float) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).floatValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (float)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (float)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (float)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (float)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (float)v;
|
||||
}
|
||||
}
|
||||
|
91
java/src/org/msgpack/schema/GenericClassSchema.java
Normal file
91
java/src/org/msgpack/schema/GenericClassSchema.java
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
192
java/src/org/msgpack/schema/GenericSchema.java
Normal file
192
java/src/org/msgpack/schema/GenericSchema.java
Normal file
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// 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.*;
|
||||
//import org.msgpack.generic.*;
|
||||
|
||||
public class GenericSchema extends Schema implements IArraySchema, IMapSchema {
|
||||
public GenericSchema() {
|
||||
super("Object");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "object";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
pk.pack(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getElementSchema(int index) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getKeySchema() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getValueSchema() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromNil() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromBoolean(boolean v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
byte[] bytes = new byte[length];
|
||||
System.arraycopy(b, offset, bytes, 0, length);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromArray(Object[] obj) {
|
||||
return Arrays.asList(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object createFromMap(Object[] obj) {
|
||||
HashMap m = new HashMap(obj.length / 2);
|
||||
int i = 0;
|
||||
while(i < obj.length) {
|
||||
Object k = obj[i++];
|
||||
Object v = obj[i++];
|
||||
m.put(k, v);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public Object createFromNil() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromBoolean(boolean v) {
|
||||
return new GenericBoolean(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFromByte(byte v) {
|
||||
return new GenericByte(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return new GenericShort(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return new GenericInt(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return new GenericLong(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return new GenericFloat(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return new GenericDouble(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
return new GenericRaw(b, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromArray(Object[] obj) {
|
||||
// FIXME GenericArray
|
||||
return Arrays.asList(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromMap(Object[] obj) {
|
||||
GenericMap m = new GenericMap(obj.length / 2);
|
||||
int i = 0;
|
||||
while(i < obj.length) {
|
||||
Object k = obj[i++];
|
||||
Object v = obj[i++];
|
||||
m.put(k, v);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
26
java/src/org/msgpack/schema/IArraySchema.java
Normal file
26
java/src/org/msgpack/schema/IArraySchema.java
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// MessagePack for Java
|
||||
//
|
||||
// Copyright (C) 2009-2010 FURUHASHI Sadayuki
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
package org.msgpack.schema;
|
||||
|
||||
import org.msgpack.Schema;
|
||||
|
||||
public interface IArraySchema {
|
||||
public Schema getElementSchema(int index);
|
||||
public Object createFromArray(Object[] obj);
|
||||
}
|
||||
|
27
java/src/org/msgpack/schema/IMapSchema.java
Normal file
27
java/src/org/msgpack/schema/IMapSchema.java
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
|
89
java/src/org/msgpack/schema/IntSchema.java
Normal file
89
java/src/org/msgpack/schema/IntSchema.java
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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() {
|
||||
super("Integer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "int";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packInt( ((Number)obj).intValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Integer) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).intValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (int)v;
|
||||
}
|
||||
}
|
||||
|
89
java/src/org/msgpack/schema/LongSchema.java
Normal file
89
java/src/org/msgpack/schema/LongSchema.java
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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() {
|
||||
super("Long");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "long";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packLong( ((Number)obj).longValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Long) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).longValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (long)v;
|
||||
}
|
||||
}
|
||||
|
103
java/src/org/msgpack/schema/MapSchema.java
Normal file
103
java/src/org/msgpack/schema/MapSchema.java
Normal file
@@ -0,0 +1,103 @@
|
||||
//
|
||||
// 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) {
|
||||
super("map");
|
||||
this.keySchema = keySchema;
|
||||
this.valueSchema = valueSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return "HashList<"+keySchema.getFullName()+", "+valueSchema.getFullName()+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "(map "+keySchema.getExpression()+" "+valueSchema.getExpression()+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Map) {
|
||||
Map<Object,Object> d = (Map<Object,Object>)obj;
|
||||
pk.packMap(d.size());
|
||||
for(Map.Entry<Object,Object> e : d.entrySet()) {
|
||||
keySchema.pack(pk, e.getKey());
|
||||
valueSchema.pack(pk, e.getValue());
|
||||
}
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Map) {
|
||||
Map<Object,Object> d = (Map<Object,Object>)obj;
|
||||
Map<Object,Object> m = new HashMap<Object,Object>();
|
||||
for(Map.Entry<Object,Object> e : d.entrySet()) {
|
||||
m.put(keySchema.convert(e.getKey()), valueSchema.convert(e.getValue()));
|
||||
}
|
||||
return m;
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getKeySchema() {
|
||||
return keySchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Schema getValueSchema() {
|
||||
return valueSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
105
java/src/org/msgpack/schema/RawSchema.java
Normal file
105
java/src/org/msgpack/schema/RawSchema.java
Normal file
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// 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 RawSchema extends Schema {
|
||||
public RawSchema() {
|
||||
super("raw");
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return "byte[]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
// FIXME instanceof GenericObject
|
||||
if(obj instanceof byte[]) {
|
||||
byte[] d = (byte[])obj;
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
|
||||
} else if(obj instanceof ByteBuffer) {
|
||||
ByteBuffer d = (ByteBuffer)obj;
|
||||
if(!d.hasArray()) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
pk.packRaw(d.capacity());
|
||||
pk.packRawBody(d.array(), d.position(), d.capacity());
|
||||
|
||||
} else if(obj instanceof String) {
|
||||
try {
|
||||
byte[] d = ((String)obj).getBytes("UTF-8");
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
// FIXME instanceof GenericObject
|
||||
if(obj instanceof byte[]) {
|
||||
// FIXME copy?
|
||||
//byte[] d = (byte[])obj;
|
||||
//byte[] v = new byte[d.length];
|
||||
//System.arraycopy(d, 0, v, 0, d.length);
|
||||
//return v;
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof ByteBuffer) {
|
||||
ByteBuffer d = (ByteBuffer)obj;
|
||||
byte[] v = new byte[d.capacity()];
|
||||
int pos = d.position();
|
||||
d.get(v);
|
||||
d.position(pos);
|
||||
return v;
|
||||
|
||||
} else if(obj instanceof String) {
|
||||
try {
|
||||
return ((String)obj).getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
byte[] d = new byte[length];
|
||||
System.arraycopy(b, offset, d, 0, length);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
64
java/src/org/msgpack/schema/ReflectionClassSchema.java
Normal file
64
java/src/org/msgpack/schema/ReflectionClassSchema.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package org.msgpack.schema;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.lang.reflect.*;
|
||||
import org.msgpack.*;
|
||||
|
||||
// FIXME
|
||||
public abstract class ReflectionClassSchema extends ClassSchema {
|
||||
private Constructor constructorCache;
|
||||
|
||||
public ReflectionClassSchema(String name, List<FieldSchema> fields, String namespace, List<String> imports) {
|
||||
super(name, namespace, imports, fields);
|
||||
}
|
||||
|
||||
/*
|
||||
Schema getElementSchema(int index)
|
||||
{
|
||||
// FIXME check index < fields.length
|
||||
fields[index].getSchema();
|
||||
}
|
||||
|
||||
Object createFromArray(Object[] obj)
|
||||
{
|
||||
Object o = newInstance();
|
||||
((MessageConvertable)o).messageConvert(obj);
|
||||
return o;
|
||||
}
|
||||
|
||||
Object newInstance()
|
||||
{
|
||||
if(constructorCache == null) {
|
||||
cacheConstructor();
|
||||
}
|
||||
try {
|
||||
return constructorCache.newInstance((Object[])null);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheConstructor()
|
||||
{
|
||||
try {
|
||||
Class c = Class.forName(fqdn);
|
||||
int index = 0;
|
||||
for(SpecificFieldSchema f : fields) {
|
||||
f.cacheField(c, index++);
|
||||
}
|
||||
constructorCache = c.getDeclaredConstructor((Class[])null);
|
||||
constructorCache.setAccessible(true);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
254
java/src/org/msgpack/schema/SSchemaParser.java
Normal file
254
java/src/org/msgpack/schema/SSchemaParser.java
Normal file
@@ -0,0 +1,254 @@
|
||||
//
|
||||
// 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 RawSchema();
|
||||
} else if(type.equals("byte")) {
|
||||
return new ByteSchema();
|
||||
} else if(type.equals("short")) {
|
||||
return new ShortSchema();
|
||||
} else if(type.equals("int")) {
|
||||
return new IntSchema();
|
||||
} else if(type.equals("long")) {
|
||||
return new LongSchema();
|
||||
} else if(type.equals("float")) {
|
||||
return new FloatSchema();
|
||||
} else if(type.equals("double")) {
|
||||
return new DoubleSchema();
|
||||
} else if(type.equals("object")) {
|
||||
return new GenericSchema();
|
||||
} else {
|
||||
throw new RuntimeException("byte, short, int, long, float, double, raw, string or object is expected but got '"+type+"': "+exp);
|
||||
}
|
||||
} else {
|
||||
String type = exp.getTuple(0).getAtom();
|
||||
if(type.equals("class")) {
|
||||
return parseClass(exp);
|
||||
} else if(type.equals("array")) {
|
||||
return parseArray(exp);
|
||||
} else if(type.equals("map")) {
|
||||
return parseMap(exp);
|
||||
} else {
|
||||
throw new RuntimeException("class, array or map is expected but got '"+type+"': "+exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClassSchema parseClass(SExp exp) {
|
||||
if(exp.size() < 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("class is (class NAME CLASS_BODY): "+exp);
|
||||
}
|
||||
|
||||
String namespace = null;
|
||||
List<String> imports = new ArrayList<String>();
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
List<FieldSchema> fields = new ArrayList<FieldSchema>();
|
||||
|
||||
for(Iterator<SExp> i=exp.iterator(2); i.hasNext();) {
|
||||
SExp subexp = i.next();
|
||||
if(!subexp.isTuple() || subexp.empty() || !subexp.getTuple(0).isAtom()) {
|
||||
throw new RuntimeException("field, package or import is expected: "+subexp);
|
||||
}
|
||||
String type = subexp.getTuple(0).getAtom();
|
||||
if(type.equals("field")) {
|
||||
fields.add( parseField(subexp) );
|
||||
} else if(type.equals("package")) {
|
||||
if(namespace != null) {
|
||||
throw new RuntimeException("duplicated package definition: "+subexp);
|
||||
}
|
||||
namespace = parseNamespace(subexp);
|
||||
} else if(type.equals("import")) {
|
||||
imports.add( parseImport(subexp) );
|
||||
} else {
|
||||
throw new RuntimeException("field, package or import is expected but got '"+type+"': "+subexp);
|
||||
}
|
||||
}
|
||||
|
||||
if(specificClass) {
|
||||
return new SpecificClassSchema(name, namespace, imports, fields);
|
||||
} else {
|
||||
return new GenericClassSchema(name, namespace, imports, fields);
|
||||
}
|
||||
}
|
||||
|
||||
private ArraySchema parseArray(SExp exp) {
|
||||
if(exp.size() != 2) {
|
||||
throw new RuntimeException("array is (array ELEMENT_TYPE): "+exp);
|
||||
}
|
||||
Schema elementType = readType(exp.getTuple(1));
|
||||
return new ArraySchema(elementType);
|
||||
}
|
||||
|
||||
private MapSchema parseMap(SExp exp) {
|
||||
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("map is (map KEY_TYPE VALUE_TYPE): "+exp);
|
||||
}
|
||||
Schema keyType = readType(exp.getTuple(1));
|
||||
Schema valueType = readType(exp.getTuple(2));
|
||||
return new MapSchema(keyType, valueType);
|
||||
}
|
||||
|
||||
private String parseNamespace(SExp exp) {
|
||||
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("package is (package NAME): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
return name;
|
||||
}
|
||||
|
||||
private String parseImport(SExp exp) {
|
||||
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("import is (import NAME): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
return name;
|
||||
}
|
||||
|
||||
private FieldSchema parseField(SExp exp) {
|
||||
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("field is (field NAME TYPE): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
Schema type = readType(exp.getTuple(2));
|
||||
return new FieldSchema(name, type);
|
||||
}
|
||||
}
|
||||
|
89
java/src/org/msgpack/schema/ShortSchema.java
Normal file
89
java/src/org/msgpack/schema/ShortSchema.java
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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() {
|
||||
super("Short");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression() {
|
||||
return "short";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
if(obj instanceof Number) {
|
||||
pk.packShort( ((Number)obj).shortValue() );
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
if(obj instanceof Short) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof Number) {
|
||||
return ((Number)obj).shortValue();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromByte(byte v) {
|
||||
return (short)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromShort(short v) {
|
||||
return (short)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromInt(int v) {
|
||||
return (short)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromLong(long v) {
|
||||
return (short)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromFloat(float v) {
|
||||
return (short)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromDouble(double v) {
|
||||
return (short)v;
|
||||
}
|
||||
}
|
||||
|
122
java/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
122
java/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// 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 {
|
||||
MessageMergeable o = (MessageMergeable)constructorCache.newInstance((Object[])null);
|
||||
o.messageMerge(obj);
|
||||
return o;
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
public Schema getElementSchema(int index) {
|
||||
// FIXME check index < fields.length
|
||||
return fields[index].getSchema();
|
||||
}
|
||||
|
||||
public Object createFromArray(Object[] obj) {
|
||||
if(factoryCache == null) {
|
||||
cacheFactory();
|
||||
}
|
||||
try {
|
||||
return factoryCache.invoke(null, new Object[]{obj});
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getCause());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void cacheFactory() {
|
||||
try {
|
||||
classCache = Class.forName(fqdn);
|
||||
factoryCache = classCache.getDeclaredMethod("createFromMessage", new Class[]{Object[].class});
|
||||
factoryCache.setAccessible(true);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void cacheConstructor() {
|
||||
try {
|
||||
classCache = Class.forName(fqdn);
|
||||
constructorCache = classCache.getDeclaredConstructor((Class[])null);
|
||||
constructorCache.setAccessible(true);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
111
java/src/org/msgpack/schema/StringSchema.java
Normal file
111
java/src/org/msgpack/schema/StringSchema.java
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// 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() {
|
||||
super("string");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return "String";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException {
|
||||
// FIXME instanceof GenericObject
|
||||
if(obj instanceof String) {
|
||||
try {
|
||||
byte[] d = ((String)obj).getBytes("UTF-8");
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
|
||||
} else if(obj instanceof byte[]) {
|
||||
byte[] d = (byte[])obj;
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
|
||||
} else if(obj instanceof ByteBuffer) {
|
||||
ByteBuffer d = (ByteBuffer)obj;
|
||||
if(!d.hasArray()) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
pk.packRaw(d.capacity());
|
||||
pk.packRawBody(d.array(), d.position(), d.capacity());
|
||||
|
||||
} else if(obj == null) {
|
||||
pk.packNil();
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(Object obj) throws MessageTypeException {
|
||||
// FIXME instanceof GenericObject
|
||||
if(obj instanceof String) {
|
||||
return obj;
|
||||
|
||||
} else if(obj instanceof byte[]) {
|
||||
try {
|
||||
return new String((byte[])obj, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
|
||||
} else if(obj instanceof ByteBuffer) {
|
||||
ByteBuffer d = (ByteBuffer)obj;
|
||||
try {
|
||||
if(d.hasArray()) {
|
||||
return new String(d.array(), d.position(), d.capacity(), "UTF-8");
|
||||
} else {
|
||||
byte[] v = new byte[d.capacity()];
|
||||
int pos = d.position();
|
||||
d.get(v);
|
||||
d.position(pos);
|
||||
return new String(v, "UTF-8");
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw MessageTypeException.invalidConvert(obj, this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createFromRaw(byte[] b, int offset, int length) {
|
||||
try {
|
||||
return new String(b, offset, length, "UTF-8");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user