xentara-utils v1.2.1
Xentara utilities library
Loading...
Searching...
No Matches
xentara::utils::io::OutputDevice Class Referenceabstract

Base class for all output devices. More...

#include <io/OutputDevice.hpp>

+ Inheritance diagram for xentara::utils::io::OutputDevice:

Public Member Functions

virtual ~OutputDevice () noexcept(false)=0
 Virtual, throwing destructor.
 
Write Functions
template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto write (const Data &data) -> void
 Writes a block of data.
 
auto writeByte (std::byte byte) -> void
 Write a single byte.
 
template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto writeChunk (const Data &data) -> std::ranges::range_size_t< Data >
 Writes a single chunk of data contained in an iterator range.
 
template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto tryWrite (const Data &data) -> std::ranges::range_size_t< Data >
 Write as much of a data block as is possible without blocking.
 
auto tryWriteByte (std::byte byte) -> bool
 Write a single byte, if this can be done without blocking.
 
Iterator Based Write Functions
template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_cv_t<std::iter_value_t<Iterator>>, std::byte>
auto write (Iterator first, Sentinel last) -> void
 Writes the data contained in an iterator range.
 
template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_cv_t<std::iter_value_t<Iterator>>, std::byte>
auto writeChunk (Iterator first, Sentinel last) -> Iterator
 Writes a single chunk of data from an an iterator range.
 
template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::iter_value_t<Iterator>, std::byte>
auto tryWrite (Iterator first, Sentinel last) -> Iterator
 Write as much of the data contained in an iterator range as is possible without blocking.
 
Low Level Write Functions
auto write (const std::byte *data, std::size_t size) -> void
 Write a block of data.
 
auto writeChunk (const std::byte *data, std::size_t size) -> std::size_t
 Writes a single chunk of data.
 
auto tryWrite (const std::byte *data, std::size_t size) -> std::size_t
 Write as much of a data block as is possible without blocking.
 
Accessing the Write Position
auto writePosition () const -> std::optional< std::size_t >
 Gets the current write position within the device.
 
auto setWritePosition (std::size_t position) -> std::optional< std::size_t >
 Sets the current write position within the device.
 
auto moveWritePosition (std::ptrdiff_t offset, std::ios_base::seekdir origin=std::ios_base::cur) -> std::optional< std::size_t >
 Advances or retreats the current write position within the device.
 
Waiting to Write Data
auto waitUntilWritable (std::chrono::nanoseconds timeout) -> bool
 Waits for the device to be able to accept more write data within a certain time.
 
auto writeTimeout () const noexcept -> std::chrono::nanoseconds
 Returns the write timeout for communication devices.
 
- Public Member Functions inherited from xentara::utils::io::DeviceBase
virtual ~DeviceBase () noexcept(false)=0
 Virtual, throwing destructor.
 
auto deviceDescription () const -> std::string
 Get a description of the device.
 

Protected Member Functions

virtual auto doWrite (const std::byte *data, std::size_t size) -> std::size_t=0
 Called by the framework to write data up to a maximum size.
 
virtual auto doWaitUntilWritable (std::optional< std::chrono::nanoseconds > timeout) -> bool
 Called by the framework to wait for the device to be able to accept more write data with an optional timeout.
 
virtual auto doWaitUntilWritableAndWrite (const std::byte *data, std::size_t size, std::chrono::nanoseconds timeout) -> std::size_t
 Called by the framework to wait for the device to be able to accept more write data, and then write to it.
 
virtual auto doGetWriteTimeout () const noexcept -> std::chrono::nanoseconds
 Called by the framework to get the write timeout.
 
virtual auto doGetWritePosition () const -> std::optional< std::size_t >
 Called by the framework to get the current write position within the device.
 
virtual auto doSetWritePosition (std::size_t position) -> std::optional< std::size_t >
 Called by the framework to set the current write position within the device.
 
virtual auto doMoveWritePosition (std::ptrdiff_t offset, std::ios_base::seekdir origin=std::ios_base::cur) -> std::optional< std::size_t >
 Called by the framework to advance or retreat the current write position within the device.
 
- Protected Member Functions inherited from xentara::utils::io::DeviceBase
virtual auto doGetDeviceDescription () const -> std::string=0
 Called by the framework to get a description of the device.
 

Detailed Description

Base class for all output devices.

Constructor & Destructor Documentation

◆ ~OutputDevice()

virtual xentara::utils::io::OutputDevice::~OutputDevice ( )
pure virtual

Virtual, throwing destructor.

Member Function Documentation

◆ doGetWritePosition()

virtual auto xentara::utils::io::OutputDevice::doGetWritePosition ( ) const -> std::optional<std::size_t>
protectedvirtual

Called by the framework to get the current write position within the device.

The default implementation returns std::nullopt

Returns
The write position as an offset from the beginning of the device, or std::nullopt if the device does not support the functionality.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doGetWriteTimeout()

virtual auto xentara::utils::io::OutputDevice::doGetWriteTimeout ( ) const -> std::chrono::nanoseconds
protectedvirtualnoexcept

Called by the framework to get the write timeout.

The write timeout is the maximum time allowed between chunks of data before write() or writeByte() throw an exception of type WriteTimeoutError.

Default Implementation
The default implementation returns a zero length timeout, causing a WriteTimeoutError to be thrown immediately once no data can be written.
Returns
The maximum allowed time between write data chunks on communication devices.

◆ doMoveWritePosition()

virtual auto xentara::utils::io::OutputDevice::doMoveWritePosition ( std::ptrdiff_t  offset,
std::ios_base::seekdir  origin = std::ios_base::cur 
) -> std::optional<std::size_t>
protectedvirtual

Called by the framework to advance or retreat the current write position within the device.

The default implementation returns std::nullopt

Parameters
offsetThe desired offset for write position. This offset may put the position past the end of the device, or before the beginning of the device, in which case the position must be set to the end or beginning of the device, respectively.
originThe origin for the move.
Returns
The new write position as an offset from the beginning of the device, or std::nullopt if the device does not support the functionality.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doSetWritePosition()

virtual auto xentara::utils::io::OutputDevice::doSetWritePosition ( std::size_t  position) -> std::optional<std::size_t>
protectedvirtual

Called by the framework to set the current write position within the device.

The default implementation calls doMoveWritePosition() with origin std::ios_base::cur

Parameters
positionThe desired new write position. This may lie past the end of the device, in which case the position must be set to the end of the device.
Returns
The actual new write position as an offset from the beginning of the device, or std::nullopt if the device does not support the functionality.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doWaitUntilWritable()

virtual auto xentara::utils::io::OutputDevice::doWaitUntilWritable ( std::optional< std::chrono::nanoseconds timeout) -> bool
protectedvirtual

Called by the framework to wait for the device to be able to accept more write data with an optional timeout.

This function must wait for the device to enter a state where the next call to doWrite() will not return std::nullopt, but either return an actual size, or throw an exception.

This function is usually only overridden for communication devices, which will wait for the device to go into a writable state or into an error state.

Default Implementation
The default implementation returns true, indicating that the next write will not block.
Parameters
timeoutThe number of nanoseconds to wait, or std::nullopt to wait indefinitely. If a timeout of 0 is passed, the function should not wait, but simply return whether the device can be written without blocking or not. The framework will never pass a negative value.
Returns
This function must always return true, except when a timeout was specified, and the timeout elapsed before anything relevent happened. The function must return true even if attempting to write to the device will result in an exception.
Exceptions
StopRequestedImplementations that use a stop source should throw this exception if the stop source was triggered.
std::runtime_error

This exception, or an appropriate subclass, must be thrown if an error occurs waiting for the data. Throwing an exception on error is optional if a subsequent call to doWrite() will itself throw a suitable exception.

Throwing an error is only required if doWaitUntilWritable() failed, but a subsequent call to doWrite() might still succeed. If this function uses the Linux poll(2) command, for example, and poll(2) sets the POLLERR flag in revents, you can just return true instead of throwing an exception, because a subsequent call to send(2) is guaranteed to fail. If poll(2) return -1, however, you must throw an exception, because a subsequent call to send(2) might still be successful.

◆ doWaitUntilWritableAndWrite()

virtual auto xentara::utils::io::OutputDevice::doWaitUntilWritableAndWrite ( const std::byte data,
std::size_t  size,
std::chrono::nanoseconds  timeout 
) -> std::size_t
protectedvirtual

Called by the framework to wait for the device to be able to accept more write data, and then write to it.

This function enables subclasses to optimize the case where the framework wants to wait for the device to become writable with a certain timeout, and then immediately write some data.

On most platforms, waiting for writability is accomplished by first attempting to do a non-blocking write to write any data that can be written immediately. If the write returns a special status to indicate that the operation would need to block, a wait function is called, and the write is repeated. On Posix platforms, for example, send() can be used to write data to a socket. If send() returns -1 with errno set to EAGAIN or EWOULDBLOCK, then poll() or select() is called to wait for the device to become writable, and the call to send() is repeated. The default implementation of doWaitUntilWritableAndWrite() uses exactly this strategy, calling doWrite() and doWaitUntilWritable() to do the writing and waiting, respectively.

On some platforms, however, different strategies are used. On Windows, for example, writing with a timeout is accomplished using overlapped I/O. Here, the write function returns FALSE with the last error set to ERROR_IO_PENDING if no buffer space is immediately available. In that case, WaitForSingleObject() is called to wait for the device to become writable, and GetOverlappedResult() to complete the write. Unlike Posix, the write function itself is never called a second time. In order to efficiently use overlapped I/O, doWaitUntilWritableAndWrite() must be overwritten to implement this strategy.

If you reimplement this function, it must be functionally equivalent to the following:

auto result = doWrite(data, size);
if (result == 0 && doWaitUntilWritable(timeout))
{
result = doWrite(data, size);
}
return result;
virtual auto doWaitUntilWritable(std::optional< std::chrono::nanoseconds > timeout) -> bool
Called by the framework to wait for the device to be able to accept more write data with an optional ...
Definition OutputDevice.hpp:348
virtual auto doWrite(const std::byte *data, std::size_t size) -> std::size_t=0
Called by the framework to write data up to a maximum size.
Parameters
dataA pointer to the data that needs to be written
sizeThe size of the data. The framework will never pass 0 for this parameter. Please note that this value may be greater than the maximum written size of the operating system (SSIZE_MAX on Posix, maximum DWORD value on Windows). Care must be taken to account for this in the implementation.
timeoutThe number of nanoseconds to wait. The framework will never always pass a positive value for the timeout. timeout will never be 0 or negative.
Returns
The number of bytes actually written, or 0 on timeout.
Default Implementation
The default implementation calls doWrite(const std::byte *, size) and doWaitUntilWritable() as described in the description.
Exceptions
std::runtime_errorThis exception or an appropriate subclass must be thrown if an error occurs. If the error is caused by the connection being closed on a communication device, the exception thrown should also be derived from ConnectionClosed, e.g. by using throwWithConnectionClosed().

◆ doWrite()

virtual auto xentara::utils::io::OutputDevice::doWrite ( const std::byte data,
std::size_t  size 
) -> std::size_t
protectedpure virtual

Called by the framework to write data up to a maximum size.

This function must write as much of the data as is possible without waiting, up to the size specified.

Parameters
dataA pointer to the data that needs to be written
sizeThe size of the data. The framework will never pass 0 for this parameter. Please note that this value may be greater than the maximum written size of the operating system (SSIZE_MAX on Posix, maximum DWORD value on Windows). Care must be taken to account for this in the implementation.
Returns
The number of bytes actually written, or 0, if no data can be written without blocking.
Exceptions
std::runtime_errorThis exception or an appropriate subclass must be thrown if an error occurs. If the error is caused by the connection being closed on a communication device, the exception thrown should also be derived from ConnectionClosed, e.g. by using throwWithConnectionClosed().

◆ moveWritePosition()

auto xentara::utils::io::OutputDevice::moveWritePosition ( std::ptrdiff_t  offset,
std::ios_base::seekdir  origin = std::ios_base::cur 
) -> std::optional< std::size_t >

Advances or retreats the current write position within the device.

This function will not move the write position beyond the boundaries of the device's data.

Parameters
offsetThe desired offset for the write position
originThe origin for the move
Returns
The new write position as an offset from the beginning of the device, or std::nullopt if the device does not support moving the write position using the given origin
Exceptions
std::runtime_errorMoving the write position as indicated is supported in principal, but an error occurred

◆ setWritePosition()

auto xentara::utils::io::OutputDevice::setWritePosition ( std::size_t  position) -> std::optional< std::size_t >

Sets the current write position within the device.

This function will adjust the write position if it lies outside the device's data.

Returns
The actual new write position as an offset from the beginning of the data, or std::nullopt if the device does not support setting the write position.
Exceptions
std::runtime_errorSetting the write position is supported in principal, but an error occurred

◆ tryWrite() [1/3]

template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto xentara::utils::io::OutputDevice::tryWrite ( const Data &  data) -> std::ranges::range_size_t<Data>

Write as much of a data block as is possible without blocking.

Writes as much data from a data block to the device as possible without blocking. The function will not block to wait until the device becomes writable. To wait until data can be written, use waitUntilWritable().

Parameters
dataThe data to write
Returns
The number of bytes actually written, or 0 if the device is not ready for writing.
Exceptions
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ tryWrite() [2/3]

auto xentara::utils::io::OutputDevice::tryWrite ( const std::byte data,
std::size_t  size 
) -> std::size_t

Write as much of a data block as is possible without blocking.

Writes as much data from a data block to the device as possible without blocking. The function will not block to wait until the device becomes writable. To wait until data can be written, use waitUntilWritable().

Parameters
dataThe address of the data block
sizeThe size of the data block
Returns
The number of bytes actually written.
Exceptions
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ tryWrite() [3/3]

template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::iter_value_t<Iterator>, std::byte>
auto xentara::utils::io::OutputDevice::tryWrite ( Iterator  first,
Sentinel  last 
) -> Iterator

Write as much of the data contained in an iterator range as is possible without blocking.

Writes as much data from an iterator range to the device as possible without blocking. The function will not block to wait until the device becomes writable. To wait until data can be written, use waitUntilWritable().

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Returns
The position after the last byte actually written
Exceptions
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ tryWriteByte()

auto xentara::utils::io::OutputDevice::tryWriteByte ( std::byte  byte) -> bool

Write a single byte, if this can be done without blocking.

Tries to writes a single byte to the device. The function will not block to wait until the device becomes writable. To wait until data can be written, use waitUntilWritable().

Parameters
byteThe byte to write.
Returns
Returns true if the byte `was written, or false if the device is not ready for writing
Exceptions
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ waitUntilWritable()

auto xentara::utils::io::OutputDevice::waitUntilWritable ( std::chrono::nanoseconds  timeout) -> bool

Waits for the device to be able to accept more write data within a certain time.

On communication devices, this function waits until the device is in a state where the next write operation will not block, and return true if that state was reached before the timeout elapsed.

On non-communication devices, this function always returns true immediately.

Note
A return value of true does not guarantee that the next write will be successful. This function will also return true if the next write operation will throw an exception, as long as it will not block.
Parameters
timeoutThe number of nanoseconds to wait. If you pass 0 or a negative value to this function, it will not wait, but simply return whether the device can be written without blocking or not.
Returns
Returns true if the device can be written without blocking, or false on timeout.
Exceptions
StopRequestedThe device is a communication device that uses a stop source, and that stop source was triggered.
std::runtime_errorAn error occurred accessing the device.

◆ write() [1/3]

template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto xentara::utils::io::OutputDevice::write ( const Data &  data) -> void

Writes a block of data.

On communication devices, this function will allow short delays (of up to the time returned by writeTimeout()) when sending the data. This ensures that data will still be sent correctly, even if network packets get delayed, or if the receiver is slow. The function will not block for long periods of time, however.

Parameters
dataThe data to write
Exceptions
WriteTimeoutErrorThis exception is thrown on communication devices if the send buffer is full and the data takes too long to be sent. This can mean that there is a network congestion, that the receiver is too slow, or that the receiver is not reading the data at all.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ write() [2/3]

auto xentara::utils::io::OutputDevice::write ( const std::byte data,
std::size_t  size 
) -> void

Write a block of data.

On communication devices, this function will allow short delays (of up to the time returned by writeTimeout()) when sending the data. This ensures that data will still be sent correctly, even if network packets get delayed, or if the receiver is slow. The function will not block for long periods of time, however.

Parameters
dataThe address of the data block
sizeThe size of the data block long to send all the data
Exceptions
WriteTimeoutErrorThis exception is thrown on communication devices if the send buffer is full and the data takes too long to be sent. This can mean that there is a network congestion, that the receiver is too slow, or that the receiver is not reading the data at all.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ write() [3/3]

template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_cv_t<std::iter_value_t<Iterator>>, std::byte>
auto xentara::utils::io::OutputDevice::write ( Iterator  first,
Sentinel  last 
) -> void

Writes the data contained in an iterator range.

On communication devices, this function will allow short delays (of up to the time returned by writeTimeout()) when sending the data. This ensures that data will still be sent correctly, even if network packets get delayed, or if the receiver is slow. The function will not block for long periods of time, however.

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Exceptions
WriteTimeoutErrorThis exception is thrown on communication devices if the send buffer is full and the data takes too long to be sent. This can mean that there is a network congestion, that the receiver is too slow, or that the receiver is not reading the data at all.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ writeByte()

auto xentara::utils::io::OutputDevice::writeByte ( std::byte  byte) -> void

Write a single byte.

On communication devices, this function will allow a short delay (of up to the time returned by writeTimeout()) when sending the byte. This ensures that the byte will still be sent correctly, even if network packets get delayed, or if the receiver is slow. The function will not block for long periods of time, however.

Parameters
byteThe byte to write.
Exceptions
WriteTimeoutErrorThis exception is thrown on communication devices if the send buffer is full and the data takes too long to be sent. This can mean that there is a network congestion, that the receiver is too slow, or that the receiver is not reading the data at all.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ writeChunk() [1/3]

template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, std::byte>
auto xentara::utils::io::OutputDevice::writeChunk ( const Data &  data) -> std::ranges::range_size_t<Data>

Writes a single chunk of data contained in an iterator range.

This function is intended to be called in a loop to write data to a device. It will write a chunk of data on each call.

On non-communication devices, this function is equivalant to tryWrite(). It will write some or all of the data in the block, at the discression of the operating system.

On communication devices, this function will try to wait for the device to become writable if no data can be written immediately. If the device cannot accept data after a certain time (the time returned by writeTimeout()), an exception is thrown.

Parameters
dataThe data to write
Returns
The number of bytes actually written. This function will never return 0, unless you pass an empty data block.
Exceptions
WriteTimeoutErrorNo data could be written before the write timeout on a communication device. On non-communication devices, this exception is never thrown.
std::runtime_errorAn error occurred writing the data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ writeChunk() [2/3]

auto xentara::utils::io::OutputDevice::writeChunk ( const std::byte data,
std::size_t  size 
) -> std::size_t

Writes a single chunk of data.

This function is intended to be called in a loop to write data to a device. It will write a chunk of data on each call.

On non-communication devices, this function is equivalant to tryWrite(). It will write some or all of the data in the block, at the discression of the operating system.

On communication devices, this function will try to wait for the device to become writable if no data can be written immediately. If the device cannot accept data after a certain time (the time returned by writeTimeout()), an exception is thrown.

Parameters
dataThe address of the data block
sizeThe size of the data block
Returns
The number of bytes actually written. This function will never return 0, unless you pass 0 for size.
Exceptions
WriteTimeoutErrorNo data could be written before the write timeout on a communication device. On non-communication devices, this exception is never thrown.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ writeChunk() [3/3]

template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_cv_t<std::iter_value_t<Iterator>>, std::byte>
auto xentara::utils::io::OutputDevice::writeChunk ( Iterator  first,
Sentinel  last 
) -> Iterator

Writes a single chunk of data from an an iterator range.

This function is intended to be called in a loop to write data to a device. It will write a chunk of data on each call.

On non-communication devices, this function is equivalant to tryWrite(). It will write some or all of the data in the block, at the discression of the operating system.

On communication devices, this function will try to wait for the device to become writable if no data can be written immediately. If the device cannot accept data after a certain time (the time returned by writeTimeout()), an exception is thrown.

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Returns
The position after the last byte actually written. This function will never return first itself (indicating no data was written), unless you pass an empty range.
Exceptions
WriteTimeoutErrorNo data could be written before the write timeout on a communication device. On non-communication devices, this exception is never thrown.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the device to become writable.
std::runtime_errorAn error occurred writing the data.
ConnectionClosedOn communication devices, errors thrown because the connection was closed are derived from ConnectionClosed in addition to std::runtime_error. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ writePosition()

auto xentara::utils::io::OutputDevice::writePosition ( ) const -> std::optional< std::size_t >

Gets the current write position within the device.

Returns
The write position as an offset from the beginning of the data, or std::nullopt if the device does not track a write position.
Exceptions
std::runtime_errorThe device tracks a write position, but an error occurred retreiving it

◆ writeTimeout()

auto xentara::utils::io::OutputDevice::writeTimeout ( ) const -> std::chrono::nanoseconds
noexcept

Returns the write timeout for communication devices.

The write timeout is the maximum time allowed between chunks of data before write() or writeByte() throw an exception of type WriteTimeoutError.

Returns
The maximum allowed time between write data chunks on communication devices.. On non-communication device, this function returns a zero-length timeout.