]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraph1Serializer.java
770d6c6cab10b5844d7f9485e7476cac1e97cb4e
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / TransferableGraph1Serializer.java
1 package org.simantics.graph.representation;
2
3
4 import gnu.trove.map.hash.TObjectIntHashMap;
5
6 import java.io.DataInput;
7 import java.io.DataOutput;
8 import java.io.File;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.UTFDataFormatException;
12 import java.util.List;
13
14 import org.simantics.databoard.Bindings;
15 import org.simantics.databoard.serialization.Serializer;
16
17 public class TransferableGraph1Serializer extends Serializer {
18
19     public static final TransferableGraph1Serializer INSTANCE = 
20             new TransferableGraph1Serializer();
21     
22     private TransferableGraph1Serializer() {}
23     
24         static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException {
25                 
26                 int strlen = str.length();
27                 int utflen = 0;
28                 int c;
29                 int count = byteIndex;
30
31                 /* use charAt instead of copying String to char array */
32                 for (int i = 0; i < strlen; i++) {
33                         c = str.charAt(i);
34                         if ((c >= 0x0001) && (c <= 0x007F)) {
35                                 utflen++;
36                         } else if (c > 0x07FF) {
37                                 utflen += 3;
38                         } else {
39                                 utflen += 2;
40                         }
41                 }
42
43                 if (utflen > 65535)
44                         throw new UTFDataFormatException(
45                                         "encoded string too long: " + utflen + " bytes");
46
47                 if(utflen < 0x80) {
48                         bytearr[count++] = ((byte)utflen);
49                 }
50                 else {
51                         utflen -= 0x80;
52                         if(utflen < 0x4000) {
53                                 bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) );
54                                 bytearr[count++] = (byte)( (utflen>>>6) );
55                         }
56                         else {
57                                 utflen -= 0x4000;
58                                 if(utflen < 0x200000) {
59                                         bytearr[count++] = (byte)( ((utflen&0x1f) | 0xc0) );
60                                         bytearr[count++] = (byte)( ((utflen>>>5)&0xff) );
61                                         bytearr[count++] = (byte)( ((utflen>>>13)&0xff) );      
62                                 }
63                                 else {
64                                         utflen -= 0x200000;
65                                         if(utflen < 0x10000000) {
66                                                 bytearr[count++] = (byte)( ((utflen&0x0f) | 0xe0) );
67                                                 bytearr[count++] = (byte)( ((utflen>>>4)&0xff) );
68                                                 bytearr[count++] = (byte)( ((utflen>>>12)&0xff) );      
69                                                 bytearr[count++] = (byte)( ((utflen>>>20)&0xff) );
70                                         }
71                                         else {
72                                                 utflen -= 0x10000000;
73                                                 bytearr[count++] = (byte)( ((utflen&0x07) | 0xf0) );
74                                                 bytearr[count++] = (byte)( ((utflen>>>3)&0xff) );
75                                                 bytearr[count++] = (byte)( ((utflen>>>11)&0xff) );      
76                                                 bytearr[count++] = (byte)( ((utflen>>>19)&0xff) );
77                                                 bytearr[count++] = (byte)( ((utflen>>>27)&0xff) );
78                                         }
79                                 }                               
80                         }
81                 }       
82
83                 int i=0;
84                 for (i=0; i<strlen; i++) {
85                         c = str.charAt(i);
86                         if (!((c >= 0x0001) && (c <= 0x007F))) break;
87                         bytearr[count++] = (byte) c;
88                 }
89
90                 for (;i < strlen; i++){
91                         c = str.charAt(i);
92                         if ((c >= 0x0001) && (c <= 0x007F)) {
93                                 bytearr[count++] = (byte) c;
94
95                         } else if (c > 0x07FF) {
96                                 bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
97                                 bytearr[count++] = (byte) (0x80 | ((c >>  6) & 0x3F));
98                                 bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
99                         } else {
100                                 bytearr[count++] = (byte) (0xC0 | ((c >>  6) & 0x1F));
101                                 bytearr[count++] = (byte) (0x80 | ((c >>  0) & 0x3F));
102                         }
103                 }
104                 
105                 return count - byteIndex;
106                 
107         }
108         
109         @Override
110         public Object deserialize(File file) throws IOException {
111                 TransferableGraphFileReader reader = new TransferableGraphFileReader(file);
112                 try {
113                         return reader.readTG();
114                 } finally {
115                         reader.close();
116                 }
117         }
118         
119         public Object deserialize(InputStream in) throws IOException {
120                 TransferableGraphFileReader reader = new TransferableGraphFileReader(in);
121                 try {
122                         return reader.readTG();
123                 } finally {
124                         reader.close();
125                 }
126         }
127         
128         @Override
129         public byte[] serialize(Object obj) throws IOException {
130                 
131                 TransferableGraph1 tg = (TransferableGraph1)obj;
132
133                 Extensions ex = new Extensions(tg.extensions);
134                 byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);
135
136                 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
137                 
138                 int actualSize = 16 + 4*tg.values.length + 4*tg.statements.length + 5*tg.identities.length + extensions.length;
139                 for(Value v : tg.values) actualSize += variantSerializer.getSize(v.value);
140                 for(Identity id : tg.identities) { 
141                         if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5);
142                         else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5);
143                         else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10);
144                         else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5);
145                 }
146                 
147                 byte[] bytes = new byte[actualSize];
148                 int byteIndex = 0;
149
150                 int i = tg.resourceCount;
151                 
152                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
153                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
154                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
155                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
156                 byteIndex+=4;
157                 
158                 i = tg.identities.length;
159
160                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
161                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
162                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
163                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
164                 byteIndex+=4;
165                 
166                 for(Identity id : tg.identities) {
167
168                         i = id.resource;
169                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
170                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
171                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
172                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
173                         byteIndex+=4;
174                         
175                         if(id.definition instanceof Internal) {
176
177                                 Internal r = (Internal)id.definition;
178
179                                 bytes[byteIndex++] = 3;
180
181                                 i = r.parent;
182                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
183                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
184                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
185                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
186                                 byteIndex+=4;
187                                 
188                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
189
190                         } else if(id.definition instanceof External) {
191
192                                 External r = (External)id.definition;
193
194                                 bytes[byteIndex++] = 1;
195
196                                 i = r.parent;
197                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
198                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
199                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
200                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
201                                 byteIndex+=4;
202                                 
203                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
204                                 
205                         } else if(id.definition instanceof Root) {
206                                 
207                                 bytes[byteIndex++] = 0;
208                                 
209                                 Root r = (Root)id.definition;
210                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
211                                 byteIndex += writeUTF(r.type, bytes, byteIndex);
212                                 
213                         } else if(id.definition instanceof Optional) {
214
215                                 Optional r = (Optional)id.definition;
216
217                                 bytes[byteIndex++] = 2;
218
219                                 i = r.parent;
220                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
221                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
222                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
223                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
224                                 byteIndex+=4;
225                                 
226                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
227                                 
228                         }
229                         
230                 }
231                 
232                 i = tg.statements.length;
233                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
234                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
235                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
236                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
237                 byteIndex+=4;
238                 
239                 for(int s : tg.statements) {
240                         i = s;
241                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
242                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
243                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
244                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
245                         byteIndex+=4;
246                 }
247
248                 i = tg.values.length;
249                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
250                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
251                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
252                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
253                 byteIndex+=4;
254                 
255                 for(Value v : tg.values) {
256                         
257                         i = v.resource;
258                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
259                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
260                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
261                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
262                         byteIndex+=4;
263
264                         byte[] temp = variantSerializer.serialize(v.value);
265                         System.arraycopy(temp, 0, bytes, byteIndex, temp.length);
266                         byteIndex += temp.length;                       
267                 }
268
269                 System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);
270                 
271                 return bytes; 
272                 
273         }
274         
275         @Override
276         public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,
277                         Object obj) throws IOException {
278                 TransferableGraph1.SERIALIZER.serialize(out, identities, obj);
279         }
280
281         @Override
282         public void serialize(DataOutput out, Object obj) throws IOException {
283                 TransferableGraph1.SERIALIZER.serialize(out, obj);
284         }
285
286         @Override
287         public Object deserialize(DataInput in, List<Object> identities)
288                         throws IOException {
289                 return TransferableGraph1.SERIALIZER.deserialize(in, identities);
290         }
291
292         @Override
293         public Object deserialize(DataInput in) throws IOException {
294                 return TransferableGraph1.SERIALIZER.deserialize(in);
295         }
296
297         @Override
298         public void deserializeTo(DataInput in, List<Object> identities, Object obj)
299                         throws IOException {
300                 TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);
301         }
302
303         @Override
304         public void deserializeTo(DataInput in, Object obj) throws IOException {
305                 TransferableGraph1.SERIALIZER.deserializeTo(in, obj);
306         }
307
308         @Override
309         public void skip(DataInput in, List<Object> identities) throws IOException {
310                 TransferableGraph1.SERIALIZER.skip(in, identities);
311         }
312
313         @Override
314         public void skip(DataInput in) throws IOException {
315                 TransferableGraph1.SERIALIZER.skip(in);
316         }
317
318         @Override
319         public Integer getConstantSize() {
320                 return TransferableGraph1.SERIALIZER.getConstantSize();
321         }
322
323         @Override
324         public int getSize(Object obj, TObjectIntHashMap<Object> identities)
325                         throws IOException {
326                 return TransferableGraph1.SERIALIZER.getSize(obj, identities);
327         }
328
329         @Override
330         public int getSize(Object obj) throws IOException {
331                 return TransferableGraph1.SERIALIZER.getSize(obj);
332         }
333
334         @Override
335         public int getMinSize() {
336                 return TransferableGraph1.SERIALIZER.getMinSize();
337         }
338
339 }