util/*FifoBuffer: migrate from WritableBuffer to std::span
This commit is contained in:
parent
570755f05a
commit
bb7be9a4cd
|
@ -53,13 +53,13 @@ Response::VFmt(fmt::string_view format_str, fmt::format_args args) noexcept
|
|||
}
|
||||
|
||||
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
|
||||
Fmt("binary: {}\n", payload.size) &&
|
||||
Write(payload.data, payload.size) &&
|
||||
Fmt("binary: {}\n", payload.size()) &&
|
||||
Write(payload.data(), payload.size()) &&
|
||||
Write("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
|
||||
template<typename T> struct ConstBuffer;
|
||||
class Client;
|
||||
class TagMask;
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
|||
*
|
||||
* @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;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ DecoderBuffer::Fill()
|
|||
return false;
|
||||
|
||||
size_t nbytes = decoder_read(client, is,
|
||||
w.data, w.size);
|
||||
w.data(), w.size());
|
||||
if (nbytes == 0)
|
||||
/* end of file, I/O error or decoder command
|
||||
received */
|
||||
|
@ -39,16 +39,16 @@ DecoderBuffer::Fill()
|
|||
return true;
|
||||
}
|
||||
|
||||
ConstBuffer<void>
|
||||
std::span<const std::byte>
|
||||
DecoderBuffer::Need(size_t min_size)
|
||||
{
|
||||
while (true) {
|
||||
const auto r = Read();
|
||||
if (r.size >= min_size)
|
||||
if (r.size() >= min_size)
|
||||
return r;
|
||||
|
||||
if (!Fill())
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,13 +56,13 @@ bool
|
|||
DecoderBuffer::Skip(size_t nbytes)
|
||||
{
|
||||
const auto r = buffer.Read();
|
||||
if (r.size >= nbytes) {
|
||||
if (r.size() >= nbytes) {
|
||||
buffer.Consume(nbytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
buffer.Clear();
|
||||
nbytes -= r.size;
|
||||
nbytes -= r.size();
|
||||
|
||||
return decoder_skip(client, is, nbytes);
|
||||
}
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
#define MPD_DECODER_BUFFER_HXX
|
||||
|
||||
#include "util/DynamicFifoBuffer.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class DecoderClient;
|
||||
class InputStream;
|
||||
|
@ -38,7 +34,7 @@ class DecoderBuffer {
|
|||
DecoderClient *const client;
|
||||
InputStream &is;
|
||||
|
||||
DynamicFifoBuffer<uint8_t> buffer;
|
||||
DynamicFifoBuffer<std::byte> buffer;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -83,16 +79,15 @@ public:
|
|||
* you have to call Consume() to do that. The returned buffer
|
||||
* becomes invalid after a Fill() or a Consume() call.
|
||||
*/
|
||||
ConstBuffer<void> Read() const noexcept {
|
||||
auto r = buffer.Read();
|
||||
return { r.data, r.size };
|
||||
std::span<const std::byte> Read() const noexcept {
|
||||
return buffer.Read();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until this number of bytes are available. Returns nullptr on
|
||||
* 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
|
||||
|
|
|
@ -93,7 +93,7 @@ adts_find_frame(DecoderBuffer &buffer)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (buffer.Need(frame_length).IsNull()) {
|
||||
if (buffer.Need(frame_length).empty()) {
|
||||
/* not enough data; discard this frame to
|
||||
prevent a possible buffer overflow */
|
||||
buffer.Clear();
|
||||
|
|
|
@ -237,11 +237,11 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
|
|||
auto w = buffer.Write();
|
||||
if (!w.empty()) {
|
||||
if (remaining_bytes < (1<<30ULL) &&
|
||||
w.size > size_t(remaining_bytes))
|
||||
w.size = remaining_bytes;
|
||||
w.size() > size_t(remaining_bytes))
|
||||
w = w.first(remaining_bytes);
|
||||
|
||||
const size_t nbytes = client.Read(input,
|
||||
w.data, w.size);
|
||||
w.data(), w.size());
|
||||
if (nbytes == 0)
|
||||
return;
|
||||
|
||||
|
@ -251,9 +251,9 @@ HybridDsdDecode(DecoderClient &client, InputStream &input)
|
|||
|
||||
/* submit the buffer to our client */
|
||||
auto r = buffer.Read();
|
||||
auto n_frames = r.size / frame_size;
|
||||
auto n_frames = r.size() / frame_size;
|
||||
if (n_frames > 0) {
|
||||
cmd = client.SubmitData(input, r.data,
|
||||
cmd = client.SubmitData(input, r.data(),
|
||||
n_frames * frame_size,
|
||||
kbit_rate);
|
||||
buffer.Consume(n_frames * frame_size);
|
||||
|
|
|
@ -51,7 +51,7 @@ FillBuffer(DecoderClient &client, InputStream &is, B &buffer)
|
|||
if (w.empty())
|
||||
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())
|
||||
return false;
|
||||
|
||||
|
@ -188,25 +188,28 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
|
|||
/* round down to the nearest frame size, because we
|
||||
must not pass partial frames to
|
||||
DecoderClient::SubmitData() */
|
||||
r.size -= r.size % in_frame_size;
|
||||
buffer.Consume(r.size);
|
||||
r = r.first(r.size() - r.size() % in_frame_size);
|
||||
buffer.Consume(r.size());
|
||||
|
||||
if (reverse_endian)
|
||||
/* make sure we deliver samples in host byte order */
|
||||
reverse_bytes_16((uint16_t *)r.data,
|
||||
(uint16_t *)r.data,
|
||||
(uint16_t *)(r.data + r.size));
|
||||
reverse_bytes_16((uint16_t *)r.data(),
|
||||
(uint16_t *)r.data(),
|
||||
(uint16_t *)(r.data() + r.size()));
|
||||
else if (l24) {
|
||||
/* convert big-endian packed 24 bit
|
||||
(audio/L24) to native-endian 24 bit (in 32
|
||||
bit integers) */
|
||||
pcm_unpack_24be(unpack_buffer, r.begin(), r.end());
|
||||
r.data = (uint8_t *)&unpack_buffer[0];
|
||||
r.size = (r.size / 3) * 4;
|
||||
pcm_unpack_24be(unpack_buffer,
|
||||
r.data(), r.data() + r.size());
|
||||
r = {
|
||||
(uint8_t *)&unpack_buffer[0],
|
||||
(r.size() / 3) * 4,
|
||||
};
|
||||
}
|
||||
|
||||
cmd = !r.empty()
|
||||
? client.SubmitData(is, r.data, r.size, 0)
|
||||
? client.SubmitData(is, r.data(), r.size(), 0)
|
||||
: client.GetCommand();
|
||||
if (cmd == DecoderCommand::SEEK) {
|
||||
uint64_t frame = client.GetSeekFrame();
|
||||
|
|
|
@ -131,8 +131,8 @@ WaveEncoder::WaveEncoder(AudioFormat &audio_format) noexcept
|
|||
}
|
||||
|
||||
auto range = buffer.Write();
|
||||
assert(range.size >= sizeof(WaveHeader));
|
||||
auto *header = (WaveHeader *)range.data;
|
||||
assert(range.size() >= sizeof(WaveHeader));
|
||||
auto *header = (WaveHeader *)(void *)range.data();
|
||||
|
||||
/* create PCM wave header in initial buffer */
|
||||
*header = MakeWaveHeader(audio_format.channels,
|
||||
|
|
|
@ -54,7 +54,7 @@ BufferedSocket::ReadToBuffer() noexcept
|
|||
const auto buffer = input.Write();
|
||||
assert(!buffer.empty());
|
||||
|
||||
const auto nbytes = DirectRead(buffer.data, buffer.size);
|
||||
const auto nbytes = DirectRead(buffer.data(), buffer.size());
|
||||
if (nbytes > 0)
|
||||
input.Append(nbytes);
|
||||
|
||||
|
@ -73,7 +73,7 @@ BufferedSocket::ResumeInput() noexcept
|
|||
return true;
|
||||
}
|
||||
|
||||
const auto result = OnSocketInput(buffer.data, buffer.size);
|
||||
const auto result = OnSocketInput(buffer.data(), buffer.size());
|
||||
switch (result) {
|
||||
case InputResult::MORE:
|
||||
if (input.IsFull()) {
|
||||
|
|
|
@ -58,7 +58,7 @@ FullyBufferedSocket::Flush() noexcept
|
|||
return true;
|
||||
}
|
||||
|
||||
auto nbytes = DirectWrite(data.data, data.size);
|
||||
auto nbytes = DirectWrite(data.data(), data.size());
|
||||
if (gcc_unlikely(nbytes <= 0))
|
||||
return nbytes == 0;
|
||||
|
||||
|
@ -82,7 +82,7 @@ FullyBufferedSocket::Write(const void *data, size_t length) noexcept
|
|||
|
||||
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")));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ TextInputStream::ReadLine()
|
|||
|
||||
while (true) {
|
||||
auto dest = buffer.Write();
|
||||
if (dest.size < 2) {
|
||||
if (dest.size() < 2) {
|
||||
/* line too long: terminate the current
|
||||
line */
|
||||
|
||||
assert(!dest.empty());
|
||||
dest[0] = 0;
|
||||
line = buffer.Read().data;
|
||||
line = buffer.Read().data();
|
||||
buffer.Clear();
|
||||
return line;
|
||||
}
|
||||
|
@ -53,9 +53,9 @@ TextInputStream::ReadLine()
|
|||
/* reserve one byte for the null terminator if the
|
||||
last line is not terminated by a newline
|
||||
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);
|
||||
|
||||
|
@ -75,7 +75,7 @@ TextInputStream::ReadLine()
|
|||
buffer.Clear();
|
||||
return r.empty()
|
||||
? nullptr
|
||||
: r.data;
|
||||
: r.data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ bool
|
|||
BufferedOutputStream::AppendToBuffer(const void *data, std::size_t size) noexcept
|
||||
{
|
||||
auto r = buffer.Write();
|
||||
if (r.size < size)
|
||||
if (r.size() < size)
|
||||
return false;
|
||||
|
||||
memcpy(r.data, data, size);
|
||||
memcpy(r.data(), data, size);
|
||||
buffer.Append(size);
|
||||
return true;
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ BufferedOutputStream::Format(const char *fmt, ...)
|
|||
/* format into the buffer */
|
||||
std::va_list ap;
|
||||
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);
|
||||
|
||||
if (gcc_unlikely(size >= r.size)) {
|
||||
if (gcc_unlikely(size >= r.size())) {
|
||||
/* buffer was not large enough; flush it and try
|
||||
again */
|
||||
|
||||
|
@ -99,20 +99,20 @@ BufferedOutputStream::Format(const char *fmt, ...)
|
|||
|
||||
r = buffer.Write();
|
||||
|
||||
if (gcc_unlikely(size >= r.size)) {
|
||||
if (gcc_unlikely(size >= r.size())) {
|
||||
/* still not enough space: grow the buffer and
|
||||
try again */
|
||||
r.size = size + 1;
|
||||
r.data = buffer.Write(r.size);
|
||||
++size;
|
||||
r = {buffer.Write(size), size};
|
||||
}
|
||||
|
||||
/* format into the new buffer */
|
||||
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);
|
||||
|
||||
/* this time, it must fit */
|
||||
assert(size < r.size);
|
||||
assert(size < r.size());
|
||||
}
|
||||
|
||||
buffer.Append(size);
|
||||
|
@ -140,7 +140,7 @@ BufferedOutputStream::WriteWideToUTF8(const wchar_t *src,
|
|||
}
|
||||
|
||||
int length = WideCharToMultiByte(CP_UTF8, 0, src, src_length,
|
||||
(char *)r.data, r.size,
|
||||
(char *)r.data(), r.size(),
|
||||
nullptr, nullptr);
|
||||
if (length <= 0) {
|
||||
const auto error = GetLastError();
|
||||
|
@ -173,6 +173,6 @@ BufferedOutputStream::Flush()
|
|||
if (r.empty())
|
||||
return;
|
||||
|
||||
os.Write(r.data, r.size);
|
||||
buffer.Consume(r.size);
|
||||
os.Write(r.data(), r.size());
|
||||
buffer.Consume(r.size());
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ BufferedReader::Fill(bool need_more)
|
|||
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) {
|
||||
eof = true;
|
||||
return !need_more;
|
||||
|
@ -122,7 +122,7 @@ BufferedReader::ReadLine()
|
|||
/* terminate the last line */
|
||||
w[0] = 0;
|
||||
|
||||
char *line = buffer.Read().data;
|
||||
char *line = buffer.Read().data();
|
||||
buffer.Clear();
|
||||
++line_number;
|
||||
return line;
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
|
||||
[[gnu::pure]]
|
||||
std::span<std::byte> Read() const noexcept {
|
||||
return buffer.Read().ToVoid();
|
||||
return std::as_writable_bytes(buffer.Read());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -50,7 +50,7 @@ GunzipReader::FillBuffer()
|
|||
auto w = buffer.Write();
|
||||
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)
|
||||
return false;
|
||||
|
||||
|
@ -78,8 +78,8 @@ GunzipReader::Read(void *data, std::size_t size)
|
|||
flush = Z_FINISH;
|
||||
}
|
||||
|
||||
z.next_in = r.data;
|
||||
z.avail_in = r.size;
|
||||
z.next_in = r.data();
|
||||
z.avail_in = r.size();
|
||||
|
||||
int result = inflate(&z, flush);
|
||||
if (result == Z_STREAM_END) {
|
||||
|
@ -88,7 +88,7 @@ GunzipReader::Read(void *data, std::size_t size)
|
|||
} else if (result != Z_OK)
|
||||
throw ZlibError(result);
|
||||
|
||||
buffer.Consume(r.size - z.avail_in);
|
||||
buffer.Consume(r.size() - z.avail_in);
|
||||
|
||||
if (z.avail_out < size)
|
||||
return size - z.avail_out;
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
*/
|
||||
pointer Write(size_type n) noexcept {
|
||||
WantWrite(n);
|
||||
return Write().data;
|
||||
return Write().data();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -27,14 +27,12 @@
|
|||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef FOREIGN_FIFO_BUFFER_HXX
|
||||
#define FOREIGN_FIFO_BUFFER_HXX
|
||||
|
||||
#include "WritableBuffer.hxx"
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
|
@ -50,7 +48,7 @@ template<typename T>
|
|||
class ForeignFifoBuffer {
|
||||
public:
|
||||
using size_type = std::size_t;
|
||||
using Range = WritableBuffer<T>;
|
||||
using Range = std::span<T>;
|
||||
using pointer = typename Range::pointer;
|
||||
using const_pointer = typename Range::const_pointer;
|
||||
|
||||
|
@ -211,9 +209,9 @@ public:
|
|||
|
||||
size_type Read(pointer p, size_type n) noexcept {
|
||||
auto range = Read();
|
||||
if (n > range.size)
|
||||
n = range.size;
|
||||
std::copy_n(range.data, n, p);
|
||||
if (n > range.size())
|
||||
n = range.size();
|
||||
std::copy_n(range.data(), n, p);
|
||||
Consume(n);
|
||||
return n;
|
||||
}
|
||||
|
@ -227,7 +225,7 @@ public:
|
|||
auto r = src.Read();
|
||||
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
|
||||
can append at the tail, try to make more
|
||||
room by shifting the head to 0 */
|
||||
|
@ -235,9 +233,9 @@ public:
|
|||
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);
|
||||
src.Consume(n);
|
||||
return n;
|
||||
|
@ -258,5 +256,3 @@ protected:
|
|||
head = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
PeakBuffer::~PeakBuffer() noexcept
|
||||
{
|
||||
delete normal_buffer;
|
||||
|
@ -38,22 +36,22 @@ PeakBuffer::empty() const noexcept
|
|||
(peak_buffer == nullptr || peak_buffer->empty());
|
||||
}
|
||||
|
||||
WritableBuffer<void>
|
||||
std::span<std::byte>
|
||||
PeakBuffer::Read() const noexcept
|
||||
{
|
||||
if (normal_buffer != nullptr) {
|
||||
const auto p = normal_buffer->Read();
|
||||
if (!p.empty())
|
||||
return p.ToVoid();
|
||||
return p;
|
||||
}
|
||||
|
||||
if (peak_buffer != nullptr) {
|
||||
const auto p = peak_buffer->Read();
|
||||
if (!p.empty())
|
||||
return p.ToVoid();
|
||||
return p;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -77,10 +75,9 @@ PeakBuffer::Consume(std::size_t length) noexcept
|
|||
|
||||
static std::size_t
|
||||
AppendTo(DynamicFifoBuffer<std::byte> &buffer,
|
||||
const void *data, size_t length) noexcept
|
||||
std::span<const std::byte> src) noexcept
|
||||
{
|
||||
assert(data != nullptr);
|
||||
assert(length > 0);
|
||||
assert(!src.empty());
|
||||
|
||||
std::size_t total = 0;
|
||||
|
||||
|
@ -89,37 +86,35 @@ AppendTo(DynamicFifoBuffer<std::byte> &buffer,
|
|||
if (p.empty())
|
||||
break;
|
||||
|
||||
const std::size_t nbytes = std::min(length, p.size);
|
||||
memcpy(p.data, data, nbytes);
|
||||
const std::size_t nbytes = std::min(src.size(), p.size());
|
||||
std::copy_n(src.begin(), nbytes, p.begin());
|
||||
buffer.Append(nbytes);
|
||||
|
||||
data = (const std::byte *)data + nbytes;
|
||||
length -= nbytes;
|
||||
src = src.subspan(nbytes);
|
||||
total += nbytes;
|
||||
} while (length > 0);
|
||||
} while (!src.empty());
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (peak_buffer != nullptr && !peak_buffer->empty()) {
|
||||
std::size_t nbytes = AppendTo(*peak_buffer, data, length);
|
||||
return nbytes == length;
|
||||
std::size_t nbytes = AppendTo(*peak_buffer, src);
|
||||
return nbytes == src.size();
|
||||
}
|
||||
|
||||
if (normal_buffer == nullptr)
|
||||
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) {
|
||||
data = (const std::byte *)data + nbytes;
|
||||
length -= nbytes;
|
||||
if (length == 0)
|
||||
src = src.subspan(nbytes);
|
||||
if (src.empty())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -130,6 +125,6 @@ PeakBuffer::Append(const void *data, std::size_t length)
|
|||
return false;
|
||||
}
|
||||
|
||||
nbytes = AppendTo(*peak_buffer, data, length);
|
||||
return nbytes == length;
|
||||
nbytes = AppendTo(*peak_buffer, src);
|
||||
return nbytes == src.size();
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#define MPD_PEAK_BUFFER_HXX
|
||||
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
|
||||
template<typename T> struct WritableBuffer;
|
||||
template<typename T> class DynamicFifoBuffer;
|
||||
|
||||
/**
|
||||
|
@ -61,11 +61,11 @@ public:
|
|||
bool empty() const noexcept;
|
||||
|
||||
[[gnu::pure]]
|
||||
WritableBuffer<void> Read() const noexcept;
|
||||
std::span<std::byte> Read() const 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
|
||||
|
|
|
@ -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
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -27,14 +27,12 @@
|
|||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef STATIC_FIFO_BUFFER_HXX
|
||||
#define STATIC_FIFO_BUFFER_HXX
|
||||
|
||||
#include "WritableBuffer.hxx"
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
|
@ -46,7 +44,7 @@ template<class T, size_t size>
|
|||
class StaticFifoBuffer {
|
||||
public:
|
||||
using size_type = std::size_t;
|
||||
using Range = WritableBuffer<T>;
|
||||
using Range = std::span<T>;
|
||||
|
||||
protected:
|
||||
size_type head = 0, tail = 0;
|
||||
|
@ -132,5 +130,3 @@ public:
|
|||
head += n;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,16 +37,16 @@ char *
|
|||
ReadBufferedLine(B &buffer)
|
||||
{
|
||||
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)
|
||||
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 = 0;
|
||||
return r.data;
|
||||
return r.data();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -116,7 +116,7 @@ RunConvert(PcmConvert &convert, size_t in_frame_size,
|
|||
const auto dest = buffer.Write();
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -126,13 +126,13 @@ RunConvert(PcmConvert &convert, size_t in_frame_size,
|
|||
auto src = buffer.Read();
|
||||
assert(!src.empty());
|
||||
|
||||
src.size -= src.size % in_frame_size;
|
||||
src = src.first(src.size() - src.size() % in_frame_size);
|
||||
if (src.empty())
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ RunOutput(AudioOutput &ao, AudioFormat audio_format,
|
|||
const auto dest = buffer.Write();
|
||||
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)
|
||||
break;
|
||||
|
||||
|
@ -151,13 +151,13 @@ RunOutput(AudioOutput &ao, AudioFormat audio_format,
|
|||
auto src = buffer.Read();
|
||||
assert(!src.empty());
|
||||
|
||||
src.size -= src.size % in_frame_size;
|
||||
src = src.first(src.size() - src.size() % in_frame_size);
|
||||
if (src.empty())
|
||||
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);
|
||||
|
||||
buffer.Consume(consumed);
|
||||
|
|
Loading…
Reference in New Issue