xbuffer 1.0.0

Growing @nogc buffer with generic type

To use this package, put the following dependency into your project's dependencies section:



DUB Package codecov Build Status

A @nogc buffer that automatically grows when writing and frees its memory on destruction.

Jump to: Buffer, Typed Buffer


The Buffer class is located in xbuffer.buffer and is the base buffer class. The buffer has a fixed chunk size that is used to expand it when more data is needed.

Buffer buffer = new Buffer(4);

assert(buffer.capacity == 4);

assert(buffer.capacity == 8);

The buffer can be also constructed using an array of data, the chunk size will be the length (in bytes) of that data.

Buffer buffer = new Buffer([1, 2, 3, 4]);
assert(buffer.capacity == 16); // 4 * int.sizeof

buffer = new Buffer(cast(ubyte[])[1, 2, 3, 4]);
assert(buffer.capacity == 4);

Jump to: data, writing, reading, peeking


The buffer's data is stored as a void[] but can be converted to any fixed-size type using the data property.

Buffer buffer = new Buffer([1, 2, 3]);
assert(buffer.data!int == [1, 2, 3]);
assert(buffer.data!ubyte == [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]); // on a little-endian system

The data property can also be used to assign an array of a fixed-size type to the buffer. The chunk size of the buffer does not change.

Buffer buffer = new Buffer(8);
buffer.data = [1, 2, 3];
buffer.data = cast(ubyte[])[1, 2, 3];


Data is written to the buffer using the write template. It is possible to write any fixed-size type of data (even structs).

Every write method is pure, nothrow, @safe and @nogc.

Buffer buffer = new Buffer(16);

// an integer, using the system's endianness

// a big-endian short
buffer.write!(Endian.bigEndian, short)(42);

// an array of integers, using the system's endianness
buffer.write([1, 2, 3]);

// an array of little-endian floats
buffer.write!(Endian.littleEndian)([0f, 1f, .5f]);

The operation of writing increases the data's length but doesn't increase the buffer's reading index; this means that the written data can also be read/peeked in the same order it was written (see examples in next section).


Data is read from the buffer using the read template.

Every read method may throw a BufferOverflowException if there isn't enough data to read. That's also the only reason why read methods are not @nogc.

Buffer buffer = new Buffer(new ubyte[30]);

// an integer, using the system's endianness

// a little-endian short
buffer.read!(Endian.littleEndian, short)();

// an array of 2 integers, using the system's endianness

// an array of 4 big-endian floats
buffer.read!(Endian.bigEndian, float[])(4);

The operation of reading increases the data's index but doesn't change the buffer's length.

Buffer buffer = new Buffer(8);

// buffer is empty
assert(buffer.index == 0);
assert(buffer.length == 0);
assert(buffer.data!ubtye == []);

assert(buffer.index == 0); // not increased
assert(buffer.length == 8);

assert(buffer.index == 4); // increased
assert(buffer.length == 8);


Peeking is the same as reading, except it doesn't increase the reading index.

Buffer buffer = new Buffer(4);

auto data = buffer.data!ubyte;
assert(buffer.peek!int() == 1);
assert(buffer.data!ubyte == data);

assert(buffer.peek!int() == buffer.read!int());

Typed Buffer

Typed is a utility template that provides methods and properties to simplify the use of a buffer with a single type of data.

alias ByteBuffer = Typed!ubyte;
alias StringBuffer = Typed!string; // or Typed!(immutable(char))

put, get and get(size_t) can be used to write and read data or arrays of data, in addition of all the methods provided by Buffer, which the typed buffer extends.

  • Kripth
1.0.0 2018-Jun-13
0.3.0 2018-Jun-06
0.2.0 2018-Mar-31
0.1.0 2018-Mar-21
~master 2018-Jun-13
Show all 5 versions
Download Stats:
  • 48 downloads today

  • 220 downloads this week

  • 658 downloads this month

  • 1788 downloads total

Short URL: