diff options
Diffstat (limited to 'include/jau/byte_stream.hpp')
-rw-r--r-- | include/jau/byte_stream.hpp | 516 |
1 files changed, 240 insertions, 276 deletions
diff --git a/include/jau/byte_stream.hpp b/include/jau/byte_stream.hpp index 220af27..e67d81c 100644 --- a/include/jau/byte_stream.hpp +++ b/include/jau/byte_stream.hpp @@ -2,10 +2,6 @@ * Author: Sven Gothel <[email protected]> * Copyright (c) 2021 Gothel Software e.K. * - * ByteInStream, ByteInStream_SecMemory and ByteInStream_istream are derived from Botan under same license: - * - Copyright (c) 1999-2007 Jack Lloyd - * - Copyright (c) 2005 Matthew Gregan - * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -38,9 +34,6 @@ #include <jau/ringbuffer.hpp> #include <jau/file_util.hpp> -// Include Botan header files before this one to be integrated w/ Botan! -// #include <botan_all.h> - #include <jau/io_util.hpp> using namespace jau::fractions_i64_literals; @@ -52,49 +45,153 @@ namespace jau::io { * @{ */ -#ifdef BOTAN_VERSION_MAJOR - #define VIRTUAL_BOTAN - #define OVERRIDE_BOTAN override - #define NOEXCEPT_BOTAN -#else - #define VIRTUAL_BOTAN virtual - #define OVERRIDE_BOTAN - #define NOEXCEPT_BOTAN noexcept -#endif + /** + * Mimic std::ios_base::iostate for state functionality, see iostate_func. + * + * This `enum class` type fulfills `C++ named requirements: BitmaskType`. + */ + enum class iostate : uint32_t { + /** No error occurred nor has EOS being reached. Value is no bit set! */ + none = 0, + + /** No error occurred nor has EOS being reached. Value is no bit set! */ + goodbit = 0, + + /** Irrecoverable stream error, including loss of integrity of the underlying stream or media. */ + badbit = 1 << 0, + + /** An input operation reached the end of its stream. */ + eofbit = 1 << 1, + + /** Input or output operation failed (formatting or extraction error). */ + failbit = 1 << 2 + }; + constexpr uint32_t number(const iostate rhs) noexcept { + return static_cast<uint32_t>(rhs); + } + constexpr iostate operator ~(const iostate rhs) noexcept { + return static_cast<iostate> ( ~number(rhs) ); + } + constexpr iostate operator ^(const iostate lhs, const iostate rhs) noexcept { + return static_cast<iostate> ( number(lhs) ^ number(rhs) ); + } + constexpr iostate operator |(const iostate lhs, const iostate rhs) noexcept { + return static_cast<iostate> ( number(lhs) | number(rhs) ); + } + constexpr iostate operator &(const iostate lhs, const iostate rhs) noexcept { + return static_cast<iostate> ( number(lhs) & number(rhs) ); + } + constexpr iostate& operator |=(iostate& lhs, const iostate rhs) noexcept { + lhs = static_cast<iostate> ( number(lhs) | number(rhs) ); + return lhs; + } + constexpr iostate& operator &=(iostate& lhs, const iostate rhs) noexcept { + lhs = static_cast<iostate> ( number(lhs) & number(rhs) ); + return lhs; + } + constexpr iostate& operator ^=(iostate& lhs, const iostate rhs) noexcept { + lhs = static_cast<iostate> ( number(lhs) ^ number(rhs) ); + return lhs; + } + constexpr bool operator ==(const iostate lhs, const iostate rhs) noexcept { + return number(lhs) == number(rhs); + } + constexpr bool operator !=(const iostate lhs, const iostate rhs) noexcept { + return !( lhs == rhs ); + } + std::string to_string(const iostate mask) noexcept; /** - * This class represents an abstract byte input stream object. + * Supporting std::basic_ios's iostate functionality for all ByteInStream implementations. + */ + class iostate_func { + private: + iostate m_state; + + protected: + constexpr iostate rdstate_impl() const noexcept { return m_state; } + constexpr void setstate_impl(iostate state) const noexcept { const_cast<iostate_func*>(this)->m_state |= state; } + + public: + iostate_func() noexcept + : m_state( iostate::goodbit ) {} + + iostate_func(const iostate_func& o) noexcept = default; + iostate_func(iostate_func&& o) noexcept = default; + iostate_func& operator=(const iostate_func &o) noexcept = default; + iostate_func& operator=(iostate_func &&o) noexcept = default; + + virtual ~iostate_func() noexcept {} + + /** Clears state flags by assignment to the given value. */ + virtual void clear(const iostate state = iostate::goodbit) noexcept { m_state = state; } + + /** + * Returns the current state flags. + * + * Method is marked `virtual` to allow implementations with asynchronous resources + * to determine or update the current iostate. + * + * Method is used throughout all query members and setstate(), + * hence they all will use the updated state from a potential override implementation. + */ + virtual iostate rdstate() const noexcept { return m_state; } + + /** Sets state flags, by keeping its previous bits. */ + void setstate(const iostate state) noexcept { clear( rdstate() | state ); } + + /** Checks if no error nor eof() has occurred i.e. I/O operations are available. */ + bool good() const noexcept + { return iostate::goodbit == rdstate(); } + + /** Checks if end-of-file has been reached. */ + bool eof() const noexcept + { return iostate::none != ( rdstate() & iostate::eofbit ); } + + /** Checks if an error has occurred. */ + bool fail() const noexcept + { return iostate::none != ( rdstate() & ( iostate::badbit | iostate::failbit ) ); } + + /** Checks if an error has occurred, synonym of fail(). */ + bool operator!() const noexcept { return fail(); } + + /** Checks if no error has occurred, synonym of !fail(). */ + explicit operator bool() const noexcept { return !fail(); } + + /** Checks if a non-recoverable error has occurred. */ + bool bad() const noexcept + { return iostate::none != ( rdstate() & iostate::badbit ); } + }; + + /** + * Abstract byte input stream object. * * @anchor byte_in_stream_properties * ### ByteInStream Properties * The byte input stream can originate from a local source w/o delay, * remote URL like http connection or even from another thread feeding the input buffer.<br /> * Both latter asynchronous resources may expose blocking properties - * in check_available(). + * in available(). * * Asynchronous resources benefit from knowing their content size, - * as their check_available() implementation may avoid + * as their available() implementation may avoid * blocking and waiting for requested bytes available * if the stream is already beyond its scope. * - * All method implementations are of `noexcept` - * and declared as such if used standalone w/o Botan.<br/> - * However, if using Botan, the `noexcept` qualifier is dropped - * for compatibility with Botan::DataSource virtual function table. + * All method implementations are of `noexcept`. * - * One may use error() to detect whether an error has occurred, - * while end_of_data() not only covered the EOS case but includes error(). + * One may use fail() to detect whether an error has occurred, + * while end_of_data() not only covers the end-of-stream (EOS) case but includes fail(). * * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - class ByteInStream -#ifdef BOTAN_VERSION_MAJOR - : public Botan::DataSource -#endif + class ByteInStream : public iostate_func { public: - ByteInStream() = default; - virtual ~ByteInStream() NOEXCEPT_BOTAN = default; + ByteInStream() noexcept + : iostate_func() {} + + virtual ~ByteInStream() noexcept = default; ByteInStream& operator=(const ByteInStream&) = delete; ByteInStream(const ByteInStream&) = delete; @@ -104,38 +201,56 @@ namespace jau::io { virtual void close() noexcept = 0; /** - * Check whether n bytes are available in the input stream. + * Return whether n bytes are available in the input stream, + * if has_content_size() or using an asynchronous source. * - * This method may be blocking when using an asynchronous source - * up until the requested bytes are actually available. + * If !has_content_size() and not being an asynchronous source, + * !end_of_data() is returned. + * + * Method may be blocking when using an asynchronous source + * up until the requested bytes are available. * * A subsequent call to read() shall return immediately with at least - * the requested numbers of bytes available. + * the requested numbers of bytes available, + * if has_content_size() or using an asynchronous source. + * + * See details of the implementing class. * * @param n byte count to wait for * @return true if n bytes are available, otherwise false * + * @see has_content_size() * @see read() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - VIRTUAL_BOTAN bool check_available(size_t n) NOEXCEPT_BOTAN OVERRIDE_BOTAN = 0; + virtual bool available(size_t n) noexcept = 0; /** * Read from the source. Moves the internal offset so that every * call to read will return a new portion of the source. * - * Use check_available() to wait and ensure a certain amount of bytes are available. + * Use available() to try to wait for a certain amount of bytes available. + * + * This method shall only block until `min(available, length)` bytes are transfered. * - * This method is not blocking. + * See details of the implementing class. * * @param out the byte array to write the result to * @param length the length of the byte array out * @return length in bytes that was actually read and put into out * - * @see check_available() + * @see available() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - [[nodiscard]] VIRTUAL_BOTAN size_t read(uint8_t out[], size_t length) NOEXCEPT_BOTAN OVERRIDE_BOTAN = 0; + [[nodiscard]] virtual size_t read(void* out, size_t length) noexcept = 0; + + /** + * Read one byte. + * @param out the byte to read to + * @return length in bytes that was actually read and put + * into out + */ + size_t read(uint8_t& out) noexcept; /** * Read from the source but do not modify the internal @@ -147,40 +262,7 @@ namespace jau::io { * @param peek_offset the offset into the stream to read at * @return length in bytes that was actually read and put into out */ - [[nodiscard]] VIRTUAL_BOTAN size_t peek(uint8_t out[], size_t length, size_t peek_offset) const NOEXCEPT_BOTAN OVERRIDE_BOTAN = 0; - - /** - * Test whether the source still has data that can be read. - * - * This may include a failure and/or error in the underlying implementation, see error() - * - * @return true if there is no more data to read, false otherwise - * @see error() - */ - VIRTUAL_BOTAN bool end_of_data() const NOEXCEPT_BOTAN OVERRIDE_BOTAN = 0; - - /** - * Return whether an error has occurred, excluding end_of_data(). - * - * @return true if an error has occurred, false otherwise - */ - virtual bool error() const noexcept = 0; - -#ifndef BOTAN_VERSION_MAJOR - - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const noexcept { return ""; } - - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(uint8_t& out) noexcept; + [[nodiscard]] virtual size_t peek(void* out, size_t length, size_t peek_offset) noexcept = 0; /** * Peek at one byte. @@ -188,27 +270,38 @@ namespace jau::io { * @return length in bytes that was actually read and put * into out */ - size_t peek_byte(uint8_t& out) const noexcept; + size_t peek(uint8_t& out) noexcept; /** * Discard the next N bytes of the data * @param N the number of bytes to discard * @return number of bytes actually discarded */ - size_t discard_next(size_t N) noexcept; + size_t discard(size_t N) noexcept; -#endif /* BOTAN_VERSION_MAJOR */ + /** + * Test whether the source still has data that can be read, synonym for !good(). + * + * Hence this includes errors in the underlying implementation, see fail() + * + * @return true if there is no more data to read, false otherwise + * @see good() + * @see fail() + */ + bool end_of_data() const noexcept { return !good(); } /** - * @return number of bytes read so far. + * return the id of this data source + * @return std::string representing the id of this data source */ - VIRTUAL_BOTAN size_t get_bytes_read() const NOEXCEPT_BOTAN OVERRIDE_BOTAN = 0; + virtual std::string id() const noexcept { return ""; } /** - * Variant of Botan's get_byte_read() using uint64_t for big files on a 32-bit platform. + * Returns the input position indicator, similar to std::basic_istream. + * * @return number of bytes read so far. */ - virtual uint64_t bytes_read() const noexcept = 0; + virtual uint64_t tellg() const noexcept = 0; /** * Returns true if implementation is aware of content_size(), otherwise false. @@ -226,19 +319,15 @@ namespace jau::io { }; /** - * This class represents a secure Memory-Based byte input stream + * Secure Memory-Based byte input stream */ class ByteInStream_SecMemory final : public ByteInStream { public: - size_t read(uint8_t[], size_t) NOEXCEPT_BOTAN override; - - size_t peek(uint8_t[], size_t, size_t) const NOEXCEPT_BOTAN override; + size_t read(void*, size_t) noexcept override; - bool check_available(size_t n) NOEXCEPT_BOTAN override; + size_t peek(void*, size_t, size_t) noexcept override; - bool end_of_data() const NOEXCEPT_BOTAN override; - - bool error() const noexcept override { return false; } + bool available(size_t n) noexcept override; /** * Construct a secure memory source that reads from a string @@ -270,11 +359,9 @@ namespace jau::io { void close() noexcept override; - ~ByteInStream_SecMemory() NOEXCEPT_BOTAN override { close(); } - - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return m_offset; } + ~ByteInStream_SecMemory() noexcept override { close(); } - uint64_t bytes_read() const noexcept override { return m_offset; } + uint64_t tellg() const noexcept override { return m_offset; } bool has_content_size() const noexcept override { return true; } @@ -288,146 +375,42 @@ namespace jau::io { }; /** - * This class represents a std::istream based byte input stream. - */ - class ByteInStream_istream final : public ByteInStream { - public: - size_t read(uint8_t[], size_t) NOEXCEPT_BOTAN override; - size_t peek(uint8_t[], size_t, size_t) const NOEXCEPT_BOTAN override; - bool check_available(size_t n) NOEXCEPT_BOTAN override; - bool end_of_data() const NOEXCEPT_BOTAN override; - bool error() const noexcept override { return m_source.bad(); } - std::string id() const NOEXCEPT_BOTAN override; - - ByteInStream_istream(std::istream&, const std::string& id = "<std::istream>") noexcept; - - ByteInStream_istream(const ByteInStream_istream&) = delete; - - ByteInStream_istream& operator=(const ByteInStream_istream&) = delete; - - void close() noexcept override; - - ~ByteInStream_istream() NOEXCEPT_BOTAN override { close(); } - - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return m_bytes_consumed; } - - uint64_t bytes_read() const noexcept override { return m_bytes_consumed; } - - bool has_content_size() const noexcept override { return false; } - - uint64_t content_size() const noexcept override { return 0; } - - std::string to_string() const noexcept override; - - private: - const std::string m_identifier; - - std::istream& m_source; - size_t m_bytes_consumed; - }; - - - /** - * Mimic std::iobase::iostate + * File based byte input stream, including named file descriptor. * - * This `enum class` type fulfills `C++ named requirements: BitmaskType`. - */ - enum class iostate : uint32_t { - /** No error occurred nor has EOS being reached. Value is no bit set! */ - none = 0, - - /** No error occurred nor has EOS being reached. Value is no bit set! */ - goodbit = 0, - - /** Irrecoverable stream error, including loss of integrity of the underlying stream or media. */ - badbit = 1 << 0, - - /** An input operation reached the end of its stream. */ - eofbit = 1 << 1, - - /** Input or output operation failed (formatting or extraction error). */ - failbit = 1 << 2 - }; - constexpr uint32_t number(const iostate rhs) noexcept { - return static_cast<uint32_t>(rhs); - } - constexpr iostate operator ~(const iostate rhs) noexcept { - return static_cast<iostate> ( ~number(rhs) ); - } - constexpr iostate operator ^(const iostate lhs, const iostate rhs) noexcept { - return static_cast<iostate> ( number(lhs) ^ number(rhs) ); - } - constexpr iostate operator |(const iostate lhs, const iostate rhs) noexcept { - return static_cast<iostate> ( number(lhs) | number(rhs) ); - } - constexpr iostate operator &(const iostate lhs, const iostate rhs) noexcept { - return static_cast<iostate> ( number(lhs) & number(rhs) ); - } - constexpr iostate& operator |=(iostate& lhs, const iostate rhs) noexcept { - lhs = static_cast<iostate> ( number(lhs) | number(rhs) ); - return lhs; - } - constexpr iostate& operator &=(iostate& lhs, const iostate rhs) noexcept { - lhs = static_cast<iostate> ( number(lhs) & number(rhs) ); - return lhs; - } - constexpr iostate& operator ^=(iostate& lhs, const iostate rhs) noexcept { - lhs = static_cast<iostate> ( number(lhs) ^ number(rhs) ); - return lhs; - } - constexpr bool operator ==(const iostate lhs, const iostate rhs) noexcept { - return number(lhs) == number(rhs); - } - constexpr bool operator !=(const iostate lhs, const iostate rhs) noexcept { - return !( lhs == rhs ); - } - std::string to_string(const iostate mask) noexcept; - - /** - * This class represents a file based byte input stream, including named file descriptor. + * Implementation mimics std::ifstream via OS level file descriptor (FD) operations, + * giving more flexibility, allowing reusing existing FD and enabling openat() operations. * * If source path denotes a named file descriptor, i.e. jau::fs::file_stats::is_fd() returns true, - * has_content_size() returns false and check_available() returns true as long the stream is open and EOS hasn't occurred. + * has_content_size() returns false and available() returns true as long the stream is open and EOS hasn't occurred. */ class ByteInStream_File final : public ByteInStream { private: jau::fs::file_stats stats; - /** - * We mimic std::ifstream via OS level file descriptor operations, - * giving us more flexibility and enabling use of openat() operations. - */ + int m_fd; - mutable iostate m_state; + bool m_has_content_length; + uint64_t m_content_size; + uint64_t m_bytes_consumed; + uint64_t get_available() const noexcept { return m_has_content_length ? m_content_size - m_bytes_consumed : 0; } - // Remember: constexpr specifier used in a function or static data member (since C++17) declaration implies inline + public: + size_t read(void*, size_t) noexcept override; + size_t peek(void*, size_t, size_t) noexcept override; + bool available(size_t n) noexcept override; + /** Checks if the stream has an associated file. */ constexpr bool is_open() const noexcept { return 0 <= m_fd; } - constexpr bool good() const noexcept - { return iostate::goodbit == m_state; } + std::string id() const noexcept override { return stats.path(); } - constexpr bool eof() const noexcept - { return iostate::none != ( m_state & iostate::eofbit ); } - - constexpr bool fail() const noexcept - { return iostate::none != ( m_state & ( iostate::badbit | iostate::failbit ) ); } - - constexpr bool bad() const noexcept - { return iostate::none != ( m_state & iostate::badbit ); } - - constexpr iostate rdstate() const noexcept { return m_state; } - void clear(iostate state = iostate::goodbit) const noexcept { m_state = state; } - void setstate(iostate state) const noexcept { m_state |= state; } - - public: - size_t read(uint8_t[], size_t) NOEXCEPT_BOTAN override; - size_t peek(uint8_t[], size_t, size_t) const NOEXCEPT_BOTAN override; - bool check_available(size_t n) NOEXCEPT_BOTAN override; - bool end_of_data() const NOEXCEPT_BOTAN override; - bool error() const noexcept override { return fail(); } - std::string id() const NOEXCEPT_BOTAN override { return stats.path(); } + /** + * Returns the file descriptor if is_open(), otherwise -1 for no file descriptor. + * + * @see is_open() + */ + int fd() const noexcept { return m_fd; } /** * Construct a stream based byte input stream from filesystem path @@ -466,23 +449,15 @@ namespace jau::io { void close() noexcept override; - ~ByteInStream_File() NOEXCEPT_BOTAN override { close(); } - - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return (size_t)m_bytes_consumed; } + virtual ~ByteInStream_File() noexcept override { close(); } - uint64_t bytes_read() const noexcept override { return m_bytes_consumed; } + uint64_t tellg() const noexcept override { return m_bytes_consumed; } bool has_content_size() const noexcept override { return m_has_content_length; } uint64_t content_size() const noexcept override { return m_content_size; } std::string to_string() const noexcept override; - - private: - uint64_t get_available() const noexcept { return m_has_content_length ? m_content_size - m_bytes_consumed : 0; } - bool m_has_content_length; - uint64_t m_content_size; - uint64_t m_bytes_consumed; }; /** @@ -507,37 +482,35 @@ namespace jau::io { * @see read() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - bool check_available(size_t n) NOEXCEPT_BOTAN override; + bool available(size_t n) noexcept override; /** * Read from the source. Moves the internal offset so that every * call to read will return a new portion of the source. * - * Use check_available() to wait and ensure a certain amount of bytes are available. + * Use available() to wait and ensure a certain amount of bytes are available. * - * This method is not blocking. + * This method is not blocking beyond the transfer of `min(available, length)` bytes. * * @param out the byte array to write the result to * @param length the length of the byte array out * @return length in bytes that was actually read and put into out * - * @see check_available() + * @see available() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - size_t read(uint8_t out[], size_t length) NOEXCEPT_BOTAN override; - - size_t peek(uint8_t out[], size_t length, size_t peek_offset) const NOEXCEPT_BOTAN override; + size_t read(void* out, size_t length) noexcept override; - bool end_of_data() const NOEXCEPT_BOTAN override; + size_t peek(void* out, size_t length, size_t peek_offset) noexcept override; - bool error() const noexcept override { return async_io_result_t::FAILED == m_result; } + iostate rdstate() const noexcept override; - std::string id() const NOEXCEPT_BOTAN override { return m_url; } + std::string id() const noexcept override { return m_url; } /** * Construct a ringbuffer backed Http byte input stream * @param url the URL of the data to read - * @param timeout maximum duration in fractions of seconds to wait @ check_available() for next bytes, where fractions_i64::zero waits infinitely + * @param timeout maximum duration in fractions of seconds to wait @ available() for next bytes, where fractions_i64::zero waits infinitely */ ByteInStream_URL(const std::string& url, const jau::fraction_i64& timeout) noexcept; @@ -547,11 +520,9 @@ namespace jau::io { void close() noexcept override; - ~ByteInStream_URL() NOEXCEPT_BOTAN override { close(); } + ~ByteInStream_URL() noexcept override { close(); } - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return (size_t)m_bytes_consumed; } - - uint64_t bytes_read() const noexcept override { return m_bytes_consumed; } + uint64_t tellg() const noexcept override { return m_bytes_consumed; } bool has_content_size() const noexcept override { return m_has_content_length; } @@ -580,11 +551,11 @@ namespace jau::io { * * If the above fails, ByteInStream_File is attempted. * - * If non of the above leads to a ByteInStream without ByteInStream::error(), nullptr is returned. + * If non of the above leads to a ByteInStream without ByteInStream::fail(), nullptr is returned. * * @param path_or_uri given path or uri for with a ByteInStream instance shall be established. - * @param timeout in case `path_or_uri` resolves to ByteInStream_URL, timeout is being used as maximum duration to wait for next bytes at ByteInStream_URL::check_available(), defaults to 20_s - * @return a working ByteInStream w/o ByteInStream::error() or nullptr + * @param timeout in case `path_or_uri` resolves to ByteInStream_URL, timeout is being used as maximum duration to wait for next bytes at ByteInStream_URL::available(), defaults to 20_s + * @return a working ByteInStream w/o ByteInStream::fail() or nullptr */ std::unique_ptr<ByteInStream> to_ByteInStream(const std::string& path_or_uri, jau::fraction_i64 timeout=20_s) noexcept; @@ -606,37 +577,35 @@ namespace jau::io { * @see read() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - bool check_available(size_t n) NOEXCEPT_BOTAN override; + bool available(size_t n) noexcept override; /** * Read from the source. Moves the internal offset so that every * call to read will return a new portion of the source. * - * Use check_available() to wait and ensure a certain amount of bytes are available. + * Use available() to wait and ensure a certain amount of bytes are available. * - * This method is not blocking. + * This method is not blocking beyond the transfer of `min(available, length)` bytes. * * @param out the byte array to write the result to * @param length the length of the byte array out * @return length in bytes that was actually read and put into out * - * @see check_available() + * @see available() * @see @ref byte_in_stream_properties "ByteInStream Properties" */ - size_t read(uint8_t out[], size_t length) NOEXCEPT_BOTAN override; - - size_t peek(uint8_t out[], size_t length, size_t peek_offset) const NOEXCEPT_BOTAN override; + size_t read(void* out, size_t length) noexcept override; - bool end_of_data() const NOEXCEPT_BOTAN override; + size_t peek(void* out, size_t length, size_t peek_offset) noexcept override; - bool error() const noexcept override { return async_io_result_t::FAILED == m_result; } + iostate rdstate() const noexcept override; - std::string id() const NOEXCEPT_BOTAN override { return m_id; } + std::string id() const noexcept override { return m_id; } /** * Construct a ringbuffer backed externally provisioned byte input stream * @param id_name arbitrary identifier for this instance - * @param timeout maximum duration in fractions of seconds to wait @ check_available() and write(), where fractions_i64::zero waits infinitely + * @param timeout maximum duration in fractions of seconds to wait @ available() and write(), where fractions_i64::zero waits infinitely */ ByteInStream_Feed(const std::string& id_name, const jau::fraction_i64& timeout) noexcept; @@ -646,11 +615,9 @@ namespace jau::io { void close() noexcept override; - ~ByteInStream_Feed() NOEXCEPT_BOTAN override { close(); } + ~ByteInStream_Feed() noexcept override { close(); } - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return m_bytes_consumed; } - - uint64_t bytes_read() const noexcept override { return m_bytes_consumed; } + uint64_t tellg() const noexcept override { return m_bytes_consumed; } bool has_content_size() const noexcept override { return m_has_content_length; } @@ -659,7 +626,7 @@ namespace jau::io { /** * Interrupt a potentially blocked reader. * - * Call this method if intended to abort streaming and to interrupt the reader thread's potentially blocked check_available() call, + * Call this method if intended to abort streaming and to interrupt the reader thread's potentially blocked available() call, * i.e. done at set_eof() * * @see set_eof() @@ -699,7 +666,7 @@ namespace jau::io { * * @see interruptReader() */ - void set_eof(const async_io_result_t result) noexcept { m_result = result; interruptReader(); } + void set_eof(const async_io_result_t result) noexcept; std::string to_string() const noexcept override; @@ -719,27 +686,26 @@ namespace jau::io { /** * This class represents a wrapped byte input stream with the capability - * to record the byte stream read out at will. + * to record the read byte stream at will. * * Peek'ed bytes won't be recorded, only read bytes. */ class ByteInStream_Recorder final : public ByteInStream { public: - size_t read(uint8_t[], size_t) NOEXCEPT_BOTAN override; + size_t read(void*, size_t) noexcept override; - size_t peek(uint8_t out[], size_t length, size_t peek_offset) const NOEXCEPT_BOTAN override { + size_t peek(void* out, size_t length, size_t peek_offset) noexcept override { return m_parent.peek(out, length, peek_offset); } - bool check_available(size_t n) NOEXCEPT_BOTAN override { - return m_parent.check_available(n); + bool available(size_t n) noexcept override { + return m_parent.available(n); } - bool end_of_data() const NOEXCEPT_BOTAN override { return m_parent.end_of_data(); } - - bool error() const noexcept override { return m_parent.error(); } + void clear(iostate state = iostate::goodbit) noexcept override { m_parent.clear( state ); } + iostate rdstate() const noexcept override { return m_parent.rdstate(); } - std::string id() const NOEXCEPT_BOTAN override { return m_parent.id(); } + std::string id() const noexcept override { return m_parent.id(); } /** * Construct a byte input stream wrapper using the given parent ByteInStream. @@ -755,11 +721,9 @@ namespace jau::io { void close() noexcept override; - ~ByteInStream_Recorder() NOEXCEPT_BOTAN override { close(); } - - size_t get_bytes_read() const NOEXCEPT_BOTAN override { return m_parent.get_bytes_read(); } + ~ByteInStream_Recorder() noexcept override { close(); } - uint64_t bytes_read() const noexcept override { return m_bytes_consumed; } + uint64_t tellg() const noexcept override { return m_bytes_consumed; } bool has_content_size() const noexcept override { return m_parent.has_content_size(); } |