]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraph1Serializer.java
Finalizing improve startup time for fresh or rollback'd session
[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                 return TransferableGraphFileReader.read(file);
112         }
113         
114         public Object deserialize(InputStream in) throws IOException {
115                 return TransferableGraphFileReader.read(in);
116         }
117         
118         @Override
119         public byte[] serialize(Object obj) throws IOException {
120                 
121                 TransferableGraph1 tg = (TransferableGraph1)obj;
122
123                 Extensions ex = new Extensions(tg.extensions);
124                 byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);
125
126                 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
127                 
128                 int actualSize = 16 + 4*tg.values.length + 4*tg.statements.length + 5*tg.identities.length + extensions.length;
129                 for(Value v : tg.values) actualSize += variantSerializer.getSize(v.value);
130                 for(Identity id : tg.identities) { 
131                         if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5);
132                         else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5);
133                         else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10);
134                         else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5);
135                 }
136                 
137                 byte[] bytes = new byte[actualSize];
138                 int byteIndex = 0;
139
140                 int i = tg.resourceCount;
141                 
142                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
143                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
144                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
145                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
146                 byteIndex+=4;
147                 
148                 i = tg.identities.length;
149
150                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
151                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
152                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
153                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
154                 byteIndex+=4;
155                 
156                 for(Identity id : tg.identities) {
157
158                         i = id.resource;
159                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
160                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
161                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
162                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
163                         byteIndex+=4;
164                         
165                         if(id.definition instanceof Internal) {
166
167                                 Internal r = (Internal)id.definition;
168
169                                 bytes[byteIndex++] = 3;
170
171                                 i = r.parent;
172                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
173                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
174                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
175                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
176                                 byteIndex+=4;
177                                 
178                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
179
180                         } else if(id.definition instanceof External) {
181
182                                 External r = (External)id.definition;
183
184                                 bytes[byteIndex++] = 1;
185
186                                 i = r.parent;
187                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
188                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
189                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
190                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
191                                 byteIndex+=4;
192                                 
193                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
194                                 
195                         } else if(id.definition instanceof Root) {
196                                 
197                                 bytes[byteIndex++] = 0;
198                                 
199                                 Root r = (Root)id.definition;
200                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
201                                 byteIndex += writeUTF(r.type, bytes, byteIndex);
202                                 
203                         } else if(id.definition instanceof Optional) {
204
205                                 Optional r = (Optional)id.definition;
206
207                                 bytes[byteIndex++] = 2;
208
209                                 i = r.parent;
210                                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
211                                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
212                                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
213                                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
214                                 byteIndex+=4;
215                                 
216                                 byteIndex += writeUTF(r.name, bytes, byteIndex);
217                                 
218                         }
219                         
220                 }
221                 
222                 i = tg.statements.length;
223                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
224                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
225                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
226                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
227                 byteIndex+=4;
228                 
229                 for(int s : tg.statements) {
230                         i = s;
231                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
232                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
233                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
234                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
235                         byteIndex+=4;
236                 }
237
238                 i = tg.values.length;
239                 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
240                 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
241                 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
242                 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
243                 byteIndex+=4;
244                 
245                 for(Value v : tg.values) {
246                         
247                         i = v.resource;
248                         bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
249                         bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
250                         bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
251                         bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
252                         byteIndex+=4;
253
254                         byte[] temp = variantSerializer.serialize(v.value);
255                         System.arraycopy(temp, 0, bytes, byteIndex, temp.length);
256                         byteIndex += temp.length;                       
257                 }
258
259                 System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);
260                 
261                 return bytes; 
262                 
263         }
264         
265         @Override
266         public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,
267                         Object obj) throws IOException {
268                 TransferableGraph1.SERIALIZER.serialize(out, identities, obj);
269         }
270
271         @Override
272         public void serialize(DataOutput out, Object obj) throws IOException {
273                 TransferableGraph1.SERIALIZER.serialize(out, obj);
274         }
275
276         @Override
277         public Object deserialize(DataInput in, List<Object> identities)
278                         throws IOException {
279                 return TransferableGraph1.SERIALIZER.deserialize(in, identities);
280         }
281
282         @Override
283         public Object deserialize(DataInput in) throws IOException {
284                 return TransferableGraph1.SERIALIZER.deserialize(in);
285         }
286
287         @Override
288         public void deserializeTo(DataInput in, List<Object> identities, Object obj)
289                         throws IOException {
290                 TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);
291         }
292
293         @Override
294         public void deserializeTo(DataInput in, Object obj) throws IOException {
295                 TransferableGraph1.SERIALIZER.deserializeTo(in, obj);
296         }
297
298         @Override
299         public void skip(DataInput in, List<Object> identities) throws IOException {
300                 TransferableGraph1.SERIALIZER.skip(in, identities);
301         }
302
303         @Override
304         public void skip(DataInput in) throws IOException {
305                 TransferableGraph1.SERIALIZER.skip(in);
306         }
307
308         @Override
309         public Integer getConstantSize() {
310                 return TransferableGraph1.SERIALIZER.getConstantSize();
311         }
312
313         @Override
314         public int getSize(Object obj, TObjectIntHashMap<Object> identities)
315                         throws IOException {
316                 return TransferableGraph1.SERIALIZER.getSize(obj, identities);
317         }
318
319         @Override
320         public int getSize(Object obj) throws IOException {
321                 return TransferableGraph1.SERIALIZER.getSize(obj);
322         }
323
324         @Override
325         public int getMinSize() {
326                 return TransferableGraph1.SERIALIZER.getMinSize();
327         }
328
329 }