diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SongPrint.cxx | 9 | ||||
-rw-r--r-- | src/client/Client.hxx | 7 | ||||
-rw-r--r-- | src/client/Response.cxx | 2 | ||||
-rw-r--r-- | src/client/Response.hxx | 4 | ||||
-rw-r--r-- | src/command/AllCommands.cxx | 1 | ||||
-rw-r--r-- | src/command/ClientCommands.cxx | 15 | ||||
-rw-r--r-- | src/command/ClientCommands.hxx | 3 | ||||
-rw-r--r-- | src/command/FileCommands.cxx | 28 | ||||
-rw-r--r-- | src/command/Request.hxx | 4 | ||||
-rw-r--r-- | src/db/plugins/simple/Directory.cxx | 4 | ||||
-rw-r--r-- | src/db/plugins/simple/ExportedSong.hxx | 42 | ||||
-rw-r--r-- | src/db/plugins/simple/SimpleDatabasePlugin.cxx | 12 | ||||
-rw-r--r-- | src/db/plugins/simple/SimpleDatabasePlugin.hxx | 4 | ||||
-rw-r--r-- | src/db/plugins/simple/Song.cxx | 86 | ||||
-rw-r--r-- | src/db/plugins/simple/Song.hxx | 4 | ||||
-rw-r--r-- | src/event/FullyBufferedSocket.hxx | 4 | ||||
-rw-r--r-- | src/input/plugins/CurlInputPlugin.cxx | 11 | ||||
-rw-r--r-- | src/lib/pcre/RegexPointer.hxx | 11 | ||||
-rw-r--r-- | src/output/plugins/sles/SlesOutputPlugin.cxx | 1 | ||||
-rw-r--r-- | src/storage/plugins/CurlStorage.cxx | 24 | ||||
-rw-r--r-- | src/util/ForeignFifoBuffer.hxx | 2 | ||||
-rw-r--r-- | src/util/PeakBuffer.cxx | 26 | ||||
-rw-r--r-- | src/util/PeakBuffer.hxx | 19 |
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 |