Streams#

Output Streams/Buffer#

#include <dplx/dp/streams/output_buffer.hpp>
namespace dplx::dp {}
class output_buffer#

The (soon to be) universal way encoders interact with output streams. It is an abstract base class managing the memory being written to by the encoder and forwards the content to the underlying stream via do_grow and do_bulk_write.

output_buffer models a contiguous_range of bytes which can be directly written. If an encoder needs more space than currently available it may call ensure_size which asks the underlying stream for the next buffer (and fails with errc::end_of_stream if it runs out of space).

Type Aliases

using element_type = std::byte#
using value_type = std::byte#
using pointer = std::byte*#
using iterator = std::byte*#
using size_type = std::size_t#
using difference_type = std::ptrdiff_t#

Special Member Functions

protected ~output_buffer() noexcept = default#

The destructor is trivial but protected to prevent accidental deletion of the base instead of the derived object.

protected output_buffer() noexcept#

Initializes the output_buffer to an empty range/buffer.

output_buffer(output_buffer const&) noexcept = default#

The copy constructor is trivial but protected to prevent accidental slicing.

auto operator=(output_buffer const&) noexcept -> output_buffer& = default#

The copy assignment operator is trivial but protected to prevent accidental slicing.

protected output_buffer(std::byte *buffer, std::size_t bufferSize) noexcept#

Initializes the instance with the given buffer. This should be used to avoid a do_grow call on the first write if possible.

Member Functions

void commit_written(size_type numBytes)#

Informs the buffer that numBytes have been written. The buffer will remove these bytes from the beginning of the output_range and therefore shrink by numBytes.

auto ensure_size(size_type requestedSize) noexcept -> result<void>#

Tries to get a buffer from the underlying stream which is at least requestedSize bytes big. May invalidate all iterators and pointers.

If the current buffer doesn’t satisfy the new size requirement do_grow will be called which may fail if no more space is available.

Warning

Data written to the current buffer which has not been committed by calling commit_written() is not guaranteed to survive and might be lost.

private virtual auto do_grow(size_type requestedSize) noexcept -> result<void> = 0#

Asks the derived class to reset() this instance with a buffer at least as big as requestedSize. The implementation is responsible for actually outputting the committed area of the current buffer (which _might_ be a no-op if streaming to memory).

protected void reset() noexcept#

Resets this output range to an empty state.

protected void reset(std::byte *buffer, std::size_t bufferSize)#

Resets this output range to [buffer, buffer + bufferSize).

auto bulk_write(std::byte const *bytes, std::size_t bytesSize) noexcept -> result<void>#

Fills the current buffer starting at begin() with the data pointed at by bytes and commits these bytes as if calling commit_written() afterwards. If more bytes are being written than can fit into the current buffer, the remainder gets forwarded to do_bulk_write().

private auto do_bulk_write(std::byte const *bytes, std::size_t bytesSize) noexcept -> result<void> = 0#

Asks the derived class to output the current buffer and append the given data to the stream. The current buffer is guaranteed to be full i.e. empty() returns true. The implementation is encouraged to reset() this instance to a (not necessarily) new buffer to avoid a do_grow() call.

Contiguous Output Range Functions

[[nodiscard]] auto begin() noexcept -> iterator#
[[nodiscard]] auto end() noexcept -> iterator#
[[nodiscard]] auto data() noexcept -> pointer#
[[nodiscard]] auto size() const noexcept -> size_type#
[[nodiscard]] auto empty() const noexcept -> bool#