util/CircularBuffer: add method MoveTo()

This implements wraparound, so AsyncInputStream and ThreadInputStream
can now return all of the buffer contents in one Read() call.
This commit is contained in:
Max Kellermann
2025-01-29 21:04:52 +01:00
parent 950f5f4d32
commit e06d775af5
3 changed files with 39 additions and 12 deletions

View File

@@ -162,14 +162,10 @@ AsyncInputStream::IsAvailable() const noexcept
inline std::size_t
AsyncInputStream::ReadFromBuffer(std::span<std::byte> dest) noexcept
{
const auto r = buffer.Read();
if (r.empty())
const size_t nbytes = buffer.MoveTo(dest);
if (nbytes == 0)
return 0;
const size_t nbytes = std::min(dest.size(), r.size());
memcpy(dest.data(), r.data(), nbytes);
buffer.Consume(nbytes);
if (buffer.empty())
/* when the buffer becomes empty, reset its head and
tail so the next write can fill the whole buffer

View File

@@ -152,14 +152,10 @@ ThreadInputStream::Seek([[maybe_unused]] std::unique_lock<Mutex> &lock,
inline std::size_t
ThreadInputStream::ReadFromBuffer(std::span<std::byte> dest) noexcept
{
const auto r = buffer.Read();
if (r.empty())
const size_t nbytes = buffer.MoveTo(dest);
if (nbytes == 0)
return 0;
const size_t nbytes = std::min(dest.size(), r.size());
memcpy(dest.data(), r.data(), nbytes);
buffer.Consume(nbytes);
if (buffer.empty())
/* when the buffer becomes empty, reset its head and
tail so the next write can fill the whole buffer