1 package org.simantics.graph.representation;
4 import gnu.trove.map.hash.TObjectIntHashMap;
6 import java.io.DataInput;
7 import java.io.DataOutput;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.UTFDataFormatException;
12 import java.util.List;
14 import org.simantics.databoard.Bindings;
15 import org.simantics.databoard.serialization.Serializer;
17 public class TransferableGraph1Serializer extends Serializer {
19 public static final TransferableGraph1Serializer INSTANCE =
20 new TransferableGraph1Serializer();
22 private TransferableGraph1Serializer() {}
24 static int writeUTF(String str, byte[] bytearr, int byteIndex) throws IOException {
26 int strlen = str.length();
29 int count = byteIndex;
31 /* use charAt instead of copying String to char array */
32 for (int i = 0; i < strlen; i++) {
34 if ((c >= 0x0001) && (c <= 0x007F)) {
36 } else if (c > 0x07FF) {
44 throw new UTFDataFormatException(
45 "encoded string too long: " + utflen + " bytes");
48 bytearr[count++] = ((byte)utflen);
53 bytearr[count++] = (byte)( ((utflen&0x3f) | 0x80) );
54 bytearr[count++] = (byte)( (utflen>>>6) );
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) );
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) );
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) );
84 for (i=0; i<strlen; i++) {
86 if (!((c >= 0x0001) && (c <= 0x007F))) break;
87 bytearr[count++] = (byte) c;
90 for (;i < strlen; i++){
92 if ((c >= 0x0001) && (c <= 0x007F)) {
93 bytearr[count++] = (byte) c;
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));
100 bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
101 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
105 return count - byteIndex;
110 public Object deserialize(File file) throws IOException {
111 TransferableGraphFileReader reader = new TransferableGraphFileReader(file);
113 return reader.readTG();
119 public Object deserialize(InputStream in) throws IOException {
120 TransferableGraphFileReader reader = new TransferableGraphFileReader(in);
122 return reader.readTG();
129 public byte[] serialize(Object obj) throws IOException {
131 TransferableGraph1 tg = (TransferableGraph1)obj;
133 Extensions ex = new Extensions(tg.extensions);
134 byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);
136 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
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);
147 byte[] bytes = new byte[actualSize];
150 int i = tg.resourceCount;
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;
158 i = tg.identities.length;
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;
166 for(Identity id : tg.identities) {
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;
175 if(id.definition instanceof Internal) {
177 Internal r = (Internal)id.definition;
179 bytes[byteIndex++] = 3;
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;
188 byteIndex += writeUTF(r.name, bytes, byteIndex);
190 } else if(id.definition instanceof External) {
192 External r = (External)id.definition;
194 bytes[byteIndex++] = 1;
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;
203 byteIndex += writeUTF(r.name, bytes, byteIndex);
205 } else if(id.definition instanceof Root) {
207 bytes[byteIndex++] = 0;
209 Root r = (Root)id.definition;
210 byteIndex += writeUTF(r.name, bytes, byteIndex);
211 byteIndex += writeUTF(r.type, bytes, byteIndex);
213 } else if(id.definition instanceof Optional) {
215 Optional r = (Optional)id.definition;
217 bytes[byteIndex++] = 2;
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;
226 byteIndex += writeUTF(r.name, bytes, byteIndex);
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;
239 for(int s : tg.statements) {
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;
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;
255 for(Value v : tg.values) {
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;
264 byte[] temp = variantSerializer.serialize(v.value);
265 System.arraycopy(temp, 0, bytes, byteIndex, temp.length);
266 byteIndex += temp.length;
269 System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);
276 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,
277 Object obj) throws IOException {
278 TransferableGraph1.SERIALIZER.serialize(out, identities, obj);
282 public void serialize(DataOutput out, Object obj) throws IOException {
283 TransferableGraph1.SERIALIZER.serialize(out, obj);
287 public Object deserialize(DataInput in, List<Object> identities)
289 return TransferableGraph1.SERIALIZER.deserialize(in, identities);
293 public Object deserialize(DataInput in) throws IOException {
294 return TransferableGraph1.SERIALIZER.deserialize(in);
298 public void deserializeTo(DataInput in, List<Object> identities, Object obj)
300 TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);
304 public void deserializeTo(DataInput in, Object obj) throws IOException {
305 TransferableGraph1.SERIALIZER.deserializeTo(in, obj);
309 public void skip(DataInput in, List<Object> identities) throws IOException {
310 TransferableGraph1.SERIALIZER.skip(in, identities);
314 public void skip(DataInput in) throws IOException {
315 TransferableGraph1.SERIALIZER.skip(in);
319 public Integer getConstantSize() {
320 return TransferableGraph1.SERIALIZER.getConstantSize();
324 public int getSize(Object obj, TObjectIntHashMap<Object> identities)
326 return TransferableGraph1.SERIALIZER.getSize(obj, identities);
330 public int getSize(Object obj) throws IOException {
331 return TransferableGraph1.SERIALIZER.getSize(obj);
335 public int getMinSize() {
336 return TransferableGraph1.SERIALIZER.getMinSize();