From ce271f82f16ee89a18e7bfc9ed8eab7cbd6f37bc Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Mon, 22 Sep 2025 23:38:21 +0200 Subject: Change io::Reader and company to return ReadError::Eof instead of 0. It's debatable if Eof should be considered an error or not. But it is pretty clear it generally is a special response that needs special handling, so easier to keep with the unexpected lot. Also keeps better at higher abstraction levels, such as the line reader. --- src/io.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/io.cc') diff --git a/src/io.cc b/src/io.cc index 44970fe..99c0518 100644 --- a/src/io.cc +++ b/src/io.cc @@ -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 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(ptr_) + offset_, ret); offset_ += ret; @@ -147,14 +153,14 @@ class StringReader : public MemoryReader { std::expected 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(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 Reader::repeat_read(void* dst, size_t max) { std::expected 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) -- cgit v1.3