xentara-utils v2.0.4
The Xentara Utility Library
Loading...
Searching...
No Matches
xentara::utils::io::OutputStream< Element > Class Template Referenceabstract

Base class for input streams. More...

#include <xentara/utils/io/OutputStream.hpp>

+ Inheritance diagram for xentara::utils::io::OutputStream< Element >:

Public Types

using element_type = Element
 The element type.
 

Public Member Functions

virtual ~OutputStream () noexcept(false)=0
 Virtual, throwing destructor.
 
Write Functions
auto write (Element element) -> void
 Write a single element to the stream.
 
template<std::ranges::contiguous_range Data>
requires std::same_as<std::remove_cv_t<std::ranges::range_value_t<Data>>, Element>
auto write (const Data &data) -> void
 Write a block of data.
 
template<std::size_t kDataSize>
auto write (const Element(&data)[kDataSize]) -> void
 Write a block of data contained in an array.
 
template<std::contiguous_iterator Iterator, std::sized_sentinel_for< Iterator > Sentinel>
requires std::same_as<std::remove_cv_t<std::iter_value_t<Iterator>>, Element>
auto write (Iterator first, Sentinel last) -> void
 Write a block of data contained in an iterator range.
 
auto write (const Element *data, std::size_t size) -> void
 Write a block of data contained in a region of memory.
 
auto write (const Element *nullTerminatedString) -> void
 Write a NULL-teminated string.
 
auto flush () -> void
 Flushes the buffer.
 
- Public Member Functions inherited from xentara::utils::io::StreamBase
virtual ~StreamBase () noexcept(false)=0
 Virtual, throwing destructor.
 
auto streamDescription () const -> std::string
 Get a description of the device.
 

Protected Member Functions

 OutputStream () noexcept=default
 Default constructor.
 
 OutputStream (Element *bufferBegin, Element *bufferEnd) noexcept
 Constructor that sets an initially empty buffer.
 
 OutputStream (Element *bufferBegin, Element *bufferEnd, Element *dataEnd) noexcept
 Constructor that sets a buffer that possibly already contains some data.
 
 OutputStream (OutputStream &&other) noexcept
 Move constructor.
 
auto operator= (OutputStream &&rhs) noexcept -> OutputStream &
 Move assignemnt operator.
 
auto setWriteBuffer (Element *bufferBegin, Element *bufferEnd) noexcept -> void
 Sets a new empty buffer.
 
auto setWriteBuffer (Element *bufferBegin, Element *bufferEnd, Element *dataEnd) noexcept -> void
 Sets the buffer.
 
auto setWriteDataEnd (Element *dataEnd) noexcept -> void
 Sets the end of the data within the buffer.
 
auto writeBufferBegin () const -> Element *
 Writes back the buffer start position.
 
auto writeBufferEnd () const -> Element *
 Writes back the buffer end position.
 
auto writeBufferSize () const -> std::size_t
 Gets the buffer size.
 
auto writeDataBegin () const -> Element *
 Returns the beginning of data in the buffer.
 
auto writeDataEnd () const -> Element *
 Returns the end of the data in the buffer.
 
auto writeDataSize () const -> std::size_t
 Returns the size of the unwritten data in the buffer.
 
auto freeBufferBegin () const -> Element *
 Returns the beginning of the free region of the buffer.
 
auto freeBufferSize () const -> std::size_t
 Returns the size of the unwritten data in the buffer.
 
virtual auto doFlushWriteBuffer () -> void
 Called by the framework to write the buffered data to the underlying device once it is full.
 
virtual auto doWrite (const Element *data, std::size_t size) -> std::size_t=0
 Called by the framework to write data from a memory region to the underlying device.
 
- Protected Member Functions inherited from xentara::utils::io::StreamBase
virtual auto doGetStreamDescription () const -> std::string=0
 Called by the framework to get a description of the stream.
 

Detailed Description

template<StreamElement Element>
class xentara::utils::io::OutputStream< Element >

Base class for input streams.

Output streams provide an efficient way of writing data to a device as a sequence of elements. Output streams buffer the data, and hence generally provide better performance than raw devices.

Note
When deriving this class, you must supply a memory region to be used as write buffer. The derived class is responsible for allocating and deallocating the buffer, if this is necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.

Member Typedef Documentation

◆ element_type

template<StreamElement Element>
using xentara::utils::io::OutputStream< Element >::element_type = Element

The element type.

Constructor & Destructor Documentation

◆ ~OutputStream()

template<StreamElement Element>
virtual xentara::utils::io::OutputStream< Element >::~OutputStream ( )
pure virtual

Virtual, throwing destructor.

◆ OutputStream() [1/4]

template<StreamElement Element>
xentara::utils::io::OutputStream< Element >::OutputStream ( )
protecteddefaultnoexcept

Default constructor.

This constructor creates an empty stream with no buffer. You can set a buffer later on using the function setWriteBuffer()

◆ OutputStream() [2/4]

template<StreamElement Element>
xentara::utils::io::OutputStream< Element >::OutputStream ( Element *  bufferBegin,
Element *  bufferEnd 
)
protectednoexcept

Constructor that sets an initially empty buffer.

Note
The derived class is responsible for allocating and deallocating the buffer, if this is necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.
Parameters
bufferBeginA pointer to the beginning of the write buffer
bufferEndA pointer one past the end of the buffer

◆ OutputStream() [3/4]

template<StreamElement Element>
xentara::utils::io::OutputStream< Element >::OutputStream ( Element *  bufferBegin,
Element *  bufferEnd,
Element *  dataEnd 
)
protectednoexcept

Constructor that sets a buffer that possibly already contains some data.

Note
The derived class is responsible for allocating and deallocating the buffer, if this is necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.
Parameters
bufferBeginA pointer to the beginning of the read buffer
bufferEndA pointer one past the end of the buffer
dataEndA pointer one past the end of the data already in the buffer

◆ OutputStream() [4/4]

template<StreamElement Element>
xentara::utils::io::OutputStream< Element >::OutputStream ( OutputStream< Element > &&  other)
protectednoexcept

Move constructor.

This function will transfer the buffer and data positions from the other stream. The buffer and data positions of the other stream will be left as nullptr.

Parameters
otherThe stream to move from

Member Function Documentation

◆ doFlushWriteBuffer()

template<StreamElement Element>
virtual auto xentara::utils::io::OutputStream< Element >::doFlushWriteBuffer ( ) -> void
protectedvirtual

Called by the framework to write the buffered data to the underlying device once it is full.

This function must make new room in the buffer, usually by writing the data from the buffer to the stream, and emptying the buffer using setWriteDataEnd(). If the device supports write positions, this function should write data to the current write position, and advance the write position accordingly, as if conducting a regular write.

The framework clears the buffer after calling this function.

A reimplementation of this function can relocate or resize the buffer, if it whishes, by calling setWriteBuffer(). The derived class is then responsible for allocating the new buffer and deallocating the old buffer, if necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.

For communication streams, this function can block for a short time to wait for the stream to become writable. If the stream did not become writable within a reasonable time, an exception of type WriteTimeoutError should be thrown.

Default Implementation
The default implementation calls doWrite() to try to write out the buffered data.
Exceptions
StopRequestedImplementations that use a stop source may throw this exception if the stop source was triggered.
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 stream, the exception thrown should also be derived from ConnectionClosed, e.g. by using throwWithConnectionClosed().

◆ doWrite()

template<StreamElement Element>
virtual auto xentara::utils::io::OutputStream< Element >::doWrite ( const Element *  data,
std::size_t  size 
) -> std::size_t
protectedpure virtual

Called by the framework to write data from a memory region to the underlying device.

This function must write out at least some of the data contained in the given memory region. You can write less than the full amount of the data, in which case the framework may call the function multiple times as necessary.

This function is used in two ways:

  • The default implementaion of doFlushWriteBuffer() calls this function to flush the write buffer if it is full. doFlushWriteBuffer() will always pass the entire write buffer in data and size.
  • If you reimplement doFlushWriteBuffer(), the framework will only call this function if it whishes to bypass the normal write buffer and write data to the device directly. In this case the given buffer will always lie entirely outside the normal write buffer. In the first case, this function is only called when the normal write buffer is full. In the second case, it is only called when the normal write buffer is empty.

For communication streams, this function can block for a short time to wait for the stream to become writable. If the stream did not become writable within a reasonable time, an exception of type WriteTimeoutError should be thrown, or 0 returned.

Parameters
dataA pointer to the beginning of the data to be written. This is not necessarily the normal write buffer (see above).
sizeThe amout of data to write. The framework will never pass 0 for this parameter. Please note that this value may be greater than the maximum write 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 elements actually written. A return value of 0 is treated as an error.
Exceptions
StopRequestedImplementations that use a stop source may throw this exception if the stop source was triggered.
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 stream, the exception thrown should also be derived from ConnectionClosed, e.g. by using throwWithConnectionClosed().

Implemented in xentara::utils::io::AbstractDeviceOutputStream< Element >.

◆ flush()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::flush ( ) -> void

Flushes the buffer.

Exceptions
std::runtime_errorAn error occurred writing data to the underlying device

◆ freeBufferBegin()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::freeBufferBegin ( ) const -> Element *
protected

Returns the beginning of the free region of the buffer.

Note
This function is the same as writeDataEnd().
Returns
A pointer to the first free element of the buffer, which is always one past the end of the buffered data

◆ freeBufferSize()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::freeBufferSize ( ) const -> std::size_t
protected

Returns the size of the unwritten data in the buffer.

Returns
The size of the portion of the write buffer that does not contain any data yet

◆ operator=()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::operator= ( OutputStream< Element > &&  rhs) -> OutputStream &
protectednoexcept

Move assignemnt operator.

This operator swaps the buffer and data positions of this object and the other object

Parameters
rhsThe stream to move from
Returns
A reference to this object

◆ setWriteBuffer() [1/2]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::setWriteBuffer ( Element *  bufferBegin,
Element *  bufferEnd 
) -> void
protectednoexcept

Sets a new empty buffer.

This function discards any data in the old buffer.

Note
The derived class is responsible for allocating the new buffer and deallocating the old buffer, if necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.
Parameters
bufferBeginA pointer to the beginning of the write buffer
bufferEndA pointer one past the end of the buffer

◆ setWriteBuffer() [2/2]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::setWriteBuffer ( Element *  bufferBegin,
Element *  bufferEnd,
Element *  dataEnd 
) -> void
protectednoexcept

Sets the buffer.

This function discards any data in the old buffer.

Note
The derived class is responsible for allocating the new buffer and deallocating the old buffer, if necessary. This class only tracks the location of the buffer, it does not take ownership or responsibility for it.
Parameters
bufferBeginA pointer to the beginning of the read buffer
bufferEndA pointer one past the end of the buffer
dataEndA pointer one past the end of the data already in the buffer

◆ setWriteDataEnd()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::setWriteDataEnd ( Element *  dataEnd) -> void
protectednoexcept

Sets the end of the data within the buffer.

This function discards the old data.

Parameters
dataEndA pointer one past the end of the data already in the buffer

◆ write() [1/6]

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

Write a block of data.

Parameters
dataThe data to write
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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/6]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::write ( const Element *  data,
std::size_t  size 
) -> void

Write a block of data contained in a region of memory.

Parameters
dataA pointer to the data
sizeThe size of the data
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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/6]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::write ( const Element *  nullTerminatedString) -> void

Write a NULL-teminated string.

Requirements:
This function is only available for streams with characters as element.
Parameters
nullTerminatedStringThe string
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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() [4/6]

template<StreamElement Element>
template<std::size_t kDataSize>
auto xentara::utils::io::OutputStream< Element >::write ( const Element(&)  data[kDataSize]) -> void

Write a block of data contained in an array.

Parameters
dataThe array that contains the data
Template Parameters
kDataSizeThe size of the data. For character based streams, this includes the terminating NULL. The terminating NULL itself is not written.
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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() [5/6]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::write ( Element  element) -> void

Write a single element to the stream.

Parameters
elementThe element to write
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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() [6/6]

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::write ( Iterator  first,
Sentinel  last 
) -> void

Write a block of data contained in an iterator range.

Parameters
firstThe beginning of the range
lastThe postion after the end of the range
Exceptions
WriteTimeoutErrorThis exception is thrown on communication streams 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 streams that use a stop source if the stop source was triggered while waiting for the underlying device to become writable.
std::runtime_errorAn error occurred writing data to the underlying device
ConnectionClosedOn communication streams, 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.

◆ writeBufferBegin()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeBufferBegin ( ) const -> Element *
protected

Writes back the buffer start position.

This function merely returns the pointer set using one of the constructors or one of the setWriteBuffer() functions

Returns
A pointer to the beginning of the write buffer you set

◆ writeBufferEnd()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeBufferEnd ( ) const -> Element *
protected

Writes back the buffer end position.

This function merely returns the pointer set using one of the constructors or one of the setWriteBuffer() functions

Returns
A pointer one past the end of the buffer you set

◆ writeBufferSize()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeBufferSize ( ) const -> std::size_t
protected

Gets the buffer size.

This function merely returns the difference between the pointers set using the constructor or the setWriteBuffer().

Returns
The size of the buffer

◆ writeDataBegin()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeDataBegin ( ) const -> Element *
protected

Returns the beginning of data in the buffer.

Note
This function is the same as writeBufferBegin().
Returns
A pointer to the beginning of the buffered data, which is always the beginning of the buffer

◆ writeDataEnd()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeDataEnd ( ) const -> Element *
protected

Returns the end of the data in the buffer.

Returns
A pointer one past the end of the buffered data

◆ writeDataSize()

template<StreamElement Element>
auto xentara::utils::io::OutputStream< Element >::writeDataSize ( ) const -> std::size_t
protected

Returns the size of the unwritten data in the buffer.

Returns
The size of the buffered data that has not been written yet