1 package org.simantics.db.common;
3 import java.io.IOException;
4 import java.io.UTFDataFormatException;
5 import java.nio.charset.Charset;
6 import java.util.Arrays;
8 import org.simantics.databoard.Bindings;
9 import org.simantics.databoard.Datatypes;
10 import org.simantics.databoard.binding.Binding;
11 import org.simantics.databoard.binding.error.BindingConstructionException;
12 import org.simantics.databoard.binding.impl.LongBindingDefault;
13 import org.simantics.databoard.binding.impl.StringBindingDefault;
14 import org.simantics.databoard.binding.mutable.Variant;
15 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
16 import org.simantics.databoard.serialization.SerializationException;
17 import org.simantics.databoard.serialization.Serializer;
18 import org.simantics.databoard.serialization.impl.LongSerializer;
19 import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer;
20 import org.simantics.graph.representation.External;
21 import org.simantics.graph.representation.Identity;
22 import org.simantics.graph.representation.Internal;
23 import org.simantics.graph.representation.Optional;
24 import org.simantics.graph.representation.Root;
25 import org.simantics.graph.representation.TransferableGraph1;
26 import org.simantics.graph.representation.Value;
28 public class WriteBindings {
30 static class STRING_SERIALIZER extends ModifiedUTF8StringSerializer {
32 public static final Charset UTF8 = Charset.forName("utf-8");
34 public static STRING_SERIALIZER INSTANCE = new STRING_SERIALIZER();
36 public STRING_SERIALIZER() {
37 super(STRING_BINDING.INSTANCE);
40 static byte[] writeUTF(String str) throws IOException {
42 int strlen = str.length();
46 /* use charAt instead of copying String to char array */
47 for (int i = 0; i < strlen; i++) {
49 if ((c >= 0x0001) && (c <= 0x007F)) {
51 } else if (c > 0x07FF) {
59 throw new UTFDataFormatException(
60 "encoded string too long: " + utflen + " bytes");
65 int lengthTester = utflen;
67 if(lengthTester < 0x80) {
68 bytearr = new byte[utflen+1];
69 bytearr[byteIndex++] = ((byte)utflen);
73 if(lengthTester < 0x4000) {
74 bytearr = new byte[utflen+2];
75 bytearr[byteIndex++] = (byte)( ((lengthTester&0x3f) | 0x80) );
76 bytearr[byteIndex++] = (byte)( (lengthTester>>>6) );
79 lengthTester -= 0x4000;
80 if(lengthTester < 0x200000) {
81 bytearr = new byte[utflen+3];
82 bytearr[byteIndex++] = (byte)( ((lengthTester&0x1f) | 0xc0) );
83 bytearr[byteIndex++] = (byte)( ((lengthTester>>>5)&0xff) );
84 bytearr[byteIndex++] = (byte)( ((lengthTester>>>13)&0xff) );
87 lengthTester -= 0x200000;
88 if(lengthTester < 0x10000000) {
89 bytearr = new byte[utflen+4];
90 bytearr[byteIndex++] = (byte)( ((lengthTester&0x0f) | 0xe0) );
91 bytearr[byteIndex++] = (byte)( ((lengthTester>>>4)&0xff) );
92 bytearr[byteIndex++] = (byte)( ((lengthTester>>>12)&0xff) );
93 bytearr[byteIndex++] = (byte)( ((lengthTester>>>20)&0xff) );
96 lengthTester -= 0x10000000;
97 bytearr = new byte[utflen+5];
98 bytearr[byteIndex++] = (byte)( ((lengthTester&0x07) | 0xf0) );
99 bytearr[byteIndex++] = (byte)( ((lengthTester>>>3)&0xff) );
100 bytearr[byteIndex++] = (byte)( ((lengthTester>>>11)&0xff) );
101 bytearr[byteIndex++] = (byte)( ((lengthTester>>>19)&0xff) );
102 bytearr[byteIndex++] = (byte)( ((lengthTester>>>27)&0xff) );
110 for (i=0; i<strlen; i++) {
112 if (!((c >= 0x0001) && (c <= 0x007F))) break;
113 bytearr[byteIndex++] = (byte)(c);
116 for (;i < strlen; i++){
118 if ((c >= 0x0001) && (c <= 0x007F)) {
119 bytearr[byteIndex++] = (byte)( c );
120 } else if (c > 0x07FF) {
121 bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F));
122 bytearr[byteIndex++] = (byte)(0x80 | ((c >> 6) & 0x3F));
123 bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));
125 bytearr[byteIndex++] = (byte)(0xC0 | ((c >> 6) & 0x1F));
126 bytearr[byteIndex++] = (byte)(0x80 | ((c >> 0) & 0x3F));
135 public byte[] serialize(Object obj) throws IOException {
137 return writeUTF((String)obj);
138 } catch (IOException e) {
139 throw new SerializationException();
146 static class BYTE_ARRAY_SERIALIZER extends LongSerializer {
148 public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER();
150 public BYTE_ARRAY_SERIALIZER() {
151 super(BYTE_ARRAY_BINDING.INSTANCE);
155 public byte[] serialize(Object obj) throws IOException {
162 public Object deserialize(byte[] data) throws IOException {
168 final static class LONG_ARRAY_SERIALIZER extends LongSerializer {
170 public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER();
172 public LONG_ARRAY_SERIALIZER() {
173 super(LONG_ARRAY_BINDING.INSTANCE);
176 final private void loop(byte[] result, int index, long l) {
177 result[index+7] = (byte)l;l >>>= 8;
178 result[index+6] = (byte)l;l >>>= 8;
179 result[index+5] = (byte)l;l >>>= 8;
180 result[index+4] = (byte)l;l >>>= 8;
181 result[index+3] = (byte)l;l >>>= 8;
182 result[index+2] = (byte)l;l >>>= 8;
183 result[index+1] = (byte)l;l >>>= 8;
184 result[index] = (byte)l;l >>>= 8;
186 // result[index+6] = (byte)(l & 0xFF);
188 // result[index+5] = (byte)(l & 0xFF);
190 // result[index+4] = (byte)(l & 0xFF);
192 // result[index+3] = (byte)(l & 0xFF);
194 // result[index+2] = (byte)(l & 0xFF);
196 // result[index+1] = (byte)(l & 0xFF);
198 // result[index] = (byte)(l & 0xFF);
203 public byte[] serialize(Object obj) throws IOException {
205 long[] data = (long[])obj;
206 byte[] result = new byte[4+8*data.length];
208 int len = data.length;
210 result[3] = (byte)(len & 0xFF);
212 result[2] = (byte)(len & 0xFF);
214 result[1] = (byte)(len & 0xFF);
216 result[0] = (byte)(len & 0xFF);
220 for(int i=0;i<data.length;i++) {
222 loop(result, index, data[i]);
226 // result[index+7] = (byte)(l & 0xFF);
228 // result[index+6] = (byte)(l & 0xFF);
230 // result[index+5] = (byte)(l & 0xFF);
232 // result[index+4] = (byte)(l & 0xFF);
234 // result[index+3] = (byte)(l & 0xFF);
236 // result[index+2] = (byte)(l & 0xFF);
238 // result[index+1] = (byte)(l & 0xFF);
240 // result[index] = (byte)(l & 0xFF);
253 static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer {
255 public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER();
257 public TRANSFERABLE_GRAPH_SERIALIZER() {
258 super(TRANSFERABLE_GRAPH_BINDING.INSTANCE);
262 public byte[] serialize(Object obj) throws IOException {
263 TransferableGraph1 tg = (TransferableGraph1)obj;
265 .getSerializerUnchecked(TransferableGraph1.class)
269 final private String utf(byte[] bytes) {
271 char[] chars = new char[bytes.length];
274 int length = bytes[index++]&0xff;
280 length += ((bytes[index++]&0xff)<<3);
281 length += ((bytes[index++]&0xff)<<11);
282 length += ((bytes[index++]&0xff)<<19);
283 length += 0x10204080;
287 length += ((bytes[index++]&0xff)<<4);
288 length += ((bytes[index++]&0xff)<<12);
289 length += ((bytes[index++]&0xff)<<20);
295 length += ((bytes[index++]&0xff)<<5);
296 length += ((bytes[index++]&0xff)<<13);
302 length += ((bytes[index++]&0xff)<<6);
308 int target = length+index;
309 while(index < target) {
310 int c = bytes[index++]&0xff;
312 chars[i++] = (char)(c&0x7F);
313 } else if (c > 0x07FF) {
314 int c2 = bytes[index++]&0xff;
315 int c3 = bytes[index++]&0xff;
316 chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f));
318 int c2 = bytes[index++]&0xff;
319 chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f));
324 return new String(chars, 0, i);
330 public Object deserialize(byte[] data) throws IOException {
336 static class STRING_BINDING extends StringBindingDefault {
338 public static STRING_BINDING INSTANCE = new STRING_BINDING();
340 public STRING_BINDING() {
341 super(Datatypes.STRING);
345 public Serializer serializer() throws RuntimeSerializerConstructionException {
347 return STRING_SERIALIZER.INSTANCE;
352 public boolean isInstance(Object obj) {
353 return obj instanceof String;
358 static class BYTE_ARRAY_BINDING extends LongBindingDefault {
360 public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING();
362 public BYTE_ARRAY_BINDING() {
363 super(Datatypes.LONG);
367 public Serializer serializer() throws RuntimeSerializerConstructionException {
369 return BYTE_ARRAY_SERIALIZER.INSTANCE;
374 public boolean isInstance(Object obj) {
375 return obj instanceof byte[];
380 static class LONG_ARRAY_BINDING extends LongBindingDefault {
382 public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING();
384 public LONG_ARRAY_BINDING() {
385 super(Datatypes.LONG);
389 public Serializer serializer() throws RuntimeSerializerConstructionException {
391 return LONG_ARRAY_SERIALIZER.INSTANCE;
398 static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault {
400 public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING();
402 public TRANSFERABLE_GRAPH_BINDING() {
403 super(Datatypes.LONG);
407 public Serializer serializer() throws RuntimeSerializerConstructionException {
409 return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE;
415 public static Binding STRING = STRING_BINDING.INSTANCE;
416 public static Binding BYTE_ARRAY = BYTE_ARRAY_BINDING.INSTANCE;
417 public static Binding LONG_ARRAY = LONG_ARRAY_BINDING.INSTANCE;
418 public static Binding TRANSFERABLE_GRAPH = TRANSFERABLE_GRAPH_BINDING.INSTANCE;
420 public static void main(String[] args) {
422 TransferableGraph1 tg = new TransferableGraph1(123,new Identity[] {
423 new Identity(11, new Root("foo", "bar1")),
424 new Identity(12, new External(21, "bar2")),
425 new Identity(13, new Internal(22, "bar3")),
426 new Identity(14, new Optional(23, "bar4")) },
427 new int[] { 1, 2, 3 },
428 new Value[] { new Value(31, new Variant(Bindings.INTEGER, 123)) });
431 System.err.println(Arrays.toString(Bindings.getSerializerUnchecked(Bindings.getBinding(TransferableGraph1.class)).serialize(tg)));
432 System.err.println(Arrays.toString(WriteBindings.TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE.serialize(tg)));
433 } catch (RuntimeSerializerConstructionException e) {
434 // TODO Auto-generated catch block
436 } catch (IOException e) {
437 // TODO Auto-generated catch block
439 } catch (BindingConstructionException e) {
440 // TODO Auto-generated catch block