]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/WriteBindings.java
Improved subscription CSV export wizard page initial selection handling
[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                         int lengthTester = utflen;
66                         
67                         if(lengthTester < 0x80) {
68                                 bytearr = new byte[utflen+1];
69                                 bytearr[byteIndex++] = ((byte)utflen);
70                         }
71                         else {
72                                 lengthTester -= 0x80;
73                                 if(lengthTester < 0x4000) {
74                                         bytearr = new byte[utflen+2];
75                                         bytearr[byteIndex++] = (byte)( ((lengthTester&0x3f) | 0x80) );
76                                         bytearr[byteIndex++] = (byte)( (lengthTester>>>6) );
77                                 }
78                                 else {
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) );    
85                                         }
86                                         else {
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) );
94                                                 }
95                                                 else {
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) );
103                                                 }
104                                         }                               
105                                 }
106                         }       
107
108
109                         int i=0;
110                         for (i=0; i<strlen; i++) {
111                                 c = str.charAt(i);
112                                 if (!((c >= 0x0001) && (c <= 0x007F))) break;
113                                 bytearr[byteIndex++] = (byte)(c);
114                         }
115
116                         for (;i < strlen; i++){
117                                 c = str.charAt(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));
124                                 } else {
125                                         bytearr[byteIndex++] = (byte)(0xC0 | ((c >>  6) & 0x1F));
126                                         bytearr[byteIndex++] = (byte)(0x80 | ((c >>  0) & 0x3F));
127                                 }
128                         }
129
130                         return bytearr;
131
132                 }
133
134                 @Override
135                 public byte[] serialize(Object obj) throws IOException {
136                         try {
137                                 return writeUTF((String)obj);
138                         } catch (IOException e) {
139                                 throw new SerializationException();
140                         }
141                         
142                 }
143                 
144         }
145
146         static class BYTE_ARRAY_SERIALIZER extends LongSerializer {
147
148                 public static BYTE_ARRAY_SERIALIZER INSTANCE = new BYTE_ARRAY_SERIALIZER();
149
150                 public BYTE_ARRAY_SERIALIZER() {
151                         super(BYTE_ARRAY_BINDING.INSTANCE);
152                 }
153                 
154                 @Override
155                 public byte[] serialize(Object obj) throws IOException {
156                         
157                         return (byte[])obj;
158
159                 }
160                 
161                 @Override
162                 public Object deserialize(byte[] data) throws IOException {
163                         return data;
164                 }
165                 
166         }
167
168         final static class LONG_ARRAY_SERIALIZER extends LongSerializer {
169
170                 public static LONG_ARRAY_SERIALIZER INSTANCE = new LONG_ARRAY_SERIALIZER();
171
172                 public LONG_ARRAY_SERIALIZER() {
173                         super(LONG_ARRAY_BINDING.INSTANCE);
174                 }
175                 
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;
185                         
186 //                      result[index+6] = (byte)(l & 0xFF);
187 //                      l >>>= 8;
188 //                      result[index+5] = (byte)(l & 0xFF);
189 //                      l >>>= 8;
190 //                      result[index+4] = (byte)(l & 0xFF);
191 //                      l >>>= 8;
192 //                      result[index+3] = (byte)(l & 0xFF);
193 //                      l >>>= 8;
194 //                      result[index+2] = (byte)(l & 0xFF);
195 //                      l >>>= 8;
196 //                      result[index+1] = (byte)(l & 0xFF);
197 //                      l >>>= 8;
198 //                      result[index] = (byte)(l & 0xFF);
199 //                      l >>>= 8;
200                 }
201                 
202                 @Override
203                 public byte[] serialize(Object obj) throws IOException {
204                         
205                         long[] data = (long[])obj;
206                         byte[] result = new byte[4+8*data.length];
207                         
208                         int len = data.length;
209                         
210                         result[3] = (byte)(len & 0xFF);
211                         len >>>= 8;
212                         result[2] = (byte)(len & 0xFF);
213                         len >>>= 8;
214                         result[1] = (byte)(len & 0xFF);
215                         len >>>= 8;
216                         result[0] = (byte)(len & 0xFF);
217
218                         int index = 4;
219
220                         for(int i=0;i<data.length;i++) {
221
222                                 loop(result, index, data[i]);
223
224 //                              long l = data[i];
225
226 //                              result[index+7] = (byte)(l & 0xFF);
227 //                              l >>>= 8;
228 //                              result[index+6] = (byte)(l & 0xFF);
229 //                              l >>>= 8;
230 //                              result[index+5] = (byte)(l & 0xFF);
231 //                              l >>>= 8;
232 //                              result[index+4] = (byte)(l & 0xFF);
233 //                              l >>>= 8;
234 //                              result[index+3] = (byte)(l & 0xFF);
235 //                              l >>>= 8;
236 //                              result[index+2] = (byte)(l & 0xFF);
237 //                              l >>>= 8;
238 //                              result[index+1] = (byte)(l & 0xFF);
239 //                              l >>>= 8;
240 //                              result[index] = (byte)(l & 0xFF);
241 //                              l >>>= 8;
242                                 
243                                 index += 8;
244
245                         }
246                         
247                         return result;
248
249                 }
250                 
251         }
252
253         static class TRANSFERABLE_GRAPH_SERIALIZER extends LongSerializer {
254
255                 public static TRANSFERABLE_GRAPH_SERIALIZER INSTANCE = new TRANSFERABLE_GRAPH_SERIALIZER();
256
257                 public TRANSFERABLE_GRAPH_SERIALIZER() {
258                         super(TRANSFERABLE_GRAPH_BINDING.INSTANCE);
259                 }
260
261                 @Override
262                 public byte[] serialize(Object obj) throws IOException {
263                         TransferableGraph1 tg = (TransferableGraph1)obj;
264                         return Bindings
265                                         .getSerializerUnchecked(TransferableGraph1.class)
266                                         .serialize(tg);
267                 }
268
269                 final private String utf(byte[] bytes) {
270                         
271                         char[] chars = new char[bytes.length];
272                         
273                         int index = 0;
274                         int length = bytes[index++]&0xff; 
275                         if(length >= 0x80) {
276                                 if(length >= 0xc0) {
277                                         if(length >= 0xe0) {
278                                                 if(length >= 0xf0) {
279                                                         length &= 0x0f;
280                                                         length += ((bytes[index++]&0xff)<<3);
281                                                         length += ((bytes[index++]&0xff)<<11);
282                                                         length += ((bytes[index++]&0xff)<<19);
283                                                         length += 0x10204080;
284                                                 }
285                                                 else {
286                                                         length &= 0x1f;
287                                                         length += ((bytes[index++]&0xff)<<4);
288                                                         length += ((bytes[index++]&0xff)<<12);
289                                                         length += ((bytes[index++]&0xff)<<20);
290                                                         length += 0x204080;
291                                                 }
292                                         }
293                                         else {
294                                                 length &= 0x3f;
295                                                 length += ((bytes[index++]&0xff)<<5);
296                                                 length += ((bytes[index++]&0xff)<<13);
297                                                 length += 0x4080;
298                                         }
299                                 }
300                                 else {
301                                         length &= 0x7f;
302                                         length += ((bytes[index++]&0xff)<<6);
303                                         length += 0x80;
304                                 }
305                         }
306                         
307                         int i = 0;
308                         int target = length+index;
309                         while(index < target) {
310                                 int c = bytes[index++]&0xff;
311                                 if(c <= 0x7F) {
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)); 
317                                 } else {
318                                         int c2 = bytes[index++]&0xff;
319                                         chars[i++] = (char)(((c&0x1f)<<6) + (c2&0x3f)); 
320                                 }
321                                 
322                         }
323                         
324                         return new String(chars, 0, i);
325                         
326                 }
327
328                 
329                 @Override
330                 public Object deserialize(byte[] data) throws IOException {
331                         return utf(data);
332                 }
333                 
334         }
335
336         static class STRING_BINDING extends StringBindingDefault {
337                 
338                 public static STRING_BINDING INSTANCE = new STRING_BINDING();
339                 
340                 public STRING_BINDING() {
341                         super(Datatypes.STRING);
342                 }
343                 
344                 @Override
345                 public Serializer serializer() throws RuntimeSerializerConstructionException {
346                         
347                         return STRING_SERIALIZER.INSTANCE;
348                         
349                 }
350                 
351                 @Override
352                 public boolean isInstance(Object obj) {
353                         return obj instanceof String;
354                 }
355                 
356         }
357         
358         static class BYTE_ARRAY_BINDING extends LongBindingDefault {
359                 
360                 public static BYTE_ARRAY_BINDING INSTANCE = new BYTE_ARRAY_BINDING();
361                 
362                 public BYTE_ARRAY_BINDING() {
363                         super(Datatypes.LONG);
364                 }
365                 
366                 @Override
367                 public Serializer serializer() throws RuntimeSerializerConstructionException {
368                         
369                         return BYTE_ARRAY_SERIALIZER.INSTANCE;
370                         
371                 }
372                 
373                 @Override
374                 public boolean isInstance(Object obj) {
375                         return obj instanceof byte[];
376                 }
377                 
378         }
379
380         static class LONG_ARRAY_BINDING extends LongBindingDefault {
381                 
382                 public static LONG_ARRAY_BINDING INSTANCE = new LONG_ARRAY_BINDING();
383                 
384                 public LONG_ARRAY_BINDING() {
385                         super(Datatypes.LONG);
386                 }
387                 
388                 @Override
389                 public Serializer serializer() throws RuntimeSerializerConstructionException {
390                         
391                         return LONG_ARRAY_SERIALIZER.INSTANCE;
392                         
393                 }
394                 
395         }
396
397         
398         static class TRANSFERABLE_GRAPH_BINDING extends LongBindingDefault {
399                 
400                 public static TRANSFERABLE_GRAPH_BINDING INSTANCE = new TRANSFERABLE_GRAPH_BINDING();
401                 
402                 public TRANSFERABLE_GRAPH_BINDING() {
403                         super(Datatypes.LONG);
404                 }
405                 
406                 @Override
407                 public Serializer serializer() throws RuntimeSerializerConstructionException {
408                         
409                         return TRANSFERABLE_GRAPH_SERIALIZER.INSTANCE;
410                         
411                 }
412                 
413         }
414
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;
419
420         public static void main(String[] args) {
421
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)) });
429
430                 try {
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
435                         e.printStackTrace();
436                 } catch (IOException e) {
437                         // TODO Auto-generated catch block
438                         e.printStackTrace();
439                 } catch (BindingConstructionException e) {
440                         // TODO Auto-generated catch block
441                         e.printStackTrace();
442                 }
443                 
444         }
445         
446 }