Streams
Stream and memory-buffer abstractions used by the codecs.
ua::FileStream
class
A seekable byte stream backed by a file on the local filesystem.
Wraps a C FILE* handle and implements the Stream contract over it. The stream owns its handle: the file is opened by open_for_read or open_for_write and closed by close or the destructor. Move transfers ownership of the handle and leaves the moved-from stream closed; the type is non-copyable.
Operations throw UaException carrying an ErrorDetail on failure (e.g. the file is not open, the underlying C stdio call fails, or an argument is out of range). Positions and lengths are byte offsets. Instances are not thread-safe; serialise access externally if shared across threads.
Stream
Functions
FileStream(std::filesystem::path filePath)
Constructs a closed stream bound to the given filesystem path.
filePath(std::filesystem::path) - Path to the target file. Must not be empty.
~FileStream() override
Closes the underlying file if it is still open.
FileStream(FileStream &&other) noexcept
Move-constructs from other, transferring ownership of its file handle.
other(FileStream &&) - Source stream; left closed after the move.
FileStream & operator=(FileStream &&other) noexcept
Move-assigns from other, closing any handle currently held first.
other(FileStream &&) - Source stream; left closed after the move.
Returns: Reference to this stream.
StatusCode open_for_read()
Opens the file for reading at the start of its contents.
Returns: Status::Good on success, or a Bad status if the file cannot be opened.
StatusCode open_for_write(bool eraseExisting, bool append)
Opens the file for reading and writing.
eraseExisting(bool) - If true, truncates any existing contents to zero length; if false, preserves them.append(bool) - If true, positions the stream at the end of the file after opening so writes append.
Returns: Status::Good on success, or a Bad status if the file cannot be opened.
bool can_read() const override
Returns true; a file stream always supports reading.
Returns: true; a file stream always supports reading.
bool can_write() const override
Returns true only when the stream was opened via open_for_write.
Returns: true if the stream was opened for writing; otherwise false.
bool can_seek() const override
Returns true; a file stream always supports seeking.
Returns: true; a file stream always supports seeking.
bool is_empty() const override
Returns true when the file is currently zero bytes long.
Returns: true if the file is currently zero bytes long.
size_t get_capacity() const override
Not supported for file streams.
Returns: Never returns; this operation is unsupported for file streams.
size_t get_length() const override
Returns the total length of the file in bytes.
Returns: File length in bytes.
size_t get_position() const override
Returns the current read/write position as a byte offset from the start.
Returns: Current position in bytes.
void flush() override
Flushes buffered writes to the underlying file.
void close() override
Closes the underlying file and releases its handle.
void read_all(span< byte > dest) const override
Reads exactly dest.size() bytes into dest, starting at the current position.
dest(span< byte >) - Destination buffer to fill; its size sets the byte count.
size_t read(span< byte > dest) const override
Reads up to dest.size() bytes into dest, starting at the current position.
dest(span< byte >) - Destination buffer; its size bounds the byte count.
Returns: Number of bytes actually read.
void write_all(span< const byte > source) override
Writes all of source to the file at the current position.
source(span< const byte >) - Bytes to write.
size_t write(span< const byte > source) override
Writes up to source.size() bytes to the file at the current position.
source(span< const byte >) - Bytes to write.
Returns: Number of bytes actually written.
void seek(int offset) const override
Moves the current position by offset bytes relative to its present value.
offset(int) - Signed byte delta; negative seeks toward the start.
void seek_from_start(size_t offset) const override
Moves the current position to offset bytes from the start of the file.
offset(size_t) - Absolute byte offset from the start.
void seek_from_end(int offset) const override
Moves the current position to offset bytes relative to the end of file.
offset(int) - Signed byte delta from end of file; negative seeks back into the file, zero positions at end of file.
ua::memory_stream_device::Dynamic
class
A growable, owning in-memory buffer.
Backs a writable MemoryStream with a std::vector<byte> that the device owns and grows on demand up to a fixed capacity. Writes past the current length extend the buffer; the capacity is the hard upper bound and is set at construction. Lengths and capacities are byte counts.
MemoryStream, ExternalWritable, ExternalReadOnly
Static functions
bool can_write()
Returns true; a dynamic buffer is always writable.
Returns: true; a dynamic buffer is always writable.
Functions
Dynamic()
Constructs a device whose capacity is the maximum 32-bit value and that reserves no storage up front.
Dynamic(size_t capacity, bool reserve)
Constructs a device with a fixed maximum capacity.
capacity(size_t) - Maximum number of bytes the buffer may grow to, in bytes; must be non-zero.reserve(bool) - When true, reserves capacity bytes of storage immediately so growth does not reallocate.
bool is_empty() const
Returns true when no bytes have been written yet.
Returns: true when no bytes have been written yet; false otherwise.
size_t get_capacity() const
Returns the maximum number of bytes the buffer may grow to, in bytes.
Returns: The maximum number of bytes the buffer may grow to, in bytes.
span< const byte > get_data() const
Returns a view over the bytes written so far.
Returns: A view over the bytes written so far.
std::vector< byte > move_storage_out()
Moves the underlying storage out of the device.
Returns: The owning byte vector. The device is left empty afterwards.
void write(span< const byte > source, size_t offset)
Writes source into the buffer at offset, growing it if needed.
source(span< const byte >) - Bytes to copy in.offset(size_t) - Byte offset at which to place source. offset plus the size of source must not exceed the capacity.
Static attributes
constexpr bool sPersistentExternalStorage
Not externally-owned persistent storage: the buffer is device-owned and may grow/reallocate, so its bytes must never be borrowed past a write or the device's lifetime.
ua::memory_stream_device::ExternalWritable
class
A writable, non-owning view over caller-provided storage.
Backs a writable MemoryStream with externally owned memory. The device does not own the buffer: the caller must keep the underlying storage alive for the lifetime of the device and any stream wrapping it. Capacity is the size of the storage span and is fixed; content length tracks how far the buffer has been filled. Lengths and capacities are byte counts.
MemoryStream, Dynamic, ExternalReadOnly
Static functions
bool can_write()
Returns true; external writable storage is always writable.
Returns: true; external writable storage is always writable.
Functions
ExternalWritable(span< byte > storage, size_t contentLength=0)
Wraps externally owned writable storage.
storage(span< byte >) - Caller-owned buffer the device writes into; must outlive the device.contentLength(size_t) - Number of leading bytes already populated, in bytes; must not exceed the size of storage.
bool is_empty() const
Returns true when the populated content length is zero.
Returns: true when the populated content length is zero; false otherwise.
size_t get_capacity() const
Returns the size of the backing storage, in bytes.
Returns: The size of the backing storage, in bytes.
span< const byte > get_data() const
Returns a view over the populated bytes.
Returns: A view over the populated bytes.
void write(span< const byte > source, size_t offset)
Writes source into the storage at offset, extending the content length if needed.
source(span< const byte >) - Bytes to copy in.offset(size_t) - Byte offset at which to place source. offset plus the size of source must not exceed the storage size.
Static attributes
constexpr bool sPersistentExternalStorage
Not eligible for a borrowed contiguous view: although the storage is caller-owned, it is writable (hence not immutable) and exposes only the populated content, which may not be NUL-terminated.
ua::memory_stream_device::ExternalReadOnly
class
A read-only, non-owning view over caller-provided storage.
Backs a non-writable MemoryStream with externally owned immutable memory. The device does not own the buffer: the caller must keep the underlying storage alive for the lifetime of the device and any stream wrapping it. Any write attempt fails. Lengths and capacities are byte counts.
MemoryStream, Dynamic, ExternalWritable
Static functions
bool can_write()
Returns false; read-only storage cannot be written.
Returns: false; read-only storage cannot be written.
void write(span< const byte > source, size_t offset)
Always fails; read-only storage cannot be written.
source(span< const byte >) - Bytes that would be written; ignored, as this device never accepts writes.offset(size_t) - Byte offset that would be written to; ignored.
Functions
ExternalReadOnly(span< const byte > storage)
Wraps externally owned read-only storage.
storage(span< const byte >) - Caller-owned immutable buffer the device reads from; must outlive the device.
bool is_empty() const
Returns true when the backing storage is empty.
Returns: true when the backing storage is empty; false otherwise.
size_t get_capacity() const
Returns the size of the backing storage, in bytes.
Returns: The size of the backing storage, in bytes.
span< const byte > get_data() const
Returns a view over the backing storage.
Returns: A view over the backing storage.
Static attributes
constexpr bool sPersistentExternalStorage
Externally-owned immutable storage: the buffer belongs to the caller (who must keep it alive), is never written, and get_data exposes it whole.
ua::MemoryStream
class
A seekable byte Stream backed by an in-memory buffer.
Implements the Stream contract over a storage device from memory_stream_device, selected as the Device template argument. The stream holds a non-owning reference to the device: the device (and any external buffer it refers to) must outlive the stream. Reads, writes and seeks move a single byte position; positions and lengths are byte offsets. Whether the stream is writable is delegated to the device.
Operations throw UaException carrying an ErrorDetail on failure (e.g. seeking past the end of the data, a null buffer argument, exceeding device capacity, or writing to a read-only device). Instances are not thread-safe; serialise access externally if shared across threads.
Device Storage backend from memory_stream_device (memory_stream_device::Dynamic, memory_stream_device::ExternalWritable, or memory_stream_device::ExternalReadOnly). Stream
Functions
MemoryStream(Device &device)
Wraps device, positioned at the start of its data.
device(Device &) - Storage backend the stream reads from and writes to; must outlive the stream.
bool can_read() const override
Returns true; a memory stream is always readable.
Returns: true; a memory stream is always readable.
bool can_write() const override
Returns true when the backing device is writable.
Returns: true when the backing device is writable; false otherwise.
bool can_seek() const override
Returns true; a memory stream is always seekable.
Returns: true; a memory stream is always seekable.
bool is_empty() const override
Returns true when the backing device holds no data.
Returns: true when the backing device holds no data; false otherwise.
size_t get_capacity() const override
Returns the maximum number of bytes the stream can hold, in bytes.
Returns: The maximum number of bytes the stream can hold, in bytes.
size_t get_length() const override
Returns the number of bytes currently stored, in bytes.
Returns: The number of bytes currently stored, in bytes.
size_t get_position() const override
Returns the current byte position within the stream.
Returns: The current byte position within the stream.
void flush() override
No-op; an in-memory stream has nothing to flush.
void close() override
No-op; an in-memory stream holds no resource to close.
void read_all(span< byte > dest) const override
Reads exactly dest.size() bytes into dest, advancing the position.
dest(span< byte >) - Buffer to fill; its size sets the number of bytes read.
size_t read(span< byte > dest) const override
Reads up to dest.size() bytes into dest, advancing the position.
dest(span< byte >) - Buffer to fill; its size sets the maximum bytes read.
Returns: The number of bytes read, which may be fewer than requested.
void write_all(span< const byte > source) override
Writes all of source into the stream, advancing the position.
source(span< const byte >) - Bytes to write.
size_t write(span< const byte > source) override
Writes up to the remaining capacity from source, advancing the position.
source(span< const byte >) - Bytes to write.
Returns: The number of bytes written, which may be fewer than source.size().
void seek(int offset) const override
Moves the current position by offset bytes, relative to the current position.
offset(int) - Signed byte displacement; negative values seek backwards.
void seek_from_start(size_t offset) const override
Sets the current position to offset bytes from the start.
offset(size_t) - Absolute byte position from the start of the data.
void seek_from_end(int offset) const override
Moves the current position by offset bytes, relative to the current position.
offset(int) - Signed byte displacement; negative values seek backwards.
optional< span< const byte > > contiguous_view() const override
Returns a view over the backing buffer when Device is externally-owned immutable storage (memory_stream_device::ExternalReadOnly); std::nullopt for owning/writable devices.
Returns: A view over the backing buffer, or std::nullopt for owning or writable devices.
ua::NullStream
class
A bottomless sink stream: writes are discarded and reads are unsupported.
Implements the Stream contract as a write-only "null device". Every byte written is discarded but still counted, so get_position advances by the number of bytes written; capacity is effectively unbounded. The stream is not readable and not seekable, and it has no defined length.
Read operations (read, read_all) and get_length throw UaException carrying a Status::BadNotSupported ErrorDetail. Positions are byte offsets. Instances are not thread-safe; serialise access externally if shared across threads.
Stream, FileStream
Functions
NullStream()=default
~NullStream()
bool can_read() const override
Returns false: a null stream is never readable.
Returns: false: a null stream is never readable.
bool can_write() const override
Returns true: writes are always accepted (and discarded).
Returns: true: writes are always accepted (and discarded).
bool can_seek() const override
Returns false: a null stream cannot seek.
Returns: false: a null stream cannot seek.
bool is_empty() const override
Returns false: a null stream is never considered empty.
Returns: false: a null stream is never considered empty.
size_t get_capacity() const override
Returns the effectively unbounded capacity (SIZE_MAX bytes).
Returns: The effectively unbounded capacity (SIZE_MAX bytes).
size_t get_length() const override
Not supported by a null stream.
Returns: Never returns; a null stream has no defined length.
size_t get_position() const override
Returns the current write position in bytes.
Returns: The current write position, in bytes.
void flush() override
Does nothing: there is no buffered data to flush.
void close() override
Does nothing: a null stream holds no resources to release.
void read_all(span< byte > dest) const override
Not supported by a null stream.
dest(span< byte >) - Destination buffer; left untouched.
size_t read(span< byte > dest) const override
Not supported by a null stream.
dest(span< byte >) - Destination buffer; left untouched.
Returns: Never returns; a null stream cannot be read.
void write_all(span< const byte > source) override
Discards all of source, advancing the position by its size.
source(span< const byte >) - Bytes to discard; their contents are ignored.
size_t write(span< const byte > source) override
Discards all of source, advancing the position by its size.
source(span< const byte >) - Bytes to discard; their contents are ignored.
Returns: The number of bytes accepted, always equal to source.size().
void seek(int offset) const override
Does nothing: a null stream cannot seek.
offset(int) - Ignored.
void seek_from_start(size_t offset) const override
Does nothing: a null stream cannot seek.
offset(size_t) - Ignored.
void seek_from_end(int offset) const override
Does nothing: a null stream cannot seek.
offset(int) - Ignored.
ua::Stream
class
Abstract interface for a seekable byte stream.
Models a stream of bytes that concrete devices (files, in-memory buffers, the null sink) implement. Reads and writes operate on raw std::byte spans and act at the stream's current position, which advances by the number of bytes transferred. All positions, lengths, and capacities are byte counts.
Operations are synchronous and blocking. On failure an implementation throws UaException carrying an ErrorDetail (e.g. the stream is closed, an argument is out of range, or the underlying device fails); a capability not offered by a device throws Status::BadNotSupported. Implementations are not thread-safe - serialise access externally if a stream is shared across threads.
FileStream, MemoryStream, NullStream
Functions
Stream()=default
Default-constructs the abstract base; only derived streams are instantiable.
~Stream()=default
Destroys the stream, releasing any underlying device or handle.
Copy-constructs the base subobject; a no-op as Stream holds no state (see note above).
Copy-assigns the base subobject; a no-op as Stream holds no state (see note above).
Returns: A reference to this stream.
Move-constructs the base subobject; a no-op as Stream holds no state (see note above).
Move-assigns the base subobject; a no-op as Stream holds no state (see note above).
Returns: A reference to this stream.
bool can_read() const =0
Returns whether the stream supports reading.
Returns: true if the stream supports reading; false otherwise.
bool can_write() const =0
Returns whether the stream supports writing.
Returns: true if the stream supports writing; false otherwise.
bool can_seek() const =0
Returns whether the stream supports seeking to an arbitrary position.
Returns: true if the stream supports seeking to an arbitrary position; false otherwise.
bool is_empty() const =0
Returns whether the stream currently holds no bytes (length is zero).
Returns: true if the stream currently holds no bytes; false otherwise.
size_t get_capacity() const =0
Returns the total number of bytes the stream can hold, in bytes.
Returns: The capacity in bytes.
size_t get_length() const =0
Returns the number of bytes currently stored, in bytes.
Returns: The length in bytes.
size_t get_position() const =0
Returns the current read/write position, in bytes from the start.
Returns: The position in bytes.
void flush()=0
Flushes any buffered output to the underlying device.
void close()=0
Closes the stream and releases the underlying device or handle.
void read_all(span< byte > dest) const =0
Reads exactly dest.size() bytes from the current position into dest.
dest(span< byte >) - Buffer to fill; its full size is read.
size_t read(span< byte > dest) const =0
Reads up to dest.size() bytes from the current position into dest.
dest(span< byte >) - Buffer to fill.
Returns: The number of bytes actually read, in the range [0, dest.size()].
void write_all(span< const byte > source)=0
Writes all bytes of source at the current position.
source(span< const byte >) - Bytes to write in full.
size_t write(span< const byte > source)=0
Writes up to source.size() bytes at the current position.
source(span< const byte >) - Bytes to write.
Returns: The number of bytes actually written, in the range [0, source.size()].
void seek(int offset) const =0
Moves the current position by offset bytes, relative to the current position.
offset(int) - Signed byte displacement; negative seeks backward.
void seek_from_start(size_t offset) const =0
Moves the current position to offset bytes from the start of the stream.
offset(size_t) - Absolute byte offset from the start.
void seek_from_end(int offset) const =0
Moves the current position by offset bytes, relative to the end of the stream.
offset(int) - Signed byte displacement from the end; negative seeks backward into the stream and zero positions at the end.
optional< span< const byte > > contiguous_view() const
Optional capability: a view over the stream's entire content when that content lives in externally-owned, immutable, contiguous storage that outlives the stream.
Returns: A view over the full content, or std::nullopt if the stream cannot make this guarantee.

