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(); } }