DataWriter

Read time 2 minutes Package: Nalix.Environment
On this page

Namespace: Nalix.Environment.Memory Assembly: Nalix.Environment

Nalix.Environment.Memory.DataWriter is a mutable, growable, high-performance write buffer implemented as a ref struct. It is specifically designed to handle high-throughput serialization with minimal overhead.

Buffer Modes

DataWriter can operate in two distinct modes depending on how it is constructed:

  1. Rented Mode: Constructed via new DataWriter(int size) (allocates at least 32 bytes via Math.Max(size, 32)). The writer internally rents a byte[] from BufferLease.ByteArrayPool. In this mode, the writer can dynamically Expand() up to MemoryOptions.MaxWriterCapacity (128 MiB, 134_217_728 bytes by default; exceeding this throws SerializationFailureException). Calling Dispose() returns the rented array to the pool.
  2. Fixed Mode: Constructed via new DataWriter(byte[] buffer) or new DataWriter(Span<byte> span). The writer wraps an external, fixed-size buffer. In this mode, calling Expand() when there is insufficient space throws an InternalErrorException, and Dispose() performs no pooling actions.

Key Properties

  • WrittenCount: The number of bytes successfully committed to the buffer.
  • FreeBuffer: A Span<byte> representing the remaining, unwritten segment of the buffer.

Writing Data

1. Expand (Ensuring Capacity)

public void Expand(int minimumSize)

Ensures that at least minimumSize bytes are available in the FreeBuffer. If operating in Rented Mode and capacity is insufficient, it will rent a new buffer (typically doubling the current size) and copy existing written bytes into the new array.

2. GetFreeBufferReference

public readonly ref byte GetFreeBufferReference()

Returns a reference to the first byte of the free space. Always call Expand() before retrieving this reference to guarantee safety.

3. Advance

public void Advance(int count)

Advances the write cursor by count bytes, effectively committing them to the WrittenCount. Throws ArgumentOutOfRangeException if count is non-positive or exceeds FreeBuffer.

4. Write

DataWriter provides direct write helpers that automatically expand when needed (in Rented Mode):

  • Write<T>(T value) where T : unmanaged: Writes any unmanaged value directly, expanding if necessary.
  • Write(ReadOnlySpan<byte> value): Writes a span of bytes, expanding if necessary.
  • Write(byte[] value): Writes a byte array, expanding if necessary.

These are convenience wrappers around Expand + GetFreeBufferReference + Advance.

Finalizing

  • ToArray(): Copies the committed data into a brand new, tightly-sized byte[]. Allocates a new array.
  • Dispose(): Clears the state and, if in Rented Mode, returns the underlying array to the pool.

Example Usage

public void WriteInt32(ref DataWriter writer, int value)
{
    // 1. Ensure enough space is available
    writer.Expand(sizeof(int));
    
    // 2. Write directly to the buffer reference
    Unsafe.WriteUnaligned(ref writer.GetFreeBufferReference(), value);
    
    // 3. Advance the cursor
    writer.Advance(sizeof(int));
}