diff options
Diffstat (limited to 'src/io.cc')
| -rw-r--r-- | src/io.cc | 18 |
1 files changed, 12 insertions, 6 deletions
@@ -39,6 +39,8 @@ class BasicReader : public Reader { default: return std::unexpected(ReadError::Error); } + } else if (ret == 0 && max > 0) { + return std::unexpected(ReadError::Eof); } offset_ += ret; return ret; @@ -60,7 +62,7 @@ class BasicReader : public Reader { return std::unexpected(ReadError::Error); } // Don't want skip to go past (cached) file end. - if (!size_.has_value() || ret > size_.value()) { + if (!size_.has_value() || ret >= size_.value()) { // When going past end, double check that it still is the end. off_t ret2 = lseek(fd_.get(), 0, SEEK_END); if (ret2 < 0) { @@ -71,9 +73,11 @@ class BasicReader : public Reader { return std::unexpected(ReadError::Error); } size_ = ret2; - if (ret > ret2) { + if (ret >= ret2) { auto distance = ret2 - offset_; offset_ = ret2; + if (distance == 0 && max > 0) + return std::unexpected(ReadError::Eof); return distance; } // Seek back to where we should be @@ -99,6 +103,8 @@ class MemoryReader : public Reader { [[nodiscard]] std::expected<size_t, ReadError> read(void* dst, size_t max) override { size_t avail = size_ - offset_; + if (avail == 0 && max > 0) + return std::unexpected(io::ReadError::Eof); size_t ret = std::min(max, avail); memcpy(dst, reinterpret_cast<char*>(ptr_) + offset_, ret); offset_ += ret; @@ -147,14 +153,14 @@ class StringReader : public MemoryReader { std::expected<size_t, ReadError> Reader::repeat_read(void* dst, size_t max) { auto ret = read(dst, max); - if (!ret.has_value() || ret.value() == 0 || ret.value() == max) + if (!ret.has_value() || ret.value() == max) return ret; char* d = reinterpret_cast<char*>(dst); size_t offset = ret.value(); while (true) { ret = read(d + offset, max - offset); - if (!ret.has_value() || ret.value() == 0) + if (!ret.has_value()) break; offset += ret.value(); if (offset == max) @@ -165,13 +171,13 @@ std::expected<size_t, ReadError> Reader::repeat_read(void* dst, size_t max) { std::expected<size_t, ReadError> Reader::repeat_skip(size_t max) { auto ret = skip(max); - if (!ret.has_value() || ret.value() == 0 || ret.value() == max) + if (!ret.has_value() || ret.value() == max) return ret; size_t offset = ret.value(); while (true) { ret = skip(max - offset); - if (!ret.has_value() || ret.value() == 0) + if (!ret.has_value()) break; offset += ret.value(); if (offset == max) |
