]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / WriteBindings.java
1 package org.simantics.db.common;\r
2 \r
3 import java.io.IOException;\r
4 import java.io.UTFDataFormatException;\r
5 import java.nio.charset.Charset;\r
6 import java.util.Arrays;\r
7 \r
8 import org.simantics.databoard.Bindings;\r
9 import org.simantics.databoard.Datatypes;\r
10 import org.simantics.databoard.binding.Binding;\r
11 import org.simantics.databoard.binding.error.BindingConstructionException;\r
12 import org.simantics.databoard.binding.impl.LongBindingDefault;\r
13 import org.simantics.databoard.binding.impl.StringBindingDefault;\r
14 import org.simantics.databoard.binding.mutable.Variant;\r
15 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;\r
16 import org.simantics.databoard.serialization.SerializationException;\r
17 import org.simantics.databoard.serialization.Serializer;\r
18 import org.simantics.databoard.serialization.impl.LongSerializer;\r
19 import org.simantics.databoard.serialization.impl.ModifiedUTF8StringSerializer;\r
20 import org.simantics.graph.representation.External;\r
21 import org.simantics.graph.representation.Identity;\r
22 import org.simantics.graph.representation.Internal;\r
23 import org.simantics.graph.representation.Optional;\r
24 import org.simantics.graph.representation.Root;\r
25 import org.simantics.graph.representation.TransferableGraph1;\r
26 import org.simantics.graph.representation.Value;\r
27 \r
28 public class WriteBindings {\r
29 \r
30         static class STRING_SERIALIZER extends ModifiedUTF8StringSerializer {\r
31 \r
32                 public static final Charset UTF8 = Charset.forName("utf-8");\r
33 \r
34                 public static STRING_SERIALIZER INSTANCE = new STRING_SERIALIZER();\r
35 \r
36                 public STRING_SERIALIZER() {\r
37                         super(STRING_BINDING.INSTANCE);\r
38                 }\r
39 \r
40                 static byte[] writeUTF(String str) throws IOException {\r
41 \r
42                         int strlen = str.length();\r
43                         int utflen = 0;\r
44                         int c/*, count = 0*/;\r
45 \r
46                         /* use charAt instead of copying String to char array */\r
47                         for (int i = 0; i < strlen; i++) {\r
48                                 c = str.charAt(i);\r
49                                 if ((c >= 0x0001) && (c <= 0x007F)) {\r
50                                         utflen++;\r
51                                 } else if (c > 0x07FF) {\r
52                                         utflen += 3;\r
53                                 } else {\r
54                                         utflen += 2;\r
55                                 }\r
56                         }\r
57 \r
58                         if (utflen > 65535)\r
59                                 throw new UTFDataFormatException(\r
60                                                 "encoded string too long: " + utflen + " bytes");\r
61 \r
62                         int byteIndex = 0;\r
63                         byte[] bytearr;\r
64 \r
65                         if(utflen < 0x80) {\r
66                                 bytearr = new byte[utflen+1];\r
67                                 bytearr[byteIndex++] = ((byte)utflen);\r
68                         }\r
69                         else {\r
70                                 utflen -= 0x80;\r
71                                 if(utflen < 0x4000) {\r
72                                         bytearr = new byte[utflen+2];\r
73                                         bytearr[byteIndex++] = (byte)( ((utflen&0x3f) | 0x80) );\r
74                                         bytearr[byteIndex++] = (byte)( (utflen>>>6) );\r
75                                 }\r
76                                 else {\r
77                                         utflen -= 0x4000;\r
78                                         if(utflen < 0x200000) {\r
79                                                 bytearr = new byte[utflen+3];\r
80                                                 bytearr[byteIndex++] = (byte)( ((utflen&0x1f) | 0xc0) );\r
81                                                 bytearr[byteIndex++] = (byte)( ((utflen>>>5)&0xff) );\r
82                                                 bytearr[byteIndex++] = (byte)( ((utflen>>>13)&0xff) );  \r
83                                         }\r
84                                         else {\r
85                                                 utflen -= 0x200000;\r
86                                                 if(utflen < 0x10000000) {\r
87                                                         bytearr = new byte[utflen+4];\r
88                                                         bytearr[byteIndex++] = (byte)( ((utflen&0x0f) | 0xe0) );\r
89                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>4)&0xff) );\r
90                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>12)&0xff) );  \r
91                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>20)&0xff) );\r
92                                                 }\r
93                                                 else {\r
94                                                         utflen -= 0x10000000;\r
95                                                         bytearr = new byte[utflen+5];\r
96                                                         bytearr[byteIndex++] = (byte)( ((utflen&0x07) | 0xf0) );\r
97                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>3)&0xff) );\r
98                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>11)&0xff) );  \r
99                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>19)&0xff) );\r
100                                                         bytearr[byteIndex++] = (byte)( ((utflen>>>27)&0xff) );\r
101                                                 }\r
102                                         }                               \r
103                                 }\r
104                         }       \r
105 \r
106 \r
107                         int i=0;\r
108                         for (i=0; i<strlen; i++) {\r
109                                 c = str.charAt(i);\r
110                                 if (!((c >= 0x0001) && (c <= 0x007F))) break;\r
111                                 bytearr[byteIndex++] = (byte)(c);\r
112                         }\r
113 \r
114                         for (;i < strlen; i++){\r
115                                 c = str.charAt(i);\r
116                                 if ((c >= 0x0001) && (c <= 0x007F)) {\r
117                                         bytearr[byteIndex++] = (byte)( c );\r
118                                 } else if (c > 0x07FF) {\r
119                                         bytearr[byteIndex++] = (byte)(0xE0 | ((c >> 12) & 0x0F));\r
120                                         bytearr[byteIndex++] = (byte)(0x80 | ((c >>  6) & 0x3F));\r
121                                         bytearr[byteIndex++] = (byte)(0x80 | ((c >>  0) & 0x3F));\r
122                                 } else {\r
123                                         bytearr[byteIndex++] = (byte)(0xC0 | ((c >>  6) & 0x1F));\r
124                                         bytearr[byteIndex++] = (byte)(0x80 | ((c >>  0) & 0x3F));\r
125                                 }\r
126                         }\r
127 \r
128                         return bytearr;\r
129 \r
130                 }\r
131 \r
132                 @Override\r
133                 public byte[] serialize(Object obj) throws IOException {\r
134                         try {\r
135                                 return writeUTF((String)obj);\r
136                         } catch (IOException e) {\r
137                                 throw new SerializationException();\r
138                         }\r
139                         \r
140                 }\r
141                 \r
142         }\r
143 \r
144         static class BYTE_ARRAY_SERIALIZER extends LongSerializer {\r
145 \r
146                 public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER();\r
147 \r
148                 public BYTE_ARRAY_SERIALIZER() {\r
149                         super(BYTE_ARRAY_BINDING.INSTANCE);\r
150                 }\r
151                 \r
152                 @Override\r
153                 public byte[] serialize(Object obj) throws IOException {\r
154                         \r
155                         return (byte[])obj;\r
156 \r
157                 }\r
158                 \r
159                 @Override\r
160                 public Object deserialize(byte[] data) throws IOException {\r
161                         return data;\r
162                 }\r
163                 \r
164         }\r
165 \r
166         final static class LONG_ARRAY_SERIALIZER extends LongSerializer {\r
167 \r
168                 public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER();\r
169 \r
170                 public LONG_ARRAY_SERIALIZER() {\r
171                         super(LONG_ARRAY_BINDING.INSTANCE);\r
172                 }\r
173                 \r
174                 final private void loop(byte[] result, int index, long l) {\r
175                         result[index+7] = (byte)l;l >>>= 8;\r
176                         result[index+6] = (byte)l;l >>>= 8;\r
177                         result[index+5] = (byte)l;l >>>= 8;\r
178                         result[index+4] = (byte)l;l >>>= 8;\r
179                         result[index+3] = (byte)l;l >>>= 8;\r
180                         result[index+2] = (byte)l;l >>>= 8;\r
181                         result[index+1] = (byte)l;l >>>= 8;\r
182                         result[index] = (byte)l;l >>>= 8;\r
183                         \r
184 //                      result[index+6] = (byte)(l & 0xFF);\r
185 //                      l >>>= 8;\r
186 //                      result[index+5] = (byte)(l & 0xFF);\r
187 //                      l >>>= 8;\r
188 //                      result[index+4] = (byte)(l & 0xFF);\r
189 //                      l >>>= 8;\r
190 //                      result[index+3] = (byte)(l & 0xFF);\r
191 //                      l >>>= 8;\r
192 //                      result[index+2] = (byte)(l & 0xFF);\r
193 //                      l >>>= 8;\r
194 //                      result[index+1] = (byte)(l & 0xFF);\r
195 //                      l >>>= 8;\r
196 //                      result[index] = (byte)(l & 0xFF);\r
197 //                      l >>>= 8;\r
198                 }\r
199                 \r
200                 @Override\r
201                 public byte[] serialize(Object obj) throws IOException {\r
202                         \r
203                         long[] data = (long[])obj;\r
204                         byte[] result = new byte[4+8*data.length];\r
205                         \r
206                         int len = data.length;\r
207                         \r
208                         result[3] = (byte)(len & 0xFF);\r
209                         len >>>= 8;\r
210                         result[2] = (byte)(len & 0xFF);\r
211                         len >>>= 8;\r
212                         result[1] = (byte)(len & 0xFF);\r
213                         len >>>= 8;\r
214                         result[0] = (byte)(len & 0xFF);\r
215 \r
216                         int index = 4;\r
217 \r
218                         for(int i=0;i<data.length;i++) {\r
219 \r
220                                 loop(result, index, data[i]);\r
221 \r
222 //                              long l = data[i];\r
223 \r
224 //                              result[index+7] = (byte)(l & 0xFF);\r
225 //                              l >>>= 8;\r
226 //                              result[index+6] = (byte)(l & 0xFF);\r
227 //                              l >>>= 8;\r
228 //                              result[index+5] = (byte)(l & 0xFF);\r
229 //                              l >>>= 8;\r
230 //                              result[index+4] = (byte)(l & 0xFF);\r
231 //                              l >>>= 8;\r
232 //                              result[index+3] = (byte)(l & 0xFF);\r
233 //                              l >>>= 8;\r
234 //                              result[index+2] = (byte)(l & 0xFF);\r
235 //                              l >>>= 8;\r
236 //                              result[index+1] = (byte)(l & 0xFF);\r
237 //                              l >>>= 8;\r
238 //                              result[index] = (byte)(l & 0xFF);\r
239 //                              l >>>= 8;\r
240                                 \r
241                                 index += 8;\r
242 \r
243                         }\r
244                         \r
245                         return result;\r
246 \r
247                 }\r
248                 \r
249         }\r
250 \r
251         static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer {\r
252 \r
253                 public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER();\r
254 \r
255                 public TRANSFERABLE_GRAPH_SERIALIZER() {\r
256                         super(TRANSFERABLE_GRAPH_BINDING.INSTANCE);\r
257                 }\r
258                 \r
259                 static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException {\r
260                         \r
261                         int strlen = str.length();\r
262                         int utflen = 0;\r
263                         int c;\r
264                         int count = byteIndex;\r
265 \r
266                         /* use charAt instead of copying String to char array */\r
267                         for (int i = 0; i < strlen; i++) {\r
268                                 c = str.charAt(i);\r
269                                 if ((c >= 0x0001) && (c <= 0x007F)) {\r
270                                         utflen++;\r
271                                 } else if (c > 0x07FF) {\r
272                                         utflen += 3;\r
273                                 } else {\r
274                                         utflen += 2;\r
275                                 }\r
276                         }\r
277 \r
278                         if (utflen > 65535)\r
279                                 throw new UTFDataFormatException(\r
280                                                 "encoded string too long: " + utflen + " bytes");\r
281 \r
282 //                      byte[] bytearr = new byte[utflen+2];\r
283 \r
284                         if(utflen < 0x80) {\r
285                                 bytearr[count++] = ((byte)utflen);\r
286                         }\r
287                         else {\r
288                                 utflen -= 0x80;\r
289                                 if(utflen < 0x4000) {\r
290                                         bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) );\r
291                                         bytearr[count++] = (byte)( (utflen>>>6) );\r
292                                 }\r
293                                 else {\r
294                                         utflen -= 0x4000;\r
295                                         if(utflen < 0x200000) {\r
296                                                 bytearr[count++] = (byte)( ((utflen&0x1f) | 0xc0) );\r
297                                                 bytearr[count++] = (byte)( ((utflen>>>5)&0xff) );\r
298                                                 bytearr[count++] = (byte)( ((utflen>>>13)&0xff) );      \r
299                                         }\r
300                                         else {\r
301                                                 utflen -= 0x200000;\r
302                                                 if(utflen < 0x10000000) {\r
303                                                         bytearr[count++] = (byte)( ((utflen&0x0f) | 0xe0) );\r
304                                                         bytearr[count++] = (byte)( ((utflen>>>4)&0xff) );\r
305                                                         bytearr[count++] = (byte)( ((utflen>>>12)&0xff) );      \r
306                                                         bytearr[count++] = (byte)( ((utflen>>>20)&0xff) );\r
307                                                 }\r
308                                                 else {\r
309                                                         utflen -= 0x10000000;\r
310                                                         bytearr[count++] = (byte)( ((utflen&0x07) | 0xf0) );\r
311                                                         bytearr[count++] = (byte)( ((utflen>>>3)&0xff) );\r
312                                                         bytearr[count++] = (byte)( ((utflen>>>11)&0xff) );      \r
313                                                         bytearr[count++] = (byte)( ((utflen>>>19)&0xff) );\r
314                                                         bytearr[count++] = (byte)( ((utflen>>>27)&0xff) );\r
315                                                 }\r
316                                         }                               \r
317                                 }\r
318                         }       \r
319 \r
320                         int i=0;\r
321                         for (i=0; i<strlen; i++) {\r
322                                 c = str.charAt(i);\r
323                                 if (!((c >= 0x0001) && (c <= 0x007F))) break;\r
324                                 bytearr[count++] = (byte) c;\r
325                         }\r
326 \r
327                         for (;i < strlen; i++){\r
328                                 c = str.charAt(i);\r
329                                 if ((c >= 0x0001) && (c <= 0x007F)) {\r
330                                         bytearr[count++] = (byte) c;\r
331 \r
332                                 } else if (c > 0x07FF) {\r
333                                         bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));\r
334                                         bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));\r
335                                         bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));\r
336                                 } else {\r
337                                         bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));\r
338                                         bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));\r
339                                 }\r
340                         }\r
341                         \r
342                         return count - byteIndex;\r
343                         \r
344                 }\r
345                 \r
346                 @Override\r
347                 public byte[] serialize(Object obj) throws IOException {\r
348                         \r
349                         TransferableGraph1 tg = (TransferableGraph1)obj;\r
350                         \r
351                         return Bindings\r
352                                         .getSerializerUnchecked(TransferableGraph1.class)\r
353                                         .serialize(tg);\r
354 /*\r
355                         // 16 = resourceCount + 3 arrays\r
356 //                      long start = System.nanoTime();\r
357                         int actualSize = 16 + 8*tg.values.length + 4*tg.statements.length + 5*tg.identities.length;\r
358                         for(Value v : tg.values) actualSize += v.value.length;\r
359                         for(Identity id : tg.identities) { \r
360                                 if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5);\r
361                                 else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5);\r
362                                 else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10);\r
363                                 else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5);\r
364                         }\r
365 //                      long end = System.nanoTime() - start;\r
366 //                      System.err.println("size took " + 1e-9*end);\r
367                         \r
368 //                      long start2 = System.nanoTime();\r
369                         \r
370                         \r
371                         byte[] bytes = new byte[actualSize];\r
372                         int byteIndex = 0;\r
373 \r
374                         int i = tg.resourceCount;\r
375                         \r
376                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
377                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
378                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
379                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
380                         byteIndex+=4;\r
381                         \r
382                         i = tg.identities.length;\r
383 \r
384                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
385                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
386                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
387                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
388                         byteIndex+=4;\r
389                         \r
390                         for(Identity id : tg.identities) {\r
391 \r
392                                 i = id.resource;\r
393                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
394                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
395                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
396                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
397                                 byteIndex+=4;\r
398                                 \r
399                                 if(id.definition instanceof Internal) {\r
400 \r
401                                         Internal r = (Internal)id.definition;\r
402 \r
403                                         bytes[byteIndex++] = 3;\r
404 \r
405                                         i = r.parent;\r
406                                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
407                                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
408                                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
409                                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
410                                         byteIndex+=4;\r
411                                         \r
412                                         byteIndex += writeUTF(r.name, bytes, byteIndex);\r
413 \r
414                                 } else if(id.definition instanceof External) {\r
415 \r
416                                         External r = (External)id.definition;\r
417 \r
418                                         bytes[byteIndex++] = 1;\r
419 \r
420                                         i = r.parent;\r
421                                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
422                                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
423                                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
424                                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
425                                         byteIndex+=4;\r
426                                         \r
427                                         byteIndex += writeUTF(r.name, bytes, byteIndex);\r
428                                         \r
429                                 } else if(id.definition instanceof Root) {\r
430                                         \r
431                                         bytes[byteIndex++] = 0;\r
432                                         \r
433                                         Root r = (Root)id.definition;\r
434                                         byteIndex += writeUTF(r.name, bytes, byteIndex);\r
435                                         byteIndex += writeUTF(r.type, bytes, byteIndex);\r
436                                         \r
437                                 } else if(id.definition instanceof Optional) {\r
438 \r
439                                         Optional r = (Optional)id.definition;\r
440 \r
441                                         bytes[byteIndex++] = 2;\r
442 \r
443                                         i = r.parent;\r
444                                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
445                                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
446                                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
447                                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
448                                         byteIndex+=4;\r
449                                         \r
450                                         byteIndex += writeUTF(r.name, bytes, byteIndex);\r
451                                         \r
452                                 }\r
453                                 \r
454                         }\r
455                         \r
456                         i = tg.statements.length;\r
457                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
458                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
459                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
460                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
461                         byteIndex+=4;\r
462                         \r
463                         for(int s : tg.statements) {\r
464                                 i = s;\r
465                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
466                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
467                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
468                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
469                                 byteIndex+=4;\r
470                         }\r
471 \r
472                         i = tg.values.length;\r
473                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
474                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
475                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
476                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
477                         byteIndex+=4;\r
478 \r
479                         for(Value v : tg.values) {\r
480                                 \r
481                                 i = v.resource;\r
482                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
483                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
484                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
485                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
486                                 byteIndex+=4;\r
487 \r
488                                 i = v.value.length;\r
489                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;\r
490                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;\r
491                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;\r
492                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;\r
493                                 byteIndex+=4;\r
494                                 \r
495                                 System.arraycopy(v.value, 0, bytes, byteIndex, v.value.length);\r
496                                 byteIndex += v.value.length;\r
497                                 \r
498                         }\r
499 \r
500 //                      return bytes;\r
501                         \r
502 //                      byte[] result = new byte[byteIndex];\r
503 //                      System.arraycopy(bytes, 0, result, 0, byteIndex);\r
504 //                      \r
505 //                      byte[] result = Arrays.copyOf(bytes, byteIndex); \r
506                         \r
507 //                      long end2 = System.nanoTime() - start2;\r
508 //                      System.err.println("size2 took " + 1e-9*end2);\r
509 \r
510                         return bytes; \r
511                         \r
512 //                      long[] data = (long[])obj;\r
513 //                      byte[] result = new byte[4+8*data.length];\r
514 //                      \r
515 //                      int len = data.length;\r
516 //                      \r
517 //                      result[3] = (byte)(len & 0xFF);\r
518 //                      len >>>= 8;\r
519 //                      result[2] = (byte)(len & 0xFF);\r
520 //                      len >>>= 8;\r
521 //                      result[1] = (byte)(len & 0xFF);\r
522 //                      len >>>= 8;\r
523 //                      result[0] = (byte)(len & 0xFF);\r
524 //\r
525 //                      int index = 4;\r
526 //\r
527 //                      for(int i=0;i<data.length;i++) {\r
528 //                              \r
529 //                              long l = data[i];\r
530 //\r
531 //                              result[index+7] = (byte)(l & 0xFF);\r
532 //                              l >>>= 8;\r
533 //                              result[index+6] = (byte)(l & 0xFF);\r
534 //                              l >>>= 8;\r
535 //                              result[index+5] = (byte)(l & 0xFF);\r
536 //                              l >>>= 8;\r
537 //                              result[index+4] = (byte)(l & 0xFF);\r
538 //                              l >>>= 8;\r
539 //                              result[index+3] = (byte)(l & 0xFF);\r
540 //                              l >>>= 8;\r
541 //                              result[index+2] = (byte)(l & 0xFF);\r
542 //                              l >>>= 8;\r
543 //                              result[index+1] = (byte)(l & 0xFF);\r
544 //                              l >>>= 8;\r
545 //                              result[index] = (byte)(l & 0xFF);\r
546 //                              l >>>= 8;\r
547 //                              \r
548 //                              index += 8;\r
549 //\r
550 //                      }\r
551 //                      \r
552 //                      return result;\r
553 */\r
554                 }\r
555                 \r
556                 \r
557                 final private String utf(byte[] bytes) {\r
558                         \r
559                         char[] chars = new char[bytes.length];\r
560                         \r
561                         int index = 0;\r
562                         int length = bytes[index++]&0xff; \r
563                         if(length >= 0x80) {\r
564                                 if(length >= 0xc0) {\r
565                                         if(length >= 0xe0) {\r
566                                                 if(length >= 0xf0) {\r
567                                                         length &= 0x0f;\r
568                                                         length += ((bytes[index++]&0xff)<<3);\r
569                                                         length += ((bytes[index++]&0xff)<<11);\r
570                                                         length += ((bytes[index++]&0xff)<<19);\r
571                                                         length += 0x10204080;\r
572                                                 }\r
573                                                 else {\r
574                                                         length &= 0x1f;\r
575                                                         length += ((bytes[index++]&0xff)<<4);\r
576                                                         length += ((bytes[index++]&0xff)<<12);\r
577                                                         length += ((bytes[index++]&0xff)<<20);\r
578                                                         length += 0x204080;\r
579                                                 }\r
580                                         }\r
581                                         else {\r
582                                                 length &= 0x3f;\r
583                                                 length += ((bytes[index++]&0xff)<<5);\r
584                                                 length += ((bytes[index++]&0xff)<<13);\r
585                                                 length += 0x4080;\r
586                                         }\r
587                                 }\r
588                                 else {\r
589                                         length &= 0x7f;\r
590                                         length += ((bytes[index++]&0xff)<<6);\r
591                                         length += 0x80;\r
592                                 }\r
593                         }\r
594                         \r
595                         int i = 0;\r
596                         int target = length+index;\r
597                         while(index < target) {\r
598                                 int c = bytes[index++]&0xff;\r
599                                 if(c <= 0x7F) {\r
600                                         chars[i++] = (char)(c&0x7F);\r
601                                 } else if (c > 0x07FF) {\r
602                                         int c2 = bytes[index++]&0xff;\r
603                                         int c3 = bytes[index++]&0xff;\r
604                                         chars[i++] = (char)(((c&0xf)<<12) + ((c2&0x3f)<<6) + (c3&0x3f)); \r
605                                 } else {\r
606                                         int c2 = bytes[index++]&0xff;\r
607                                         chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); \r
608                                 }\r
609                                 \r
610                         }\r
611                         \r
612                         return new String(chars, 0, i);\r
613                         \r
614                 }\r
615 \r
616                 \r
617                 @Override\r
618                 public Object deserialize(byte[] data) throws IOException {\r
619                         return utf(data);\r
620                 }\r
621                 \r
622         }\r
623 \r
624         static class STRING_BINDING extends StringBindingDefault {\r
625                 \r
626                 public static STRING_BINDING INSTANCE = new STRING_BINDING();\r
627                 \r
628                 public STRING_BINDING() {\r
629                         super(Datatypes.STRING);\r
630                 }\r
631                 \r
632                 @Override\r
633                 public Serializer serializer() throws RuntimeSerializerConstructionException {\r
634                         \r
635                         return STRING_SERIALIZER.INSTANCE;\r
636                         \r
637                 }\r
638                 \r
639                 @Override\r
640                 public boolean isInstance(Object obj) {\r
641                         return obj instanceof String;\r
642                 }\r
643                 \r
644         }\r
645         \r
646         static class BYTE_ARRAY_BINDING extends LongBindingDefault {\r
647                 \r
648                 public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING();\r
649                 \r
650                 public BYTE_ARRAY_BINDING() {\r
651                         super(Datatypes.LONG);\r
652                 }\r
653                 \r
654                 @Override\r
655                 public Serializer serializer() throws RuntimeSerializerConstructionException {\r
656                         \r
657                         return BYTE_ARRAY_SERIALIZER.INSTANCE;\r
658                         \r
659                 }\r
660                 \r
661                 @Override\r
662                 public boolean isInstance(Object obj) {\r
663                         return obj instanceof byte[];\r
664                 }\r
665                 \r
666         }\r
667 \r
668         static class LONG_ARRAY_BINDING extends LongBindingDefault {\r
669                 \r
670                 public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING();\r
671                 \r
672                 public LONG_ARRAY_BINDING() {\r
673                         super(Datatypes.LONG);\r
674                 }\r
675                 \r
676                 @Override\r
677                 public Serializer serializer() throws RuntimeSerializerConstructionException {\r
678                         \r
679                         return LONG_ARRAY_SERIALIZER.INSTANCE;\r
680                         \r
681                 }\r
682                 \r
683         }\r
684 \r
685         \r
686         static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault {\r
687                 \r
688                 public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING();\r
689                 \r
690                 public TRANSFERABLE_GRAPH_BINDING() {\r
691                         super(Datatypes.LONG);\r
692                 }\r
693                 \r
694                 @Override\r
695                 public Serializer serializer() throws RuntimeSerializerConstructionException {\r
696                         \r
697                         return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE;\r
698                         \r
699                 }\r
700                 \r
701         }\r
702 \r
703         public static Binding STRING = STRING_BINDING.INSTANCE;\r
704         public static Binding BYTE_ARRAY = BYTE_ARRAY_BINDING.INSTANCE;\r
705         public static Binding LONG_ARRAY = LONG_ARRAY_BINDING.INSTANCE;\r
706         public static Binding TRANSFERABLE_GRAPH = TRANSFERABLE_GRAPH_BINDING.INSTANCE;\r
707 \r
708         public static void main(String[] args) {\r
709 \r
710                 TransferableGraph1 tg = new TransferableGraph1(123,new Identity[] { \r
711                                 new Identity(11, new Root("foo", "bar1")), \r
712                                 new Identity(12, new External(21, "bar2")), \r
713                                 new Identity(13, new Internal(22, "bar3")), \r
714                                 new Identity(14, new Optional(23, "bar4")) },\r
715                                 new int[] { 1, 2, 3 },\r
716                                 new Value[] { new Value(31, new Variant(Bindings.INTEGER, 123)) });\r
717 \r
718                 try {\r
719                         System.err.println(Arrays.toString(Bindings.getSerializerUnchecked(Bindings.getBinding(TransferableGraph1.class)).serialize(tg)));\r
720                         System.err.println(Arrays.toString(WriteBindings.TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE.serialize(tg)));\r
721                 } catch (RuntimeSerializerConstructionException e) {\r
722                         // TODO Auto-generated catch block\r
723                         e.printStackTrace();\r
724                 } catch (IOException e) {\r
725                         // TODO Auto-generated catch block\r
726                         e.printStackTrace();\r
727                 } catch (BindingConstructionException e) {\r
728                         // TODO Auto-generated catch block\r
729                         e.printStackTrace();\r
730                 }\r
731                 \r
732         }\r
733         \r
734 }\r