or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

buffer-management.mdgraph-processing.mdindex.mdinput-output-streams.mdserialization-utilities.md
tile.json

input-output-streams.mddocs/

Input and Output Streams

The input and output stream classes provide low-level interfaces for reading and writing protobuf-encoded data. These classes offer fine-grained control over the serialization process and support various data sources.

Input Classes

CodedInput

Abstract base class for reading protobuf-encoded data from various sources.

public abstract class CodedInput {
    public abstract int readRawByte() throws IOException;
    public abstract byte[] readRawBytes(int size) throws IOException;
    public abstract void readRawBytes(byte[] buffer, int offset, int length) throws IOException;
    public abstract boolean readBool() throws IOException;
    public abstract double readDouble() throws IOException;
    public abstract float readFloat() throws IOException;
    public abstract long readFixed64() throws IOException;
    public abstract int readFixed32() throws IOException;
    public abstract int readRawVarint32() throws IOException;
    public abstract long readRawVarint64() throws IOException;
    public abstract int readUInt32() throws IOException;
    public abstract long readUInt64() throws IOException;
    public abstract int readSInt32() throws IOException;
    public abstract long readSInt64() throws IOException;
    public abstract int readInt32() throws IOException;
    public abstract long readInt64() throws IOException;
    public abstract String readString() throws IOException;
    public abstract ByteString readBytes() throws IOException;
    public abstract byte[] readByteArray() throws IOException;
    public abstract int readTag() throws IOException;
    public abstract boolean isAtEnd() throws IOException;
    public abstract int getLastTag();
    public abstract void checkLastTagWas(int value) throws IOException;
    public abstract int readRawLittleEndian32() throws IOException;
    public abstract long readRawLittleEndian64() throws IOException;
}

ByteArrayInput

Concrete implementation for reading from byte arrays.

public final class ByteArrayInput extends CodedInput {
    public ByteArrayInput(byte[] buffer, boolean decodeNestedMessageAsGroup);
    public ByteArrayInput(byte[] buffer, int offset, int len, boolean decodeNestedMessageAsGroup);
    public int getOffset();
    public int getLimit();
}

Parameters:

  • buffer - Source byte array
  • offset - Starting position in the array (optional)
  • len - Number of bytes to read (optional)
  • decodeNestedMessageAsGroup - Whether to decode nested messages as groups

Usage Example:

byte[] data = // ... serialized data
ByteArrayInput input = new ByteArrayInput(data, false);

while (!input.isAtEnd()) {
    int tag = input.readTag();
    switch (tag) {
        case 10: // field 1, wire type 2 (string)
            String value = input.readString();
            break;
        case 16: // field 2, wire type 0 (int)
            int number = input.readInt32();
            break;
        default:
            input.skipField(tag);
    }
}

ByteBufferInput

Implementation for reading from Java NIO ByteBuffers.

public final class ByteBufferInput implements Input {
    public ByteBufferInput(ByteBuffer buffer, boolean protostuffMessage);
    public ByteBufferInput reset(int offset, int len);
}

Parameters:

  • buffer - Source ByteBuffer
  • protostuffMessage - Whether the message uses protostuff format encoding

Usage Example:

ByteBuffer buffer = // ... data source
ByteBufferInput input = new ByteBufferInput(buffer, false);
String message = input.readString();

GraphCodedInput

Specialized input for reading object graphs with reference tracking.

public final class GraphCodedInput extends CodedInput {
    public GraphCodedInput(CodedInput input);
}

Wraps an existing CodedInput to add support for object reference resolution during deserialization of complex object graphs.

GraphByteArrayInput

ByteArrayInput variant optimized for object graph deserialization.

public final class GraphByteArrayInput extends ByteArrayInput {
    public GraphByteArrayInput(byte[] buffer, boolean decodeNestedMessageAsGroup);
}

Output Classes

ProtobufOutput

Output implementation for writing data in Protocol Buffer format.

public final class ProtobufOutput implements Output {
    public ProtobufOutput(LinkedBuffer buffer);
    public ProtobufOutput(LinkedBuffer head, LinkedBuffer tail);
    
    public void writeInt32(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeUInt32(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeSInt32(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeFixed32(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeSFixed32(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeInt64(int fieldNumber, long value, boolean repeated) throws IOException;
    public void writeUInt64(int fieldNumber, long value, boolean repeated) throws IOException;
    public void writeSInt64(int fieldNumber, long value, boolean repeated) throws IOException;
    public void writeFixed64(int fieldNumber, long value, boolean repeated) throws IOException;
    public void writeSFixed64(int fieldNumber, long value, boolean repeated) throws IOException;
    public void writeFloat(int fieldNumber, float value, boolean repeated) throws IOException;
    public void writeDouble(int fieldNumber, double value, boolean repeated) throws IOException;
    public void writeBool(int fieldNumber, boolean value, boolean repeated) throws IOException;
    public void writeEnum(int fieldNumber, int value, boolean repeated) throws IOException;
    public void writeString(int fieldNumber, CharSequence value, boolean repeated) throws IOException;
    public void writeBytes(int fieldNumber, ByteString value, boolean repeated) throws IOException;
    public void writeByteArray(int fieldNumber, byte[] value, boolean repeated) throws IOException;
    public void writeByteRange(boolean utf8String, int fieldNumber, byte[] value, int offset, int length, boolean repeated) throws IOException;
    public void writeObject(int fieldNumber, Object value, Schema schema, boolean repeated) throws IOException;
}

Usage Example:

LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
ProtobufOutput output = new ProtobufOutput(buffer);

output.writeString(1, "Hello World", false);
output.writeInt32(2, 42, false);

// Get serialized data
byte[] data = output.toByteArray();

ProtostuffOutput

Output implementation for writing data in Protostuff format.

public final class ProtostuffOutput extends WriteSession implements Output {
    public ProtostuffOutput(LinkedBuffer buffer);
    public ProtostuffOutput(LinkedBuffer buffer, OutputStream out);
    public ProtostuffOutput(LinkedBuffer buffer, OutputStream out, Schema nextSchema);
    public ProtostuffOutput clear();
}

ProtostuffOutput provides the same API as ProtobufOutput but uses the optimized Protostuff encoding format.

Low-Copy Output Variants

For memory-efficient operations, protostuff-core provides low-copy variants:

public final class LowCopyProtobufOutput implements Output {
    public LowCopyProtobufOutput(LinkedBuffer buffer);
}

public final class LowCopyProtostuffOutput implements Output {
    public LowCopyProtostuffOutput(LinkedBuffer buffer);
}

These classes minimize memory copying operations during serialization, improving performance for large data sets.

GraphProtostuffOutput

Specialized output for writing object graphs with reference tracking.

public final class GraphProtostuffOutput implements Output {
    public GraphProtostuffOutput(LinkedBuffer buffer);
}

Handles serialization of complex object graphs including circular references and shared objects.

Utility Classes

LimitedInputStream

A utility class that wraps an InputStream and limits the number of bytes that can be read from it.

public final class LimitedInputStream extends FilterInputStream {
    public LimitedInputStream(InputStream in);
    public LimitedInputStream(InputStream in, int limit);
}

Parameters:

  • in - The underlying InputStream to wrap
  • limit - Maximum number of bytes that can be read (optional, defaults to unlimited)

Usage Example:

InputStream original = // ... some input stream
LimitedInputStream limited = new LimitedInputStream(original, 1024);
// Can only read up to 1024 bytes from this stream

Data Type Support

All output classes support the following protobuf wire types:

Numeric Types

  • int32, uint32, sint32 - 32-bit integers with different encoding strategies
  • fixed32, sfixed32 - Fixed-width 32-bit integers
  • int64, uint64, sint64 - 64-bit integers with different encoding strategies
  • fixed64, sfixed64 - Fixed-width 64-bit integers
  • float, double - IEEE 754 floating point numbers

Other Types

  • bool - Boolean values
  • string - UTF-8 encoded strings
  • bytes - Raw byte arrays
  • enum - Enumeration values (as integers)

Special Parameters

fieldNumber: The protobuf field number (1-based) identifying the field in the message schema.

repeated: Boolean flag indicating whether this is a repeated field (list/array).

Usage Patterns

Manual Serialization

LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
ProtobufOutput output = new ProtobufOutput(buffer);

// Write fields manually
output.writeString(1, person.getName(), false);
output.writeInt32(2, person.getAge(), false);
output.writeString(3, person.getEmail(), false);

byte[] data = output.toByteArray();

Manual Deserialization

ByteArrayInput input = new ByteArrayInput(data, false);
Person person = new Person();

while (!input.isAtEnd()) {
    int tag = input.readTag();
    switch (tag) {
        case 10: // field 1, string
            person.setName(input.readString());
            break;
        case 16: // field 2, int32
            person.setAge(input.readInt32());
            break;
        case 26: // field 3, string
            person.setEmail(input.readString());
            break;
        default:
            input.skipField(tag);
    }
}

Error Handling

Input/Output classes throw:

  • IOException for I/O related errors
  • ProtobufException for protocol violations
  • ArrayIndexOutOfBoundsException for buffer overruns (wrapped in RuntimeException)

Performance Considerations

  • Use appropriate input class for your data source (ByteArrayInput for byte arrays, ByteBufferInput for NIO buffers)
  • Reuse LinkedBuffer instances to minimize memory allocations
  • Consider low-copy variants for large data sets
  • Use graph variants only when object references are needed