Streaming serialization of values, debugger for corrupted values
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / streaming / DataReader.java
1 package org.simantics.databoard.streaming;
2
3 import java.io.DataInput;
4 import java.io.DataInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
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 decoding scheme.
16  * It can be used for streaming value reading.
17  */
18 public class DataReader {
19     private static final Serializer DATATYPE_SERIALIZER = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked( Datatype.class ));
20
21     private final DataInput in;
22     
23     public DataReader(DataInput in) {
24         this.in = in;
25     }
26     
27     public DataReader(InputStream stream) {
28         this.in = new DataInputStream(stream);
29     }
30     
31     public boolean readBoolean() throws IOException {
32         return in.readByte() != 0;
33     }
34     
35     public byte readByte() throws IOException {
36         return in.readByte();
37     }
38     
39     public int readInteger() throws IOException {
40         return in.readInt();
41     }
42     
43     public long readLong() throws IOException {
44         return in.readLong();
45     }
46     
47     public float readFloat() throws IOException {
48         return in.readFloat();
49     }
50     
51     public double readDouble() throws IOException {
52         return in.readDouble();
53     }
54     
55     public int readStringLength() throws IOException {
56         return Endian.readDynamicUInt32(in);
57     }
58     
59     public String readStringContent(int length) throws IOException {
60         return UTF8.readModifiedUTF(in, length); 
61     }
62     
63     public String readString() throws IOException {
64         int length = readStringLength();
65         return readStringContent(length);
66     }
67     
68     public Datatype readDatatype() throws IOException {
69         return (Datatype)DATATYPE_SERIALIZER.deserialize(in);
70     }
71     
72     /**
73      * A variable length array is started with the length
74      * followed by the serialization of all elements.
75      */
76     public int beginVariableLengthArray() throws IOException {
77         return in.readInt();
78     }
79     
80     /**
81      * A map is started with its size followed by 
82      * serialization of interleaved keys and values.
83      */
84     public int beginMap() throws IOException {
85         return in.readInt();
86     }
87     
88     /**
89      * Starts reading optional value. False is returned,
90      * if the optional is null.
91      */
92     public boolean beginOptional() throws IOException {
93         return in.readByte() != 0;
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 int readUnionTag(int tagCount) throws IOException {
102         return Endian.getUInt(in, tagCount-1);
103     }
104     
105     /**
106      * Reads a record reference. Value 0 indicates that a new record is encountered.
107      * In this case reading the reference again returns the id of the new record.
108      */
109     public int readReferableRecordReference() throws IOException {
110         return in.readInt();
111     }
112 }