util/*FifoBuffer: migrate from WritableBuffer to std::span

This commit is contained in:
Max Kellermann 2022-05-10 17:26:41 +02:00 committed by Max Kellermann
parent 570755f05a
commit bb7be9a4cd
23 changed files with 114 additions and 129 deletions

View File

@ -53,13 +53,13 @@ Response::VFmt(fmt::string_view format_str, fmt::format_args args) noexcept
} }
bool bool
Response::WriteBinary(ConstBuffer<void> payload) noexcept Response::WriteBinary(std::span<const std::byte> payload) noexcept
{ {
assert(payload.size <= client.binary_limit); assert(payload.size() <= client.binary_limit);
return return
Fmt("binary: {}\n", payload.size) && Fmt("binary: {}\n", payload.size()) &&
Write(payload.data, payload.size) && Write(payload.data(), payload.size()) &&
Write("\n"); Write("\n");
} }

View File

@ -28,8 +28,8 @@
#endif #endif
#include <cstddef> #include <cstddef>
#include <span>
template<typename T> struct ConstBuffer;
class Client; class Client;
class TagMask; class TagMask;
@ -99,7 +99,7 @@ public:
* *
* @return true on success * @return true on success
*/ */
bool WriteBinary(ConstBuffer<void> payload) noexcept; bool WriteBinary(std::span<const std::byte> payload) noexcept;
void Error(enum ack code, const char *msg) noexcept; void Error(enum ack code, const char *msg) noexcept;

View File

@ -29,7 +29,7 @@ DecoderBuffer::Fill()
return false; return false;
size_t nbytes = decoder_read(client, is, size_t nbytes = decoder_read(client, is,
w.data, w.size); w.data(), w.size());
if (nbytes == 0) if (nbytes == 0)
/* end of file, I/O error or decoder command /* end of file, I/O error or decoder command
received */ received */
@ -39,16 +39,16 @@ DecoderBuffer::Fill()
return true; return true;
} }
ConstBuffer<void> std::span<const std::byte>
DecoderBuffer::Need(size_t min_size) DecoderBuffer::Need(size_t min_size)
{ {
while (true) { while (true) {
const auto r = Read(); const auto r = Read();
if (r.size >= min_size) if (r.size() >= min_size)
return r; return r;
if (!Fill()) if (!Fill())
return nullptr; return {};
} }
} }
@ -56,13 +56,13 @@ bool
DecoderBuffer::Skip(size_t nbytes) DecoderBuffer::Skip(size_t nbytes)
{ {
const auto r = buffer.Read(); const auto r = buffer.Read();
if (r.size >= nbytes) { if (r.size() >= nbytes) {
buffer.Consume(nbytes); buffer.Consume(nbytes);
return true; return true;
} }
buffer.Clear(); buffer.Clear();
nbytes -= r.size; nbytes -= r.size();
return decoder_skip(client, is, nbytes); return decoder_skip(client, is, nbytes);
} }

View File

@ -21,10 +21,6 @@
#define MPD_DECODER_BUFFER_HXX #define MPD_DECODER_BUFFER_HXX
#include "util/DynamicFifoBuffer.hxx" #include "util/DynamicFifoBuffer.hxx"
#include "util/ConstBuffer.hxx"
#include <cstddef>
#include <cstdint>
class DecoderClient; class DecoderClient;
class InputStream; class InputStream;
@ -38,7 +34,7 @@ class DecoderBuffer {
DecoderClient *const client; DecoderClient *const client;
InputStream &is; InputStream &is;
DynamicFifoBuffer<uint8_t> buffer; DynamicFifoBuffer<std::byte> buffer;
public: public:
/** /**
@ -83,16 +79,15 @@ public:
* you have to call Consume() to do that. The returned buffer * you have to call Consume() to do that. The returned buffer
* becomes invalid after a Fill() or a Consume() call. * becomes invalid after a Fill() or a Consume() call.
*/ */
ConstBuffer<void> Read() const noexcept { std::span<const std::byte> Read() const noexcept {
auto r = buffer.Read(); return buffer.Read();
return { r.data, r.size };
} }
/** /**
* Wait until this number of bytes are available. Returns nullptr on * Wait until this number of bytes are available. Returns nullptr on
* error. * error.
*/ */
ConstBuffer<void> Need(size_t min_size); std::span<const std::byte> Need(size_t min_size);
/** /**
* Consume (delete, invalidate) a part of the buffer. The * Consume (delete, invalidate) a part of the buffer. The

View File

@ -93,7 +93,7 @@ adts_find_frame(DecoderBuffer &buffer)
continue; continue;
} }
if (buffer.Need(frame_length).IsNull()) { if (buffer.Need(frame_length).empty()) {
/* not enough data; discard this frame to /* not enough data; discard this frame to
prevent a possible buffer overflow */ prevent a possible buffer overflow */
buffer.Clear(); buffer.Clear();

View File

@ -237,11 +237,11 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
auto w = buffer.Write(); auto w = buffer.Write();
if (!w.empty()) { if (!w.empty()) {
if (remaining_bytes < (1<<30ULL) && if (remaining_bytes < (1<<30ULL) &&
w.size > size_t(remaining_bytes)) w.size() > size_t(remaining_bytes))
w.size = remaining_bytes; w = w.first(remaining_bytes);
const size_t nbytes = client.Read(input, const size_t nbytes = client.Read(input,
w.data, w.size); w.data(), w.size());
if (nbytes == 0) if (nbytes == 0)
return; return;
@ -251,9 +251,9 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
/* submit the buffer to our client */ /* submit the buffer to our client */
auto r = buffer.Read(); auto r = buffer.Read();
auto n_frames = r.size / frame_size; auto n_frames = r.size() / frame_size;
if (n_frames > 0) { if (n_frames > 0) {
cmd = client.SubmitData(input, r.data, cmd = client.SubmitData(input, r.data(),
n_frames * frame_size, n_frames * frame_size,
kbit_rate); kbit_rate);
buffer.Consume(n_frames * frame_size); buffer.Consume(n_frames * frame_size);

View File

@ -51,7 +51,7 @@ FillBuffer(DecoderClient &client, InputStream &is, B &buffer)
if (w.empty()) if (w.empty())
return true; return true;
size_t nbytes = decoder_read(client, is, w.data, w.size); size_t nbytes = decoder_read(client, is, w.data(), w.size());
if (nbytes == 0 && is.LockIsEOF()) if (nbytes == 0 && is.LockIsEOF())
return false; return false;
@ -188,25 +188,28 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
/* round down to the nearest frame size, because we /* round down to the nearest frame size, because we
must not pass partial frames to must not pass partial frames to
DecoderClient::SubmitData() */ DecoderClient::SubmitData() */
r.size -= r.size % in_frame_size; r = r.first(r.size() - r.size() % in_frame_size);
buffer.Consume(r.size); buffer.Consume(r.size());
if (reverse_endian) if (reverse_endian)
/* make sure we deliver samples in host byte order */ /* make sure we deliver samples in host byte order */
reverse_bytes_16((uint16_t *)r.data, reverse_bytes_16((uint16_t *)r.data(),
(uint16_t *)r.data, (uint16_t *)r.data(),
(uint16_t *)(r.data + r.size)); (uint16_t *)(r.data() + r.size()));
else if (l24) { else if (l24) {
/* convert big-endian packed 24 bit /* convert big-endian packed 24 bit
(audio/L24) to native-endian 24 bit (in 32 (audio/L24) to native-endian 24 bit (in 32
bit integers) */ bit integers) */
pcm_unpack_24be(unpack_buffer, r.begin(), r.end()); pcm_unpack_24be(unpack_buffer,
r.data = (uint8_t *)&unpack_buffer[0]; r.data(), r.data() + r.size());
r.size = (r.size / 3) * 4; r = {
(uint8_t *)&unpack_buffer[0],
(r.size() / 3) * 4,
};
} }
cmd = !r.empty() cmd = !r.empty()
? client.SubmitData(is, r.data, r.size, 0) ? client.SubmitData(is, r.data(), r.size(), 0)
: client.GetCommand(); : client.GetCommand();
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {
uint64_t frame = client.GetSeekFrame(); uint64_t frame = client.GetSeekFrame();

View File

@ -131,8 +131,8 @@ WaveEncoder::WaveEncoder(AudioFormat &audio_format) noexcept
} }
auto range = buffer.Write(); auto range = buffer.Write();
assert(range.size >= sizeof(WaveHeader)); assert(range.size() >= sizeof(WaveHeader));
auto *header = (WaveHeader *)range.data; auto *header = (WaveHeader *)(void *)range.data();
/* create PCM wave header in initial buffer */ /* create PCM wave header in initial buffer */
*header = MakeWaveHeader(audio_format.channels, *header = MakeWaveHeader(audio_format.channels,

View File

@ -54,7 +54,7 @@ BufferedSocket::ReadToBuffer() noexcept
const auto buffer = input.Write(); const auto buffer = input.Write();
assert(!buffer.empty()); assert(!buffer.empty());
const auto nbytes = DirectRead(buffer.data, buffer.size); const auto nbytes = DirectRead(buffer.data(), buffer.size());
if (nbytes > 0) if (nbytes > 0)
input.Append(nbytes); input.Append(nbytes);
@ -73,7 +73,7 @@ BufferedSocket::ResumeInput() noexcept
return true; return true;
} }
const auto result = OnSocketInput(buffer.data, buffer.size); const auto result = OnSocketInput(buffer.data(), buffer.size());
switch (result) { switch (result) {
case InputResult::MORE: case InputResult::MORE:
if (input.IsFull()) { if (input.IsFull()) {

View File

@ -58,7 +58,7 @@ FullyBufferedSocket::Flush() noexcept
return true; return true;
} }
auto nbytes = DirectWrite(data.data, data.size); auto nbytes = DirectWrite(data.data(), data.size());
if (gcc_unlikely(nbytes <= 0)) if (gcc_unlikely(nbytes <= 0))
return nbytes == 0; return nbytes == 0;
@ -82,7 +82,7 @@ FullyBufferedSocket::Write(const void *data, size_t length) noexcept
const bool was_empty = output.empty(); const bool was_empty = output.empty();
if (!output.Append(data, length)) { if (!output.Append({(const std::byte *)data, length})) {
OnSocketError(std::make_exception_ptr(std::runtime_error("Output buffer is full"))); OnSocketError(std::make_exception_ptr(std::runtime_error("Output buffer is full")));
return false; return false;
} }

View File

@ -39,13 +39,13 @@ TextInputStream::ReadLine()
while (true) { while (true) {
auto dest = buffer.Write(); auto dest = buffer.Write();
if (dest.size < 2) { if (dest.size() < 2) {
/* line too long: terminate the current /* line too long: terminate the current
line */ line */
assert(!dest.empty()); assert(!dest.empty());
dest[0] = 0; dest[0] = 0;
line = buffer.Read().data; line = buffer.Read().data();
buffer.Clear(); buffer.Clear();
return line; return line;
} }
@ -53,9 +53,9 @@ TextInputStream::ReadLine()
/* reserve one byte for the null terminator if the /* reserve one byte for the null terminator if the
last line is not terminated by a newline last line is not terminated by a newline
character */ character */
--dest.size; dest = dest.first(dest.size() - 1);
size_t nbytes = is->LockRead(dest.data, dest.size); size_t nbytes = is->LockRead(dest.data(), dest.size());
buffer.Append(nbytes); buffer.Append(nbytes);
@ -75,7 +75,7 @@ TextInputStream::ReadLine()
buffer.Clear(); buffer.Clear();
return r.empty() return r.empty()
? nullptr ? nullptr
: r.data; : r.data();
} }
} }
} }

View File

@ -44,10 +44,10 @@ bool
BufferedOutputStream::AppendToBuffer(const void *data, std::size_t size) noexcept BufferedOutputStream::AppendToBuffer(const void *data, std::size_t size) noexcept
{ {
auto r = buffer.Write(); auto r = buffer.Write();
if (r.size < size) if (r.size() < size)
return false; return false;
memcpy(r.data, data, size); memcpy(r.data(), data, size);
buffer.Append(size); buffer.Append(size);
return true; return true;
} }
@ -88,10 +88,10 @@ BufferedOutputStream::Format(const char *fmt, ...)
/* format into the buffer */ /* format into the buffer */
std::va_list ap; std::va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
std::size_t size = vsnprintf((char *)r.data, r.size, fmt, ap); std::size_t size = vsnprintf((char *)r.data(), r.size(), fmt, ap);
va_end(ap); va_end(ap);
if (gcc_unlikely(size >= r.size)) { if (gcc_unlikely(size >= r.size())) {
/* buffer was not large enough; flush it and try /* buffer was not large enough; flush it and try
again */ again */
@ -99,20 +99,20 @@ BufferedOutputStream::Format(const char *fmt, ...)
r = buffer.Write(); r = buffer.Write();
if (gcc_unlikely(size >= r.size)) { if (gcc_unlikely(size >= r.size())) {
/* still not enough space: grow the buffer and /* still not enough space: grow the buffer and
try again */ try again */
r.size = size + 1; ++size;
r.data = buffer.Write(r.size); r = {buffer.Write(size), size};
} }
/* format into the new buffer */ /* format into the new buffer */
va_start(ap, fmt); va_start(ap, fmt);
size = vsnprintf((char *)r.data, r.size, fmt, ap); size = vsnprintf((char *)r.data(), r.size(), fmt, ap);
va_end(ap); va_end(ap);
/* this time, it must fit */ /* this time, it must fit */
assert(size < r.size); assert(size < r.size());
} }
buffer.Append(size); buffer.Append(size);
@ -140,7 +140,7 @@ BufferedOutputStream::WriteWideToUTF8(const wchar_t *src,
} }
int length = WideCharToMultiByte(CP_UTF8, 0, src, src_length, int length = WideCharToMultiByte(CP_UTF8, 0, src, src_length,
(char *)r.data, r.size, (char *)r.data(), r.size(),
nullptr, nullptr); nullptr, nullptr);
if (length <= 0) { if (length <= 0) {
const auto error = GetLastError(); const auto error = GetLastError();
@ -173,6 +173,6 @@ BufferedOutputStream::Flush()
if (r.empty()) if (r.empty())
return; return;
os.Write(r.data, r.size); os.Write(r.data(), r.size());
buffer.Consume(r.size); buffer.Consume(r.size());
} }

View File

@ -51,7 +51,7 @@ BufferedReader::Fill(bool need_more)
assert(!w.empty()); assert(!w.empty());
} }
std::size_t nbytes = reader.Read(w.data, w.size); std::size_t nbytes = reader.Read(w.data(), w.size());
if (nbytes == 0) { if (nbytes == 0) {
eof = true; eof = true;
return !need_more; return !need_more;
@ -122,7 +122,7 @@ BufferedReader::ReadLine()
/* terminate the last line */ /* terminate the last line */
w[0] = 0; w[0] = 0;
char *line = buffer.Read().data; char *line = buffer.Read().data();
buffer.Clear(); buffer.Clear();
++line_number; ++line_number;
return line; return line;

View File

@ -65,7 +65,7 @@ public:
[[gnu::pure]] [[gnu::pure]]
std::span<std::byte> Read() const noexcept { std::span<std::byte> Read() const noexcept {
return buffer.Read().ToVoid(); return std::as_writable_bytes(buffer.Read());
} }
/** /**

View File

@ -50,7 +50,7 @@ GunzipReader::FillBuffer()
auto w = buffer.Write(); auto w = buffer.Write();
assert(!w.empty()); assert(!w.empty());
std::size_t nbytes = next.Read(w.data, w.size); std::size_t nbytes = next.Read(w.data(), w.size());
if (nbytes == 0) if (nbytes == 0)
return false; return false;
@ -78,8 +78,8 @@ GunzipReader::Read(void *data, std::size_t size)
flush = Z_FINISH; flush = Z_FINISH;
} }
z.next_in = r.data; z.next_in = r.data();
z.avail_in = r.size; z.avail_in = r.size();
int result = inflate(&z, flush); int result = inflate(&z, flush);
if (result == Z_STREAM_END) { if (result == Z_STREAM_END) {
@ -88,7 +88,7 @@ GunzipReader::Read(void *data, std::size_t size)
} else if (result != Z_OK) } else if (result != Z_OK)
throw ZlibError(result); throw ZlibError(result);
buffer.Consume(r.size - z.avail_in); buffer.Consume(r.size() - z.avail_in);
if (z.avail_out < size) if (z.avail_out < size)
return size - z.avail_out; return size - z.avail_out;

View File

@ -103,7 +103,7 @@ public:
*/ */
pointer Write(size_type n) noexcept { pointer Write(size_type n) noexcept {
WantWrite(n); WantWrite(n);
return Write().data; return Write().data();
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2019 Max Kellermann <max.kellermann@gmail.com> * Copyright 2003-2022 Max Kellermann <max.kellermann@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -27,14 +27,12 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef FOREIGN_FIFO_BUFFER_HXX #pragma once
#define FOREIGN_FIFO_BUFFER_HXX
#include "WritableBuffer.hxx"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <span>
#include <utility> #include <utility>
/** /**
@ -50,7 +48,7 @@ template<typename T>
class ForeignFifoBuffer { class ForeignFifoBuffer {
public: public:
using size_type = std::size_t; using size_type = std::size_t;
using Range = WritableBuffer<T>; using Range = std::span<T>;
using pointer = typename Range::pointer; using pointer = typename Range::pointer;
using const_pointer = typename Range::const_pointer; using const_pointer = typename Range::const_pointer;
@ -211,9 +209,9 @@ public:
size_type Read(pointer p, size_type n) noexcept { size_type Read(pointer p, size_type n) noexcept {
auto range = Read(); auto range = Read();
if (n > range.size) if (n > range.size())
n = range.size; n = range.size();
std::copy_n(range.data, n, p); std::copy_n(range.data(), n, p);
Consume(n); Consume(n);
return n; return n;
} }
@ -227,7 +225,7 @@ public:
auto r = src.Read(); auto r = src.Read();
auto w = Write(); auto w = Write();
if (w.size < r.size && head > 0) { if (w.size() < r.size() && head > 0) {
/* if the source contains more data than we /* if the source contains more data than we
can append at the tail, try to make more can append at the tail, try to make more
room by shifting the head to 0 */ room by shifting the head to 0 */
@ -235,9 +233,9 @@ public:
w = Write(); w = Write();
} }
const auto n = std::min(r.size, w.size); const auto n = std::min(r.size(), w.size());
std::move(r.data, r.data + n, w.data); std::move(r.data(), r.data() + n, w.data());
Append(n); Append(n);
src.Consume(n); src.Consume(n);
return n; return n;
@ -258,5 +256,3 @@ protected:
head = 0; head = 0;
} }
}; };
#endif

View File

@ -23,8 +23,6 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <string.h>
PeakBuffer::~PeakBuffer() noexcept PeakBuffer::~PeakBuffer() noexcept
{ {
delete normal_buffer; delete normal_buffer;
@ -38,22 +36,22 @@ PeakBuffer::empty() const noexcept
(peak_buffer == nullptr || peak_buffer->empty()); (peak_buffer == nullptr || peak_buffer->empty());
} }
WritableBuffer<void> std::span<std::byte>
PeakBuffer::Read() const noexcept PeakBuffer::Read() const noexcept
{ {
if (normal_buffer != nullptr) { if (normal_buffer != nullptr) {
const auto p = normal_buffer->Read(); const auto p = normal_buffer->Read();
if (!p.empty()) if (!p.empty())
return p.ToVoid(); return p;
} }
if (peak_buffer != nullptr) { if (peak_buffer != nullptr) {
const auto p = peak_buffer->Read(); const auto p = peak_buffer->Read();
if (!p.empty()) if (!p.empty())
return p.ToVoid(); return p;
} }
return nullptr; return {};
} }
void void
@ -77,10 +75,9 @@ PeakBuffer::Consume(std::size_t length) noexcept
static std::size_t static std::size_t
AppendTo(DynamicFifoBuffer<std::byte> &buffer, AppendTo(DynamicFifoBuffer<std::byte> &buffer,
const void *data, size_t length) noexcept std::span<const std::byte> src) noexcept
{ {
assert(data != nullptr); assert(!src.empty());
assert(length > 0);
std::size_t total = 0; std::size_t total = 0;
@ -89,37 +86,35 @@ AppendTo(DynamicFifoBuffer<std::byte> &buffer,
if (p.empty()) if (p.empty())
break; break;
const std::size_t nbytes = std::min(length, p.size); const std::size_t nbytes = std::min(src.size(), p.size());
memcpy(p.data, data, nbytes); std::copy_n(src.begin(), nbytes, p.begin());
buffer.Append(nbytes); buffer.Append(nbytes);
data = (const std::byte *)data + nbytes; src = src.subspan(nbytes);
length -= nbytes;
total += nbytes; total += nbytes;
} while (length > 0); } while (!src.empty());
return total; return total;
} }
bool bool
PeakBuffer::Append(const void *data, std::size_t length) PeakBuffer::Append(std::span<const std::byte> src)
{ {
if (length == 0) if (src.empty())
return true; return true;
if (peak_buffer != nullptr && !peak_buffer->empty()) { if (peak_buffer != nullptr && !peak_buffer->empty()) {
std::size_t nbytes = AppendTo(*peak_buffer, data, length); std::size_t nbytes = AppendTo(*peak_buffer, src);
return nbytes == length; return nbytes == src.size();
} }
if (normal_buffer == nullptr) if (normal_buffer == nullptr)
normal_buffer = new DynamicFifoBuffer<std::byte>(normal_size); normal_buffer = new DynamicFifoBuffer<std::byte>(normal_size);
std::size_t nbytes = AppendTo(*normal_buffer, data, length); std::size_t nbytes = AppendTo(*normal_buffer, src);
if (nbytes > 0) { if (nbytes > 0) {
data = (const std::byte *)data + nbytes; src = src.subspan(nbytes);
length -= nbytes; if (src.empty())
if (length == 0)
return true; return true;
} }
@ -130,6 +125,6 @@ PeakBuffer::Append(const void *data, std::size_t length)
return false; return false;
} }
nbytes = AppendTo(*peak_buffer, data, length); nbytes = AppendTo(*peak_buffer, src);
return nbytes == length; return nbytes == src.size();
} }

View File

@ -21,8 +21,8 @@
#define MPD_PEAK_BUFFER_HXX #define MPD_PEAK_BUFFER_HXX
#include <cstddef> #include <cstddef>
#include <span>
template<typename T> struct WritableBuffer;
template<typename T> class DynamicFifoBuffer; template<typename T> class DynamicFifoBuffer;
/** /**
@ -61,11 +61,11 @@ public:
bool empty() const noexcept; bool empty() const noexcept;
[[gnu::pure]] [[gnu::pure]]
WritableBuffer<void> Read() const noexcept; std::span<std::byte> Read() const noexcept;
void Consume(std::size_t length) noexcept; void Consume(std::size_t length) noexcept;
bool Append(const void *data, std::size_t length); bool Append(std::span<const std::byte> src);
}; };
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2019 Max Kellermann <max.kellermann@gmail.com> * Copyright 2003-2022 Max Kellermann <max.kellermann@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -27,14 +27,12 @@
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef STATIC_FIFO_BUFFER_HXX #pragma once
#define STATIC_FIFO_BUFFER_HXX
#include "WritableBuffer.hxx"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <span>
#include <utility> #include <utility>
/** /**
@ -46,7 +44,7 @@ template<class T, size_t size>
class StaticFifoBuffer { class StaticFifoBuffer {
public: public:
using size_type = std::size_t; using size_type = std::size_t;
using Range = WritableBuffer<T>; using Range = std::span<T>;
protected: protected:
size_type head = 0, tail = 0; size_type head = 0, tail = 0;
@ -132,5 +130,3 @@ public:
head += n; head += n;
} }
}; };
#endif

View File

@ -37,16 +37,16 @@ char *
ReadBufferedLine(B &buffer) ReadBufferedLine(B &buffer)
{ {
auto r = buffer.Read(); auto r = buffer.Read();
char *newline = reinterpret_cast<char*>(std::memchr(r.data, '\n', r.size)); char *newline = reinterpret_cast<char*>(std::memchr(r.data(), '\n', r.size()));
if (newline == nullptr) if (newline == nullptr)
return nullptr; return nullptr;
buffer.Consume(newline + 1 - r.data); buffer.Consume(newline + 1 - r.data());
if (newline > r.data && newline[-1] == '\r') if (newline > r.data() && newline[-1] == '\r')
--newline; --newline;
*newline = 0; *newline = 0;
return r.data; return r.data();
} }
#endif #endif

View File

@ -116,7 +116,7 @@ RunConvert(PcmConvert &convert, size_t in_frame_size,
const auto dest = buffer.Write(); const auto dest = buffer.Write();
assert(!dest.empty()); assert(!dest.empty());
ssize_t nbytes = in_fd.Read(dest.data, dest.size); ssize_t nbytes = in_fd.Read(dest.data(), dest.size());
if (nbytes <= 0) if (nbytes <= 0)
break; break;
@ -126,13 +126,13 @@ RunConvert(PcmConvert &convert, size_t in_frame_size,
auto src = buffer.Read(); auto src = buffer.Read();
assert(!src.empty()); assert(!src.empty());
src.size -= src.size % in_frame_size; src = src.first(src.size() - src.size() % in_frame_size);
if (src.empty()) if (src.empty())
continue; continue;
buffer.Consume(src.size); buffer.Consume(src.size());
auto output = convert.Convert({src.data, src.size}); auto output = convert.Convert({src.data(), src.size()});
out_fd.FullWrite(output.data, output.size); out_fd.FullWrite(output.data, output.size);
} }

View File

@ -141,7 +141,7 @@ RunOutput(AudioOutput &ao, AudioFormat audio_format,
const auto dest = buffer.Write(); const auto dest = buffer.Write();
assert(!dest.empty()); assert(!dest.empty());
ssize_t nbytes = in_fd.Read(dest.data, dest.size); ssize_t nbytes = in_fd.Read(dest.data(), dest.size());
if (nbytes <= 0) if (nbytes <= 0)
break; break;
@ -151,13 +151,13 @@ RunOutput(AudioOutput &ao, AudioFormat audio_format,
auto src = buffer.Read(); auto src = buffer.Read();
assert(!src.empty()); assert(!src.empty());
src.size -= src.size % in_frame_size; src = src.first(src.size() - src.size() % in_frame_size);
if (src.empty()) if (src.empty())
continue; continue;
size_t consumed = ao.Play(src.data, src.size); size_t consumed = ao.Play(src.data(), src.size());
assert(consumed <= src.size); assert(consumed <= src.size());
assert(consumed % in_frame_size == 0); assert(consumed % in_frame_size == 0);
buffer.Consume(consumed); buffer.Consume(consumed);