1 package org.simantics.graph.representation;
\r
4 import gnu.trove.map.hash.TObjectIntHashMap;
\r
6 import java.io.DataInput;
\r
7 import java.io.DataOutput;
\r
9 import java.io.IOException;
\r
10 import java.io.InputStream;
\r
11 import java.io.UTFDataFormatException;
\r
12 import java.util.List;
\r
14 import org.simantics.databoard.Bindings;
\r
15 import org.simantics.databoard.serialization.Serializer;
\r
17 public class TransferableGraph1Serializer extends Serializer {
\r
19 public static final TransferableGraph1Serializer INSTANCE =
\r
20 new TransferableGraph1Serializer();
\r
22 private TransferableGraph1Serializer() {}
\r
24 static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException {
\r
26 int strlen = str.length();
\r
29 int count = byteIndex;
\r
31 /* use charAt instead of copying String to char array */
\r
32 for (int i = 0; i < strlen; i++) {
\r
34 if ((c >= 0x0001) && (c <= 0x007F)) {
\r
36 } else if (c > 0x07FF) {
\r
44 throw new UTFDataFormatException(
\r
45 "encoded string too long: " + utflen + " bytes");
\r
48 bytearr[count++] = ((byte)utflen);
\r
52 if(utflen < 0x4000) {
\r
53 bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) );
\r
54 bytearr[count++] = (byte)( (utflen>>>6) );
\r
58 if(utflen < 0x200000) {
\r
59 bytearr[count++] = (byte)( ((utflen&0x1f) | 0xc0) );
\r
60 bytearr[count++] = (byte)( ((utflen>>>5)&0xff) );
\r
61 bytearr[count++] = (byte)( ((utflen>>>13)&0xff) );
\r
65 if(utflen < 0x10000000) {
\r
66 bytearr[count++] = (byte)( ((utflen&0x0f) | 0xe0) );
\r
67 bytearr[count++] = (byte)( ((utflen>>>4)&0xff) );
\r
68 bytearr[count++] = (byte)( ((utflen>>>12)&0xff) );
\r
69 bytearr[count++] = (byte)( ((utflen>>>20)&0xff) );
\r
72 utflen -= 0x10000000;
\r
73 bytearr[count++] = (byte)( ((utflen&0x07) | 0xf0) );
\r
74 bytearr[count++] = (byte)( ((utflen>>>3)&0xff) );
\r
75 bytearr[count++] = (byte)( ((utflen>>>11)&0xff) );
\r
76 bytearr[count++] = (byte)( ((utflen>>>19)&0xff) );
\r
77 bytearr[count++] = (byte)( ((utflen>>>27)&0xff) );
\r
84 for (i=0; i<strlen; i++) {
\r
86 if (!((c >= 0x0001) && (c <= 0x007F))) break;
\r
87 bytearr[count++] = (byte) c;
\r
90 for (;i < strlen; i++){
\r
92 if ((c >= 0x0001) && (c <= 0x007F)) {
\r
93 bytearr[count++] = (byte) c;
\r
95 } else if (c > 0x07FF) {
\r
96 bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
\r
97 bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
\r
98 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
\r
100 bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
\r
101 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
\r
105 return count - byteIndex;
\r
110 public Object deserialize(File file) throws IOException {
\r
111 TransferableGraphFileReader reader = new TransferableGraphFileReader(file);
\r
113 return reader.readTG();
\r
119 public Object deserialize(InputStream in) throws IOException {
\r
120 TransferableGraphFileReader reader = new TransferableGraphFileReader(in);
\r
122 return reader.readTG();
\r
129 public byte[] serialize(Object obj) throws IOException {
\r
131 TransferableGraph1 tg = (TransferableGraph1)obj;
\r
133 Extensions ex = new Extensions(tg.extensions);
\r
134 byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);
\r
136 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
\r
138 int actualSize = 16 + 4*tg.values.length + 4*tg.statements.length + 5*tg.identities.length + extensions.length;
\r
139 for(Value v : tg.values) actualSize += variantSerializer.getSize(v.value);
\r
140 for(Identity id : tg.identities) {
\r
141 if(id.definition instanceof Internal) actualSize += (4 + ((Internal)id.definition).name.length() + 5);
\r
142 else if(id.definition instanceof External) actualSize += (4 + ((External)id.definition).name.length() + 5);
\r
143 else if(id.definition instanceof Root) actualSize += (((Root)id.definition).name.length() + ((Root)id.definition).type.length() + 10);
\r
144 else if(id.definition instanceof Optional) actualSize += (4 + ((Optional)id.definition).name.length() + 5);
\r
147 byte[] bytes = new byte[actualSize];
\r
150 int i = tg.resourceCount;
\r
152 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
153 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
154 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
155 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
158 i = tg.identities.length;
\r
160 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
161 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
162 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
163 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
166 for(Identity id : tg.identities) {
\r
169 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
170 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
171 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
172 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
175 if(id.definition instanceof Internal) {
\r
177 Internal r = (Internal)id.definition;
\r
179 bytes[byteIndex++] = 3;
\r
182 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
183 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
184 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
185 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
188 byteIndex += writeUTF(r.name, bytes, byteIndex);
\r
190 } else if(id.definition instanceof External) {
\r
192 External r = (External)id.definition;
\r
194 bytes[byteIndex++] = 1;
\r
197 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
198 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
199 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
200 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
203 byteIndex += writeUTF(r.name, bytes, byteIndex);
\r
205 } else if(id.definition instanceof Root) {
\r
207 bytes[byteIndex++] = 0;
\r
209 Root r = (Root)id.definition;
\r
210 byteIndex += writeUTF(r.name, bytes, byteIndex);
\r
211 byteIndex += writeUTF(r.type, bytes, byteIndex);
\r
213 } else if(id.definition instanceof Optional) {
\r
215 Optional r = (Optional)id.definition;
\r
217 bytes[byteIndex++] = 2;
\r
220 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
221 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
222 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
223 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
226 byteIndex += writeUTF(r.name, bytes, byteIndex);
\r
232 i = tg.statements.length;
\r
233 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
234 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
235 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
236 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
239 for(int s : tg.statements) {
\r
241 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
242 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
243 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
244 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
248 i = tg.values.length;
\r
249 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
250 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
251 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
252 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
255 for(Value v : tg.values) {
\r
258 bytes[byteIndex+3] = (byte)(i & 0xFF);i >>>= 8;
\r
259 bytes[byteIndex+2] = (byte)(i & 0xFF);i >>>= 8;
\r
260 bytes[byteIndex+1] = (byte)(i & 0xFF);i >>>= 8;
\r
261 bytes[byteIndex] = (byte)(i & 0xFF);i >>>= 8;
\r
264 byte[] temp = variantSerializer.serialize(v.value);
\r
265 System.arraycopy(temp, 0, bytes, byteIndex, temp.length);
\r
266 byteIndex += temp.length;
\r
269 System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);
\r
276 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,
\r
277 Object obj) throws IOException {
\r
278 TransferableGraph1.SERIALIZER.serialize(out, identities, obj);
\r
282 public void serialize(DataOutput out, Object obj) throws IOException {
\r
283 TransferableGraph1.SERIALIZER.serialize(out, obj);
\r
287 public Object deserialize(DataInput in, List<Object> identities)
\r
288 throws IOException {
\r
289 return TransferableGraph1.SERIALIZER.deserialize(in, identities);
\r
293 public Object deserialize(DataInput in) throws IOException {
\r
294 return TransferableGraph1.SERIALIZER.deserialize(in);
\r
298 public void deserializeTo(DataInput in, List<Object> identities, Object obj)
\r
299 throws IOException {
\r
300 TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);
\r
304 public void deserializeTo(DataInput in, Object obj) throws IOException {
\r
305 TransferableGraph1.SERIALIZER.deserializeTo(in, obj);
\r
309 public void skip(DataInput in, List<Object> identities) throws IOException {
\r
310 TransferableGraph1.SERIALIZER.skip(in, identities);
\r
314 public void skip(DataInput in) throws IOException {
\r
315 TransferableGraph1.SERIALIZER.skip(in);
\r
319 public Integer getConstantSize() {
\r
320 return TransferableGraph1.SERIALIZER.getConstantSize();
\r
324 public int getSize(Object obj, TObjectIntHashMap<Object> identities)
\r
325 throws IOException {
\r
326 return TransferableGraph1.SERIALIZER.getSize(obj, identities);
\r
330 public int getSize(Object obj) throws IOException {
\r
331 return TransferableGraph1.SERIALIZER.getSize(obj);
\r
335 public int getMinSize() {
\r
336 return TransferableGraph1.SERIALIZER.getMinSize();
\r