class Bitstream

Allows encoding/decoding of types into a stream of bits.

Supports various methods of storing data in a compact form. The bitstream can manage its internal memory or a user can provide an external source of data. If using internal memory the bitstream will automatically grow the memory storage as needed.

The stream keeps an internal cursor that represents the bit at which to perform read

& write operations. Read

& write operations will operate at the current cursor location and the cursor will be advanced by the number of bits read or written. If writing outside of range the internal memory buffer will be automatically expanded, except when external memory buffer is used, in which case it is undefined behaviour. Reading outside of range is always undefined behaviour.

Public

Constructors

Bitstream

Bitstream() noexcept = default

Initializes an empty bitstream.

As data is written the stream will grow its internal memory storage automatically.

Bitstream

Bitstream(uint32_t capacity)

Initializes a bitstream with some initial capacity.

If more bytes than capacity is written, the bitstream will grow its internal memory storage.

capacity
Number of bytes to initially allocate for the internal memory storage.

Bitstream

Bitstream(QuantType *data, uint32_t count)

Initializes a bitstream with external data storage.

The bitstream will not manage internal memory and will not grow memory storage if capacity is exceeded. The user is responsible for keeping track and not writing outside of buffer range.

data
Address of the external memory buffer. The user is responsible of keeping this memory alive for the lifetime of the bitstream, as well as releasing it. Must have enough capacity to store bits.
count
Size of the provided data, in bytes.

Bitstream

Bitstream(const Bitstream &other)

Bitstream

Bitstream(Bitstream &&other)

Methods

~Bitstream

~Bitstream() noexcept

WriteBits

uint64_t WriteBits(const QuantType *data, uint64_t count)

Writes bits from the provided buffer into the stream at the current cursor location and advances the cursor.

data
Buffer to write the data from. Must have enough capacity to store bits.
count
Number of bits to write.

Returns: Number of bits written.

ReadBits

uint64_t ReadBits(QuantType *outData, uint64_t count)

Reads bits from the stream into the provided buffer from the current cursor location and advances the cursor.

outData
Buffer to read the data from. Must have enough capacity to store bits.
count
Number of bits to read.

Returns: Number of bits read.

Write

uint64_t Write(const bool &value)

Read

uint64_t Read(bool &outValue)

Write

uint64_t Write(const String &value)

Read

uint64_t Read(String &outValue)

WriteBytes

uint32_t WriteBytes(const QuantType *data, uint32_t count)

Writes bytes from the provided buffer into the stream at the current cursor location and advances the cursor.

data
Buffer to write the data from. Must have enough capacity to store bytes.
count
Number of bytes to write.

Returns: Number of bytes written.

ReadBytes

uint32_t ReadBytes(QuantType *outData, uint32_t count)

Reads bytes from the stream into the provided buffer from the current cursor location and advances the cursor.

outData
Buffer to read the data from. Must have enough capacity to store bytes.
count
Number of bytes to read.

Returns: Number of bytes read.

WriteDelta

uint32_t WriteDelta(bool value, bool lastValue)

ReadDelta

uint32_t ReadDelta(bool &outValue, bool lastValue)

WriteVarInt

uint32_t WriteVarInt(uint32_t value)

Encodes a 32-bit integer value as a base-128 varint and writes it to the stream.

Write is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

WriteVarInt

uint32_t WriteVarInt(int32_t value)

Encodes a 32-bit integer value as a base-128 varint and writes it to the stream.

Write is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

WriteVarInt

uint32_t WriteVarInt(uint64_t value)

Encodes a 64-bit integer value as a base-128 varint and writes it to the stream.

Write is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

WriteVarInt

uint32_t WriteVarInt(int64_t value)

Encodes a 64-bit integer value as a base-128 varint and writes it to the stream.

Write is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

ReadVarInt

uint32_t ReadVarInt(uint32_t &outValue)

Decodes a 32-bit integer value encoded as a base-128 varint from the stream.

Read is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

ReadVarInt

uint32_t ReadVarInt(int32_t &outValue)

Decodes a 32-bit integer value encoded as a base-128 varint from the stream.

Read is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

ReadVarInt

uint32_t ReadVarInt(uint64_t &outValue)

Decodes a 32-bit integer value encoded as a base-128 varint from the stream.

Read is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

ReadVarInt

uint32_t ReadVarInt(int64_t &outValue)

Decodes a 32-bit integer value encoded as a base-128 varint from the stream.

Read is performed at the current cursor location and advances the cursor. Varints are a method of serializing integers using one or more bytes, where smaller values use less bytes. Returns the number of bits written.

WriteNorm

void WriteNorm(float value, uint32_t bits = 16)

Encodes a float in range [0, 1] into a fixed point representation using a specific number of bits, and writes it to the stream.

Write is performed at the current cursor location and advances the cursor.

ReadNorm

void ReadNorm(float &outValue, uint32_t bits = 16)

Decodes a float encoded using writeNorm(float, uint32_t).

Read is performed at the current cursor location and advances the cursor. Same number of bits need to be used as when the float was encoded.

WriteNorm

void WriteNorm(const Vector3 &value, uint32_t bits = 16)

Encodes a 3D vector with individual components in range [-1, 1] into a fixed point representation where each component uses a specific number of bits, and writes it to the stream.

Write is performed at the current cursor location and advances the cursor.

ReadNorm

void ReadNorm(Vector3 &outValue, uint32_t bits = 16)

Decodes a 3D vector encoded using writeNorm(Vector3, uint32_t).

Read is performed at the current cursor location and advances the cursor. Same number of bits need to be used as when the float was encoded.

WriteNorm

void WriteNorm(const Quaternion &value, uint32_t bits = 16)

Encodes a quaternion with individual components in range [-1, 1] into a fixed point representation where each component uses a specific number of bits, and writes it to the stream.

Write is performed at the current cursor location and advances the cursor.

ReadNorm

void ReadNorm(Quaternion &outValue, uint32_t bits = 16)

Decodes a quaternion encoded using writeNorm(Quaternion, uint32_t).

Read is performed at the current cursor location and advances the cursor. Same number of bits need to be used as when the float was encoded.

WriteRange

void WriteRange(float value, float min, float max, uint32_t bits = 16)

Encodes a float in a specific range into a fixed point representation using a specific number of bits, and writes it to the stream.

Write is performed at the current cursor location and advances the cursor.

ReadRange

void ReadRange(float &outValue, float min, float max, uint32_t bits = 16)

Decodes a float encoded using writeRange(float, float, float, uint32_t).

Read is performed at the current cursor location and advances the cursor. Same number of bits, and the same range needs to be used as when the float was encoded.

WriteRangeDelta

void WriteRangeDelta(float value, float lastValue, float min, float max, uint32_t bits = 16)

Checks if the provided value differs from the last provided value, and if they are equivalent writes just a single bit signifying no change.

Otherwise the value is encoded as if calling writeRange(float, float, float, uint32_t).

ReadRangeDelta

void ReadRangeDelta(float &outValue, float lastValue, float min, float max, uint32_t bits = 16)

Reads the data written by writeRangeDelta(float, float, float, float, uint32_t) from the current cursor location and advances the cursor.

Skip

void Skip(int64_t count)

Skip a defined number of bits, moving the read/write cursor by this amount.

This can also be a negative value, in which case the file pointer rewinds a defined number of bits. Note the cursor can never skip past the capacity of the buffer, and will be clamped.

SkipBytes

void SkipBytes(int32_t count)

Same as skip() except is uses number of bytes instead of number of bits as the parameter.

Seek

void Seek(uint64_t pos)

Repositions the read/write cursor to the specified bit.

Note the cursor can never skip past the capacity of the buffer, and will be clamped.

Align

u64 Align(uint32_t count = 1)

Aligns the read/write cursor to a byte boundary. determines the alignment in bytes.

Note the requested alignment might not be achieved if count > 1 and it would move the cursor past the capacity of the buffer, as the cursor will be clamped to buffer end regardless of alignment.

Returns number of bits skipped due to alignment.

Reserve

void Reserve(uint32_t count)

Expands the capacity to the specified number of bytes, unless already equal or greater.

Resize

void Resize(uint32_t count)

Expands the capacity and size to the specified number of bytes.

Capacity will not be reduced if already equal or larger.

Tell

uint64_t Tell() const

Returns the current read/write cursor position, in bits.

Eof

bool Eof() const

Returns true if the stream has reached the end.

Size

uint64_t Size() const

Returns the total number of bits available in the stream.

Capacity

uint64_t Capacity() const

Returns the total number of bits the stream can store without needing to allocate more memory.

Data

QuantType *Data() const

Returns the internal data buffer.

Cursor

QuantType *Cursor() const

Returns the byte the read/write cursor is currently positioned on.

Operators

operator=

Bitstream &operator=(const Bitstream &other)

operator=

Bitstream &operator=(Bitstream &&other)

Private

Methods

ReallocIfNeeded

void ReallocIfNeeded(uint64_t numBits)

Checks if the internal memory buffer needs to grow in order to accomodate bits.

Realloc

void Realloc(uint64_t numBits)

Reallocates the internal buffer making enough room for (rounded to a multiple of BYTES_PER_QUANT.

Fields

mData

QuantType * mData

mMaxBits

uint64_t mMaxBits

mNumBits

uint64_t mNumBits

mOwnsMemory

bool mOwnsMemory

mCursor

uint64_t mCursor