Streaming serialization of values, debugger for corrupted values
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / streaming / DataWriter.java
1 package org.simantics.databoard.streaming;
2
3 import java.io.DataOutput;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.io.OutputStream;
7
8 import org.simantics.databoard.Bindings;
9 import org.simantics.databoard.serialization.Serializer;
10 import org.simantics.databoard.type.Datatype;
11 import org.simantics.databoard.util.binary.Endian;
12 import org.simantics.databoard.util.binary.UTF8;
13
14 /**
15  * This is an utility class that encapsulates the databoard value encoding scheme.
16  * It can be used for streaming value writing. 
17  */
18 public class DataWriter {
19     private static final Serializer DATATYPE_SERIALIZER = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked( Datatype.class ));
20
21     private final DataOutput out;
22
23     public DataWriter(DataOutput out) {
24         this.out = out;
25     }
26     
27     public DataWriter(OutputStream stream) {
28         this.out = new DataOutputStream(stream);
29     }
30     
31     public void writeBoolean(boolean value) throws IOException {
32         out.write(value ? 1 : 0);
33     }
34     
35     public void writeByte(byte value) throws IOException {
36         out.write(value);
37     }
38     
39     public void writeInteger(int value) throws IOException {
40         out.writeInt(value);
41     }
42     
43     public void writeLong(long value) throws IOException {
44         out.writeLong(value);
45     }
46     
47     public void writeFloat(float value) throws IOException {
48         out.writeFloat(value);
49     }
50     
51     public void writeDouble(double value) throws IOException {
52         out.writeDouble(value);
53     }
54     
55     public void writeString(String value) throws IOException {
56         int utflen = UTF8.getModifiedUTF8EncodingByteLength(value);
57         Endian.writeDynamicUInt32(out, utflen);
58         UTF8.writeModifiedUTF(out, value);
59     }
60     
61     public void writeDatatype(Datatype datatype) throws IOException {
62         DATATYPE_SERIALIZER.serialize(out, datatype);
63     }
64     
65     /**
66      * A variable length array is started with the length
67      * followed by the serialization of all elements.
68      */
69     public void beginVariableLengthArray(int length) throws IOException {
70         out.writeInt(length);
71     }
72     
73     /**
74      * A map is started with its size followed by 
75      * serialization of interleaved keys and values.
76      */
77     public void beginMap(int size) throws IOException {
78         out.writeInt(size);
79     }
80     
81     /**
82      * An optional value that is null is written as byte 0.
83      */
84     public void writeOptionalNull() throws IOException {
85         out.write(0);
86     }
87     
88     /**
89      * An optional value that is not null is started
90      * with byte 1 followed by the actual value.
91      */
92     public void beginOptionalValue() throws IOException {
93         out.write(1);
94     }
95     
96     /**
97      * Selects the constructor of the union type.
98      * It is written as a variable length integer,
99      * so the total number of tags is required.
100      */
101     public void writeUnionTag(int tag, int tagCount) throws IOException {
102         Endian.putUInt(out, tag, tagCount-1);
103     }
104     
105     public void writeReferenceToKnownReferableRecord(int id) throws IOException {
106         out.writeInt(id);
107     }
108     
109     public void beginUnknownReferableRecord(int id) throws IOException {
110         out.writeInt(0);
111         out.writeInt(id);
112     }
113 }