mirror of
https://github.com/msgpack/msgpack-python.git
synced 2026-02-07 18:29:53 +00:00
import MessagePack for Java implementation plan 2
This commit is contained in:
parent
93a95725fc
commit
e39e1d4f60
48 changed files with 3676 additions and 0 deletions
61
java-plan2/src/org/msgpack/schema/ArraySchema.java
Normal file
61
java-plan2/src/org/msgpack/schema/ArraySchema.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ArraySchema extends Schema {
|
||||
private Schema elementType;
|
||||
|
||||
public ArraySchema(Schema elementType)
|
||||
{
|
||||
super("array");
|
||||
this.elementType = elementType;
|
||||
}
|
||||
|
||||
public Schema getElementType()
|
||||
{
|
||||
return elementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName()
|
||||
{
|
||||
return "ArrayList<"+elementType.getFullName()+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "(array "+elementType.getExpression()+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
List<Object> d = (List<Object>)obj;
|
||||
pk.packArray(d.size());
|
||||
for(Object e : d) {
|
||||
elementType.pack(pk, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
List<GenericObject> d = obj.asArray();
|
||||
List<Object> g = new ArrayList<Object>();
|
||||
for(GenericObject o : d) {
|
||||
g.add( elementType.convert(o) );
|
||||
}
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
230
java-plan2/src/org/msgpack/schema/ClassGenerator.java
Normal file
230
java-plan2/src/org/msgpack/schema/ClassGenerator.java
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
public class ClassGenerator {
|
||||
private ClassSchema schema;
|
||||
private Writer writer;
|
||||
private int indent;
|
||||
|
||||
private ClassGenerator(Writer writer)
|
||||
{
|
||||
this.writer = writer;
|
||||
this.indent = 0;
|
||||
}
|
||||
|
||||
public static void write(Schema schema, Writer dest) throws IOException
|
||||
{
|
||||
if(!(schema instanceof ClassSchema)) {
|
||||
throw new RuntimeException("schema is not class schema");
|
||||
}
|
||||
ClassSchema cs = (ClassSchema)schema;
|
||||
new ClassGenerator(dest).run(cs);
|
||||
}
|
||||
|
||||
private void run(ClassSchema cs) throws IOException
|
||||
{
|
||||
List<ClassSchema> subclasses = new ArrayList<ClassSchema>();
|
||||
for(FieldSchema f : cs.getFields()) {
|
||||
findSubclassSchema(subclasses, f.getType());
|
||||
}
|
||||
|
||||
for(ClassSchema sub : subclasses) {
|
||||
sub.setNamespace(cs.getNamespace());
|
||||
sub.setImports(cs.getImports());
|
||||
}
|
||||
|
||||
this.schema = cs;
|
||||
|
||||
writeHeader();
|
||||
|
||||
writeClass();
|
||||
|
||||
for(ClassSchema sub : subclasses) {
|
||||
this.schema = sub;
|
||||
writeSubclass();
|
||||
}
|
||||
|
||||
writeFooter();
|
||||
|
||||
this.schema = null;
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
private void findSubclassSchema(List<ClassSchema> dst, Schema s)
|
||||
{
|
||||
if(s instanceof ClassSchema) {
|
||||
ClassSchema cs = (ClassSchema)s;
|
||||
if(!dst.contains(cs)) { dst.add(cs); }
|
||||
for(FieldSchema f : cs.getFields()) {
|
||||
findSubclassSchema(dst, f.getType());
|
||||
}
|
||||
} else if(s instanceof ArraySchema) {
|
||||
ArraySchema as = (ArraySchema)s;
|
||||
findSubclassSchema(dst, as.getElementType());
|
||||
} else if(s instanceof MapSchema) {
|
||||
MapSchema as = (MapSchema)s;
|
||||
findSubclassSchema(dst, as.getKeyType());
|
||||
findSubclassSchema(dst, as.getValueType());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeHeader() throws IOException
|
||||
{
|
||||
if(schema.getNamespace() != null) {
|
||||
line("package "+schema.getNamespace()+";");
|
||||
line();
|
||||
}
|
||||
line("import java.util.*;");
|
||||
line("import java.io.*;");
|
||||
line("import org.msgpack.*;");
|
||||
line("import org.msgpack.schema.*;");
|
||||
}
|
||||
|
||||
private void writeFooter() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
private void writeClass() throws IOException
|
||||
{
|
||||
line();
|
||||
line("public final class "+schema.getName()+" implements MessagePackable, MessageConvertable");
|
||||
line("{");
|
||||
pushIndent();
|
||||
writeSchema();
|
||||
writeMemberVariables();
|
||||
writeMemberFunctions();
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeSubclass() throws IOException
|
||||
{
|
||||
line();
|
||||
line("final class "+schema.getName()+" implements MessagePackable, MessageConvertable");
|
||||
line("{");
|
||||
pushIndent();
|
||||
writeSchema();
|
||||
writeMemberVariables();
|
||||
writeMemberFunctions();
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeSchema() throws IOException
|
||||
{
|
||||
line("private static final ClassSchema _SCHEMA = (ClassSchema)Schema.load(\""+schema.getExpression()+"\");");
|
||||
line("public static ClassSchema getSchema() { return _SCHEMA; }");
|
||||
}
|
||||
|
||||
private void writeMemberVariables() throws IOException
|
||||
{
|
||||
line();
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("public "+f.getType().getFullName()+" "+f.getName()+";");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMemberFunctions() throws IOException
|
||||
{
|
||||
// void messagePack(Packer pk)
|
||||
// boolean equals(Object obj)
|
||||
// int hashCode()
|
||||
// void set(int _index, Object _value)
|
||||
// Object get(int _index);
|
||||
// getXxx()
|
||||
// setXxx(Xxx xxx)
|
||||
writeConstructors();
|
||||
writeAccessors();
|
||||
writePackFunction();
|
||||
writeConvertFunction();
|
||||
}
|
||||
|
||||
private void writeConstructors() throws IOException
|
||||
{
|
||||
line();
|
||||
line("public "+schema.getName()+"() { }");
|
||||
}
|
||||
|
||||
private void writeAccessors() throws IOException
|
||||
{
|
||||
// FIXME
|
||||
//line();
|
||||
//for(FieldSchema f : schema.getFields()) {
|
||||
// line("");
|
||||
//}
|
||||
}
|
||||
|
||||
private void writePackFunction() throws IOException
|
||||
{
|
||||
line();
|
||||
line("@Override");
|
||||
line("public void messagePack(Packer pk) throws IOException");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line("List<? extends FieldSchema> _f = _SCHEMA.getFields();");
|
||||
line("pk.packArray("+schema.getFields().size()+");");
|
||||
int i = 0;
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("_f.get("+i+").getType().pack(pk, "+f.getName()+");");
|
||||
++i;
|
||||
}
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void writeConvertFunction() throws IOException
|
||||
{
|
||||
line();
|
||||
line("@Override");
|
||||
line("@SuppressWarnings(\"unchecked\")");
|
||||
line("public void messageConvert(GenericObject obj)");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line("List<GenericObject> _l = obj.asArray();");
|
||||
line("List<? extends FieldSchema> _f = _SCHEMA.getFields();");
|
||||
int i = 0;
|
||||
for(FieldSchema f : schema.getFields()) {
|
||||
line("if(_l.size() <= "+i+") { return; } "+f.getName()+" = ("+f.getType().getFullName()+")_f.get("+i+").getType().convert(_l.get("+i+"));");
|
||||
++i;
|
||||
}
|
||||
popIndent();
|
||||
line("}");
|
||||
line();
|
||||
line("public static "+schema.getName()+" convert(GenericObject obj)");
|
||||
line("{");
|
||||
pushIndent();
|
||||
line("return ("+schema.getName()+")_SCHEMA.convert(obj);");
|
||||
popIndent();
|
||||
line("}");
|
||||
}
|
||||
|
||||
private void line(String str) throws IOException
|
||||
{
|
||||
for(int i=0; i < indent; ++i) {
|
||||
writer.write("\t");
|
||||
}
|
||||
writer.write(str+"\n");
|
||||
}
|
||||
|
||||
private void line() throws IOException
|
||||
{
|
||||
writer.write("\n");
|
||||
}
|
||||
|
||||
private void pushIndent()
|
||||
{
|
||||
indent += 1;
|
||||
}
|
||||
|
||||
private void popIndent()
|
||||
{
|
||||
indent -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
39
java-plan2/src/org/msgpack/schema/ClassSchema.java
Normal file
39
java-plan2/src/org/msgpack/schema/ClassSchema.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ClassSchema extends Schema {
|
||||
protected String namespace;
|
||||
protected List<String> imports;
|
||||
|
||||
public ClassSchema(String name, String namespace, List<String> imports)
|
||||
{
|
||||
super(name);
|
||||
this.namespace = namespace;
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
public String getNamespace()
|
||||
{
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public List<String> getImports()
|
||||
{
|
||||
return imports;
|
||||
}
|
||||
|
||||
void setNamespace(String namespace)
|
||||
{
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
void setImports(List<String> imports)
|
||||
{
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
public abstract List<? extends FieldSchema> getFields();
|
||||
public abstract Object newInstance();
|
||||
}
|
||||
|
||||
31
java-plan2/src/org/msgpack/schema/FieldSchema.java
Normal file
31
java-plan2/src/org/msgpack/schema/FieldSchema.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
public abstract class FieldSchema {
|
||||
private String name;
|
||||
private Schema type;
|
||||
|
||||
public FieldSchema(String name, Schema type)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Schema getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getExpression()
|
||||
{
|
||||
return "(field "+name+" "+type.getExpression()+")";
|
||||
}
|
||||
|
||||
public abstract Object getFieldValue(Object obj);
|
||||
public abstract void setFieldValue(Object obj, Object value);
|
||||
}
|
||||
|
||||
89
java-plan2/src/org/msgpack/schema/GenericClassSchema.java
Normal file
89
java-plan2/src/org/msgpack/schema/GenericClassSchema.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.msgpack.*;
|
||||
|
||||
|
||||
public class GenericClassSchema extends ClassSchema {
|
||||
private List<GenericFieldSchema> fields;
|
||||
|
||||
private String fqdn;
|
||||
private Constructor constructorCache;
|
||||
|
||||
public GenericClassSchema(String name, List<GenericFieldSchema> fields, String namespace, List<String> imports)
|
||||
{
|
||||
super(name, namespace, imports);
|
||||
this.fields = fields;
|
||||
if(namespace == null) {
|
||||
this.fqdn = name;
|
||||
} else {
|
||||
this.fqdn = namespace+"."+name;
|
||||
}
|
||||
}
|
||||
|
||||
//@Override
|
||||
//public String getFullName()
|
||||
//{
|
||||
// if(namespace == null) {
|
||||
// return getName();
|
||||
// } else {
|
||||
// return namespace+"."+getName();
|
||||
// }
|
||||
//}
|
||||
|
||||
public List<? extends FieldSchema> getFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
|
||||
public String getNamespace()
|
||||
{
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("(class ");
|
||||
b.append(getName());
|
||||
if(namespace != null) {
|
||||
b.append(" (package "+namespace+")");
|
||||
}
|
||||
for(GenericFieldSchema f : fields) {
|
||||
b.append(" "+f.getExpression());
|
||||
}
|
||||
b.append(")");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
// FIXME
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
// FIXME
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newInstance()
|
||||
{
|
||||
return new HashMap(fields.size());
|
||||
}
|
||||
}
|
||||
|
||||
25
java-plan2/src/org/msgpack/schema/GenericFieldSchema.java
Normal file
25
java-plan2/src/org/msgpack/schema/GenericFieldSchema.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.Map;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class GenericFieldSchema extends FieldSchema {
|
||||
public GenericFieldSchema(String name, Schema type)
|
||||
{
|
||||
super(name, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFieldValue(Object obj)
|
||||
{
|
||||
return ((Map)obj).get(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setFieldValue(Object obj, Object value)
|
||||
{
|
||||
((Map)obj).put(getName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
58
java-plan2/src/org/msgpack/schema/IntSchema.java
Normal file
58
java-plan2/src/org/msgpack/schema/IntSchema.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class IntSchema extends Schema {
|
||||
public IntSchema()
|
||||
{
|
||||
super("Integer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "int";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
pk.packInt((Integer)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj.asInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createByte(byte v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createShort(short v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createInt(int v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createLong(long v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
}
|
||||
|
||||
58
java-plan2/src/org/msgpack/schema/LongSchema.java
Normal file
58
java-plan2/src/org/msgpack/schema/LongSchema.java
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class LongSchema extends Schema {
|
||||
public LongSchema()
|
||||
{
|
||||
super("Long");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "long";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
pk.packLong((Long)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj.asLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createByte(byte v)
|
||||
{
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createShort(short v)
|
||||
{
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createInt(int v)
|
||||
{
|
||||
return (long)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createLong(long v)
|
||||
{
|
||||
return (long)v;
|
||||
}
|
||||
}
|
||||
|
||||
70
java-plan2/src/org/msgpack/schema/MapSchema.java
Normal file
70
java-plan2/src/org/msgpack/schema/MapSchema.java
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class MapSchema extends Schema {
|
||||
private Schema keyType;
|
||||
private Schema valueType;
|
||||
|
||||
public MapSchema(Schema keyType, Schema valueType)
|
||||
{
|
||||
super("map");
|
||||
this.keyType = keyType;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
|
||||
public Schema getKeyType()
|
||||
{
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public Schema getValueType()
|
||||
{
|
||||
return valueType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName()
|
||||
{
|
||||
return "HashList<"+keyType.getFullName()+", "+valueType.getFullName()+">";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "(map "+keyType.getExpression()+" "+valueType.getExpression()+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
Map<Object,Object> d = (Map<Object,Object>)obj;
|
||||
pk.packMap(d.size());
|
||||
for(Map.Entry<Object,Object> e : d.entrySet()) {
|
||||
keyType.pack(pk, e.getKey());
|
||||
valueType.pack(pk, e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
Map<GenericObject,GenericObject> d = obj.asMap();
|
||||
Map<Object,Object> g = new HashMap<Object,Object>();
|
||||
for(Map.Entry<GenericObject,GenericObject> e : d.entrySet()) {
|
||||
g.put(keyType.convert(e.getKey()), valueType.convert(e.getValue()));
|
||||
}
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
33
java-plan2/src/org/msgpack/schema/ObjectSchema.java
Normal file
33
java-plan2/src/org/msgpack/schema/ObjectSchema.java
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ObjectSchema extends Schema {
|
||||
public ObjectSchema()
|
||||
{
|
||||
super("object");
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return "GenericObject";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
pk.pack(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
21
java-plan2/src/org/msgpack/schema/PrimitiveSchema.java
Normal file
21
java-plan2/src/org/msgpack/schema/PrimitiveSchema.java
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
public abstract class PrimitiveSchema extends Schema {
|
||||
public static enum PrimitiveType {
|
||||
BYTE,
|
||||
SHORT,
|
||||
INT,
|
||||
LONG,
|
||||
FLOAT,
|
||||
DOUBLE,
|
||||
}
|
||||
|
||||
public final PrimitiveType type;
|
||||
|
||||
protected PrimitiveSchema(String name, PrimitiveType type)
|
||||
{
|
||||
super(name);
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
44
java-plan2/src/org/msgpack/schema/RawSchema.java
Normal file
44
java-plan2/src/org/msgpack/schema/RawSchema.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class RawSchema extends Schema {
|
||||
public RawSchema()
|
||||
{
|
||||
super("raw");
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return "byte[]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
byte[] d = (byte[])obj;
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj.asBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createRaw(byte[] b, int offset, int length)
|
||||
{
|
||||
byte[] d = new byte[length];
|
||||
System.arraycopy(b, offset, d, 0, length);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
246
java-plan2/src/org/msgpack/schema/SSchemaParser.java
Normal file
246
java-plan2/src/org/msgpack/schema/SSchemaParser.java
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
// FIXME exception class
|
||||
|
||||
class SSchemaParser {
|
||||
public static Schema parse(String source)
|
||||
{
|
||||
return new SSchemaParser(false).run(source);
|
||||
}
|
||||
|
||||
public static Schema load(String source)
|
||||
{
|
||||
return new SSchemaParser(true).run(source);
|
||||
}
|
||||
|
||||
private static abstract class SExp {
|
||||
boolean isAtom() { return false; }
|
||||
public String getAtom() { return null; }
|
||||
|
||||
boolean isTuple() { return false; }
|
||||
public SExp getTuple(int i) { return null; }
|
||||
public int size() { return 0; }
|
||||
public boolean empty() { return size() == 0; }
|
||||
Iterator<SExp> iterator(int offset) { return null; }
|
||||
}
|
||||
|
||||
private static class SAtom extends SExp {
|
||||
private String atom;
|
||||
|
||||
SAtom(String atom) { this.atom = atom; }
|
||||
|
||||
boolean isAtom() { return true; }
|
||||
public String getAtom() { return atom; }
|
||||
|
||||
public String toString() { return atom; }
|
||||
}
|
||||
|
||||
private static class STuple extends SExp {
|
||||
private List<SExp> tuple;
|
||||
|
||||
STuple() { this.tuple = new ArrayList<SExp>(); }
|
||||
|
||||
public void add(SExp e) { tuple.add(e); }
|
||||
|
||||
boolean isTuple() { return true; }
|
||||
public SExp getTuple(int i) { return tuple.get(i); }
|
||||
public int size() { return tuple.size(); }
|
||||
|
||||
Iterator<SExp> iterator(int skip) {
|
||||
Iterator<SExp> i = tuple.iterator();
|
||||
for(int s=0; s < skip; ++s) { i.next(); }
|
||||
return i;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if(tuple.isEmpty()) { return "()"; }
|
||||
Iterator<SExp> i = tuple.iterator();
|
||||
StringBuffer o = new StringBuffer();
|
||||
o.append("(").append(i.next());
|
||||
while(i.hasNext()) { o.append(" ").append(i.next()); }
|
||||
o.append(")");
|
||||
return o.toString();
|
||||
}
|
||||
}
|
||||
|
||||
boolean specificClass;
|
||||
|
||||
private SSchemaParser(boolean specificClass)
|
||||
{
|
||||
this.specificClass = specificClass;
|
||||
}
|
||||
|
||||
private static Pattern pattern = Pattern.compile(
|
||||
"(?:\\s+)|([\\(\\)]|[\\d\\w\\.]+)");
|
||||
|
||||
private Schema run(String source)
|
||||
{
|
||||
Matcher m = pattern.matcher(source);
|
||||
|
||||
Stack<STuple> stack = new Stack<STuple>();
|
||||
String token;
|
||||
|
||||
while(true) {
|
||||
while(true) {
|
||||
if(!m.find()) { throw new RuntimeException("unexpected end of file"); }
|
||||
token = m.group(1);
|
||||
if(token != null) { break; }
|
||||
}
|
||||
|
||||
if(token.equals("(")) {
|
||||
stack.push(new STuple());
|
||||
} else if(token.equals(")")) {
|
||||
STuple top = stack.pop();
|
||||
if(stack.empty()) {
|
||||
stack.push(top);
|
||||
break;
|
||||
}
|
||||
stack.peek().add(top);
|
||||
} else {
|
||||
if(stack.empty()) {
|
||||
throw new RuntimeException("unexpected token '"+token+"'");
|
||||
}
|
||||
stack.peek().add(new SAtom(token));
|
||||
}
|
||||
}
|
||||
|
||||
while(true) {
|
||||
if(!m.find()) { break; }
|
||||
token = m.group(1);
|
||||
if(token != null) { throw new RuntimeException("unexpected token '"+token+"'"); }
|
||||
}
|
||||
|
||||
return readType( stack.pop() );
|
||||
}
|
||||
|
||||
private Schema readType(SExp exp)
|
||||
{
|
||||
if(exp.isAtom()) {
|
||||
String type = exp.getAtom();
|
||||
// FIXME
|
||||
if(type.equals("string")) {
|
||||
return new StringSchema();
|
||||
} else if(type.equals("raw")) {
|
||||
return new RawSchema();
|
||||
} else if(type.equals("short")) {
|
||||
return new ShortSchema();
|
||||
} else if(type.equals("int")) {
|
||||
return new IntSchema();
|
||||
} else if(type.equals("long")) {
|
||||
return new LongSchema();
|
||||
} else if(type.equals("object")) {
|
||||
return new ObjectSchema();
|
||||
} else {
|
||||
throw new RuntimeException("byte, short, int, long, float, double, raw, string or object is expected but got '"+type+"': "+exp);
|
||||
}
|
||||
} else {
|
||||
String type = exp.getTuple(0).getAtom();
|
||||
if(type.equals("class")) {
|
||||
return parseClass(exp);
|
||||
} else if(type.equals("array")) {
|
||||
return parseArray(exp);
|
||||
} else if(type.equals("map")) {
|
||||
return parseMap(exp);
|
||||
} else {
|
||||
throw new RuntimeException("class, array or map is expected but got '"+type+"': "+exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClassSchema parseClass(SExp exp)
|
||||
{
|
||||
if(exp.size() < 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("class is (class NAME CLASS_BODY): "+exp);
|
||||
}
|
||||
|
||||
String namespace = null;
|
||||
List<String> imports = new ArrayList<String>();
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
List fields = new ArrayList();
|
||||
|
||||
for(Iterator<SExp> i=exp.iterator(2); i.hasNext();) {
|
||||
SExp subexp = i.next();
|
||||
if(!subexp.isTuple() || subexp.empty() || !subexp.getTuple(0).isAtom()) {
|
||||
throw new RuntimeException("field, package or import is expected: "+subexp);
|
||||
}
|
||||
String type = subexp.getTuple(0).getAtom();
|
||||
if(type.equals("field")) {
|
||||
fields.add( parseField(subexp) );
|
||||
} else if(type.equals("package")) {
|
||||
if(namespace != null) {
|
||||
throw new RuntimeException("duplicated package definition: "+subexp);
|
||||
}
|
||||
namespace = parseNamespace(subexp);
|
||||
} else if(type.equals("import")) {
|
||||
imports.add( parseImport(subexp) );
|
||||
} else {
|
||||
throw new RuntimeException("field, package or import is expected but got '"+type+"': "+subexp);
|
||||
}
|
||||
}
|
||||
|
||||
if(specificClass) {
|
||||
return new SpecificClassSchema(name, fields, namespace, imports);
|
||||
} else {
|
||||
return new GenericClassSchema(name, fields, namespace, imports);
|
||||
}
|
||||
}
|
||||
|
||||
private ArraySchema parseArray(SExp exp)
|
||||
{
|
||||
if(exp.size() != 2) {
|
||||
throw new RuntimeException("array is (array ELEMENT_TYPE): "+exp);
|
||||
}
|
||||
Schema elementType = readType(exp.getTuple(1));
|
||||
return new ArraySchema(elementType);
|
||||
}
|
||||
|
||||
private MapSchema parseMap(SExp exp)
|
||||
{
|
||||
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("map is (map KEY_TYPE VALUE_TYPE): "+exp);
|
||||
}
|
||||
Schema keyType = readType(exp.getTuple(1));
|
||||
Schema valueType = readType(exp.getTuple(2));
|
||||
return new MapSchema(keyType, valueType);
|
||||
}
|
||||
|
||||
private String parseNamespace(SExp exp)
|
||||
{
|
||||
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("package is (package NAME): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
return name;
|
||||
}
|
||||
|
||||
private String parseImport(SExp exp)
|
||||
{
|
||||
if(exp.size() != 2 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("import is (import NAME): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
return name;
|
||||
}
|
||||
|
||||
private FieldSchema parseField(SExp exp)
|
||||
{
|
||||
if(exp.size() != 3 || !exp.getTuple(1).isAtom()) {
|
||||
throw new RuntimeException("field is (field NAME TYPE): "+exp);
|
||||
}
|
||||
String name = exp.getTuple(1).getAtom();
|
||||
Schema type = readType(exp.getTuple(2));
|
||||
if(specificClass) {
|
||||
return new SpecificFieldSchema(name, type);
|
||||
} else {
|
||||
return new GenericFieldSchema(name, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
93
java-plan2/src/org/msgpack/schema/Schema.java
Normal file
93
java-plan2/src/org/msgpack/schema/Schema.java
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.impl.*;
|
||||
import org.msgpack.Packer;
|
||||
import org.msgpack.GenericObject;
|
||||
|
||||
public abstract class Schema {
|
||||
private String expression;
|
||||
private String name;
|
||||
|
||||
public Schema(String name)
|
||||
{
|
||||
this.expression = expression;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getExpression()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Schema parse(String source)
|
||||
{
|
||||
return SSchemaParser.parse(source);
|
||||
}
|
||||
|
||||
public static Schema load(String source)
|
||||
{
|
||||
return SSchemaParser.load(source);
|
||||
}
|
||||
|
||||
public abstract void pack(Packer pk, Object obj) throws IOException;
|
||||
public abstract Object convert(GenericObject obj);
|
||||
//public abstract Object convertGeneric(GenericObject obj);
|
||||
|
||||
|
||||
public Object createNil()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object createBoolean(boolean v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createByte(byte v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createShort(short v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createInt(int v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createLong(long v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createFloat(float v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createDouble(double v)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
|
||||
public Object createRaw(byte[] b, int offset, int length)
|
||||
{
|
||||
throw new RuntimeException("type error");
|
||||
}
|
||||
}
|
||||
|
||||
46
java-plan2/src/org/msgpack/schema/ShortSchema.java
Normal file
46
java-plan2/src/org/msgpack/schema/ShortSchema.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class ShortSchema extends Schema {
|
||||
public ShortSchema()
|
||||
{
|
||||
super("Short");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
return "short";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
pk.packShort((Short)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj.asShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createByte(byte v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createShort(short v)
|
||||
{
|
||||
return (int)v;
|
||||
}
|
||||
}
|
||||
|
||||
156
java-plan2/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
156
java-plan2/src/org/msgpack/schema/SpecificClassSchema.java
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class SpecificClassSchema extends ClassSchema {
|
||||
private List<SpecificFieldSchema> fields;
|
||||
private String namespace;
|
||||
private List<String> imports;
|
||||
|
||||
private String fqdn;
|
||||
private Constructor constructorCache;
|
||||
|
||||
public SpecificClassSchema(String name, List<SpecificFieldSchema> fields, String namespace, List<String> imports)
|
||||
{
|
||||
super(name, namespace, imports);
|
||||
this.fields = fields;
|
||||
if(namespace == null) {
|
||||
this.fqdn = name;
|
||||
} else {
|
||||
this.fqdn = namespace+"."+name;
|
||||
}
|
||||
}
|
||||
|
||||
//@Override
|
||||
//public String getFullName()
|
||||
//{
|
||||
// if(namespace == null) {
|
||||
// return getName();
|
||||
// } else {
|
||||
// return namespace+"."+getName();
|
||||
// }
|
||||
//}
|
||||
|
||||
public List<? extends FieldSchema> getFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpression()
|
||||
{
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("(class ");
|
||||
b.append(getName());
|
||||
if(namespace != null) {
|
||||
b.append(" (package "+namespace+")");
|
||||
}
|
||||
for(SpecificFieldSchema f : fields) {
|
||||
b.append(" "+f.getExpression());
|
||||
}
|
||||
b.append(")");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
|
||||
if(constructorCache == null) {
|
||||
cacheConstructor();
|
||||
}
|
||||
|
||||
pk.packArray(fields.size());
|
||||
for(SpecificFieldSchema f : fields) {
|
||||
f.getType().pack(pk, f.getFieldValue(obj));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
if(constructorCache == null) {
|
||||
cacheConstructor();
|
||||
}
|
||||
|
||||
List<GenericObject> d = obj.asArray();
|
||||
|
||||
try {
|
||||
Object g = constructorCache.newInstance((Object[])null);
|
||||
|
||||
Iterator<GenericObject> vi = d.iterator();
|
||||
Iterator<SpecificFieldSchema> fi = fields.iterator();
|
||||
while(fi.hasNext() && vi.hasNext()) {
|
||||
SpecificFieldSchema f = fi.next();
|
||||
GenericObject v = vi.next();
|
||||
f.setFieldValue(g, f.getType().convert(v));
|
||||
}
|
||||
// leave it as uninitialized
|
||||
//while(fi.hasNext()) {
|
||||
// SpecificFieldSchema f = fi.next();
|
||||
// g.put(f.getName(), null);
|
||||
//}
|
||||
|
||||
return g;
|
||||
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheConstructor()
|
||||
{
|
||||
try {
|
||||
Class c = Class.forName(fqdn);
|
||||
int index = 0;
|
||||
for(SpecificFieldSchema f : fields) {
|
||||
f.cacheField(c, index++);
|
||||
}
|
||||
constructorCache = c.getDeclaredConstructor((Class[])null);
|
||||
constructorCache.setAccessible(true);
|
||||
} catch(ClassNotFoundException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("class not found: "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newInstance()
|
||||
{
|
||||
if(constructorCache == null) {
|
||||
cacheConstructor();
|
||||
}
|
||||
try {
|
||||
return constructorCache.newInstance((Object[])null);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("can't instantiate "+fqdn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(SpecificClassSchema o)
|
||||
{
|
||||
return (namespace != null ? namespace.equals(o.getNamespace()) : o.getNamespace() == null) &&
|
||||
getName().equals(o.getName());
|
||||
}
|
||||
}
|
||||
|
||||
78
java-plan2/src/org/msgpack/schema/SpecificFieldSchema.java
Normal file
78
java-plan2/src/org/msgpack/schema/SpecificFieldSchema.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.lang.reflect.Field;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class SpecificFieldSchema extends FieldSchema {
|
||||
public Field fieldCache;
|
||||
private int index;
|
||||
|
||||
public SpecificFieldSchema(String name, Schema type)
|
||||
{
|
||||
super(name, type);
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFieldValue(Object obj)
|
||||
{
|
||||
if(index >= 0) {
|
||||
return ((MessageMergeable)obj).getField(index);
|
||||
}
|
||||
|
||||
try {
|
||||
return fieldCache.get(obj);
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new RuntimeException("can't get value from '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||
} catch(IllegalAccessException e) {
|
||||
throw new RuntimeException("can't get value from '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFieldValue(Object obj, Object value)
|
||||
{
|
||||
if(index >= 0) {
|
||||
((MessageMergeable)obj).setField(index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
fieldCache.set(obj, value);
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new RuntimeException("can't set value into '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||
} catch(IllegalAccessException e) {
|
||||
throw new RuntimeException("can't set value into '"+getName()+"' field of '"+obj.getClass().getName()+"' class: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void cacheField(Class c, int index)
|
||||
{
|
||||
for(Class i : c.getInterfaces()) {
|
||||
if(i.equals(MessageMergeable.class)) {
|
||||
this.index = index;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
fieldCache = c.getDeclaredField(getName());
|
||||
if(!fieldCache.isAccessible()) {
|
||||
fieldCache.setAccessible(true);
|
||||
}
|
||||
} catch(NoSuchFieldException e) {
|
||||
throw new RuntimeException("can't get '"+getName()+"' field of '"+c.getName()+"' class: "+e.getMessage());
|
||||
} catch(SecurityException e) {
|
||||
throw new RuntimeException("can't get '"+getName()+"' field of '"+c.getName()+"' class: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//public void setFieldInt(Object obj, int value)
|
||||
//{
|
||||
// if(type instanceof PrimitiveSchema) {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
48
java-plan2/src/org/msgpack/schema/StringSchema.java
Normal file
48
java-plan2/src/org/msgpack/schema/StringSchema.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package org.msgpack.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import org.msgpack.*;
|
||||
|
||||
public class StringSchema extends Schema {
|
||||
public StringSchema()
|
||||
{
|
||||
super("string");
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return "String";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pack(Packer pk, Object obj) throws IOException
|
||||
{
|
||||
if(obj == null) {
|
||||
pk.packNil();
|
||||
return;
|
||||
}
|
||||
String s = (String)obj;
|
||||
byte[] d = s.getBytes("UTF-8");
|
||||
pk.packRaw(d.length);
|
||||
pk.packRawBody(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert(GenericObject obj)
|
||||
{
|
||||
return obj.asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createRaw(byte[] b, int offset, int length)
|
||||
{
|
||||
try {
|
||||
return new String(b, offset, length, "UTF-8"); // XXX FIXME debug
|
||||
} catch (Exception e) {
|
||||
// FIXME
|
||||
throw new RuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue