diff --git a/src/input/IcyInputStream.cxx b/src/input/IcyInputStream.cxx index 6b48dd838..d8051d6fa 100644 --- a/src/input/IcyInputStream.cxx +++ b/src/input/IcyInputStream.cxx @@ -81,7 +81,7 @@ IcyInputStream::Read(std::unique_lock &lock, return 0; } - size_t result = parser->ParseInPlace(ptr, nbytes); + size_t result = parser->ParseInPlace({static_cast(ptr), nbytes}); if (result > 0) { override_offset += result; offset = override_offset; diff --git a/src/tag/IcyMetaDataParser.cxx b/src/tag/IcyMetaDataParser.cxx index 306cf0700..d033842ed 100644 --- a/src/tag/IcyMetaDataParser.cxx +++ b/src/tag/IcyMetaDataParser.cxx @@ -156,28 +156,29 @@ icy_parse_tag( return tag.CommitNew(); } -size_t -IcyMetaDataParser::Meta(const void *data, size_t length) noexcept +std::size_t +IcyMetaDataParser::Meta(std::span src) noexcept { - const auto *p = (const unsigned char *)data; - assert(IsDefined()); assert(data_rest == 0); - assert(length > 0); + assert(!src.empty()); + + std::size_t consumed = 0; if (meta_size == 0) { /* read meta_size from the first byte of a meta block */ - meta_size = *p++ * 16; + meta_size = static_cast(src.front()) * 16; if (meta_size == 0) { /* special case: no metadata */ data_rest = data_size; return 1; } - /* 1 byte was consumed (must be re-added later for the - return value */ - --length; + src = src.subspan(1); + + /* 1 byte was consumed */ + ++consumed; /* initialize metadata reader, allocate enough memory (+1 for the null terminator) */ @@ -187,15 +188,12 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept assert(meta_position < meta_size); - if (length > meta_size - meta_position) - length = meta_size - meta_position; + if (src.size() > meta_size - meta_position) + src = src.first(meta_size - meta_position); - memcpy(meta_data + meta_position, p, length); - meta_position += length; - - if (p != data) - /* re-add the first byte (which contained meta_size) */ - ++length; + memcpy(meta_data + meta_position, src.data(), src.size()); + meta_position += src.size(); + consumed += src.size(); if (meta_position == meta_size) { /* parse */ @@ -213,34 +211,29 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept data_rest = data_size; } - return length; + return consumed; } size_t -IcyMetaDataParser::ParseInPlace(void *data, size_t length) noexcept +IcyMetaDataParser::ParseInPlace(std::span buffer) noexcept { - auto *const dest0 = (std::byte *)data; - std::byte *dest = dest0; - const std::byte *src = dest0; + const auto begin = buffer.begin(); + auto dest = begin; + auto src = buffer; - while (length > 0) { - size_t chunk = Data(length); + while (!src.empty()) { + std::size_t chunk = Data(src.size()); if (chunk > 0) { - memmove(dest, src, chunk); - dest += chunk; - src += chunk; - length -= chunk; - - if (length == 0) + dest = std::copy_n(src.begin(), chunk, dest); + src = src.subspan(chunk); + if (src.empty()) break; } - chunk = Meta(src, length); - if (chunk > 0) { - src += chunk; - length -= chunk; - } + chunk = Meta(src); + if (chunk > 0) + src = src.subspan(chunk); } - return dest - dest0; + return std::distance(begin, dest); } diff --git a/src/tag/IcyMetaDataParser.hxx b/src/tag/IcyMetaDataParser.hxx index 868fada11..a59b1ec87 100644 --- a/src/tag/IcyMetaDataParser.hxx +++ b/src/tag/IcyMetaDataParser.hxx @@ -10,6 +10,7 @@ #include #include +#include class IcyMetaDataParser { size_t data_size = 0, data_rest; @@ -66,18 +67,18 @@ public: size_t Data(size_t length) noexcept; /** - * Reads metadata from the stream. Returns the number of bytes - * consumed. If the return value is smaller than "length", the caller - * should invoke icy_data(). + * Reads metadata from the stream. Returns the number of + * bytes consumed. If the return value is smaller than + * "src.size()", the caller should invoke Data(). */ - size_t Meta(const void *data, size_t length) noexcept; + std::size_t Meta(std::span src) noexcept; /** * Parse data and eliminate metadata. * * @return the number of data bytes remaining in the buffer */ - size_t ParseInPlace(void *data, size_t length) noexcept; + size_t ParseInPlace(std::span buffer) noexcept; std::unique_ptr ReadTag() noexcept { return std::exchange(tag, nullptr);