summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SongPrint.cxx9
-rw-r--r--src/client/Client.hxx7
-rw-r--r--src/client/Response.cxx2
-rw-r--r--src/client/Response.hxx4
-rw-r--r--src/command/AllCommands.cxx1
-rw-r--r--src/command/ClientCommands.cxx15
-rw-r--r--src/command/ClientCommands.hxx3
-rw-r--r--src/command/FileCommands.cxx28
-rw-r--r--src/command/Request.hxx4
-rw-r--r--src/db/plugins/simple/Directory.cxx4
-rw-r--r--src/db/plugins/simple/ExportedSong.hxx42
-rw-r--r--src/db/plugins/simple/SimpleDatabasePlugin.cxx12
-rw-r--r--src/db/plugins/simple/SimpleDatabasePlugin.hxx4
-rw-r--r--src/db/plugins/simple/Song.cxx86
-rw-r--r--src/db/plugins/simple/Song.hxx4
-rw-r--r--src/event/FullyBufferedSocket.hxx4
-rw-r--r--src/input/plugins/CurlInputPlugin.cxx11
-rw-r--r--src/lib/pcre/RegexPointer.hxx11
-rw-r--r--src/output/plugins/sles/SlesOutputPlugin.cxx1
-rw-r--r--src/storage/plugins/CurlStorage.cxx24
-rw-r--r--src/util/ForeignFifoBuffer.hxx2
-rw-r--r--src/util/PeakBuffer.cxx26
-rw-r--r--src/util/PeakBuffer.hxx19
23 files changed, 247 insertions, 76 deletions
diff --git a/src/SongPrint.cxx b/src/SongPrint.cxx
index 7e8729ad0..5ad300081 100644
--- a/src/SongPrint.cxx
+++ b/src/SongPrint.cxx
@@ -91,7 +91,14 @@ song_print_info(Response &r, const LightSong &song, bool base) noexcept
if (song.audio_format.IsDefined())
r.Format("Format: %s\n", ToString(song.audio_format).c_str());
- tag_print(r, song.tag);
+ tag_print_values(r, song.tag);
+
+ const auto duration = song.GetDuration();
+ if (!duration.IsNegative())
+ r.Format("Time: %i\n"
+ "duration: %1.3f\n",
+ duration.RoundS(),
+ duration.ToDoubleS());
}
void
diff --git a/src/client/Client.hxx b/src/client/Client.hxx
index d19d08760..deb4b8caa 100644
--- a/src/client/Client.hxx
+++ b/src/client/Client.hxx
@@ -84,6 +84,12 @@ public:
*/
TagMask tag_mask = TagMask::All();
+ /**
+ * The maximum number of bytes transmitted in a binary
+ * response. Can be changed with the "binarylimit" command.
+ */
+ size_t binary_limit = 8192;
+
private:
static constexpr size_t MAX_SUBSCRIPTIONS = 16;
@@ -122,6 +128,7 @@ public:
~Client() noexcept;
using FullyBufferedSocket::GetEventLoop;
+ using FullyBufferedSocket::GetOutputMaxSize;
gcc_pure
bool IsExpired() const noexcept {
diff --git a/src/client/Response.cxx b/src/client/Response.cxx
index 3900df75e..0c9145a50 100644
--- a/src/client/Response.cxx
+++ b/src/client/Response.cxx
@@ -59,7 +59,7 @@ Response::Format(const char *fmt, ...) noexcept
bool
Response::WriteBinary(ConstBuffer<void> payload) noexcept
{
- assert(payload.size <= MAX_BINARY_SIZE);
+ assert(payload.size <= client.binary_limit);
return Format("binary: %zu\n", payload.size) &&
Write(payload.data, payload.size) &&
diff --git a/src/client/Response.hxx b/src/client/Response.hxx
index 1bf0e7c1e..4c7e40e8a 100644
--- a/src/client/Response.hxx
+++ b/src/client/Response.hxx
@@ -75,9 +75,9 @@ public:
bool Write(const void *data, size_t length) noexcept;
bool Write(const char *data) noexcept;
bool FormatV(const char *fmt, std::va_list args) noexcept;
- bool Format(const char *fmt, ...) noexcept;
- static constexpr size_t MAX_BINARY_SIZE = 8192;
+ gcc_printf(2,3)
+ bool Format(const char *fmt, ...) noexcept;
/**
* Write a binary chunk; this writes the "binary" line, the
diff --git a/src/command/AllCommands.cxx b/src/command/AllCommands.cxx
index 1fb125229..9a36b9bdb 100644
--- a/src/command/AllCommands.cxx
+++ b/src/command/AllCommands.cxx
@@ -87,6 +87,7 @@ static constexpr struct command commands[] = {
{ "addid", PERMISSION_ADD, 1, 2, handle_addid },
{ "addtagid", PERMISSION_ADD, 3, 3, handle_addtagid },
{ "albumart", PERMISSION_READ, 2, 2, handle_album_art },
+ { "binarylimit", PERMISSION_NONE, 1, 1, handle_binary_limit },
{ "channels", PERMISSION_READ, 0, 0, handle_channels },
{ "clear", PERMISSION_CONTROL, 0, 0, handle_clear },
{ "clearerror", PERMISSION_CONTROL, 0, 0, handle_clearerror },
diff --git a/src/command/ClientCommands.cxx b/src/command/ClientCommands.cxx
index f0e3470be..01bd462f2 100644
--- a/src/command/ClientCommands.cxx
+++ b/src/command/ClientCommands.cxx
@@ -41,6 +41,21 @@ handle_ping([[maybe_unused]] Client &client, [[maybe_unused]] Request args,
}
CommandResult
+handle_binary_limit(Client &client, Request args,
+ [[maybe_unused]] Response &r)
+{
+ size_t value = args.ParseUnsigned(0, client.GetOutputMaxSize() - 4096);
+ if (value < 64) {
+ r.Error(ACK_ERROR_ARG, "Value too small");
+ return CommandResult::ERROR;
+ }
+
+ client.binary_limit = value;
+
+ return CommandResult::OK;
+}
+
+CommandResult
handle_password(Client &client, Request args, Response &r)
{
unsigned permission = 0;
diff --git a/src/command/ClientCommands.hxx b/src/command/ClientCommands.hxx
index fc0dc42e1..de766e802 100644
--- a/src/command/ClientCommands.hxx
+++ b/src/command/ClientCommands.hxx
@@ -33,6 +33,9 @@ CommandResult
handle_ping(Client &client, Request request, Response &response);
CommandResult
+handle_binary_limit(Client &client, Request request, Response &response);
+
+CommandResult
handle_password(Client &client, Request request, Response &response);
CommandResult
diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx
index cb9a264ee..ce750414c 100644
--- a/src/command/FileCommands.cxx
+++ b/src/command/FileCommands.cxx
@@ -43,6 +43,7 @@
#include "thread/Mutex.hxx"
#include "Log.hxx"
+#include <algorithm>
#include <cassert>
#include <cinttypes> /* for PRIu64 */
@@ -202,17 +203,26 @@ read_stream_art(Response &r, const char *uri, size_t offset)
const offset_type art_file_size = is->GetSize();
- uint8_t buffer[Response::MAX_BINARY_SIZE];
- size_t read_size;
+ if (offset > art_file_size) {
+ r.Error(ACK_ERROR_ARG, "Offset too large");
+ return CommandResult::ERROR;
+ }
+
+ std::size_t buffer_size =
+ std::min<offset_type>(art_file_size - offset,
+ r.GetClient().binary_limit);
- {
+ std::unique_ptr<std::byte[]> buffer(new std::byte[buffer_size]);
+
+ std::size_t read_size = 0;
+ if (buffer_size > 0) {
std::unique_lock<Mutex> lock(mutex);
is->Seek(lock, offset);
- read_size = is->Read(lock, &buffer, sizeof(buffer));
+ read_size = is->Read(lock, buffer.get(), buffer_size);
}
r.Format("size: %" PRIoffset "\n", art_file_size);
- r.WriteBinary({buffer, read_size});
+ r.WriteBinary({buffer.get(), read_size});
return CommandResult::OK;
}
@@ -293,14 +303,16 @@ public:
return;
}
- response.Format("size: %" PRIoffset "\n", buffer.size);
+ response.Format("size: %zu\n", buffer.size);
if (mime_type != nullptr)
response.Format("type: %s\n", mime_type);
buffer.size -= offset;
- if (buffer.size > Response::MAX_BINARY_SIZE)
- buffer.size = Response::MAX_BINARY_SIZE;
+
+ const std::size_t binary_limit = response.GetClient().binary_limit;
+ if (buffer.size > binary_limit)
+ buffer.size = binary_limit;
buffer.data = OffsetPointer(buffer.data, offset);
response.WriteBinary(buffer);
diff --git a/src/command/Request.hxx b/src/command/Request.hxx
index f6f0072a0..7a459bb0f 100644
--- a/src/command/Request.hxx
+++ b/src/command/Request.hxx
@@ -54,12 +54,12 @@ public:
return ParseCommandArgInt(data[idx], min_value, max_value);
}
- int ParseUnsigned(unsigned idx) const {
+ unsigned ParseUnsigned(unsigned idx) const {
assert(idx < size);
return ParseCommandArgUnsigned(data[idx]);
}
- int ParseUnsigned(unsigned idx, unsigned max_value) const {
+ unsigned ParseUnsigned(unsigned idx, unsigned max_value) const {
assert(idx < size);
return ParseCommandArgUnsigned(data[idx], max_value);
}
diff --git a/src/db/plugins/simple/Directory.cxx b/src/db/plugins/simple/Directory.cxx
index 1b34655bd..1465922eb 100644
--- a/src/db/plugins/simple/Directory.cxx
+++ b/src/db/plugins/simple/Directory.cxx
@@ -18,11 +18,11 @@
*/
#include "Directory.hxx"
+#include "ExportedSong.hxx"
#include "SongSort.hxx"
#include "Song.hxx"
#include "Mount.hxx"
#include "db/LightDirectory.hxx"
-#include "song/LightSong.hxx"
#include "db/Uri.hxx"
#include "db/DatabaseLock.hxx"
#include "db/Interface.hxx"
@@ -234,7 +234,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
if (visit_song) {
for (auto &song : songs){
- const LightSong song2 = song.Export();
+ const auto song2 = song.Export();
if (filter == nullptr || filter->Match(song2))
visit_song(song2);
}
diff --git a/src/db/plugins/simple/ExportedSong.hxx b/src/db/plugins/simple/ExportedSong.hxx
new file mode 100644
index 000000000..886be078b
--- /dev/null
+++ b/src/db/plugins/simple/ExportedSong.hxx
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2003-2021 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_DB_SIMPLE_EXPORTED_SONG_HXX
+#define MPD_DB_SIMPLE_EXPORTED_SONG_HXX
+
+#include "song/LightSong.hxx"
+#include "tag/Tag.hxx"
+
+/**
+ * The return type for Song::Export(). In addition to implementing
+ * #LightSong, it hold allocations necessary to represent the #Song as
+ * a #LightSong, e.g. a merged #Tag.
+ */
+class ExportedSong : public LightSong {
+ Tag tag_buffer;
+
+public:
+ using LightSong::LightSong;
+
+ ExportedSong(const char *_uri, Tag &&_tag) noexcept
+ :LightSong(_uri, tag_buffer),
+ tag_buffer(std::move(_tag)) {}
+};
+
+#endif
diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.cxx b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
index f08938480..90dda7a01 100644
--- a/src/db/plugins/simple/SimpleDatabasePlugin.cxx
+++ b/src/db/plugins/simple/SimpleDatabasePlugin.cxx
@@ -233,25 +233,25 @@ SimpleDatabase::GetSong(std::string_view uri) const
"No such song");
const Song *song = r.directory->FindSong(r.rest);
- protect.unlock();
if (song == nullptr)
throw DatabaseError(DatabaseErrorCode::NOT_FOUND,
"No such song");
- light_song.Construct(song->Export());
+ exported_song.Construct(song->Export());
+ protect.unlock();
#ifndef NDEBUG
++borrowed_song_count;
#endif
- return &light_song.Get();
+ return &exported_song.Get();
}
void
SimpleDatabase::ReturnSong([[maybe_unused]] const LightSong *song) const noexcept
{
assert(song != nullptr);
- assert(song == prefixed_light_song || song == &light_song.Get());
+ assert(song == prefixed_light_song || song == &exported_song.Get());
if (prefixed_light_song != nullptr) {
delete prefixed_light_song;
@@ -262,7 +262,7 @@ SimpleDatabase::ReturnSong([[maybe_unused]] const LightSong *song) const noexcep
--borrowed_song_count;
#endif
- light_song.Destruct();
+ exported_song.Destruct();
}
}
@@ -316,7 +316,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
if (visit_song) {
Song *song = r.directory->FindSong(r.rest);
if (song != nullptr) {
- const LightSong song2 = song->Export();
+ const auto song2 = song->Export();
if (selection.Match(song2))
visit_song(song2);
diff --git a/src/db/plugins/simple/SimpleDatabasePlugin.hxx b/src/db/plugins/simple/SimpleDatabasePlugin.hxx
index a2245faa1..4fe68014e 100644
--- a/src/db/plugins/simple/SimpleDatabasePlugin.hxx
+++ b/src/db/plugins/simple/SimpleDatabasePlugin.hxx
@@ -20,10 +20,10 @@
#ifndef MPD_SIMPLE_DATABASE_PLUGIN_HXX
#define MPD_SIMPLE_DATABASE_PLUGIN_HXX
+#include "ExportedSong.hxx"
#include "db/Interface.hxx"
#include "db/Ptr.hxx"
#include "fs/AllocatedPath.hxx"
-#include "song/LightSong.hxx"
#include "util/Manual.hxx"
#include "util/Compiler.h"
#include "config.h"
@@ -63,7 +63,7 @@ class SimpleDatabase : public Database {
/**
* A buffer for GetSong().
*/
- mutable Manual<LightSong> light_song;
+ mutable Manual<ExportedSong> exported_song;
#ifndef NDEBUG
mutable unsigned borrowed_song_count;
diff --git a/src/db/plugins/simple/Song.cxx b/src/db/plugins/simple/Song.cxx
index 03ec19f50..8db47d03f 100644
--- a/src/db/plugins/simple/Song.cxx
+++ b/src/db/plugins/simple/Song.cxx
@@ -18,11 +18,15 @@
*/
#include "Song.hxx"
+#include "ExportedSong.hxx"
#include "Directory.hxx"
#include "tag/Tag.hxx"
+#include "tag/Builder.hxx"
#include "song/DetachedSong.hxx"
#include "song/LightSong.hxx"
#include "fs/Traits.hxx"
+#include "time/ChronoUtil.hxx"
+#include "util/IterableSplitString.hxx"
Song::Song(DetachedSong &&other, Directory &_parent) noexcept
:tag(std::move(other.WritableTag())),
@@ -53,17 +57,87 @@ Song::GetURI() const noexcept
}
}
-LightSong
+/**
+ * Path name traversal of a #Directory.
+ */
+gcc_pure
+static const Directory *
+FindTargetDirectory(const Directory &base, StringView path) noexcept
+{
+ const auto *directory = &base;
+ for (const StringView name : IterableSplitString(path, '/')) {
+ if (name.empty() || name.Equals("."))
+ continue;
+
+ directory = name.Equals("..")
+ ? directory->parent
+ : directory->FindChild(name);
+ if (directory == nullptr)
+ break;
+ }
+
+ return directory;
+}
+
+/**
+ * Path name traversal of a #Song.
+ */
+gcc_pure
+static const Song *
+FindTargetSong(const Directory &_directory, StringView target) noexcept
+{
+ auto [path, last] = target.SplitLast('/');
+ if (last == nullptr) {
+ last = path;
+ path = nullptr;
+ }
+
+ if (last.empty())
+ return nullptr;
+
+ const auto *directory = FindTargetDirectory(_directory, path);
+ if (directory == nullptr)
+ return nullptr;
+
+ return directory->FindSong(last);
+}
+
+ExportedSong
Song::Export() const noexcept
{
- LightSong dest(filename.c_str(), tag);
+ const auto *target_song = !target.empty()
+ ? FindTargetSong(parent, (std::string_view)target)
+ : nullptr;
+
+ Tag merged_tag;
+ if (target_song != nullptr) {
+ /* if we found the target song (which may be the
+ underlying song file of a CUE file), merge the tags
+ from that song with this song's tags (from the CUE
+ file) */
+ TagBuilder builder(tag);
+ builder.Complement(target_song->tag);
+ merged_tag = builder.Commit();
+ }
+
+ ExportedSong dest = merged_tag.IsDefined()
+ ? ExportedSong(filename.c_str(), std::move(merged_tag))
+ : ExportedSong(filename.c_str(), tag);
if (!parent.IsRoot())
dest.directory = parent.GetPath();
if (!target.empty())
dest.real_uri = target.c_str();
- dest.mtime = mtime;
- dest.start_time = start_time;
- dest.end_time = end_time;
- dest.audio_format = audio_format;
+ dest.mtime = IsNegative(mtime) && target_song != nullptr
+ ? target_song->mtime
+ : mtime;
+ dest.start_time = start_time.IsZero() && target_song != nullptr
+ ? target_song->start_time
+ : start_time;
+ dest.end_time = end_time.IsZero() && target_song != nullptr
+ ? target_song->end_time
+ : end_time;
+ dest.audio_format = audio_format.IsDefined() || target_song == nullptr
+ ? audio_format
+ : target_song->audio_format;
return dest;
}
diff --git a/src/db/plugins/simple/Song.hxx b/src/db/plugins/simple/Song.hxx
index 8750a91b3..eb425dc5c 100644
--- a/src/db/plugins/simple/Song.hxx
+++ b/src/db/plugins/simple/Song.hxx
@@ -32,8 +32,8 @@
#include <string>
struct StringView;
-struct LightSong;
struct Directory;
+class ExportedSong;
class DetachedSong;
class Storage;
class ArchiveFile;
@@ -153,7 +153,7 @@ struct Song {
std::string GetURI() const noexcept;
gcc_pure
- LightSong Export() const noexcept;
+ ExportedSong Export() const noexcept;
};
typedef boost::intrusive::list<Song,
diff --git a/src/event/FullyBufferedSocket.hxx b/src/event/FullyBufferedSocket.hxx
index 8ef98e3fc..c83a73153 100644
--- a/src/event/FullyBufferedSocket.hxx
+++ b/src/event/FullyBufferedSocket.hxx
@@ -48,6 +48,10 @@ public:
BufferedSocket::Close();
}
+ std::size_t GetOutputMaxSize() const noexcept {
+ return output.max_size();
+ }
+
private:
/**
* @return the number of bytes written to the socket, 0 if the
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index 740a9de61..39ba13c43 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -369,8 +369,15 @@ input_curl_init(EventLoop &event_loop, const ConfigBlock &block)
proxy_user = block.GetBlockValue("proxy_user");
proxy_password = block.GetBlockValue("proxy_password");
- verify_peer = block.GetBlockValue("verify_peer", true);
- verify_host = block.GetBlockValue("verify_host", true);
+#ifdef ANDROID
+ // TODO: figure out how to use Android's CA certificates and re-enable verify
+ constexpr bool default_verify = false;
+#else
+ constexpr bool default_verify = true;
+#endif
+
+ verify_peer = block.GetBlockValue("verify_peer", default_verify);
+ verify_host = block.GetBlockValue("verify_host", default_verify);
}
static void
diff --git a/src/lib/pcre/RegexPointer.hxx b/src/lib/pcre/RegexPointer.hxx
index 7311d0407..cb7e730ba 100644
--- a/src/lib/pcre/RegexPointer.hxx
+++ b/src/lib/pcre/RegexPointer.hxx
@@ -40,6 +40,13 @@
#include <array>
+#if GCC_CHECK_VERSION(11,0)
+#pragma GCC diagnostic push
+/* bogus GCC 11 warning "ovector may be used uninitialized" in the
+ ovector.size() call */
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+
class RegexPointer {
protected:
pcre *re = nullptr;
@@ -63,4 +70,8 @@ public:
}
};
+#if GCC_CHECK_VERSION(11,0)
+#pragma GCC diagnostic pop
+#endif
+
#endif
diff --git a/src/output/plugins/sles/SlesOutputPlugin.cxx b/src/output/plugins/sles/SlesOutputPlugin.cxx
index 61a815554..6c3978a9d 100644
--- a/src/output/plugins/sles/SlesOutputPlugin.cxx
+++ b/src/output/plugins/sles/SlesOutputPlugin.cxx
@@ -33,6 +33,7 @@
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
+#include <cassert>
#include <iterator>
#include <stdexcept>
diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx
index 8e39e6edb..d05b90a31 100644
--- a/src/storage/plugins/CurlStorage.cxx
+++ b/src/storage/plugins/CurlStorage.cxx
@@ -468,19 +468,11 @@ CurlStorage::GetInfo(std::string_view uri_utf8, [[maybe_unused]] bool follow)
gcc_pure
static std::string_view
-UriPathOrSlash(const char *uri, bool relative) noexcept
+UriPathOrSlash(const char *uri) noexcept
{
auto path = uri_get_path(uri);
if (path.data() == nullptr)
path = "/";
- else if (relative) {
- // search after first slash
- path = path.substr(1);
- auto slash = path.find('/');
- if (slash != std::string_view::npos)
- path = path.substr(slash);
- }
-
return path;
}
@@ -489,15 +481,13 @@ UriPathOrSlash(const char *uri, bool relative) noexcept
*/
class HttpListDirectoryOperation final : public PropfindOperation {
const std::string base_path;
- const std::string base_path_relative;
MemoryStorageDirectoryReader::List entries;
public:
HttpListDirectoryOperation(CurlGlobal &curl, const char *uri)
:PropfindOperation(curl, uri, 1),
- base_path(CurlUnescape(GetEasy(), UriPathOrSlash(uri, false))),
- base_path_relative(CurlUnescape(GetEasy(), UriPathOrSlash(uri, true))) {}
+ base_path(CurlUnescape(GetEasy(), UriPathOrSlash(uri))) {}
std::unique_ptr<StorageDirectoryReader> Perform() {
DeferStart();
@@ -523,15 +513,9 @@ private:
/* kludge: ignoring case in this comparison to avoid
false negatives if the web server uses a different
case */
- if (uri_has_scheme(path)) {
- path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
- } else {
- path = StringAfterPrefixIgnoreCase(path, base_path_relative.c_str());
- }
-
- if (path == nullptr || path.empty()) {
+ path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
+ if (path == nullptr || path.empty())
return nullptr;
- }
const char *slash = path.Find('/');
if (slash == nullptr)
diff --git a/src/util/ForeignFifoBuffer.hxx b/src/util/ForeignFifoBuffer.hxx
index d6912d3c2..65f6bce94 100644
--- a/src/util/ForeignFifoBuffer.hxx
+++ b/src/util/ForeignFifoBuffer.hxx
@@ -235,7 +235,7 @@ public:
w = Write();
}
- size_t 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);
Append(n);
diff --git a/src/util/PeakBuffer.cxx b/src/util/PeakBuffer.cxx
index dcc6f92aa..6af9df266 100644
--- a/src/util/PeakBuffer.cxx
+++ b/src/util/PeakBuffer.cxx
@@ -25,7 +25,7 @@
#include <string.h>
-PeakBuffer::~PeakBuffer()
+PeakBuffer::~PeakBuffer() noexcept
{
delete normal_buffer;
delete peak_buffer;
@@ -57,7 +57,7 @@ PeakBuffer::Read() const noexcept
}
void
-PeakBuffer::Consume(size_t length) noexcept
+PeakBuffer::Consume(std::size_t length) noexcept
{
if (normal_buffer != nullptr && !normal_buffer->empty()) {
normal_buffer->Consume(length);
@@ -75,25 +75,25 @@ PeakBuffer::Consume(size_t length) noexcept
}
}
-static size_t
-AppendTo(DynamicFifoBuffer<uint8_t> &buffer,
+static std::size_t
+AppendTo(DynamicFifoBuffer<std::byte> &buffer,
const void *data, size_t length) noexcept
{
assert(data != nullptr);
assert(length > 0);
- size_t total = 0;
+ std::size_t total = 0;
do {
const auto p = buffer.Write();
if (p.empty())
break;
- const size_t nbytes = std::min(length, p.size);
+ const std::size_t nbytes = std::min(length, p.size);
memcpy(p.data, data, nbytes);
buffer.Append(nbytes);
- data = (const uint8_t *)data + nbytes;
+ data = (const std::byte *)data + nbytes;
length -= nbytes;
total += nbytes;
} while (length > 0);
@@ -102,22 +102,22 @@ AppendTo(DynamicFifoBuffer<uint8_t> &buffer,
}
bool
-PeakBuffer::Append(const void *data, size_t length)
+PeakBuffer::Append(const void *data, std::size_t length)
{
if (length == 0)
return true;
if (peak_buffer != nullptr && !peak_buffer->empty()) {
- size_t nbytes = AppendTo(*peak_buffer, data, length);
+ std::size_t nbytes = AppendTo(*peak_buffer, data, length);
return nbytes == length;
}
if (normal_buffer == nullptr)
- normal_buffer = new DynamicFifoBuffer<uint8_t>(normal_size);
+ normal_buffer = new DynamicFifoBuffer<std::byte>(normal_size);
- size_t nbytes = AppendTo(*normal_buffer, data, length);
+ std::size_t nbytes = AppendTo(*normal_buffer, data, length);
if (nbytes > 0) {
- data = (const uint8_t *)data + nbytes;
+ data = (const std::byte *)data + nbytes;
length -= nbytes;
if (length == 0)
return true;
@@ -125,7 +125,7 @@ PeakBuffer::Append(const void *data, size_t length)
if (peak_buffer == nullptr) {
if (peak_size > 0)
- peak_buffer = new DynamicFifoBuffer<uint8_t>(peak_size);
+ peak_buffer = new DynamicFifoBuffer<std::byte>(peak_size);
if (peak_buffer == nullptr)
return false;
}
diff --git a/src/util/PeakBuffer.hxx b/src/util/PeakBuffer.hxx
index 0684937b4..febf8bd73 100644
--- a/src/util/PeakBuffer.hxx
+++ b/src/util/PeakBuffer.hxx
@@ -23,7 +23,6 @@
#include "Compiler.h"
#include <cstddef>
-#include <cstdint>
template<typename T> struct WritableBuffer;
template<typename T> class DynamicFifoBuffer;
@@ -34,16 +33,16 @@ template<typename T> class DynamicFifoBuffer;
* kernel when it has been consumed.
*/
class PeakBuffer {
- size_t normal_size, peak_size;
+ std::size_t normal_size, peak_size;
- DynamicFifoBuffer<uint8_t> *normal_buffer, *peak_buffer;
+ DynamicFifoBuffer<std::byte> *normal_buffer, *peak_buffer;
public:
- PeakBuffer(size_t _normal_size, size_t _peak_size)
+ PeakBuffer(std::size_t _normal_size, std::size_t _peak_size) noexcept
:normal_size(_normal_size), peak_size(_peak_size),
normal_buffer(nullptr), peak_buffer(nullptr) {}
- PeakBuffer(PeakBuffer &&other)
+ PeakBuffer(PeakBuffer &&other) noexcept
:normal_size(other.normal_size), peak_size(other.peak_size),
normal_buffer(other.normal_buffer),
peak_buffer(other.peak_buffer) {
@@ -51,20 +50,24 @@ public:
other.peak_buffer = nullptr;
}
- ~PeakBuffer();
+ ~PeakBuffer() noexcept;
PeakBuffer(const PeakBuffer &) = delete;
PeakBuffer &operator=(const PeakBuffer &) = delete;
+ std::size_t max_size() const noexcept {
+ return normal_size + peak_size;
+ }
+
gcc_pure
bool empty() const noexcept;
gcc_pure
WritableBuffer<void> Read() const noexcept;
- void Consume(size_t length) noexcept;
+ void Consume(std::size_t length) noexcept;
- bool Append(const void *data, size_t length);
+ bool Append(const void *data, std::size_t length);
};
#endif