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