]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/ReferableRecordSerializer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / serialization / impl / ReferableRecordSerializer.java
1 package org.simantics.databoard.serialization.impl;\r
2 \r
3 import gnu.trove.map.hash.TObjectIntHashMap;\r
4 \r
5 import java.io.DataInput;\r
6 import java.io.DataOutput;\r
7 import java.io.IOException;\r
8 import java.util.List;\r
9 \r
10 import org.simantics.databoard.binding.RecordBinding;\r
11 import org.simantics.databoard.binding.error.BindingException;\r
12 import org.simantics.databoard.serialization.SerializationException;\r
13 import org.simantics.databoard.serialization.Serializer;\r
14 import org.simantics.databoard.serialization.Serializer.RecursiveSerializer;\r
15 import org.simantics.databoard.type.RecordType;\r
16 \r
17 public class ReferableRecordSerializer extends RecursiveSerializer {\r
18 \r
19         RecordBinding binding;\r
20         public Serializer[] componentSerializers;\r
21         \r
22         /** The combined size elements, or <code>null</code> */ \r
23         Integer fixedSizeOfContent;\r
24         int minContentSize;\r
25         \r
26         public ReferableRecordSerializer(RecordBinding binding, Serializer[] componentSerializers) {\r
27                 this.binding = binding;\r
28                 this.componentSerializers = componentSerializers;\r
29         }\r
30         \r
31         @Override\r
32         public void finalizeConstruction() {\r
33                 fixedSizeOfContent = null;\r
34                 for (Serializer componentSerializer : componentSerializers) {\r
35                         minContentSize += componentSerializer.getMinSize();\r
36                         Integer componentFixedSize = componentSerializer.getConstantSize();\r
37                         if (componentFixedSize==null) {\r
38                                 fixedSizeOfContent = null;\r
39                                 break;\r
40                         }\r
41                         fixedSizeOfContent = fixedSizeOfContent==null ? componentFixedSize : fixedSizeOfContent + componentFixedSize; \r
42                 }\r
43         }\r
44 \r
45         boolean referable() {\r
46                 return ((RecordType)binding.type()).isReferable();\r
47         }\r
48         \r
49         @Override\r
50         public Object deserialize(DataInput in, List<Object> identities) throws IOException {\r
51                 try {\r
52                         int id = in.readInt();\r
53                         if(id > 0)\r
54                                 return identities.get(id-1);                    \r
55                         \r
56                         Object result = binding.createPartial();\r
57                         identities.add(result);\r
58                         \r
59 //                      assertRemainingBytes(in, minContentSize);\r
60                         Object[] temp = new Object[componentSerializers.length];\r
61                         for(int i=0;i<componentSerializers.length;++i)\r
62                                 temp[i] = componentSerializers[i].deserialize(in, identities);\r
63                         binding.setComponents(result, temp);\r
64                         \r
65                         return result;\r
66                 } catch (BindingException e) {\r
67                         throw new IOException( e ); \r
68                 }\r
69         }\r
70         \r
71         @Override\r
72         public void deserializeTo(DataInput in, List<Object> identities,\r
73                         Object obj) throws IOException {\r
74                 try {\r
75                         int id = in.readInt();\r
76                         if(id > 0) {\r
77                                 Object alreadyDeserializedObject = identities.get(id-1);\r
78                                 if (alreadyDeserializedObject!=obj) {\r
79                                         for (int i=0; i<binding.getComponentCount(); ++i) {\r
80                                                 Object component = binding.getComponent(alreadyDeserializedObject, i);\r
81                                                 binding.setComponent(obj, i, component);\r
82                                         }\r
83                                 }\r
84                                 return;\r
85                         }\r
86                         \r
87                         identities.add(obj);\r
88 //                      assertRemainingBytes(in, minContentSize);\r
89                         for(int i=0;i<componentSerializers.length;++i) {\r
90                                 Serializer cs = componentSerializers[i];\r
91                                 boolean csImmutable = binding.getComponentBinding(i).isImmutable();\r
92                                 if (csImmutable) {\r
93                                         Object component = cs.deserialize(in, identities);\r
94                                         binding.setComponent(obj, i, component);\r
95                                 } else {\r
96                                         Object component = binding.getComponent(obj, i);\r
97                                         component = cs.deserializeToTry(in, identities, component);\r
98                                         binding.setComponent(obj, i, component);\r
99                                 }\r
100                         }\r
101                 } catch (BindingException e) {\r
102                         throw new IOException( e ); \r
103                 }\r
104                 \r
105         }\r
106         \r
107         @Override\r
108         public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {\r
109                 \r
110                 int id = in.readInt();\r
111                 if(id > 0) return;                      \r
112                 \r
113                 for(int i=0;i<componentSerializers.length;++i)\r
114                         componentSerializers[i].skip(in, identities);\r
115         }\r
116 \r
117         @Override\r
118         public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {\r
119                 try {\r
120                         int id = identities.get(obj);\r
121                         if(id > 0) {\r
122                                 out.writeInt(id);\r
123                         }\r
124                         else {\r
125                                 out.writeInt(0);\r
126                                 identities.put(obj, identities.size() + 1);\r
127                                 for(int i=0;i<componentSerializers.length;++i)\r
128                                         componentSerializers[i].serialize(out, identities, binding.getComponent(obj, i));\r
129                         }\r
130                 } catch (BindingException e) {\r
131                         throw new IOException( e ); \r
132                 }\r
133                         \r
134         }\r
135 \r
136         @Override\r
137         public Integer getConstantSize() {\r
138                 return null;\r
139         }\r
140 \r
141         @Override\r
142         public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {\r
143                 try {\r
144                         int id = identities.get(obj);\r
145                         if (id>0) return 4;\r
146                         identities.put(obj, identities.size()+1);\r
147                         if (fixedSizeOfContent!=null) return 4+fixedSizeOfContent;\r
148                         int result = 4;                 \r
149                         for(int i=0;i<componentSerializers.length;++i)\r
150                                 result += componentSerializers[i].getSize( binding.getComponent(obj, i), identities );                  \r
151                         return result;\r
152                 } catch (BindingException e) {\r
153                         throw new IOException( e ); \r
154                 }\r
155                         \r
156         }\r
157         \r
158         @Override\r
159         public int getMinSize() {\r
160                 return 4;\r
161         }\r
162         \r
163 }\r
164 \r