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 return TransferableGraphFileReader.read(file);
114 public Object deserialize(InputStream in) throws IOException {
115 return TransferableGraphFileReader.read(in);
119 public byte[] serialize(Object obj) throws IOException {
121 TransferableGraph1 tg = (TransferableGraph1)obj;
123 Extensions ex = new Extensions(tg.extensions);
124 byte[] extensions = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked(Extensions.class)).serialize(ex);
126 Serializer variantSerializer = Bindings.getSerializerUnchecked(Bindings.VARIANT);
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);
137 byte[] bytes = new byte[actualSize];
140 int i = tg.resourceCount;
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;
148 i = tg.identities.length;
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;
156 for(Identity id : tg.identities) {
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;
165 if(id.definition instanceof Internal) {
167 Internal r = (Internal)id.definition;
169 bytes[byteIndex++] = 3;
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;
178 byteIndex += writeUTF(r.name, bytes, byteIndex);
180 } else if(id.definition instanceof External) {
182 External r = (External)id.definition;
184 bytes[byteIndex++] = 1;
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;
193 byteIndex += writeUTF(r.name, bytes, byteIndex);
195 } else if(id.definition instanceof Root) {
197 bytes[byteIndex++] = 0;
199 Root r = (Root)id.definition;
200 byteIndex += writeUTF(r.name, bytes, byteIndex);
201 byteIndex += writeUTF(r.type, bytes, byteIndex);
203 } else if(id.definition instanceof Optional) {
205 Optional r = (Optional)id.definition;
207 bytes[byteIndex++] = 2;
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;
216 byteIndex += writeUTF(r.name, bytes, byteIndex);
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;
229 for(int s : tg.statements) {
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;
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;
245 for(Value v : tg.values) {
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;
254 byte[] temp = variantSerializer.serialize(v.value);
255 System.arraycopy(temp, 0, bytes, byteIndex, temp.length);
256 byteIndex += temp.length;
259 System.arraycopy(extensions, 0, bytes, byteIndex, extensions.length);
266 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities,
267 Object obj) throws IOException {
268 TransferableGraph1.SERIALIZER.serialize(out, identities, obj);
272 public void serialize(DataOutput out, Object obj) throws IOException {
273 TransferableGraph1.SERIALIZER.serialize(out, obj);
277 public Object deserialize(DataInput in, List<Object> identities)
279 return TransferableGraph1.SERIALIZER.deserialize(in, identities);
283 public Object deserialize(DataInput in) throws IOException {
284 return TransferableGraph1.SERIALIZER.deserialize(in);
288 public void deserializeTo(DataInput in, List<Object> identities, Object obj)
290 TransferableGraph1.SERIALIZER.deserializeTo(in, identities, obj);
294 public void deserializeTo(DataInput in, Object obj) throws IOException {
295 TransferableGraph1.SERIALIZER.deserializeTo(in, obj);
299 public void skip(DataInput in, List<Object> identities) throws IOException {
300 TransferableGraph1.SERIALIZER.skip(in, identities);
304 public void skip(DataInput in) throws IOException {
305 TransferableGraph1.SERIALIZER.skip(in);
309 public Integer getConstantSize() {
310 return TransferableGraph1.SERIALIZER.getConstantSize();
314 public int getSize(Object obj, TObjectIntHashMap<Object> identities)
316 return TransferableGraph1.SERIALIZER.getSize(obj, identities);
320 public int getSize(Object obj) throws IOException {
321 return TransferableGraph1.SERIALIZER.getSize(obj);
325 public int getMinSize() {
326 return TransferableGraph1.SERIALIZER.getMinSize();