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

Base class for all input devices. More...

#include <io/InputDevice.hpp>

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

Public Member Functions

virtual ~InputDevice () noexcept(false)=0
 Virtual, throwing destructor.
 
Read Functions
auto read (std::size_t size) -> core::RawDataBlock
 Reads a block of data of a specific size.
 
auto readByte () -> std::byte
 Reads a single byte.
 
auto tryReadByte () -> std::optional< std::byte >
 Tries to read a single byte from a device.
 
auto readAll () -> core::RawDataBlock
 Reads all remaining data.
 
auto readAll (std::size_t maxSize) -> core::RawDataBlock
 Reads all remaining data up to a maximum size.
 
auto readChunk () -> core::RawDataBlock
 Reads a single chunk of data.
 
auto readChunk (std::size_t maxSize) -> core::RawDataBlock
 Reads a single chunk of data up to a maximum size.
 
auto readAvailable () -> std::pair< core::RawDataBlock, bool >
 Reads all immediately available data.
 
auto readAvailable (std::size_t maxSize) -> std::pair< core::RawDataBlock, bool >
 Reads immediately available data up to a maximum size.
 
Array Based Read Functions
template<std::size_t kArraySize>
auto read (std::byte(&array)[kArraySize]) -> void
 Read a block of data into an array.
 
template<std::size_t kArraySize>
auto read (std::array< std::byte, kArraySize > &array) -> void
 Read a block of data into an array.
 
template<std::size_t kArraySize>
auto readChunk (std::byte(&array)[kArraySize]) -> core::RawDataBlock
 Reads a single chunk of data into an array.
 
template<std::size_t kArraySize>
auto readChunk (std::array< std::byte, kArraySize > &array) -> core::RawDataBlock
 Reads a single chunk of data into an array.
 
template<std::size_t kArraySize>
auto readAvailable (std::byte(&array)[kArraySize]) -> std::pair< std::size_t, bool >
 Reads immediately available data into an array.
 
template<std::size_t kArraySize>
auto readAvailable (std::array< std::byte, kArraySize > &array) -> std::pair< std::size_t, bool >
 Reads immediately available data into an array.
 
Iterator Based Read Functions
template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_volatile_t<std::iter_value_t<Iterator>>, std::byte>
auto read (Iterator first, Sentinel last) -> void
 Read data to fill 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 readChunk (Iterator first, Sentinel last) -> Iterator
 Reads a single chunk of data data into 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 readAvailable (Iterator first, Sentinel last) -> std::pair< Iterator, bool >
 Reads immediately available data into an iterator range.
 
Low Level Read Functions
auto read (std::byte *buffer, std::size_t size) -> void
 Read a block of data into a buffer.
 
auto readChunk (std::byte *buffer, std::size_t size) -> std::size_t
 Reads a single chunk of data into a buffer.
 
auto readAvailable (std::byte *buffer, std::size_t size) -> std::pair< std::size_t, bool >
 Reads immediately available data into a buffer.
 
auto availableReadSize () const -> std::optional< std::size_t >
 Get the number of bytes for reading without blocking.
 
auto remainingReadSize () const -> std::optional< std::size_t >
 Get the number of bytes remaining before the end of the device.
 
Accessing the Read Position
auto readPosition () const -> std::optional< std::size_t >
 Gets the current read position within the device.
 
auto setReadPosition (std::size_t position) -> std::optional< std::size_t >
 Sets the current read position within the device.
 
auto moveReadPosition (std::ptrdiff_t offset, std::ios_base::seekdir origin=std::ios_base::cur) -> std::optional< std::size_t >
 Advances or retreats the current read position within the device.
 
auto advanceReadPosition (std::size_t offset) -> std::optional< std::size_t >
 Advance the current read position within the device.
 
auto rewind () -> bool
 Sets the current read position to the beginning of the device.
 
Waiting for Read Data
auto waitForData () -> void
 Waits for more read data to become available.
 
auto waitForData (std::optional< std::chrono::nanoseconds > timeout) -> bool
 Waits for more read data to become available within a certain time.
 
auto readTimeout () const noexcept -> std::chrono::nanoseconds
 Returns the read timeout for communication devices.
 
Error Handling Functions
auto throwEndOfStreamError () const -> void
 Throws an error denoting the end of the stream.
 
- 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 doRead (std::byte *buffer, std::size_t size) -> std::optional< std::size_t >=0
 Called by the framework to read available data into a buffer up to a maximum size.
 
virtual auto doThrowEndOfStreamError () const -> void
 Called by the framework to throw an error denoting the end of the stream.
 
virtual auto doGetAvailableReadSize () const -> std::optional< std::size_t >
 Called by the framework to get the number of bytes that will be read by the next call to doRead().
 
virtual auto doGetRemainingReadSize () const -> std::optional< std::size_t >
 Called by the framework to get the number of bytes remaining before the end of the device.
 
virtual auto doWaitForData (std::optional< std::chrono::nanoseconds > timeout) -> bool
 Called by the framework to wait for more read data to become available.
 
virtual auto doWaitForDataAndRead (std::byte *buffer, std::size_t size, std::chrono::nanoseconds timeout) -> std::optional< std::size_t >
 Called by the framework to wait for read data to become available, and then read it.
 
virtual auto doGetReadTimeout () const noexcept -> std::chrono::nanoseconds
 Called by the framework to get the read timeout.
 
virtual auto doGetReadPosition () const -> std::optional< std::size_t >
 Called by the framework to get the current read position within the device.
 
virtual auto doSetReadPosition (std::size_t position) -> std::optional< std::size_t >
 Called by the framework to set the current read position within the device.
 
virtual auto doMoveReadPosition (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 read position within the device.
 
virtual auto doAdvanceReadPosition (std::size_t offset) -> std::optional< std::size_t >
 Called by the framework to advance the current read 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 input devices.

Input devices provide direct lower level access to the data and functionality of a device. For most use cases, input streams should be preferred, as they use buffering and other optimizations to accelerate sequential reading of the data.

Constructor & Destructor Documentation

◆ ~InputDevice()

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

Virtual, throwing destructor.

Member Function Documentation

◆ advanceReadPosition()

auto xentara::utils::io::InputDevice::advanceReadPosition ( std::size_t  offset) -> std::optional< std::size_t >

Advance the current read position within the device.

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

Attention
In contrast to moveReadPositio(), this function returns the number of bytes the read position was advanced, not the resulting absolute read position.
Parameters
offsetThe desired offset for the read position
Returns
The number of bytes the read position was actually advanced, or std::nullopt if the device does not support advancing the read position
Exceptions
std::runtime_errorAdvancing the read position is supported in principal, but an error occurred

◆ availableReadSize()

auto xentara::utils::io::InputDevice::availableReadSize ( ) const -> std::optional< std::size_t >

Get the number of bytes for reading without blocking.

Returns
The number of bytes available for immediate reading, or std::nullopt, if the available read size is unknown.
Exceptions
std::runtime_errorThe device tracks the available read size, but an error occurred retreiving it

◆ doAdvanceReadPosition()

virtual auto xentara::utils::io::InputDevice::doAdvanceReadPosition ( std::size_t  offset) -> std::optional< std::size_t >
protectedvirtual

Called by the framework to advance the current read position within the device.

Attention
In contrast to doMoveReadPosition(), this function must return the number of bytes the read position was advanced, not the resulting absolute read position.
Default Implementation
The default implementation uses doGetReadPosition() and doSetReadPosition() to advance the read position
Parameters
offsetThe desired offset for the read position. This offset may put the position past the end of the device, in which case the position must be set to the exact end of the device.
Returns
The number of bytes the read position was actually advanced, or std::nullopt if the device does not support the functionality.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doGetAvailableReadSize()

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

Called by the framework to get the number of bytes that will be read by the next call to doRead().

Default Implementation
The default implementation returns doGetRemainingReadSize()
Returns
The number of bytes available for immediate reading, or std::nullopt, if the functionality is not supported.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doGetReadPosition()

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

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

Default Implementation
The default implementation returns std::nullopt
Returns
The read 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

◆ doGetReadTimeout()

virtual auto xentara::utils::io::InputDevice::doGetReadTimeout ( ) const -> std::chrono::nanoseconds
protectedvirtualnoexcept

Called by the framework to get the read timeout.

The read timeout is the maximum time allowed between chunks of data before read() or readByte() throw an exception of type ReadTimeoutError.

Default Implementation
The default implementation returns a zero length timeout, causing a ReadTimeoutError to be thrown immediately once no data is available.
Returns
The maximum allowed time between read data chunks on communication devices.

◆ doGetRemainingReadSize()

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

Called by the framework to get the number of bytes remaining before the end of the device.

Default Implementation
The default implementation returns std::nullopt
Returns
The number of bytes available for immediate reading, or std::nullopt, if the functionality is not supported.
Exceptions
std::runtime_errorThe functionality is supported in principal, but an error occurred

◆ doMoveReadPosition()

virtual auto xentara::utils::io::InputDevice::doMoveReadPosition ( 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 read position within the device.

Default Implementation
The default implementation returns std::nullopt
Parameters
offsetThe desired offset for the read 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 read 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

◆ doRead()

virtual auto xentara::utils::io::InputDevice::doRead ( std::byte buffer,
std::size_t  size 
) -> std::optional< std::size_t >
protectedpure virtual

Called by the framework to read available data into a buffer up to a maximum size.

This function must read immediately available data into the given buffer, up to the maximum size specified.

Parameters
bufferA pointer to the buffer that will receive the data
sizeThe size of the buffer. The framework will never pass 0 for this parameter. Please note that this value may be greater than the maximum read 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 read, or std::nullopt, if no data is available without blocking. If no data is available because the end of the device has been reached, 0 must be returned.
Exceptions
std::runtime_errorThis exception or an appropriate subclass must be thrown if an error occurs.

◆ doSetReadPosition()

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

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

Default Implementation
The default implementation calls doMoveReadPosition() with origin std::ios_base::cur
Parameters
positionThe desired new read 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 read 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

◆ doThrowEndOfStreamError()

virtual auto xentara::utils::io::InputDevice::doThrowEndOfStreamError ( ) const -> void
protectedvirtual

Called by the framework to throw an error denoting the end of the stream.

The framework calls this function if doRead() returned 0, but more data was actually needed. Derived classes should throw an error of type EndOfStreamError with a descriptive text, like e.g. “end of file”, or “connection closed”. Communication devices should throw an exception that also derives from ConnectionClosed, e.g. by using throwWithConnectionClosed().

Default Implementation
The default implementation throws an exception with a generic message.
Exceptions
EndOfStreamErrorThis exception, or a suitable subclass, must always be thrown. Communication devices should throw an exception that derives from both EndOfStreamError and ConnectionClosed, e.g. by using throwWithConnectionClosed().

◆ doWaitForData()

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

Called by the framework to wait for more read data to become available.

This function must wait for the device to enter a state where the next call to doRead() 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 readable state or into an error state.

Default Implementation
The default implementation returns true, indicating that the next read 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 read 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 relevant happened. The function must return true even if attempting to read the device will result in an exception.

Do not return false on error, as false must only be returned on timeout. Instead, either throw an exception, or return true. On a communications device, you may throw an

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 doRead() will itself throw a suitable exception.

Throwing an error is only required if doWaitForData() failed, but a subsequent call to doRead() 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 recv(2) is guaranteed to fail. If poll(2) returns -1, however, you must throw an exception, because a subsequent call to recv(2) might still be successful.

◆ doWaitForDataAndRead()

virtual auto xentara::utils::io::InputDevice::doWaitForDataAndRead ( std::byte buffer,
std::size_t  size,
std::chrono::nanoseconds  timeout 
) -> std::optional< std::size_t >
protectedvirtual

Called by the framework to wait for read data to become available, and then read it.

This function enables subclasses to optimize the case where the framework wants to wait for data to arrive with a certain timeout, and immediately read it.

On most platforms, waiting for data is accomplished by first attempting to do a non-blocking read to read any immediately available data. If the read returns a special status to indicate that the operation would need to block, a wait function is called, and the read is repeated. On Posix platforms, for example, recv() can be used to read data from a socket. If recv() returns -1 with errno set to EAGAIN or EWOULDBLOCK, then poll() or select() is called to wait for data, and the call to recv() is repeated. The default implementation of doWaitForDataAndRead() uses exactly this strategy, calling doRead() and doWaitForData() to do the reading and waiting, respectively.

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

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

auto result = doRead(buffer, size);
if (!result && doWaitForData(timeout))
{
result = doRead(buffer, size);
}
return result;
virtual auto doWaitForData(std::optional< std::chrono::nanoseconds > timeout) -> bool
Called by the framework to wait for more read data to become available.
Definition InputDevice.hpp:687
virtual auto doRead(std::byte *buffer, std::size_t size) -> std::optional< std::size_t >=0
Called by the framework to read available data into a buffer up to a maximum size.
Parameters
bufferA pointer to the buffer that will receive the data
sizeThe size of the buffer. The framework will never pass 0 for this parameter. Please note that this value may be greater than the maximum read 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 read, or std::nullopt on timeout. If no data is available because the end of the device has been reached, 0 must be returned.
Default Implementation
The default implementation calls doRead(std::byte *, size) and doWaitForData() as described in the description.
Exceptions
StopRequestedImplementations that use a stop source should throw this exception if the stop source was triggered.
std::runtime_errorThis exception or an appropriate subclass must be thrown if an error occurs.

◆ moveReadPosition()

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

Advances or retreats the current read position within the device.

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

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

◆ read() [1/5]

auto xentara::utils::io::InputDevice::read ( Iterator  first,
Sentinel  last 
) -> void

Read data to fill an iterator range.

Reads a block of data into the given iterator range, filling the whole range.

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

This function will never block for significant periods of time to wait for data to become available. To wait for data that may only be sent later, use one of the waitForData() functions.

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the requested number of bytes were read. On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if data takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send enough data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for data.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ read() [2/5]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::read ( std::array< std::byte, kArraySize > &  array) -> void

Read a block of data into an array.

Reads a block of data into the given array, filing the whole array.

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

This function will never block for significant periods of time to wait for data to become available. To wait for data that may only be sent later, use one of the waitForData() functions.

Parameters
arrayThe array that will receive the data
Template Parameters
kArraySizeThe size of the buffer
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the requested number of bytes were read. On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if data takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send enough data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for data.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ read() [3/5]

auto xentara::utils::io::InputDevice::read ( std::byte buffer,
std::size_t  size 
) -> void

Read a block of data into a buffer.

Reads a block of data of a specific size into the given buffer address.

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

This function will never block for significant periods of time to wait for data to become available. To wait for data that may only be sent later, use one of the waitForData() functions.

Parameters
bufferA pointer to the buffer that will receive the data
sizeThe size of the buffer
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the requested number of bytes were read. On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if data takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send enough data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for data.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ read() [4/5]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::read ( std::byte(&)  array[kArraySize]) -> void

Read a block of data into an array.

Reads a block of data into the given array, filing the whole array.

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

This function will never block for significant periods of time to wait for data to become available. To wait for data that may only be sent later, use one of the waitForData() functions.

Parameters
arrayThe array that will receive the data
Template Parameters
kArraySizeThe size of the array
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the requested number of bytes were read. On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if data takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send enough data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for data.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ read() [5/5]

auto xentara::utils::io::InputDevice::read ( std::size_t  size) -> core::RawDataBlock

Reads a block of data of a specific size.

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

This function will never block for significant periods of time to wait for data to become available. To wait for data that may only be sent later, use waitForData().

Parameters
sizeThe size of the data to read
Returns
The data read
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the requested number of bytes were read. On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if data takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send enough data.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for data.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ readAll() [1/2]

auto xentara::utils::io::InputDevice::readAll ( ) -> core::RawDataBlock

Reads all remaining data.

Reads all remaining data from the device. On Communication devices, this will keep reading data until the connection is closed. For this reason, this function should be used with caution on communication devices, as it may block indefinitely.

Returns
The remaining data
Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAll() [2/2]

auto xentara::utils::io::InputDevice::readAll ( std::size_t  maxSize) -> core::RawDataBlock

Reads all remaining data up to a maximum size.

Reads all remaining data from the device, up to the given maximum number of bytes. On Communication devices, this will keep reading data until the connection is closed. For this reason, this function should be used with caution on communication devices, as it may block indefinitely.

Parameters
maxSizeThe maximum size of the data to read
Returns
The data that was read.
Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [1/6]

auto xentara::utils::io::InputDevice::readAvailable ( ) -> std::pair< core::RawDataBlock, bool >

Reads all immediately available data.

Reads all immediately available data from the device. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function.

Returns

A pair containing the data read, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

On communication devices, waitForData() should be called before calling the function again, to allow for more data to arrive.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [2/6]

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::InputDevice::readAvailable ( Iterator  first,
Sentinel  last 
) -> std::pair<Iterator, bool>

Reads immediately available data into an iterator range.

Reads all immediately available data from the device into an iterator range, up to the end of the range. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function.

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Returns

A pair containing the position after the last byte written to the range, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

If you pass an empty range, then nothing will be read, and the returned flag will always be true.

On communication devices, waitForData() should be called before calling the function again, to allow more data to arrive. The call can be omitted if the returned iterator points to the end of the range, as some data that did not fit in the range may still be available right away.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [3/6]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::readAvailable ( std::array< std::byte, kArraySize > &  array) -> std::pair<std::size_t, bool>

Reads immediately available data into an array.

Reads all immediately available data from the device into an array, up to the size of the array. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function. functions.

Template Parameters
kArraySizeThe size of the array
Parameters
arrayThe array that will receive the data
Returns

A pair containing the actual size of the data read, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

On communication devices, waitForData() should be called before calling the function again, to allow more data to arrive. The call can be omitted if the returned size is the entire size of the array, as some data that did not fit in the array may still be available right away.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [4/6]

auto xentara::utils::io::InputDevice::readAvailable ( std::byte buffer,
std::size_t  size 
) -> std::pair< std::size_t, bool >

Reads immediately available data into a buffer.

Reads all immediately available data from the device into a buffer, up to the size of the buffer. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function.

Parameters
bufferA pointer to the buffer that will receive the data
sizeThe size of the buffer
Returns

A pair containing the actual size of the data read, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

If you pass 0 for size, then nothing will be read, and the returned flag will always be true.

On communication devices, waitForData() should be called before calling the function again, to allow more data to arrive. The call can be omitted if the returned size is the entire size of the buffer, as some data that did not fit in the buffer may still be available right away.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [5/6]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::readAvailable ( std::byte(&)  array[kArraySize]) -> std::pair<std::size_t, bool>

Reads immediately available data into an array.

Reads all immediately available data from the device into an array, up to the size of the array. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function.

Template Parameters
kArraySizeThe size of the array
Parameters
arrayThe array that will receive the data
Returns

A pair containing the actual size of the data read, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

On communication devices,waitForData() should be called before calling the function again, to allow more data to arrive. The call can be omitted if the returned size is the entire size of the array, as some data that did not fit in the array may still be available right away.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readAvailable() [6/6]

auto xentara::utils::io::InputDevice::readAvailable ( std::size_t  maxSize) -> std::pair< core::RawDataBlock, bool >

Reads immediately available data up to a maximum size.

Reads all immediately available data from the device, up to the given maximum number of bytes. This function will never block to wait for data to become available. To wait for data, call waitForData() before calling this function.

Parameters
maxSizeThe maximum size of the data to read
Returns

A pair containing the data read, and a flag denoting whether more data may become available if the function is called again. If the flag is true, then the function can be called again to retreive more data. If the flag is false, then all data has been exhausted, e.g. because the end of the file has been reched, or because the communications channel has been closed.

If you pass 0 for maxSize, then nothing will be read, and the returned flag will always be true.

On communication devices, waitForData() should be called before calling the function again, to allow more data to arrive. The call can be omitted if the returned data block is exactly maxSize bytes long, as some data that exceeded maxSize may still be available right away.

On non-communication devices, waitForData() do not need to be called, but it is safe to call it anyways. If you do not know (or care) if the device is a communication device, you can safely call waitForData() before calling this function.

Exceptions
std::runtime_errorAn error occurred reading the data.

◆ readByte()

auto xentara::utils::io::InputDevice::readByte ( ) -> std::byte

Reads a single byte.

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

This function will never block for significant periods of time to wait for data to become available. To wait for a byte that may only be sent later, use waitForData().

Returns
The byte that was read.
Exceptions
EndOfStreamErrorThis exception is thrown if the end of the data is reached before the byte was read On communication devices, this exception is also derived from ConnectionClosed and denotes that the connection was gracefully closed.
ReadTimeoutErrorThis exception is thrown on communication devices if the byte takes too long to arrive. This can mean that there is a network congestion, that the sender is too slow, or that the sender did not send a byte at all.
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered while waiting for the byte to arrive.
std::runtime_errorA different error occurred.
ConnectionClosedOn communication devices, any EndOfStreamError thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ readChunk() [1/6]

auto xentara::utils::io::InputDevice::readChunk ( ) -> core::RawDataBlock

Reads a single chunk of data.

This function is intended to be called in a loop to read all the data from a device. It will return a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning chunks until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), an exception is thrown.

Returns
The data read, or an empty block if the end of the data has been reached. On communication devices, this means that the connection has been closed by either side.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readChunk() [2/6]

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::InputDevice::readChunk ( Iterator  first,
Sentinel  last 
) -> Iterator

Reads a single chunk of data data into an iterator range.

This function is intended to be called in a loop to read all the data from a device. It will return a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning chunks until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), 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 written to the range, or first the end of the data has been reached. On communication devices, this means that the connection has been closed by either side. first will also be returned if you pass an empty range.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readChunk() [3/6]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::readChunk ( std::array< std::byte, kArraySize > &  array) -> core::RawDataBlock

Reads a single chunk of data into an array.

This function is intended to be called in a loop to read all the data from a device. It will read a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning data until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), an exception is thrown.

Template Parameters
kArraySizeThe size of the array
Parameters
arrayThe array that will receive the data
Returns
The data read, or 0 the end of the data has been reached. On communication devices, this means that the connection has been closed by either side.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readChunk() [4/6]

auto xentara::utils::io::InputDevice::readChunk ( std::byte buffer,
std::size_t  size 
) -> std::size_t

Reads a single chunk of data into a buffer.

This function is intended to be called in a loop to read all the data from a device. It will read a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning data until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), an exception is thrown.

Parameters
bufferA pointer to the buffer that will receive the data
sizeThe size of the buffer
Returns
The data read, or 0 the end of the data has been reached. On communication devices, this means that the connection has been closed by either side. 0 will also be returned if size is 0.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readChunk() [5/6]

template<std::size_t kArraySize>
auto xentara::utils::io::InputDevice::readChunk ( std::byte(&)  array[kArraySize]) -> core::RawDataBlock

Reads a single chunk of data into an array.

This function is intended to be called in a loop to read all the data from a device. It will read a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning data until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), an exception is thrown.

Template Parameters
kArraySizeThe size of the array
Parameters
arrayThe array that will receive the data
Returns
The data read, or 0 the end of the data has been reached. On communication devices, this means that the connection has been closed by either side.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readChunk() [6/6]

auto xentara::utils::io::InputDevice::readChunk ( std::size_t  maxSize) -> core::RawDataBlock

Reads a single chunk of data up to a maximum size.

This function is intended to be called in a loop to read all the data from a device. It will return a chunk of data on each call, until no more data is available.

On non-communication devices, this function is equivalant to readAvailable(). It will keep returning a chunk of data until the device’s data has been exhausted. On a file device, for example, this function will keep returning chunks until the end of the file.

On communication devices, this function will try to wait for data to arrive if none is available immediately. If no data has been received after a certain time (the time returned by readTimeout()), an exception is thrown.

Parameters
maxSizeThe maximum size of the data to read
Returns
The data read, or an empty block the end of the data has been reached. On communication devices, this means that the connection has been closed by either side. An empty block will also be returned if maxSize is 0.
Exceptions
ReadTimeoutErrorNo data arrived before the read 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 data.
std::runtime_errorAn error occurred reading the data.

◆ readPosition()

auto xentara::utils::io::InputDevice::readPosition ( ) const -> std::optional< std::size_t >

Gets the current read position within the device.

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

◆ readTimeout()

auto xentara::utils::io::InputDevice::readTimeout ( ) const -> std::chrono::nanoseconds
noexcept

Returns the read timeout for communication devices.

The read timeout is the maximum time allowed between chunks of data before read() or readByte() throw an exception of type ReadTimeoutError.

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

◆ remainingReadSize()

auto xentara::utils::io::InputDevice::remainingReadSize ( ) const -> std::optional< std::size_t >

Get the number of bytes remaining before the end of the device.

Returns
The number of bytes available for immediate reading, or std::nullopt, if the device size is unknown.
Exceptions
std::runtime_errorThe device tracks the data size, but an error occurred retreiving it

◆ rewind()

auto xentara::utils::io::InputDevice::rewind ( ) -> bool

Sets the current read position to the beginning of the device.

Returns
Returns false if the device does not support setting the read position.
Exceptions
std::runtime_errorSetting the read position is supported in principal, but an error occurred

◆ setReadPosition()

auto xentara::utils::io::InputDevice::setReadPosition ( std::size_t  position) -> std::optional< std::size_t >

Sets the current read position within the device.

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

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

◆ throwEndOfStreamError()

auto xentara::utils::io::InputDevice::throwEndOfStreamError ( ) const -> void

Throws an error denoting the end of the stream.

This function is meant to be used in conjunction with readAvailable(). If readAvailable() does not return enough data, and the flag returned is false, then you can call this function to throw an error. Do not throw this function if the flag returned by readAvailable() is true: instead, call waitForData() to wait for more data to arrive.

Exceptions
EndOfStreamErrorThis exception, or a suitable subclass, is always thrown.
ConnectionClosedOn communication devices, the error thrown is also derived from ConnectionClosed. This allows you to handle closed connections during read and write operations in the same catch block by catching exceptions of type ConnectionClosed.

◆ tryReadByte()

auto xentara::utils::io::InputDevice::tryReadByte ( ) -> std::optional< std::byte >

Tries to read a single byte from a device.

Tries to reads a single byte from the device.

This function will never block for significant periods of time to wait for data to become available. To wait for a byte that may only be sent later, use waitForData().

Returns
The byte that was read, or std::nullopt if th end of the device data was reached.
Exceptions
std::runtime_errorAn error occurred reading the data.

◆ waitForData() [1/2]

auto xentara::utils::io::InputDevice::waitForData ( ) -> void

Waits for more read data to become available.

On communication devices, this function waits until the device is in a state where the next read operation will not block.

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

Note
This function does not guarantee that the next read will be successful when it returns. It will also return when the next read operation will throw an exception, as long as it will not block.
Exceptions
StopRequestedThis exception is thrown on communication devices that use a stop source if the stop source was triggered during the wait.
std::runtime_errorAn error occurred accessing the device.

◆ waitForData() [2/2]

auto xentara::utils::io::InputDevice::waitForData ( std::optional< std::chrono::nanoseconds timeout) -> bool

Waits for more read data to become available within a certain time.

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

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

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