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.RecordBinding;
11 import org.simantics.databoard.binding.error.BindingException;
12 import org.simantics.databoard.serialization.SerializationException;
13 import org.simantics.databoard.serialization.Serializer;
14 import org.simantics.databoard.serialization.Serializer.RecursiveSerializer;
15 import org.simantics.databoard.type.RecordType;
17 public class ReferableRecordSerializer extends RecursiveSerializer {
19 RecordBinding binding;
20 public Serializer[] componentSerializers;
22 /** The combined size elements, or <code>null</code> */
23 Integer fixedSizeOfContent;
26 public ReferableRecordSerializer(RecordBinding binding, Serializer[] componentSerializers) {
27 this.binding = binding;
28 this.componentSerializers = componentSerializers;
32 public void finalizeConstruction() {
33 fixedSizeOfContent = null;
34 for (Serializer componentSerializer : componentSerializers) {
35 minContentSize += componentSerializer.getMinSize();
36 Integer componentFixedSize = componentSerializer.getConstantSize();
37 if (componentFixedSize==null) {
38 fixedSizeOfContent = null;
41 fixedSizeOfContent = fixedSizeOfContent==null ? componentFixedSize : fixedSizeOfContent + componentFixedSize;
46 return ((RecordType)binding.type()).isReferable();
50 public Object deserialize(DataInput in, List<Object> identities) throws IOException {
52 int id = in.readInt();
54 return identities.get(id-1);
56 Object result = binding.createPartial();
57 identities.add(result);
59 // assertRemainingBytes(in, minContentSize);
60 Object[] temp = new Object[componentSerializers.length];
61 for(int i=0;i<componentSerializers.length;++i)
62 temp[i] = componentSerializers[i].deserialize(in, identities);
63 binding.setComponents(result, temp);
66 } catch (BindingException e) {
67 throw new IOException( e );
72 public void deserializeTo(DataInput in, List<Object> identities,
73 Object obj) throws IOException {
75 int id = in.readInt();
77 Object alreadyDeserializedObject = identities.get(id-1);
78 if (alreadyDeserializedObject!=obj) {
79 for (int i=0; i<binding.getComponentCount(); ++i) {
80 Object component = binding.getComponent(alreadyDeserializedObject, i);
81 binding.setComponent(obj, i, component);
88 // assertRemainingBytes(in, minContentSize);
89 for(int i=0;i<componentSerializers.length;++i) {
90 Serializer cs = componentSerializers[i];
91 boolean csImmutable = binding.getComponentBinding(i).isImmutable();
93 Object component = cs.deserialize(in, identities);
94 binding.setComponent(obj, i, component);
96 Object component = binding.getComponent(obj, i);
97 component = cs.deserializeToTry(in, identities, component);
98 binding.setComponent(obj, i, component);
101 } catch (BindingException e) {
102 throw new IOException( e );
108 public void skip(DataInput in, List<Object> identities) throws IOException, SerializationException {
110 int id = in.readInt();
113 for(int i=0;i<componentSerializers.length;++i)
114 componentSerializers[i].skip(in, identities);
118 public void serialize(DataOutput out, TObjectIntHashMap<Object> identities, Object obj) throws IOException {
120 int id = identities.get(obj);
126 identities.put(obj, identities.size() + 1);
127 for(int i=0;i<componentSerializers.length;++i)
128 componentSerializers[i].serialize(out, identities, binding.getComponent(obj, i));
130 } catch (BindingException e) {
131 throw new IOException( e );
137 public Integer getConstantSize() {
142 public int getSize(Object obj, TObjectIntHashMap<Object> identities) throws IOException {
144 int id = identities.get(obj);
146 identities.put(obj, identities.size()+1);
147 if (fixedSizeOfContent!=null) return 4+fixedSizeOfContent;
149 for(int i=0;i<componentSerializers.length;++i)
150 result += componentSerializers[i].getSize( binding.getComponent(obj, i), identities );
152 } catch (BindingException e) {
153 throw new IOException( e );
159 public int getMinSize() {