diff options
Diffstat (limited to 'include/cru/common/io/BufferStream.h')
-rw-r--r-- | include/cru/common/io/BufferStream.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/include/cru/common/io/BufferStream.h b/include/cru/common/io/BufferStream.h new file mode 100644 index 00000000..64d1bb56 --- /dev/null +++ b/include/cru/common/io/BufferStream.h @@ -0,0 +1,89 @@ +#pragma once + +#include "../Buffer.h" +#include "Stream.h" +#include "../Exception.h" + +#include <condition_variable> +#include <list> +#include <mutex> + +namespace cru::io { +class WriteAfterEofException : public Exception { + public: + using Exception::Exception; + ~WriteAfterEofException() override = default; +}; + +struct BufferStreamOptions { + /** + * @brief The size of a single buffer allocated each time new space is needed. + * Use default value if <= 0. + * + * When current buffer is full and there is no space for following data, a new + * buffer will be allocated and appended to the buffer list. Note if sum size + * of all buffers reaches the total_buffer_limit, no more buffer will be + * allocated but wait. + */ + Index block_size = 0; + + /** + * @brief Total size limit of saved data in buffer. Use default value if < 0. + * No limit if == 0. + * + * The size will be ceil(total_size_limit / block_size). When the buffer is + * filled, it will block and wait for user to read to get free space of buffer + * to continue read. + */ + Index total_size_limit = 0; +}; + +class BufferStream : public Stream { + public: + /** + * Actually I have no ideas about the best value for this. May change it later + * when I get some ideas. + */ + constexpr static Index kDefaultBlockSize = 1024; + + /** + * Actually I have no ideas about the best value for this. May change it later + * when I get some ideas. + */ + constexpr static Index kDefaultTotalSizeLimit = 1024; + + public: + BufferStream(const BufferStreamOptions& options); + + ~BufferStream() override; + + bool CanSeek() override; + Index Seek(Index offset, SeekOrigin origin = SeekOrigin::Current) override; + + bool CanRead() override; + Index Read(std::byte* buffer, Index offset, Index size) override; + + bool CanWrite() = 0; + Index Write(const std::byte* buffer, Index offset, Index size) = 0; + + virtual void Flush(); + + virtual void Close(); + + void SetEof(); + + private: + bool CheckClosed(); + + private: + Index block_size_; + Index total_size_limit_; + Index block_count_limit_; + + std::list<Buffer> buffer_list_; + bool eof_; + + std::mutex mutex_; + std::condition_variable condition_variable_; +}; +} // namespace cru::io |