--- /dev/null
+package org.simantics.graph.representation;\r
+\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+\r
+import java.io.DataInput;\r
+import java.io.DataOutput;\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.UTFDataFormatException;\r
+import java.util.List;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.serialization.Serializer;\r
+\r
+public class TransferableGraph1Serializer extends Serializer {\r
+\r
+ public static final TransferableGraph1Serializer INSTANCE = \r
+ new TransferableGraph1Serializer();\r
+ \r
+ private TransferableGraph1Serializer() {}\r
+ \r
+ static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException {\r
+ \r
+ int strlen = str.length();\r
+ int utflen = 0;\r
+ int c;\r
+ int count = byteIndex;\r
+\r
+ /* use charAt instead of copying String to char array */\r
+ for (int i = 0; i < strlen; i++) {\r
+ c = str.charAt(i);\r
+ if ((c >= 0x0001) && (c <= 0x007F)) {\r
+ utflen++;\r
+ } else if (c > 0x07FF) {\r
+ utflen += 3;\r
+ } else {\r
+ utflen += 2;\r
+ }\r
+ }\r
+\r
+ if (utflen > 65535)\r
+ throw new UTFDataFormatException(\r
+ "encoded string too long: " + utflen + " bytes");\r
+\r
+ if(utflen < 0x80) {\r
+ bytearr[count++] = ((byte)utflen);\r
+ }\r
+ else {\r
+ utflen -= 0x80;\r
+ if(utflen < 0x4000) {\r
+ bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) );\r
+ bytearr[count++] = (byte)( (utflen>>>6) );\r
+ }\r
+ else {\r
+ utflen -= 0x4000;\r
+ if(utflen < 0x200000) {\r
+ bytearr[count++] = (byte)( ((utflen&0x1f) | 0xc0) );\r
+ bytearr[count++] = (byte)( ((utflen>>>5)&0xff) );\r
+ bytearr[count++] = (byte)( ((utflen>>>13)&0xff) ); \r
+ }\r
+ else {\r
+ utflen -= 0x200000;\r
+ if(utflen < 0x10000000) {\r
+ bytearr[count++] = (byte)( ((utflen&0x0f) | 0xe0) );\r
+ bytearr[count++] = (byte)( ((utflen>>>4)&0xff) );\r
+ bytearr[count++] = (byte)( ((utflen>>>12)&0xff) ); \r
+ bytearr[count++] = (byte)( ((utflen>>>20)&0xff) );\r
+ }\r
+ else {\r
+ utflen -= 0x10000000;\r
+ bytearr[count++] = (byte)( ((utflen&0x07) | 0xf0) );\r
+ bytearr[count++] = (byte)( ((utflen>>>3)&0xff) );\r
+ bytearr[count++] = (byte)( ((utflen>>>11)&0xff) ); \r
+ bytearr[count++] = (byte)( ((utflen>>>19)&0xff) );\r
+ bytearr[count++] = (byte)( ((utflen>>>27)&0xff) );\r
+ }\r
+ } \r
+ }\r
+ } \r
+\r
+ int i=0;\r
+ for (i=0; i<strlen; i++) {\r
+ c = str.charAt(i);\r
+ if (!((c >= 0x0001) && (c <= 0x007F))) break;\r
+ bytearr[count++] = (byte) c;\r
+ }\r
+\r
+ for (;i < strlen; i++){\r
+ c = str.charAt(i);\r
+ if ((c >= 0x0001) && (c <= 0x007F)) {\r
+ bytearr[count++] = (byte) c;\r
+\r
+ } else if (c > 0x07FF) {\r
+ bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));\r
+ bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));\r
+ bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));\r
+ } else {\r
+ bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));\r
+ bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));\r
+ }\r
+ }\r
+ \r
+ return count - byteIndex;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public Object deserialize(File file) throws IOException {\r
+ TransferableGraphFileReader reader = new TransferableGraphFileReader(file);\r
+ try {\r
+ return reader.readTG();\r
+ } finally {\r
+ reader.close();\r
+ }\r
+ }\r
+ \r
+ public Object deserialize(InputStream in) throws IOException {\r
+ TransferableGraphFileReader reader = new TransferableGraphFileReader(in);\r
+ try {\r
+ return reader.readTG();\r
+ } finally {\r
+ reader.close();\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public byte[] serialize(Object obj) throws IOException {\r
+ \r
+ TransferableGraph1 tg = (TransferableGraph1)obj;\r
+\r
+ Extensions ex = new Extensions(tg.extensions);\r
+ byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);\r
+\r
+ Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);\r
+ \r
+ int actualSize = 16 + 4*tg.values.length + 4*tg.statements.length + 5*tg.identities.length + extensions.length;\r
+ for(Value v : tg.values) actualSize += variantSerializer.getSize(v.value);\r
+ for(Identity id : tg.identities) { \r
+ if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5);\r
+ else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5);\r
+ else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10);\r
+ else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5);\r
+ }\r
+ \r
+ byte[] bytes = new byte[actualSize];\r
+ int byteIndex = 0;\r
+\r
+ int i = tg.resourceCount;\r
+ \r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ i = tg.identities.length;\r
+\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ for(Identity id : tg.identities) {\r
+\r
+ i = id.resource;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ if(id.definition instanceof Internal) {\r
+\r
+ Internal r = (Internal)id.definition;\r
+\r
+ bytes[byteIndex++] = 3;\r
+\r
+ i = r.parent;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ byteIndex += writeUTF(r.name, bytes, byteIndex);\r
+\r
+ } else if(id.definition instanceof External) {\r
+\r
+ External r = (External)id.definition;\r
+\r
+ bytes[byteIndex++] = 1;\r
+\r
+ i = r.parent;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ byteIndex += writeUTF(r.name, bytes, byteIndex);\r
+ \r
+ } else if(id.definition instanceof Root) {\r
+ \r
+ bytes[byteIndex++] = 0;\r
+ \r
+ Root r = (Root)id.definition;\r
+ byteIndex += writeUTF(r.name, bytes, byteIndex);\r
+ byteIndex += writeUTF(r.type, bytes, byteIndex);\r
+ \r
+ } else if(id.definition instanceof Optional) {\r
+\r
+ Optional r = (Optional)id.definition;\r
+\r
+ bytes[byteIndex++] = 2;\r
+\r
+ i = r.parent;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ byteIndex += writeUTF(r.name, bytes, byteIndex);\r
+ \r
+ }\r
+ \r
+ }\r
+ \r
+ i = tg.statements.length;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ for(int s : tg.statements) {\r
+ i = s;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ }\r
+\r
+ i = tg.values.length;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+ \r
+ for(Value v : tg.values) {\r
+ \r
+ i = v.resource;\r
+ bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
+ bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
+ byteIndex+=4;\r
+\r
+ byte[] temp = variantSerializer.serialize(v.value);\r
+ System.arraycopy(temp, 0, bytes, byteIndex, temp.length);\r
+ byteIndex += temp.length; \r
+ }\r
+\r
+ System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);\r
+ \r
+ return bytes; \r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,\r
+ Object obj) throws IOException {\r
+ TransferableGraph1.SERIALIZER.serialize(out, identities, obj);\r
+ }\r
+\r
+ @Override\r
+ public void serialize(DataOutput out, Object obj) throws IOException {\r
+ TransferableGraph1.SERIALIZER.serialize(out, obj);\r
+ }\r
+\r
+ @Override\r
+ public Object deserialize(DataInput in, List<Object> identities)\r
+ throws IOException {\r
+ return TransferableGraph1.SERIALIZER.deserialize(in, identities);\r
+ }\r
+\r
+ @Override\r
+ public Object deserialize(DataInput in) throws IOException {\r
+ return TransferableGraph1.SERIALIZER.deserialize(in);\r
+ }\r
+\r
+ @Override\r
+ public void deserializeTo(DataInput in, List<Object> identities, Object obj)\r
+ throws IOException {\r
+ TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);\r
+ }\r
+\r
+ @Override\r
+ public void deserializeTo(DataInput in, Object obj) throws IOException {\r
+ TransferableGraph1.SERIALIZER.deserializeTo(in, obj);\r
+ }\r
+\r
+ @Override\r
+ public void skip(DataInput in, List<Object> identities) throws IOException {\r
+ TransferableGraph1.SERIALIZER.skip(in, identities);\r
+ }\r
+\r
+ @Override\r
+ public void skip(DataInput in) throws IOException {\r
+ TransferableGraph1.SERIALIZER.skip(in);\r
+ }\r
+\r
+ @Override\r
+ public Integer getConstantSize() {\r
+ return TransferableGraph1.SERIALIZER.getConstantSize();\r
+ }\r
+\r
+ @Override\r
+ public int getSize(Object obj, TObjectIntHashMap<Object> identities)\r
+ throws IOException {\r
+ return TransferableGraph1.SERIALIZER.getSize(obj, identities);\r
+ }\r
+\r
+ @Override\r
+ public int getSize(Object obj) throws IOException {\r
+ return TransferableGraph1.SERIALIZER.getSize(obj);\r
+ }\r
+\r
+ @Override\r
+ public int getMinSize() {\r
+ return TransferableGraph1.SERIALIZER.getMinSize();\r
+ }\r
+\r
+}\r