X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2FWriteBindings.java;h=2939f12cc8c0ed5a1ba3e0c348053fd75a7b3886;hb=523ffdd55b3d6930a8984a8f24ea10297a93292f;hp=d749d6e91684fc793d067502bab11e964d1663a0;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java index d749d6e91..2939f12cc 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java @@ -1,734 +1,446 @@ -package org.simantics.db.common; - -import java.io.IOException; -import java.io.UTFDataFormatException; -import java.nio.charset.Charset; -import java.util.Arrays; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Datatypes; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.error.BindingConstructionException; -import org.simantics.databoard.binding.impl.LongBindingDefault; -import org.simantics.databoard.binding.impl.StringBindingDefault; -import org.simantics.databoard.binding.mutable.Variant; -import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; -import org.simantics.databoard.serialization.SerializationException; -import org.simantics.databoard.serialization.Serializer; -import org.simantics.databoard.serialization.impl.LongSerializer; -import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer; -import org.simantics.graph.representation.External; -import org.simantics.graph.representation.Identity; -import org.simantics.graph.representation.Internal; -import org.simantics.graph.representation.Optional; -import org.simantics.graph.representation.Root; -import org.simantics.graph.representation.TransferableGraph1; -import org.simantics.graph.representation.Value; - -public class WriteBindings { - - static class STRING_SERIALIZER extends ModifiedUTF8StringSerializer { - - public static final Charset UTF8 = Charset.forName("utf-8"); - - public static STRING_SERIALIZER INSTANCE = new STRING_SERIALIZER(); - - public STRING_SERIALIZER() { - super(STRING_BINDING.INSTANCE); - } - - static byte[] writeUTF(String str) throws IOException { - - int strlen = str.length(); - int utflen = 0; - int c/*, count = 0*/; - - /* use charAt instead of copying String to char array */ - for (int i = 0; i < strlen; i++) { - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - utflen++; - } else if (c > 0x07FF) { - utflen += 3; - } else { - utflen += 2; - } - } - - if (utflen > 65535) - throw new UTFDataFormatException( - "encoded string too long: " + utflen + " bytes"); - - int byteIndex = 0; - byte[] bytearr; - - if(utflen < 0x80) { - bytearr = new byte[utflen+1]; - bytearr[byteIndex++] = ((byte)utflen); - } - else { - utflen -= 0x80; - if(utflen < 0x4000) { - bytearr = new byte[utflen+2]; - bytearr[byteIndex++] = (byte)( ((utflen&0x3f) | 0x80) ); - bytearr[byteIndex++] = (byte)( (utflen>>>6) ); - } - else { - utflen -= 0x4000; - if(utflen < 0x200000) { - bytearr = new byte[utflen+3]; - bytearr[byteIndex++] = (byte)( ((utflen&0x1f) | 0xc0) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>5)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>13)&0xff) ); - } - else { - utflen -= 0x200000; - if(utflen < 0x10000000) { - bytearr = new byte[utflen+4]; - bytearr[byteIndex++] = (byte)( ((utflen&0x0f) | 0xe0) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>4)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>12)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>20)&0xff) ); - } - else { - utflen -= 0x10000000; - bytearr = new byte[utflen+5]; - bytearr[byteIndex++] = (byte)( ((utflen&0x07) | 0xf0) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>3)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>11)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>19)&0xff) ); - bytearr[byteIndex++] = (byte)( ((utflen>>>27)&0xff) ); - } - } - } - } - - - int i=0; - for (i=0; i= 0x0001) && (c <= 0x007F))) break; - bytearr[byteIndex++] = (byte)(c); - } - - for (;i < strlen; i++){ - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - bytearr[byteIndex++] = (byte)( c ); - } else if (c > 0x07FF) { - bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); - bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F)); - bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } else { - bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); - bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); - } - } - - return bytearr; - - } - - @Override - public byte[] serialize(Object obj) throws IOException { - try { - return writeUTF((String)obj); - } catch (IOException e) { - throw new SerializationException(); - } - - } - - } - - static class BYTE_ARRAY_SERIALIZER extends LongSerializer { - - public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER(); - - public BYTE_ARRAY_SERIALIZER() { - super(BYTE_ARRAY_BINDING.INSTANCE); - } - - @Override - public byte[] serialize(Object obj) throws IOException { - - return (byte[])obj; - - } - - @Override - public Object deserialize(byte[] data) throws IOException { - return data; - } - - } - - final static class LONG_ARRAY_SERIALIZER extends LongSerializer { - - public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER(); - - public LONG_ARRAY_SERIALIZER() { - super(LONG_ARRAY_BINDING.INSTANCE); - } - - final private void loop(byte[] result, int index, long l) { - result[index+7] = (byte)l;l >>>= 8; - result[index+6] = (byte)l;l >>>= 8; - result[index+5] = (byte)l;l >>>= 8; - result[index+4] = (byte)l;l >>>= 8; - result[index+3] = (byte)l;l >>>= 8; - result[index+2] = (byte)l;l >>>= 8; - result[index+1] = (byte)l;l >>>= 8; - result[index] = (byte)l;l >>>= 8; - -// result[index+6] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+5] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+4] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+3] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+2] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+1] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index] = (byte)(l & 0xFF); -// l >>>= 8; - } - - @Override - public byte[] serialize(Object obj) throws IOException { - - long[] data = (long[])obj; - byte[] result = new byte[4+8*data.length]; - - int len = data.length; - - result[3] = (byte)(len & 0xFF); - len >>>= 8; - result[2] = (byte)(len & 0xFF); - len >>>= 8; - result[1] = (byte)(len & 0xFF); - len >>>= 8; - result[0] = (byte)(len & 0xFF); - - int index = 4; - - for(int i=0;i>>= 8; -// result[index+6] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+5] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+4] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+3] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+2] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+1] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index] = (byte)(l & 0xFF); -// l >>>= 8; - - index += 8; - - } - - return result; - - } - - } - - static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer { - - public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER(); - - public TRANSFERABLE_GRAPH_SERIALIZER() { - super(TRANSFERABLE_GRAPH_BINDING.INSTANCE); - } - - static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException { - - int strlen = str.length(); - int utflen = 0; - int c; - int count = byteIndex; - - /* use charAt instead of copying String to char array */ - for (int i = 0; i < strlen; i++) { - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - utflen++; - } else if (c > 0x07FF) { - utflen += 3; - } else { - utflen += 2; - } - } - - if (utflen > 65535) - throw new UTFDataFormatException( - "encoded string too long: " + utflen + " bytes"); - -// byte[] bytearr = new byte[utflen+2]; - - if(utflen < 0x80) { - bytearr[count++] = ((byte)utflen); - } - else { - utflen -= 0x80; - if(utflen < 0x4000) { - bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) ); - bytearr[count++] = (byte)( (utflen>>>6) ); - } - else { - utflen -= 0x4000; - if(utflen < 0x200000) { - bytearr[count++] = (byte)( ((utflen&0x1f) | 0xc0) ); - bytearr[count++] = (byte)( ((utflen>>>5)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>13)&0xff) ); - } - else { - utflen -= 0x200000; - if(utflen < 0x10000000) { - bytearr[count++] = (byte)( ((utflen&0x0f) | 0xe0) ); - bytearr[count++] = (byte)( ((utflen>>>4)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>12)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>20)&0xff) ); - } - else { - utflen -= 0x10000000; - bytearr[count++] = (byte)( ((utflen&0x07) | 0xf0) ); - bytearr[count++] = (byte)( ((utflen>>>3)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>11)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>19)&0xff) ); - bytearr[count++] = (byte)( ((utflen>>>27)&0xff) ); - } - } - } - } - - int i=0; - for (i=0; i= 0x0001) && (c <= 0x007F))) break; - bytearr[count++] = (byte) c; - } - - for (;i < strlen; i++){ - c = str.charAt(i); - if ((c >= 0x0001) && (c <= 0x007F)) { - bytearr[count++] = (byte) c; - - } else if (c > 0x07FF) { - bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); - bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F)); - bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); - } else { - bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); - bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F)); - } - } - - return count - byteIndex; - - } - - @Override - public byte[] serialize(Object obj) throws IOException { - - TransferableGraph1 tg = (TransferableGraph1)obj; - - return Bindings - .getSerializerUnchecked(TransferableGraph1.class) - .serialize(tg); -/* - // 16 = resourceCount + 3 arrays -// long start = System.nanoTime(); - int actualSize = 16 + 8*tg.values.length + 4*tg.statements.length + 5*tg.identities.length; - for(Value v : tg.values) actualSize += v.value.length; - for(Identity id : tg.identities) { - if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5); - else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5); - else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10); - else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5); - } -// long end = System.nanoTime() - start; -// System.err.println("size took " + 1e-9*end); - -// long start2 = System.nanoTime(); - - - byte[] bytes = new byte[actualSize]; - int byteIndex = 0; - - int i = tg.resourceCount; - - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - i = tg.identities.length; - - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - for(Identity id : tg.identities) { - - i = id.resource; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - if(id.definition instanceof Internal) { - - Internal r = (Internal)id.definition; - - bytes[byteIndex++] = 3; - - i = r.parent; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - byteIndex += writeUTF(r.name, bytes, byteIndex); - - } else if(id.definition instanceof External) { - - External r = (External)id.definition; - - bytes[byteIndex++] = 1; - - i = r.parent; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - byteIndex += writeUTF(r.name, bytes, byteIndex); - - } else if(id.definition instanceof Root) { - - bytes[byteIndex++] = 0; - - Root r = (Root)id.definition; - byteIndex += writeUTF(r.name, bytes, byteIndex); - byteIndex += writeUTF(r.type, bytes, byteIndex); - - } else if(id.definition instanceof Optional) { - - Optional r = (Optional)id.definition; - - bytes[byteIndex++] = 2; - - i = r.parent; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - byteIndex += writeUTF(r.name, bytes, byteIndex); - - } - - } - - i = tg.statements.length; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - for(int s : tg.statements) { - i = s; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - } - - i = tg.values.length; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - for(Value v : tg.values) { - - i = v.resource; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - i = v.value.length; - bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8; - bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8; - byteIndex+=4; - - System.arraycopy(v.value, 0, bytes, byteIndex, v.value.length); - byteIndex += v.value.length; - - } - -// return bytes; - -// byte[] result = new byte[byteIndex]; -// System.arraycopy(bytes, 0, result, 0, byteIndex); -// -// byte[] result = Arrays.copyOf(bytes, byteIndex); - -// long end2 = System.nanoTime() - start2; -// System.err.println("size2 took " + 1e-9*end2); - - return bytes; - -// long[] data = (long[])obj; -// byte[] result = new byte[4+8*data.length]; -// -// int len = data.length; -// -// result[3] = (byte)(len & 0xFF); -// len >>>= 8; -// result[2] = (byte)(len & 0xFF); -// len >>>= 8; -// result[1] = (byte)(len & 0xFF); -// len >>>= 8; -// result[0] = (byte)(len & 0xFF); -// -// int index = 4; -// -// for(int i=0;i>>= 8; -// result[index+6] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+5] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+4] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+3] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+2] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index+1] = (byte)(l & 0xFF); -// l >>>= 8; -// result[index] = (byte)(l & 0xFF); -// l >>>= 8; -// -// index += 8; -// -// } -// -// return result; -*/ - } - - - final private String utf(byte[] bytes) { - - char[] chars = new char[bytes.length]; - - int index = 0; - int length = bytes[index++]&0xff; - if(length >= 0x80) { - if(length >= 0xc0) { - if(length >= 0xe0) { - if(length >= 0xf0) { - length &= 0x0f; - length += ((bytes[index++]&0xff)<<3); - length += ((bytes[index++]&0xff)<<11); - length += ((bytes[index++]&0xff)<<19); - length += 0x10204080; - } - else { - length &= 0x1f; - length += ((bytes[index++]&0xff)<<4); - length += ((bytes[index++]&0xff)<<12); - length += ((bytes[index++]&0xff)<<20); - length += 0x204080; - } - } - else { - length &= 0x3f; - length += ((bytes[index++]&0xff)<<5); - length += ((bytes[index++]&0xff)<<13); - length += 0x4080; - } - } - else { - length &= 0x7f; - length += ((bytes[index++]&0xff)<<6); - length += 0x80; - } - } - - int i = 0; - int target = length+index; - while(index < target) { - int c = bytes[index++]&0xff; - if(c <= 0x7F) { - chars[i++] = (char)(c&0x7F); - } else if (c > 0x07FF) { - int c2 = bytes[index++]&0xff; - int c3 = bytes[index++]&0xff; - chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); - } else { - int c2 = bytes[index++]&0xff; - chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); - } - - } - - return new String(chars, 0, i); - - } - - - @Override - public Object deserialize(byte[] data) throws IOException { - return utf(data); - } - - } - - static class STRING_BINDING extends StringBindingDefault { - - public static STRING_BINDING INSTANCE = new STRING_BINDING(); - - public STRING_BINDING() { - super(Datatypes.STRING); - } - - @Override - public Serializer serializer() throws RuntimeSerializerConstructionException { - - return STRING_SERIALIZER.INSTANCE; - - } - - @Override - public boolean isInstance(Object obj) { - return obj instanceof String; - } - - } - - static class BYTE_ARRAY_BINDING extends LongBindingDefault { - - public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING(); - - public BYTE_ARRAY_BINDING() { - super(Datatypes.LONG); - } - - @Override - public Serializer serializer() throws RuntimeSerializerConstructionException { - - return BYTE_ARRAY_SERIALIZER.INSTANCE; - - } - - @Override - public boolean isInstance(Object obj) { - return obj instanceof byte[]; - } - - } - - static class LONG_ARRAY_BINDING extends LongBindingDefault { - - public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING(); - - public LONG_ARRAY_BINDING() { - super(Datatypes.LONG); - } - - @Override - public Serializer serializer() throws RuntimeSerializerConstructionException { - - return LONG_ARRAY_SERIALIZER.INSTANCE; - - } - - } - - - static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault { - - public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING(); - - public TRANSFERABLE_GRAPH_BINDING() { - super(Datatypes.LONG); - } - - @Override - public Serializer serializer() throws RuntimeSerializerConstructionException { - - return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE; - - } - - } - - public static Binding STRING = STRING_BINDING.INSTANCE; - public static Binding BYTE_ARRAY = BYTE_ARRAY_BINDING.INSTANCE; - public static Binding LONG_ARRAY = LONG_ARRAY_BINDING.INSTANCE; - public static Binding TRANSFERABLE_GRAPH = TRANSFERABLE_GRAPH_BINDING.INSTANCE; - - public static void main(String[] args) { - - TransferableGraph1 tg = new TransferableGraph1(123,new Identity[] { - new Identity(11, new Root("foo", "bar1")), - new Identity(12, new External(21, "bar2")), - new Identity(13, new Internal(22, "bar3")), - new Identity(14, new Optional(23, "bar4")) }, - new int[] { 1, 2, 3 }, - new Value[] { new Value(31, new Variant(Bindings.INTEGER, 123)) }); - - try { - System.err.println(Arrays.toString(Bindings.getSerializerUnchecked(Bindings.getBinding(TransferableGraph1.class)).serialize(tg))); - System.err.println(Arrays.toString(WriteBindings.TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE.serialize(tg))); - } catch (RuntimeSerializerConstructionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (BindingConstructionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - -} +package org.simantics.db.common; + +import java.io.IOException; +import java.io.UTFDataFormatException; +import java.nio.charset.Charset; +import java.util.Arrays; + +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.error.BindingConstructionException; +import org.simantics.databoard.binding.impl.LongBindingDefault; +import org.simantics.databoard.binding.impl.StringBindingDefault; +import org.simantics.databoard.binding.mutable.Variant; +import org.simantics.databoard.serialization.RuntimeSerializerConstructionException; +import org.simantics.databoard.serialization.SerializationException; +import org.simantics.databoard.serialization.Serializer; +import org.simantics.databoard.serialization.impl.LongSerializer; +import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer; +import org.simantics.graph.representation.External; +import org.simantics.graph.representation.Identity; +import org.simantics.graph.representation.Internal; +import org.simantics.graph.representation.Optional; +import org.simantics.graph.representation.Root; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.graph.representation.Value; + +public class WriteBindings { + + static class STRING_SERIALIZER extends ModifiedUTF8StringSerializer { + + public static final Charset UTF8 = Charset.forName("utf-8"); + + public static STRING_SERIALIZER INSTANCE = new STRING_SERIALIZER(); + + public STRING_SERIALIZER() { + super(STRING_BINDING.INSTANCE); + } + + static byte[] writeUTF(String str) throws IOException { + + int strlen = str.length(); + int utflen = 0; + int c/*, count = 0*/; + + /* use charAt instead of copying String to char array */ + for (int i = 0; i < strlen; i++) { + c = str.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + utflen++; + } else if (c > 0x07FF) { + utflen += 3; + } else { + utflen += 2; + } + } + + if (utflen > 65535) + throw new UTFDataFormatException( + "encoded string too long: " + utflen + " bytes"); + + int byteIndex = 0; + byte[] bytearr; + + int lengthTester = utflen; + + if(lengthTester < 0x80) { + bytearr = new byte[utflen+1]; + bytearr[byteIndex++] = ((byte)utflen); + } + else { + lengthTester -= 0x80; + if(lengthTester < 0x4000) { + bytearr = new byte[utflen+2]; + bytearr[byteIndex++] = (byte)( ((lengthTester&0x3f) | 0x80) ); + bytearr[byteIndex++] = (byte)( (lengthTester>>>6) ); + } + else { + lengthTester -= 0x4000; + if(lengthTester < 0x200000) { + bytearr = new byte[utflen+3]; + bytearr[byteIndex++] = (byte)( ((lengthTester&0x1f) | 0xc0) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>5)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>13)&0xff) ); + } + else { + lengthTester -= 0x200000; + if(lengthTester < 0x10000000) { + bytearr = new byte[utflen+4]; + bytearr[byteIndex++] = (byte)( ((lengthTester&0x0f) | 0xe0) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>4)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>12)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>20)&0xff) ); + } + else { + lengthTester -= 0x10000000; + bytearr = new byte[utflen+5]; + bytearr[byteIndex++] = (byte)( ((lengthTester&0x07) | 0xf0) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>3)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>11)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>19)&0xff) ); + bytearr[byteIndex++] = (byte)( ((lengthTester>>>27)&0xff) ); + } + } + } + } + + + int i=0; + for (i=0; i= 0x0001) && (c <= 0x007F))) break; + bytearr[byteIndex++] = (byte)(c); + } + + for (;i < strlen; i++){ + c = str.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + bytearr[byteIndex++] = (byte)( c ); + } else if (c > 0x07FF) { + bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F)); + bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F)); + bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); + } else { + bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F)); + bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F)); + } + } + + return bytearr; + + } + + @Override + public byte[] serialize(Object obj) throws IOException { + try { + return writeUTF((String)obj); + } catch (IOException e) { + throw new SerializationException(); + } + + } + + } + + static class BYTE_ARRAY_SERIALIZER extends LongSerializer { + + public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER(); + + public BYTE_ARRAY_SERIALIZER() { + super(BYTE_ARRAY_BINDING.INSTANCE); + } + + @Override + public byte[] serialize(Object obj) throws IOException { + + return (byte[])obj; + + } + + @Override + public Object deserialize(byte[] data) throws IOException { + return data; + } + + } + + final static class LONG_ARRAY_SERIALIZER extends LongSerializer { + + public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER(); + + public LONG_ARRAY_SERIALIZER() { + super(LONG_ARRAY_BINDING.INSTANCE); + } + + final private void loop(byte[] result, int index, long l) { + result[index+7] = (byte)l;l >>>= 8; + result[index+6] = (byte)l;l >>>= 8; + result[index+5] = (byte)l;l >>>= 8; + result[index+4] = (byte)l;l >>>= 8; + result[index+3] = (byte)l;l >>>= 8; + result[index+2] = (byte)l;l >>>= 8; + result[index+1] = (byte)l;l >>>= 8; + result[index] = (byte)l;l >>>= 8; + +// result[index+6] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+5] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+4] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+3] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+2] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+1] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index] = (byte)(l & 0xFF); +// l >>>= 8; + } + + @Override + public byte[] serialize(Object obj) throws IOException { + + long[] data = (long[])obj; + byte[] result = new byte[4+8*data.length]; + + int len = data.length; + + result[3] = (byte)(len & 0xFF); + len >>>= 8; + result[2] = (byte)(len & 0xFF); + len >>>= 8; + result[1] = (byte)(len & 0xFF); + len >>>= 8; + result[0] = (byte)(len & 0xFF); + + int index = 4; + + for(int i=0;i>>= 8; +// result[index+6] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+5] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+4] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+3] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+2] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index+1] = (byte)(l & 0xFF); +// l >>>= 8; +// result[index] = (byte)(l & 0xFF); +// l >>>= 8; + + index += 8; + + } + + return result; + + } + + } + + static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer { + + public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER(); + + public TRANSFERABLE_GRAPH_SERIALIZER() { + super(TRANSFERABLE_GRAPH_BINDING.INSTANCE); + } + + @Override + public byte[] serialize(Object obj) throws IOException { + TransferableGraph1 tg = (TransferableGraph1)obj; + return Bindings + .getSerializerUnchecked(TransferableGraph1.class) + .serialize(tg); + } + + final private String utf(byte[] bytes) { + + char[] chars = new char[bytes.length]; + + int index = 0; + int length = bytes[index++]&0xff; + if(length >= 0x80) { + if(length >= 0xc0) { + if(length >= 0xe0) { + if(length >= 0xf0) { + length &= 0x0f; + length += ((bytes[index++]&0xff)<<3); + length += ((bytes[index++]&0xff)<<11); + length += ((bytes[index++]&0xff)<<19); + length += 0x10204080; + } + else { + length &= 0x1f; + length += ((bytes[index++]&0xff)<<4); + length += ((bytes[index++]&0xff)<<12); + length += ((bytes[index++]&0xff)<<20); + length += 0x204080; + } + } + else { + length &= 0x3f; + length += ((bytes[index++]&0xff)<<5); + length += ((bytes[index++]&0xff)<<13); + length += 0x4080; + } + } + else { + length &= 0x7f; + length += ((bytes[index++]&0xff)<<6); + length += 0x80; + } + } + + int i = 0; + int target = length+index; + while(index < target) { + int c = bytes[index++]&0xff; + if(c <= 0x7F) { + chars[i++] = (char)(c&0x7F); + } else if (c > 0x07FF) { + int c2 = bytes[index++]&0xff; + int c3 = bytes[index++]&0xff; + chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); + } else { + int c2 = bytes[index++]&0xff; + chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); + } + + } + + return new String(chars, 0, i); + + } + + + @Override + public Object deserialize(byte[] data) throws IOException { + return utf(data); + } + + } + + static class STRING_BINDING extends StringBindingDefault { + + public static STRING_BINDING INSTANCE = new STRING_BINDING(); + + public STRING_BINDING() { + super(Datatypes.STRING); + } + + @Override + public Serializer serializer() throws RuntimeSerializerConstructionException { + + return STRING_SERIALIZER.INSTANCE; + + } + + @Override + public boolean isInstance(Object obj) { + return obj instanceof String; + } + + } + + static class BYTE_ARRAY_BINDING extends LongBindingDefault { + + public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING(); + + public BYTE_ARRAY_BINDING() { + super(Datatypes.LONG); + } + + @Override + public Serializer serializer() throws RuntimeSerializerConstructionException { + + return BYTE_ARRAY_SERIALIZER.INSTANCE; + + } + + @Override + public boolean isInstance(Object obj) { + return obj instanceof byte[]; + } + + } + + static class LONG_ARRAY_BINDING extends LongBindingDefault { + + public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING(); + + public LONG_ARRAY_BINDING() { + super(Datatypes.LONG); + } + + @Override + public Serializer serializer() throws RuntimeSerializerConstructionException { + + return LONG_ARRAY_SERIALIZER.INSTANCE; + + } + + } + + + static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault { + + public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING(); + + public TRANSFERABLE_GRAPH_BINDING() { + super(Datatypes.LONG); + } + + @Override + public Serializer serializer() throws RuntimeSerializerConstructionException { + + return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE; + + } + + } + + public static Binding STRING = STRING_BINDING.INSTANCE; + public static Binding BYTE_ARRAY = BYTE_ARRAY_BINDING.INSTANCE; + public static Binding LONG_ARRAY = LONG_ARRAY_BINDING.INSTANCE; + public static Binding TRANSFERABLE_GRAPH = TRANSFERABLE_GRAPH_BINDING.INSTANCE; + + public static void main(String[] args) { + + TransferableGraph1 tg = new TransferableGraph1(123,new Identity[] { + new Identity(11, new Root("foo", "bar1")), + new Identity(12, new External(21, "bar2")), + new Identity(13, new Internal(22, "bar3")), + new Identity(14, new Optional(23, "bar4")) }, + new int[] { 1, 2, 3 }, + new Value[] { new Value(31, new Variant(Bindings.INTEGER, 123)) }); + + try { + System.err.println(Arrays.toString(Bindings.getSerializerUnchecked(Bindings.getBinding(TransferableGraph1.class)).serialize(tg))); + System.err.println(Arrays.toString(WriteBindings.TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE.serialize(tg))); + } catch (RuntimeSerializerConstructionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BindingConstructionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +}