--- /dev/null
+package org.simantics.db.common;\r
+\r
+import java.io.IOException;\r
+import java.io.UTFDataFormatException;\r
+import java.nio.charset.Charset;\r
+import java.util.Arrays;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingConstructionException;\r
+import org.simantics.databoard.binding.impl.LongBindingDefault;\r
+import org.simantics.databoard.binding.impl.StringBindingDefault;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;\r
+import org.simantics.databoard.serialization.SerializationException;\r
+import org.simantics.databoard.serialization.Serializer;\r
+import org.simantics.databoard.serialization.impl.LongSerializer;\r
+import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer;\r
+import org.simantics.graph.representation.External;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.Internal;\r
+import org.simantics.graph.representation.Optional;\r
+import org.simantics.graph.representation.Root;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.graph.representation.Value;\r
+\r
+public class WriteBindings {\r
+\r
+ static class STRING_SERIALIZER extends ModifiedUTF8StringSerializer {\r
+\r
+ public static final Charset UTF8 = Charset.forName("utf-8");\r
+\r
+ public static STRING_SERIALIZER INSTANCE = new STRING_SERIALIZER();\r
+\r
+ public STRING_SERIALIZER() {\r
+ super(STRING_BINDING.INSTANCE);\r
+ }\r
+\r
+ static byte[] writeUTF(String str) throws IOException {\r
+\r
+ int strlen = str.length();\r
+ int utflen = 0;\r
+ int c/*, count = 0*/;\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
+ int byteIndex = 0;\r
+ byte[] bytearr;\r
+\r
+ if(utflen < 0x80) {\r
+ bytearr = new byte[utflen+1];\r
+ bytearr[byteIndex++] = ((byte)utflen);\r
+ }\r
+ else {\r
+ utflen -= 0x80;\r
+ if(utflen < 0x4000) {\r
+ bytearr = new byte[utflen+2];\r
+ bytearr[byteIndex++] = (byte)( ((utflen&0x3f) | 0x80) );\r
+ bytearr[byteIndex++] = (byte)( (utflen>>>6) );\r
+ }\r
+ else {\r
+ utflen -= 0x4000;\r
+ if(utflen < 0x200000) {\r
+ bytearr = new byte[utflen+3];\r
+ bytearr[byteIndex++] = (byte)( ((utflen&0x1f) | 0xc0) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>5)&0xff) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>13)&0xff) ); \r
+ }\r
+ else {\r
+ utflen -= 0x200000;\r
+ if(utflen < 0x10000000) {\r
+ bytearr = new byte[utflen+4];\r
+ bytearr[byteIndex++] = (byte)( ((utflen&0x0f) | 0xe0) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>4)&0xff) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>12)&0xff) ); \r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>20)&0xff) );\r
+ }\r
+ else {\r
+ utflen -= 0x10000000;\r
+ bytearr = new byte[utflen+5];\r
+ bytearr[byteIndex++] = (byte)( ((utflen&0x07) | 0xf0) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>3)&0xff) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>11)&0xff) ); \r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>19)&0xff) );\r
+ bytearr[byteIndex++] = (byte)( ((utflen>>>27)&0xff) );\r
+ }\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[byteIndex++] = (byte)(c);\r
+ }\r
+\r
+ for (;i < strlen; i++){\r
+ c = str.charAt(i);\r
+ if ((c >= 0x0001) && (c <= 0x007F)) {\r
+ bytearr[byteIndex++] = (byte)( c );\r
+ } else if (c > 0x07FF) {\r
+ bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F));\r
+ bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F));\r
+ bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));\r
+ } else {\r
+ bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F));\r
+ bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));\r
+ }\r
+ }\r
+\r
+ return bytearr;\r
+\r
+ }\r
+\r
+ @Override\r
+ public byte[] serialize(Object obj) throws IOException {\r
+ try {\r
+ return writeUTF((String)obj);\r
+ } catch (IOException e) {\r
+ throw new SerializationException();\r
+ }\r
+ \r
+ }\r
+ \r
+ }\r
+\r
+ static class BYTE_ARRAY_SERIALIZER extends LongSerializer {\r
+\r
+ public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER();\r
+\r
+ public BYTE_ARRAY_SERIALIZER() {\r
+ super(BYTE_ARRAY_BINDING.INSTANCE);\r
+ }\r
+ \r
+ @Override\r
+ public byte[] serialize(Object obj) throws IOException {\r
+ \r
+ return (byte[])obj;\r
+\r
+ }\r
+ \r
+ @Override\r
+ public Object deserialize(byte[] data) throws IOException {\r
+ return data;\r
+ }\r
+ \r
+ }\r
+\r
+ final static class LONG_ARRAY_SERIALIZER extends LongSerializer {\r
+\r
+ public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER();\r
+\r
+ public LONG_ARRAY_SERIALIZER() {\r
+ super(LONG_ARRAY_BINDING.INSTANCE);\r
+ }\r
+ \r
+ final private void loop(byte[] result, int index, long l) {\r
+ result[index+7] = (byte)l;l >>>= 8;\r
+ result[index+6] = (byte)l;l >>>= 8;\r
+ result[index+5] = (byte)l;l >>>= 8;\r
+ result[index+4] = (byte)l;l >>>= 8;\r
+ result[index+3] = (byte)l;l >>>= 8;\r
+ result[index+2] = (byte)l;l >>>= 8;\r
+ result[index+1] = (byte)l;l >>>= 8;\r
+ result[index] = (byte)l;l >>>= 8;\r
+ \r
+// result[index+6] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+5] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+4] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+3] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+2] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+1] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+ }\r
+ \r
+ @Override\r
+ public byte[] serialize(Object obj) throws IOException {\r
+ \r
+ long[] data = (long[])obj;\r
+ byte[] result = new byte[4+8*data.length];\r
+ \r
+ int len = data.length;\r
+ \r
+ result[3] = (byte)(len & 0xFF);\r
+ len >>>= 8;\r
+ result[2] = (byte)(len & 0xFF);\r
+ len >>>= 8;\r
+ result[1] = (byte)(len & 0xFF);\r
+ len >>>= 8;\r
+ result[0] = (byte)(len & 0xFF);\r
+\r
+ int index = 4;\r
+\r
+ for(int i=0;i<data.length;i++) {\r
+\r
+ loop(result, index, data[i]);\r
+\r
+// long l = data[i];\r
+\r
+// result[index+7] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+6] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+5] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+4] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+3] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+2] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+1] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+ \r
+ index += 8;\r
+\r
+ }\r
+ \r
+ return result;\r
+\r
+ }\r
+ \r
+ }\r
+\r
+ static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer {\r
+\r
+ public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER();\r
+\r
+ public TRANSFERABLE_GRAPH_SERIALIZER() {\r
+ super(TRANSFERABLE_GRAPH_BINDING.INSTANCE);\r
+ }\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
+// byte[] bytearr = new byte[utflen+2];\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 byte[] serialize(Object obj) throws IOException {\r
+ \r
+ TransferableGraph1 tg = (TransferableGraph1)obj;\r
+ \r
+ return Bindings\r
+ .getSerializerUnchecked(TransferableGraph1.class)\r
+ .serialize(tg);\r
+/*\r
+ // 16 = resourceCount + 3 arrays\r
+// long start = System.nanoTime();\r
+ int actualSize = 16 + 8*tg.values.length + 4*tg.statements.length + 5*tg.identities.length;\r
+ for(Value v : tg.values) actualSize += v.value.length;\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
+// long end = System.nanoTime() - start;\r
+// System.err.println("size took " + 1e-9*end);\r
+ \r
+// long start2 = System.nanoTime();\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
+ i = v.value.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
+ System.arraycopy(v.value, 0, bytes, byteIndex, v.value.length);\r
+ byteIndex += v.value.length;\r
+ \r
+ }\r
+\r
+// return bytes;\r
+ \r
+// byte[] result = new byte[byteIndex];\r
+// System.arraycopy(bytes, 0, result, 0, byteIndex);\r
+// \r
+// byte[] result = Arrays.copyOf(bytes, byteIndex); \r
+ \r
+// long end2 = System.nanoTime() - start2;\r
+// System.err.println("size2 took " + 1e-9*end2);\r
+\r
+ return bytes; \r
+ \r
+// long[] data = (long[])obj;\r
+// byte[] result = new byte[4+8*data.length];\r
+// \r
+// int len = data.length;\r
+// \r
+// result[3] = (byte)(len & 0xFF);\r
+// len >>>= 8;\r
+// result[2] = (byte)(len & 0xFF);\r
+// len >>>= 8;\r
+// result[1] = (byte)(len & 0xFF);\r
+// len >>>= 8;\r
+// result[0] = (byte)(len & 0xFF);\r
+//\r
+// int index = 4;\r
+//\r
+// for(int i=0;i<data.length;i++) {\r
+// \r
+// long l = data[i];\r
+//\r
+// result[index+7] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+6] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+5] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+4] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+3] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+2] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index+1] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// result[index] = (byte)(l & 0xFF);\r
+// l >>>= 8;\r
+// \r
+// index += 8;\r
+//\r
+// }\r
+// \r
+// return result;\r
+*/\r
+ }\r
+ \r
+ \r
+ final private String utf(byte[] bytes) {\r
+ \r
+ char[] chars = new char[bytes.length];\r
+ \r
+ int index = 0;\r
+ int length = bytes[index++]&0xff; \r
+ if(length >= 0x80) {\r
+ if(length >= 0xc0) {\r
+ if(length >= 0xe0) {\r
+ if(length >= 0xf0) {\r
+ length &= 0x0f;\r
+ length += ((bytes[index++]&0xff)<<3);\r
+ length += ((bytes[index++]&0xff)<<11);\r
+ length += ((bytes[index++]&0xff)<<19);\r
+ length += 0x10204080;\r
+ }\r
+ else {\r
+ length &= 0x1f;\r
+ length += ((bytes[index++]&0xff)<<4);\r
+ length += ((bytes[index++]&0xff)<<12);\r
+ length += ((bytes[index++]&0xff)<<20);\r
+ length += 0x204080;\r
+ }\r
+ }\r
+ else {\r
+ length &= 0x3f;\r
+ length += ((bytes[index++]&0xff)<<5);\r
+ length += ((bytes[index++]&0xff)<<13);\r
+ length += 0x4080;\r
+ }\r
+ }\r
+ else {\r
+ length &= 0x7f;\r
+ length += ((bytes[index++]&0xff)<<6);\r
+ length += 0x80;\r
+ }\r
+ }\r
+ \r
+ int i = 0;\r
+ int target = length+index;\r
+ while(index < target) {\r
+ int c = bytes[index++]&0xff;\r
+ if(c <= 0x7F) {\r
+ chars[i++] = (char)(c&0x7F);\r
+ } else if (c > 0x07FF) {\r
+ int c2 = bytes[index++]&0xff;\r
+ int c3 = bytes[index++]&0xff;\r
+ chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); \r
+ } else {\r
+ int c2 = bytes[index++]&0xff;\r
+ chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); \r
+ }\r
+ \r
+ }\r
+ \r
+ return new String(chars, 0, i);\r
+ \r
+ }\r
+\r
+ \r
+ @Override\r
+ public Object deserialize(byte[] data) throws IOException {\r
+ return utf(data);\r
+ }\r
+ \r
+ }\r
+\r
+ static class STRING_BINDING extends StringBindingDefault {\r
+ \r
+ public static STRING_BINDING INSTANCE = new STRING_BINDING();\r
+ \r
+ public STRING_BINDING() {\r
+ super(Datatypes.STRING);\r
+ }\r
+ \r
+ @Override\r
+ public Serializer serializer() throws RuntimeSerializerConstructionException {\r
+ \r
+ return STRING_SERIALIZER.INSTANCE;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public boolean isInstance(Object obj) {\r
+ return obj instanceof String;\r
+ }\r
+ \r
+ }\r
+ \r
+ static class BYTE_ARRAY_BINDING extends LongBindingDefault {\r
+ \r
+ public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING();\r
+ \r
+ public BYTE_ARRAY_BINDING() {\r
+ super(Datatypes.LONG);\r
+ }\r
+ \r
+ @Override\r
+ public Serializer serializer() throws RuntimeSerializerConstructionException {\r
+ \r
+ return BYTE_ARRAY_SERIALIZER.INSTANCE;\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public boolean isInstance(Object obj) {\r
+ return obj instanceof byte[];\r
+ }\r
+ \r
+ }\r
+\r
+ static class LONG_ARRAY_BINDING extends LongBindingDefault {\r
+ \r
+ public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING();\r
+ \r
+ public LONG_ARRAY_BINDING() {\r
+ super(Datatypes.LONG);\r
+ }\r
+ \r
+ @Override\r
+ public Serializer serializer() throws RuntimeSerializerConstructionException {\r
+ \r
+ return LONG_ARRAY_SERIALIZER.INSTANCE;\r
+ \r
+ }\r
+ \r
+ }\r
+\r
+ \r
+ static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault {\r
+ \r
+ public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING();\r
+ \r
+ public TRANSFERABLE_GRAPH_BINDING() {\r
+ super(Datatypes.LONG);\r
+ }\r
+ \r
+ @Override\r
+ public Serializer serializer() throws RuntimeSerializerConstructionException {\r
+ \r
+ return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE;\r
+ \r
+ }\r
+ \r
+ }\r
+\r
+ public static Binding STRING = STRING_BINDING.INSTANCE;\r
+ public static Binding BYTE_ARRAY = BYTE_ARRAY_BINDING.INSTANCE;\r
+ public static Binding LONG_ARRAY = LONG_ARRAY_BINDING.INSTANCE;\r
+ public static Binding TRANSFERABLE_GRAPH = TRANSFERABLE_GRAPH_BINDING.INSTANCE;\r
+\r
+ public static void main(String[] args) {\r
+\r
+ TransferableGraph1 tg = new TransferableGraph1(123,new Identity[] { \r
+ new Identity(11, new Root("foo", "bar1")), \r
+ new Identity(12, new External(21, "bar2")), \r
+ new Identity(13, new Internal(22, "bar3")), \r
+ new Identity(14, new Optional(23, "bar4")) },\r
+ new int[] { 1, 2, 3 },\r
+ new Value[] { new Value(31, new Variant(Bindings.INTEGER, 123)) });\r
+\r
+ try {\r
+ System.err.println(Arrays.toString(Bindings.getSerializerUnchecked(Bindings.getBinding(TransferableGraph1.class)).serialize(tg)));\r
+ System.err.println(Arrays.toString(WriteBindings.TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE.serialize(tg)));\r
+ } catch (RuntimeSerializerConstructionException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (IOException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (BindingConstructionException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ \r
+}\r