]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataWriter.java
Streaming serialization of values, debugger for corrupted values
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / streaming / DataWriter.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataWriter.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/streaming/DataWriter.java
new file mode 100644 (file)
index 0000000..188ea32
--- /dev/null
@@ -0,0 +1,113 @@
+package org.simantics.databoard.streaming;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+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 encoding scheme.
+ * It can be used for streaming value writing. 
+ */
+public class DataWriter {
+    private static final Serializer DATATYPE_SERIALIZER = Bindings.getSerializerUnchecked(Bindings.getBindingUnchecked( Datatype.class ));
+
+    private final DataOutput out;
+
+    public DataWriter(DataOutput out) {
+        this.out = out;
+    }
+    
+    public DataWriter(OutputStream stream) {
+        this.out = new DataOutputStream(stream);
+    }
+    
+    public void writeBoolean(boolean value) throws IOException {
+        out.write(value ? 1 : 0);
+    }
+    
+    public void writeByte(byte value) throws IOException {
+        out.write(value);
+    }
+    
+    public void writeInteger(int value) throws IOException {
+        out.writeInt(value);
+    }
+    
+    public void writeLong(long value) throws IOException {
+        out.writeLong(value);
+    }
+    
+    public void writeFloat(float value) throws IOException {
+        out.writeFloat(value);
+    }
+    
+    public void writeDouble(double value) throws IOException {
+        out.writeDouble(value);
+    }
+    
+    public void writeString(String value) throws IOException {
+        int utflen = UTF8.getModifiedUTF8EncodingByteLength(value);
+        Endian.writeDynamicUInt32(out, utflen);
+        UTF8.writeModifiedUTF(out, value);
+    }
+    
+    public void writeDatatype(Datatype datatype) throws IOException {
+        DATATYPE_SERIALIZER.serialize(out, datatype);
+    }
+    
+    /**
+     * A variable length array is started with the length
+     * followed by the serialization of all elements.
+     */
+    public void beginVariableLengthArray(int length) throws IOException {
+        out.writeInt(length);
+    }
+    
+    /**
+     * A map is started with its size followed by 
+     * serialization of interleaved keys and values.
+     */
+    public void beginMap(int size) throws IOException {
+        out.writeInt(size);
+    }
+    
+    /**
+     * An optional value that is null is written as byte 0.
+     */
+    public void writeOptionalNull() throws IOException {
+        out.write(0);
+    }
+    
+    /**
+     * An optional value that is not null is started
+     * with byte 1 followed by the actual value.
+     */
+    public void beginOptionalValue() throws IOException {
+        out.write(1);
+    }
+    
+    /**
+     * Selects the constructor of the union type.
+     * It is written as a variable length integer,
+     * so the total number of tags is required.
+     */
+    public void writeUnionTag(int tag, int tagCount) throws IOException {
+        Endian.putUInt(out, tag, tagCount-1);
+    }
+    
+    public void writeReferenceToKnownReferableRecord(int id) throws IOException {
+        out.writeInt(id);
+    }
+    
+    public void beginUnknownReferableRecord(int id) throws IOException {
+        out.writeInt(0);
+        out.writeInt(id);
+    }
+}