diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2025-10-07 09:12:22 +0200 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2025-10-07 09:13:15 +0200 |
| commit | c87f9627efc8b612eb9b000acfcc6731cad15765 (patch) | |
| tree | 34eb4b9e70a51c2f3db3a97c2aef31ba0b139ec9 /test/io_test_helper.cc | |
Initial commit
Diffstat (limited to 'test/io_test_helper.cc')
| -rw-r--r-- | test/io_test_helper.cc | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/test/io_test_helper.cc b/test/io_test_helper.cc new file mode 100644 index 0000000..9ac663a --- /dev/null +++ b/test/io_test_helper.cc @@ -0,0 +1,82 @@ +#include "io_test_helper.hh" + +#include "io.hh" + +#include <algorithm> +#include <cstddef> +#include <expected> +#include <memory> +#include <utility> + +namespace { + +class BreakingReader : public io::Reader { + public: + BreakingReader(std::unique_ptr<io::Reader> reader, size_t offset, + io::ReadError error) + : reader_(std::move(reader)), offset_(offset), error_(error) {} + + [[nodiscard]] + std::expected<size_t, io::ReadError> read(void* dst, size_t max) override { + if (offset_ == 0) + return std::unexpected(error_); + size_t avail = std::min(offset_, max); + auto ret = reader_->read(dst, avail); + if (ret.has_value()) { + offset_ -= ret.value(); + } + return ret; + } + + [[nodiscard]] + std::expected<size_t, io::ReadError> skip(size_t max) override { + if (offset_ == 0) + return std::unexpected(error_); + size_t avail = std::min(offset_, max); + auto ret = reader_->skip(avail); + if (ret.has_value()) { + offset_ -= ret.value(); + } + return ret; + } + + private: + std::unique_ptr<io::Reader> reader_; + size_t offset_; + io::ReadError const error_; +}; + +class MaxBlockReader : public io::Reader { + public: + MaxBlockReader(std::unique_ptr<io::Reader> reader, size_t max_block_size) + : reader_(std::move(reader)), max_block_size_(max_block_size) {} + + [[nodiscard]] + std::expected<size_t, io::ReadError> read(void* dst, size_t max) override { + size_t avail = std::min(max_block_size_, max); + return reader_->read(dst, avail); + } + + [[nodiscard]] + std::expected<size_t, io::ReadError> skip(size_t max) override { + size_t avail = std::min(max_block_size_, max); + return reader_->skip(avail); + } + + private: + std::unique_ptr<io::Reader> reader_; + size_t const max_block_size_; +}; + +} // namespace + +std::unique_ptr<io::Reader> io_make_breaking(std::unique_ptr<io::Reader> reader, + size_t offset, + io::ReadError error) { + return std::make_unique<BreakingReader>(std::move(reader), offset, error); +} + +std::unique_ptr<io::Reader> io_make_max_block( + std::unique_ptr<io::Reader> reader, size_t max_block_size) { + return std::make_unique<MaxBlockReader>(std::move(reader), max_block_size); +} |
