]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/OptionalSerializer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / serialization / impl / OptionalSerializer.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/OptionalSerializer.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/serialization/impl/OptionalSerializer.java
new file mode 100644 (file)
index 0000000..ccf6e50
--- /dev/null
@@ -0,0 +1,129 @@
+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.OptionalBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.util.IsReferableQuery;\r
+import org.simantics.databoard.binding.util.Result;\r
+import org.simantics.databoard.serialization.SerializationException;\r
+import org.simantics.databoard.serialization.Serializer;\r
+import org.simantics.databoard.serialization.Serializer.CompositeSerializer;\r
+\r
+public class OptionalSerializer  extends CompositeSerializer {\r
+\r
+       OptionalBinding binding;\r
+       public Serializer componentSerializer;          \r
+       boolean componentImmutable;             \r
+       Integer fixedSize;\r
+       \r
+       /**\r
+        * Create optional serializer\r
+        * \r
+        * @param binding\r
+        * @param componentSerializer (optional), can be set after\r
+        */\r
+       public OptionalSerializer(OptionalBinding binding, Serializer componentSerializer) {\r
+               super( IsReferableQuery.isReferable( binding.type() ) != Result.No );\r
+               this.componentSerializer = componentSerializer;\r
+               this.binding = binding;\r
+               this.componentImmutable = binding.getComponentBinding().isImmutable();                  \r
+       }\r
+       \r
+       @Override\r
+       public void finalizeConstruction() {\r
+               Integer fixedSizeOfComponent = componentSerializer.getConstantSize();\r
+               if (fixedSizeOfComponent!=null && fixedSizeOfComponent==0) {\r
+                       fixedSize = fixedSizeOfComponent + 1;\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public Object deserialize(DataInput in, List<Object> identities) throws IOException {\r
+               try {\r
+                       byte x = in.readByte();\r
+                       if (x == 0) return binding.createNoValue();\r
+                       else if (x == 1) {\r
+                               Object componentValue = componentSerializer.deserialize(in, identities);\r
+                               return binding.createValue(componentValue);\r
+                       }\r
+                       else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");\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
+                       byte x = in.readByte();\r
+                       if (x == 0) {\r
+                               if (binding.hasValue(obj)) binding.setNoValue(obj);\r
+                       } else if (x == 1) {\r
+                               if (componentImmutable) {\r
+                                       Object component = componentSerializer.deserialize(in, identities);\r
+                                       binding.setValue(obj, component);\r
+                               } else {\r
+                                       Object component = binding.hasValue(obj) ? binding.getValue(obj) : binding.componentBinding.createDefault();\r
+                                       component = componentSerializer.deserializeToTry(in, identities, component);\r
+                                       binding.setValue(obj, component);\r
+                               }\r
+                               \r
+                       }\r
+                       else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {\r
+               int x = in.readByte();\r
+               if (x==1) componentSerializer.skip(in, identities);\r
+       }\r
+       \r
+       @Override\r
+       public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {\r
+               try {\r
+                       if (!binding.hasValue(obj)) {\r
+                               out.write((byte)0);\r
+                       } else {\r
+                               out.write((byte)1);\r
+                               Object componentValue = binding.getValue(obj);\r
+                               componentSerializer.serialize(out, identities, componentValue);\r
+                       }\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }\r
+                       \r
+       }\r
+\r
+       @Override\r
+       public Integer getConstantSize() {\r
+               return fixedSize;\r
+       }\r
+\r
+       @Override\r
+       public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {\r
+               try {\r
+                       if (fixedSize!=null) return fixedSize;\r
+                       if (!binding.hasValue(obj)) return 1;\r
+                       Object componentValue = binding.getValue(obj);\r
+                       return 1 + componentSerializer.getSize(componentValue, identities);\r
+               } catch (BindingException e) {\r
+                       throw new IOException( e ); \r
+               }                       \r
+       }\r
+       \r
+       @Override\r
+       public int getMinSize() {\r
+               return 1;\r
+       }\r
+       \r
+}      \r