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