Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
RuedigerMoeller committed May 28, 2015
1 parent 7e7c4ba commit 4c597a3
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 65 deletions.
16 changes: 13 additions & 3 deletions src/main/java/org/nustaq/serialization/FSTClazzInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ public int compare(FSTFieldInfo o1, FSTFieldInfo o2) {
Method writeReplaceMethod, readResolveMethod;
HashMap<Class, FSTCompatibilityInfo> compInfo = new HashMap<Class, FSTCompatibilityInfo>(7);

Object decoderAttached; // for decoders

public Object getDecoderAttached() {
return decoderAttached;
}

public void setDecoderAttached(Object decoderAttached) {
this.decoderAttached = decoderAttached;
}

boolean requiresCompatibleMode;
boolean externalizable;
boolean flat; // never share instances of this class
Expand Down Expand Up @@ -480,7 +490,7 @@ public final static class FSTFieldInfo {
int indexId; // position in serializable fields array
int align = 0;
int alignPad = 0;
byte[] bufferedName; // cache byte rep of field name (used for cross platform)
Object bufferedName; // cache byte rep of field name (used for cross platform)

// hacke required for compatibility with ancient JDK mechanics (cross JDK, e.g. Android <=> OpenJDK ).
// in rare cases, a field used in putField is not present as a real field
Expand Down Expand Up @@ -532,11 +542,11 @@ public byte getVersion() {
return version;
}

public byte[] getBufferedName() {
public Object getBufferedName() {
return bufferedName;
}

public void setBufferedName(byte[] bufferedName) {
public void setBufferedName(Object bufferedName) {
this.bufferedName = bufferedName;
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/org/nustaq/serialization/FSTConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,16 @@ public FSTConfiguration registerCrossPlatformClassMapping( String shortName, St
return this;
}

/**
* shorthand for registerCrossPlatformClassMapping(_,_)
* @param shortName - class name in json type field
* @param clz - class
* @return
*/
public FSTConfiguration cpMap(String shortName, Class clz) {
return registerCrossPlatformClassMapping(shortName,clz.getName());
}

/**
* init right after creation of configuration, not during operation as it is not threadsafe regarding mutation
*/
Expand Down
69 changes: 30 additions & 39 deletions src/main/java/org/nustaq/serialization/coders/FSTJsonDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,34 @@ public String readStringAsc() throws IOException {
*/
public Object readFPrimitiveArray(Object array, Class componentType, int len) {
try {
if (componentType == double.class) {
if (componentType == int.class) {
int[] da = (int[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken(); da[i] = (int) input.getIntValue();
}
return da;
}
else if (componentType == long.class) {
long[] da = (long[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken(); da[i] = input.getLongValue();
}
return da;
} else if (componentType == double.class) {
double[] da = (double[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken();
da[i] = input.getDoubleValue();
}
return da;
}
if (componentType == float.class) {
} else if (componentType == float.class) {
float[] da = (float[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken();
da[i] = input.getFloatValue();
}
return da;
}
Object arr = array;
int length = Array.getLength(arr);
if (len != -1 && len != length)
throw new RuntimeException("unexpected arrays size");
if (componentType == boolean.class) {
} else if (componentType == boolean.class) {
boolean[] da = (boolean[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken(); da[i] = input.getBooleanValue();
Expand Down Expand Up @@ -102,20 +109,6 @@ else if (componentType == char.class) {
}
return da;
}
else if (componentType == int.class) {
int[] da = (int[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken(); da[i] = (int) input.getIntValue();
}
return da;
}
else if (componentType == long.class) {
long[] da = (long[]) array;
for (int i = 0; i < da.length; i++) {
input.nextToken(); da[i] = input.getLongValue();
}
return da;
}
else throw new RuntimeException("unsupported type " + componentType.getName());
} catch (Exception e) {
FSTUtil.<RuntimeException>rethrow(e);
Expand Down Expand Up @@ -308,11 +301,11 @@ public byte readObjectHeaderTag() throws IOException {
}

String typeTag = input.nextFieldName();
if ( typeTag.equals("type") ) {
if ( typeTag.equals(FSTJsonEncoder.TYPE) ) {
// object
String type = input.nextTextValue();
String valueTag = input.nextFieldName();
if ( ! "obj".equals(valueTag) ) {
if ( ! FSTJsonEncoder.OBJ.equals(valueTag) ) {
throw new RuntimeException("expected value attribute for object of type:"+type);
}
if ( ! input.nextToken().isStructStart() ) {
Expand All @@ -324,13 +317,13 @@ public byte readObjectHeaderTag() throws IOException {
FSTUtil.<RuntimeException>rethrow(e);
}
return FSTObjectOutput.OBJECT;
} else if ( typeTag.equals("seqType") ) {
} else if ( typeTag.equals(FSTJsonEncoder.SEQ_TYPE) ) {
// sequence
String type = input.nextTextValue();
try {
lastDirectClass = classForName(conf.getClassForCPName(type));
String valueTag = input.nextFieldName();
if ( ! "seq".equals(valueTag) ) {
if ( ! FSTJsonEncoder.SEQ.equals(valueTag) ) {
throw new RuntimeException("expected value attribute for object of type:"+type);
}
if ( ! input.nextToken().isStructStart() ) {
Expand All @@ -340,14 +333,14 @@ public byte readObjectHeaderTag() throws IOException {
FSTUtil.<RuntimeException>rethrow(e);
}
return FSTObjectOutput.ARRAY;
} else if ( typeTag.equals("ref") ) {
} else if ( typeTag.equals(FSTJsonEncoder.REF) ) {
return FSTObjectOutput.HANDLE;
} else if ( typeTag.equals("enum") ) {
} else if ( typeTag.equals(FSTJsonEncoder.ENUM) ) {
try {
String clName = input.nextTextValue();
Class aClass = classForName(conf.getClassForCPName(clName));
String valueTag = input.nextFieldName();
if ( ! "val".equals(valueTag) ) {
if ( ! FSTJsonEncoder.VAL.equals(valueTag) ) {
throw new RuntimeException("expected value attribute for enum of type:"+clName);
}
String enumString = input.nextTextValue();
Expand Down Expand Up @@ -448,11 +441,9 @@ public FSTClazzInfo readClass() throws IOException, ClassNotFoundException {
return null;
}

HashMap<String,Class> clzCache = new HashMap<>();
HashMap<String,Class> clzCache = new HashMap<>(31);
@Override
public Class classForName(String name) throws ClassNotFoundException {
if ("Object".equals(name))
return MBObject.class;
Class aClass = clzCache.get(name);
if (aClass!=null)
return aClass;
Expand All @@ -463,13 +454,13 @@ public Class classForName(String name) throws ClassNotFoundException {

@Override
public void registerClass(Class possible) {
throw new RuntimeException("not implemented");
// throw new RuntimeException("not implemented");
}

@Override
public void close() {
//TODO
throw new RuntimeException("not implemented");
//nothing to do (?)
// throw new RuntimeException("not implemented");
}

@Override
Expand Down Expand Up @@ -509,16 +500,16 @@ public Object readArrayHeader() throws Exception {
return null;
} else {
jsonToken = input.nextToken(); // seqType
if ( "type".equals(input.getText())) {
if ( FSTJsonEncoder.TYPE.equals(input.getText())) {
// object
type = input.nextTextValue();
String valueTag = input.nextFieldName();
if ( ! "obj".equals(valueTag) ) {
if ( !FSTJsonEncoder.OBJ.equals(valueTag) ) {
throw new RuntimeException("expected value attribute for object of type:"+type);
}
return classForName(conf.getClassForCPName(type));
}
if ( ! "seqType".equals(input.getText()) ) {
if (!FSTJsonEncoder.SEQ_TYPE.equals(input.getText()) ) {
System.out.println(">" + input.getCurrentToken()+" "+input.getText());
input.nextToken();
System.out.println(">" + input.getCurrentToken()+" "+input.getText());
Expand Down
88 changes: 66 additions & 22 deletions src/main/java/org/nustaq/serialization/coders/FSTJsonEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,37 @@
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.json.UTF8JsonGenerator;
import com.fasterxml.jackson.core.io.SerializedString;
import org.nustaq.serialization.*;
import org.nustaq.serialization.util.FSTOutputStream;
import org.nustaq.serialization.util.FSTUtil;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.math.BigDecimal;

/**
* Created by ruedi on 20/05/15.
*
*/
public class FSTJsonEncoder implements FSTEncoder {

public static final String TYPE = "typ";
public static final String OBJ = "obj";
public static final String SEQ_TYPE = "styp";
public static final String SEQ = "seq";
public static final String ENUM = "enum";
public static final String VAL = "val";
public static final String REF = "ref";

public static final SerializedString TYPE_S = new SerializedString(TYPE);
public static final SerializedString OBJ_S = new SerializedString(OBJ);
public static final SerializedString SEQ_TYPE_S = new SerializedString(SEQ_TYPE);
public static final SerializedString SEQ_S = new SerializedString(SEQ);
public static final SerializedString ENUM_S = new SerializedString(ENUM);
public static final SerializedString VAL_S = new SerializedString(VAL);
public static final SerializedString REF_S = new SerializedString(REF);

JsonFactory fac;
FSTConfiguration conf;

Expand All @@ -44,12 +56,29 @@ public void writePrimitiveArray(Object array, int start, int length) throws IOEx
Class<?> componentType = array.getClass().getComponentType();
if ( componentType != int.class ) {
gen.writeString(componentType.getSimpleName());
} else { // fast path for int
int arr[] = (int[]) array;
for (int i=0; i < length; i++ ) {
gen.writeNumber(arr[i]);
}
gen.writeEndArray();
return;
}
if ( array instanceof boolean[] ) {
boolean arr[] = (boolean[]) array;
for (int i=0; i < length; i++ ) {
gen.writeBoolean(arr[i]);
}
} else if ( array instanceof long[] ) {
long arr[] = (long[]) array;
for (int i=0; i < length; i++ ) {
gen.writeNumber(arr[i]);
}
} else if ( array instanceof double[] ) {
double arr[] = (double[]) array;
for (int i=0; i < length; i++ ) {
gen.writeNumber(arr[i]);
}
} else if ( array instanceof char[] ) {
char arr[] = (char[]) array;
for (int i=0; i < length; i++ ) {
Expand Down Expand Up @@ -200,7 +229,7 @@ public boolean writeTag(byte tag, Object infoOrObject, long somValue, Object toW
switch (tag) {
case FSTObjectOutput.HANDLE:
gen.writeStartObject();
gen.writeFieldName("ref");
gen.writeFieldName(REF_S);
gen.writeNumber(somValue);
gen.writeEndObject();
return true;
Expand Down Expand Up @@ -234,16 +263,16 @@ public boolean writeTag(byte tag, Object infoOrObject, long somValue, Object toW
break;
if ( clzInfo.getSer()!=null || clzInfo.isExternalizable() ) {
gen.writeStartObject();
gen.writeFieldName("type");
writeSymbolicClazz(clzInfo.getClazz());
gen.writeFieldName("obj");
gen.writeFieldName(TYPE_S);
writeSymbolicClazz(clzInfo, clzInfo.getClazz());
gen.writeFieldName(OBJ_S);
gen.writeStartArray();
} else
{
gen.writeStartObject();
gen.writeFieldName("type");
writeSymbolicClazz(clzInfo.getClazz());
gen.writeFieldName("obj");
gen.writeFieldName(TYPE_S);
writeSymbolicClazz(clzInfo,clzInfo.getClazz());
gen.writeFieldName(OBJ_S);
gen.writeStartObject();
}
break;
Expand All @@ -270,9 +299,9 @@ public boolean writeTag(byte tag, Object infoOrObject, long somValue, Object toW
return true;
} else {
gen.writeStartObject();
gen.writeFieldName("seqType");
writeSymbolicClazz(clz);
gen.writeFieldName("seq");
gen.writeFieldName(SEQ_TYPE_S);
writeSymbolicClazz(null,clz);
gen.writeFieldName(SEQ_S);
gen.writeStartArray();
}
break;
Expand All @@ -289,9 +318,9 @@ public boolean writeTag(byte tag, Object infoOrObject, long somValue, Object toW
}
}
gen.writeStartObject();
gen.writeFieldName("enum");
writeSymbolicClazz(c);
gen.writeFieldName("val");
gen.writeFieldName(ENUM_S);
writeSymbolicClazz(null,c);
gen.writeFieldName(VAL_S);
gen.writeString(toWrite.toString());
gen.writeEndObject();
return true;
Expand All @@ -301,9 +330,18 @@ public boolean writeTag(byte tag, Object infoOrObject, long somValue, Object toW
return false;
}

private void writeSymbolicClazz(Class<?> clz) {
private void writeSymbolicClazz(FSTClazzInfo clzInfo, Class<?> clz) {
try {
gen.writeString(classToString(clz));
if ( clzInfo != null ) {
SerializedString buffered = (SerializedString) clzInfo.getDecoderAttached();
if ( buffered == null ) {
buffered = new SerializedString(classToString(clz));
clzInfo.setDecoderAttached(buffered);
}
gen.writeString(buffered);
} else {
gen.writeString(classToString(clz));
}
} catch (IOException e) {
FSTUtil.<RuntimeException>rethrow(e);
}
Expand All @@ -318,8 +356,14 @@ public void writeAttributeName(FSTClazzInfo.FSTFieldInfo subInfo) {
try {
if ( gen.getOutputContext().inArray() )
gen.writeString(subInfo.getName());
else
gen.writeFieldName(subInfo.getName());
else {
SerializedString bufferedName = (SerializedString) subInfo.getBufferedName();
if ( bufferedName == null ) {
bufferedName = new SerializedString(subInfo.getName());
subInfo.setBufferedName(bufferedName);
}
gen.writeFieldName(bufferedName);
}
} catch (IOException e) {
FSTUtil.<RuntimeException>rethrow(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public void writeClass(FSTClazzInfo clInf) {

@Override
public void writeAttributeName(FSTClazzInfo.FSTFieldInfo subInfo) {
byte[] bufferedName = subInfo.getBufferedName();
byte[] bufferedName = (byte[]) subInfo.getBufferedName();
if ( bufferedName != null ) {
out.writeRaw(bufferedName,0,bufferedName.length);
} else {
Expand Down

0 comments on commit 4c597a3

Please sign in to comment.