]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/ReferableRecordSerializer.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/ReferableRecordSerializer.java
new file mode 100644 (file)
index 0000000..c379994
--- /dev/null
@@ -0,0 +1,164 @@
+package org.simantics.databoard.serialization.impl;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+\r
+import java.io.DataInput;\r
+import java.io.DataOutput;\r
+import java.io.IOException;\r
+import java.util.List;\r
+\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.serialization.SerializationException;\r
+import org.simantics.databoard.serialization.Serializer;\r
+import org.simantics.databoard.serialization.Serializer.RecursiveSerializer;\r
+import org.simantics.databoard.type.RecordType;\r
+\r
+public class ReferableRecordSerializer extends RecursiveSerializer {\r
+\r
+       RecordBinding binding;\r
+       public Serializer[] componentSerializers;\r
+       \r
+       /** The combined size elements, or <code>null</code> */ \r
+       Integer fixedSizeOfContent;\r
+       int minContentSize;\r
+       \r
+       public ReferableRecordSerializer(RecordBinding binding, Serializer[] componentSerializers) {\r
+               this.binding = binding;\r
+               this.componentSerializers = componentSerializers;\r
+       }\r
+       \r
+       @Override\r
+       public void finalizeConstruction() {\r
+               fixedSizeOfContent = null;\r
+               for (Serializer componentSerializer : componentSerializers) {\r
+                       minContentSize += componentSerializer.getMinSize();\r
+                       Integer componentFixedSize = componentSerializer.getConstantSize();\r
+                       if (componentFixedSize==null) {\r
+                               fixedSizeOfContent = null;\r
+                               break;\r
+                       }\r
+                       fixedSizeOfContent = fixedSizeOfContent==null ? componentFixedSize : fixedSizeOfContent + componentFixedSize; \r
+               }\r
+       }\r
+\r
+       boolean referable() {\r
+               return ((RecordType)binding.type()).isReferable();\r
+       }\r
+       \r
+       @Override\r
+       public Object deserialize(DataInput in, List<Object> identities) throws IOException {\r
+               try {\r
+                       int id = in.readInt();\r
+                       if(id > 0)\r
+                               return identities.get(id-1);                    \r
+                       \r
+                       Object result = binding.createPartial();\r
+                       identities.add(result);\r
+                       \r
+//                     assertRemainingBytes(in, minContentSize);\r
+                       Object[] temp = new Object[componentSerializers.length];\r
+                       for(int i=0;i<componentSerializers.length;++i)\r
+                               temp[i] = componentSerializers[i].deserialize(in, identities);\r
+                       binding.setComponents(result, temp);\r
+                       \r
+                       return result;\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public void deserializeTo(DataInput in, List<Object> identities,\r
+                       Object obj) throws IOException {\r
+               try {\r
+                       int id = in.readInt();\r
+                       if(id > 0) {\r
+                               Object alreadyDeserializedObject = identities.get(id-1);\r
+                               if (alreadyDeserializedObject!=obj) {\r
+                                       for (int i=0; i<binding.getComponentCount(); ++i) {\r
+                                               Object component = binding.getComponent(alreadyDeserializedObject, i);\r
+                                               binding.setComponent(obj, i, component);\r
+                                       }\r
+                               }\r
+                               return;\r
+                       }\r
+                       \r
+                       identities.add(obj);\r
+//                     assertRemainingBytes(in, minContentSize);\r
+                       for(int i=0;i<componentSerializers.length;++i) {\r
+                               Serializer cs = componentSerializers[i];\r
+                               boolean csImmutable = binding.getComponentBinding(i).isImmutable();\r
+                               if (csImmutable) {\r
+                                       Object component = cs.deserialize(in, identities);\r
+                                       binding.setComponent(obj, i, component);\r
+                               } else {\r
+                                       Object component = binding.getComponent(obj, i);\r
+                                       component = cs.deserializeToTry(in, identities, component);\r
+                                       binding.setComponent(obj, i, component);\r
+                               }\r
+                       }\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {\r
+               \r
+               int id = in.readInt();\r
+               if(id > 0) return;                      \r
+               \r
+               for(int i=0;i<componentSerializers.length;++i)\r
+                       componentSerializers[i].skip(in, identities);\r
+       }\r
+\r
+       @Override\r
+       public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {\r
+               try {\r
+                       int id = identities.get(obj);\r
+                       if(id > 0) {\r
+                               out.writeInt(id);\r
+                       }\r
+                       else {\r
+                               out.writeInt(0);\r
+                               identities.put(obj, identities.size() + 1);\r
+                               for(int i=0;i<componentSerializers.length;++i)\r
+                                       componentSerializers[i].serialize(out, identities, binding.getComponent(obj, i));\r
+                       }\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+                       \r
+       }\r
+\r
+       @Override\r
+       public Integer getConstantSize() {\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {\r
+               try {\r
+                       int id = identities.get(obj);\r
+                       if (id>0) return 4;\r
+                       identities.put(obj, identities.size()+1);\r
+                       if (fixedSizeOfContent!=null) return 4+fixedSizeOfContent;\r
+                       int result = 4;                 \r
+                       for(int i=0;i<componentSerializers.length;++i)\r
+                               result += componentSerializers[i].getSize( binding.getComponent(obj, i), identities );                  \r
+                       return result;\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+                       \r
+       }\r
+       \r
+       @Override\r
+       public int getMinSize() {\r
+               return 4;\r
+       }\r
+       \r
+}\r
+\r