]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
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.OptionalBinding;\r
11 import org.simantics.databoard.binding.error.BindingException;\r
12 import org.simantics.databoard.binding.util.IsReferableQuery;\r
13 import org.simantics.databoard.binding.util.Result;\r
14 import org.simantics.databoard.serialization.SerializationException;\r
15 import org.simantics.databoard.serialization.Serializer;\r
16 import org.simantics.databoard.serialization.Serializer.CompositeSerializer;\r
17 \r
18 public class OptionalSerializer  extends CompositeSerializer {\r
19 \r
20         OptionalBinding binding;\r
21         public Serializer componentSerializer;          \r
22         boolean componentImmutable;             \r
23         Integer fixedSize;\r
24         \r
25         /**\r
26          * Create optional serializer\r
27          * \r
28          * @param binding\r
29          * @param componentSerializer (optional), can be set after\r
30          */\r
31         public OptionalSerializer(OptionalBinding binding, Serializer componentSerializer) {\r
32                 super( IsReferableQuery.isReferable( binding.type() ) != Result.No );\r
33                 this.componentSerializer = componentSerializer;\r
34                 this.binding = binding;\r
35                 this.componentImmutable = binding.getComponentBinding().isImmutable();                  \r
36         }\r
37         \r
38         @Override\r
39         public void finalizeConstruction() {\r
40                 Integer fixedSizeOfComponent = componentSerializer.getConstantSize();\r
41                 if (fixedSizeOfComponent!=null && fixedSizeOfComponent==0) {\r
42                         fixedSize = fixedSizeOfComponent + 1;\r
43                 }\r
44         }\r
45 \r
46         @Override\r
47         public Object deserialize(DataInput in, List<Object> identities) throws IOException {\r
48                 try {\r
49                         byte x = in.readByte();\r
50                         if (x == 0) return binding.createNoValue();\r
51                         else if (x == 1) {\r
52                                 Object componentValue = componentSerializer.deserialize(in, identities);\r
53                                 return binding.createValue(componentValue);\r
54                         }\r
55                         else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");\r
56                 } catch (BindingException e) {\r
57                         throw new IOException( e ); \r
58                 }\r
59         }\r
60         \r
61         @Override\r
62         public void deserializeTo(DataInput in, List<Object> identities,\r
63                         Object obj) throws IOException {\r
64                 try {\r
65                         byte x = in.readByte();\r
66                         if (x == 0) {\r
67                                 if (binding.hasValue(obj)) binding.setNoValue(obj);\r
68                         } else if (x == 1) {\r
69                                 if (componentImmutable) {\r
70                                         Object component = componentSerializer.deserialize(in, identities);\r
71                                         binding.setValue(obj, component);\r
72                                 } else {\r
73                                         Object component = binding.hasValue(obj) ? binding.getValue(obj) : binding.componentBinding.createDefault();\r
74                                         component = componentSerializer.deserializeToTry(in, identities, component);\r
75                                         binding.setValue(obj, component);\r
76                                 }\r
77                                 \r
78                         }\r
79                         else throw new SerializationException("Unexpected marker for option "+x+" 0 or 1 expected.");\r
80                 } catch (BindingException e) {\r
81                         throw new IOException( e ); \r
82                 }\r
83         }\r
84 \r
85         @Override\r
86         public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {\r
87                 int x = in.readByte();\r
88                 if (x==1) componentSerializer.skip(in, identities);\r
89         }\r
90         \r
91         @Override\r
92         public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {\r
93                 try {\r
94                         if (!binding.hasValue(obj)) {\r
95                                 out.write((byte)0);\r
96                         } else {\r
97                                 out.write((byte)1);\r
98                                 Object componentValue = binding.getValue(obj);\r
99                                 componentSerializer.serialize(out, identities, componentValue);\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 Integer getConstantSize() {\r
109                 return fixedSize;\r
110         }\r
111 \r
112         @Override\r
113         public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {\r
114                 try {\r
115                         if (fixedSize!=null) return fixedSize;\r
116                         if (!binding.hasValue(obj)) return 1;\r
117                         Object componentValue = binding.getValue(obj);\r
118                         return 1 + componentSerializer.getSize(componentValue, identities);\r
119                 } catch (BindingException e) {\r
120                         throw new IOException( e ); \r
121                 }                       \r
122         }\r
123         \r
124         @Override\r
125         public int getMinSize() {\r
126                 return 1;\r
127         }\r
128         \r
129 }       \r