]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataReader.java
Streaming serialization of values, debugger for corrupted values
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / streaming / DataReader.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataReader.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataReader.java
new file mode 100644 (file)
index 0000000..f801224
--- /dev/null
@@ -0,0 +1,112 @@
+package org.simantics.databoard.streaming;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.serialization.Serializer;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.binary.Endian;
+import org.simantics.databoard.util.binary.UTF8;
+
+/**
+ * This is an utility class that encapsulates the databoard value decoding scheme.
+ * It can be used for streaming value reading.
+ */
+public class DataReader {
+    private static final Serializer DATATYPE_SERIALIZER = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked( Datatype.class ));
+
+    private final DataInput in;
+    
+    public DataReader(DataInput in) {
+        this.in = in;
+    }
+    
+    public DataReader(InputStream stream) {
+        this.in = new DataInputStream(stream);
+    }
+    
+    public boolean readBoolean() throws IOException {
+        return in.readByte() != 0;
+    }
+    
+    public byte readByte() throws IOException {
+        return in.readByte();
+    }
+    
+    public int readInteger() throws IOException {
+        return in.readInt();
+    }
+    
+    public long readLong() throws IOException {
+        return in.readLong();
+    }
+    
+    public float readFloat() throws IOException {
+        return in.readFloat();
+    }
+    
+    public double readDouble() throws IOException {
+        return in.readDouble();
+    }
+    
+    public int readStringLength() throws IOException {
+        return Endian.readDynamicUInt32(in);
+    }
+    
+    public String readStringContent(int length) throws IOException {
+        return UTF8.readModifiedUTF(in, length); 
+    }
+    
+    public String readString() throws IOException {
+        int length = readStringLength();
+        return readStringContent(length);
+    }
+    
+    public Datatype readDatatype() throws IOException {
+        return (Datatype)DATATYPE_SERIALIZER.deserialize(in);
+    }
+    
+    /**
+     * A variable length array is started with the length
+     * followed by the serialization of all elements.
+     */
+    public int beginVariableLengthArray() throws IOException {
+        return in.readInt();
+    }
+    
+    /**
+     * A map is started with its size followed by 
+     * serialization of interleaved keys and values.
+     */
+    public int beginMap() throws IOException {
+        return in.readInt();
+    }
+    
+    /**
+     * Starts reading optional value. False is returned,
+     * if the optional is null.
+     */
+    public boolean beginOptional() throws IOException {
+        return in.readByte() != 0;
+    }
+    
+    /**
+     * Selects the constructor of the union type.
+     * It is written as a variable length integer,
+     * so the total number of tags is required.
+     */
+    public int readUnionTag(int tagCount) throws IOException {
+        return Endian.getUInt(in, tagCount-1);
+    }
+    
+    /**
+     * Reads a record reference. Value 0 indicates that a new record is encountered.
+     * In this case reading the reference again returns the id of the new record.
+     */
+    public int readReferableRecordReference() throws IOException {
+        return in.readInt();
+    }
+}