diff --git a/src/input/AsyncInputStream.cxx b/src/input/AsyncInputStream.cxx index 86024c918..f158264e1 100644 --- a/src/input/AsyncInputStream.cxx +++ b/src/input/AsyncInputStream.cxx @@ -20,7 +20,6 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, std::string_view _url, deferred_resume(event_loop, BIND_THIS_METHOD(DeferredResume)), deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)), allocation(_buffer_size), - buffer(&allocation.front(), allocation.size()), resume_at(_resume_at) { allocation.SetName("InputStream"); diff --git a/src/input/AsyncInputStream.hxx b/src/input/AsyncInputStream.hxx index 5d0aac31e..b9a0a5054 100644 --- a/src/input/AsyncInputStream.hxx +++ b/src/input/AsyncInputStream.hxx @@ -23,7 +23,7 @@ class AsyncInputStream : public InputStream { HugeArray allocation; - CircularBuffer buffer; + CircularBuffer buffer{allocation}; const size_t resume_at; enum class SeekState : uint_least8_t { diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx index 3f8ec3c63..1de8863a7 100644 --- a/src/input/ThreadInputStream.cxx +++ b/src/input/ThreadInputStream.cxx @@ -16,8 +16,7 @@ ThreadInputStream::ThreadInputStream(const char *_plugin, :InputStream(_uri, _mutex), plugin(_plugin), thread(BIND_THIS_METHOD(ThreadFunc)), - allocation(_buffer_size), - buffer(&allocation.front(), allocation.size()) + allocation(_buffer_size) { allocation.SetName("InputStream"); allocation.ForkCow(false); diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx index 22ecd8e4b..b980e636b 100644 --- a/src/input/ThreadInputStream.hxx +++ b/src/input/ThreadInputStream.hxx @@ -43,7 +43,7 @@ class ThreadInputStream : public InputStream { HugeArray allocation; - CircularBuffer buffer; + CircularBuffer buffer{allocation}; /** * Shall the stream be closed? diff --git a/src/util/CircularBuffer.hxx b/src/util/CircularBuffer.hxx index 4ee795e2b..e8c1a9a15 100644 --- a/src/util/CircularBuffer.hxx +++ b/src/util/CircularBuffer.hxx @@ -37,19 +37,18 @@ protected: */ size_type tail = 0; - const size_type capacity; - const pointer data; + const std::span buffer; public: - constexpr CircularBuffer(pointer _data, size_type _capacity) noexcept - :capacity(_capacity), data(_data) {} + explicit constexpr CircularBuffer(Range _buffer) noexcept + :buffer(_buffer) {} CircularBuffer(const CircularBuffer &other) = delete; CircularBuffer &operator=(const CircularBuffer &other) = delete; protected: constexpr size_type Next(size_type i) const noexcept { - return i + 1 == capacity + return i + 1 == buffer.size() ? 0 : i + 1; } @@ -60,7 +59,7 @@ public: } constexpr size_type GetCapacity() const noexcept { - return capacity; + return buffer.size(); } constexpr bool empty() const noexcept { @@ -77,7 +76,7 @@ public: constexpr size_type GetSize() const noexcept { return head <= tail ? tail - head - : capacity - head + tail; + : buffer.size() - head + tail; } /** @@ -87,7 +86,7 @@ public: constexpr size_type GetSpace() const noexcept { /* space = capacity - size - 1 */ return (head <= tail - ? capacity - tail + head + ? buffer.size() - tail + head : head - tail) - 1; } @@ -97,17 +96,17 @@ public: * When you are finished, call Append(). */ constexpr Range Write() noexcept { - assert(head < capacity); - assert(tail < capacity); + assert(head < buffer.size()); + assert(tail < buffer.size()); size_type end = tail < head ? head - 1 /* the "head==0" is there so we don't write the last cell, as this situation cannot be represented by head/tail */ - : capacity - (head == 0); + : buffer.size() - (head == 0); - return Range(data + tail, end - tail); + return buffer.subspan(tail, end - tail); } /** @@ -115,15 +114,15 @@ public: * to the buffer returned by Write(). */ constexpr void Append(size_type n) noexcept { - assert(head < capacity); - assert(tail < capacity); - assert(n < capacity); - assert(tail + n <= capacity); + assert(head < buffer.size()); + assert(tail < buffer.size()); + assert(n < buffer.size()); + assert(tail + n <= buffer.size()); assert(head <= tail || tail + n < head); tail += n; - if (tail == capacity) { + if (tail == buffer.size()) { assert(head > 0); tail = 0; } @@ -134,24 +133,24 @@ public: * writable, to allow modifications while parsing. */ constexpr Range Read() noexcept { - assert(head < capacity); - assert(tail < capacity); + assert(head < buffer.size()); + assert(tail < buffer.size()); - return Range(data + head, (tail < head ? capacity : tail) - head); + return buffer.subspan(head, (tail < head ? buffer.size() : tail) - head); } /** * Marks a chunk as consumed. */ constexpr void Consume(size_type n) noexcept { - assert(head < capacity); - assert(tail < capacity); - assert(n < capacity); - assert(head + n <= capacity); + assert(head < buffer.size()); + assert(tail < buffer.size()); + assert(n < buffer.size()); + assert(head + n <= buffer.size()); assert(tail < head || head + n <= tail); head += n; - if (head == capacity) + if (head == buffer.size()) head = 0; } }; diff --git a/test/util/TestCircularBuffer.cxx b/test/util/TestCircularBuffer.cxx index 2f3a5f830..2d996f522 100644 --- a/test/util/TestCircularBuffer.cxx +++ b/test/util/TestCircularBuffer.cxx @@ -10,7 +10,7 @@ TEST(CircularBuffer, Basic) { constexpr size_t N = 8; int data[N]; - CircularBuffer buffer(data, N); + CircularBuffer buffer{data}; EXPECT_EQ(size_t(N), buffer.GetCapacity());