1 package org.simantics.databoard.serialization.impl;
3 import gnu.trove.map.hash.TObjectIntHashMap;
5 import java.io.DataInput;
6 import java.io.DataOutput;
7 import java.io.IOException;
10 import org.simantics.databoard.binding.Binding;
11 import org.simantics.databoard.binding.RecordBinding;
12 import org.simantics.databoard.binding.error.BindingException;
13 import org.simantics.databoard.binding.reflection.ClassBinding;
14 import org.simantics.databoard.binding.util.IsReferableQuery;
15 import org.simantics.databoard.binding.util.Result;
16 import org.simantics.databoard.serialization.SerializationException;
17 import org.simantics.databoard.serialization.Serializer;
18 import org.simantics.databoard.serialization.Serializer.CompositeSerializer;
20 public class GenericRecordSerializer extends CompositeSerializer {
22 RecordBinding binding;
23 public Serializer[] componentSerializers;
26 boolean createPartial;
29 * Field type for each field
38 public int[] fieldType;
43 * @param componentSerializers (optional) can be set later
45 public GenericRecordSerializer(RecordBinding binding, Serializer[] componentSerializers) {
46 super( IsReferableQuery.isReferable( binding.type() ) != Result.No );
47 this.binding = binding;
48 this.componentSerializers = componentSerializers;
52 public void finalizeConstruction() {
55 createPartial = !binding.isImmutable();
57 if ( binding instanceof ClassBinding ) {
58 ClassBinding cb = (ClassBinding) binding;
59 createPartial &= cb.ci.partialConstructionPossible;
62 fieldType = new int[componentSerializers.length];
63 for (int i=0; i<componentSerializers.length; i++) {
64 Serializer cs = componentSerializers[i];
65 //createPartial &= !binding.getComponentBinding(i).isImmutable();
66 minSize += cs.getMinSize();
67 Integer componentFixedSize = cs.getConstantSize();
68 if (componentFixedSize==null) {
72 fixedSize = fixedSize==null ? componentFixedSize : fixedSize+componentFixedSize;
75 if ( cs instanceof BooleanSerializer ) type = 1;
76 else if ( cs instanceof ByteSerializer ) type = 2;
77 else if ( cs instanceof IntSerializer ) type = 3;
78 else if ( cs instanceof LongSerializer ) type = 4;
79 else if ( cs instanceof FloatSerializer ) type = 5;
80 else if ( cs instanceof DoubleSerializer ) type = 6;
84 // if ( binding instanceof ClassBinding ) {
85 // ClassBinding cb = (ClassBinding) binding;
86 // System.out.println(cb.ci.clazz.getName()+" = "+createPartial);
92 public Object deserialize(DataInput in, List<Object> identities) throws IOException {
93 // assertRemainingBytes(in, minSize);
96 Object obj = binding.createPartial();
97 deserializeTo(in, identities, obj);
100 Object[] temp = new Object[componentSerializers.length];
101 for(int i=0;i<componentSerializers.length;++i) {
102 temp[i] = componentSerializers[i].deserialize(in, identities);
104 return binding.create(temp);
107 } catch (BindingException e) {
108 throw new IOException( e );
113 public void deserializeTo(DataInput in, List<Object> identities, Object obj) throws IOException {
114 // assertRemainingBytes(in, minSize);
116 for(int i=0;i<componentSerializers.length;++i) {
117 Serializer cs = componentSerializers[i];
118 int type = fieldType[i];
122 Binding cb = binding.componentBindings[i];
123 boolean csImmutable = cb.isImmutable();
125 Object component = cs.deserialize(in, identities);
126 binding.setComponent(obj, i, component);
128 Object component = binding.getComponent(obj, i);
129 if ( component == null ) {
130 component = cs.deserialize(in, identities);
131 binding.setComponent(obj, i, component);
133 Object newComponent = cs.deserializeToTry(in, identities, component);
134 if (newComponent!=component) binding.setComponent(obj, i, newComponent);
139 binding.setBoolean(obj, i, ((BooleanSerializer)cs).getBoolean(in));
142 binding.setByte(obj, i, ((ByteSerializer)cs).getByte(in));
145 binding.setInt(obj, i, ((IntSerializer)cs).getInt(in));
148 binding.setLong(obj, i, ((LongSerializer)cs).getLong(in));
151 binding.setFloat(obj, i, ((FloatSerializer)cs).getFloat(in));
154 binding.setDouble(obj, i, ((DoubleSerializer)cs).getDouble(in));
159 } catch (BindingException e) {
160 throw new IOException( e );
165 public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {
166 if (fixedSize != null) {
167 in.skipBytes(fixedSize);
169 for(int i=0;i<componentSerializers.length;++i)
170 componentSerializers[i].skip(in, identities);
175 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {
177 for(int i=0;i<componentSerializers.length;++i) {
178 int type = fieldType[i];
179 Serializer cs = componentSerializers[i];
181 case 0: cs.serialize(out, identities, binding.getComponent(obj, i));
183 case 1: ((BooleanSerializer)cs).putBoolean(out, binding.getBoolean(obj, i));
185 case 2: ((ByteSerializer)cs).putByte(out, binding.getByte(obj, i));
187 case 3: ((IntSerializer)cs).putInt(out, binding.getInt(obj, i));
189 case 4: ((LongSerializer)cs).putLong(out, binding.getLong(obj, i));
191 case 5: ((FloatSerializer)cs).putFloat(out, binding.getFloat(obj, i));
193 case 6: ((DoubleSerializer)cs).putDouble(out, binding.getDouble(obj, i));
197 } catch (BindingException e) {
198 throw new IOException( e );
203 public Integer getConstantSize() {
208 public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {
210 if (fixedSize!=null) return fixedSize;
212 for(int i=0;i<componentSerializers.length;++i)
213 result += componentSerializers[i].getSize( binding.getComponent(obj, i), identities );
215 } catch (BindingException e) {
216 throw new IOException( e );
221 * @return the minSize
223 public int getMinSize() {