tag/Handler: pass std::span to OnPicture()

This commit is contained in:
Max Kellermann 2022-05-24 13:51:18 +02:00
parent 2e6f115bcc
commit 6d113de1f8
9 changed files with 41 additions and 39 deletions

View File

@ -339,29 +339,28 @@ public:
}
void OnPicture(const char *mime_type,
ConstBuffer<void> buffer) noexcept override {
std::span<const std::byte> buffer) noexcept override {
if (found)
/* only use the first picture */
return;
found = true;
if (offset > buffer.size) {
if (offset > buffer.size()) {
bad_offset = true;
return;
}
response.Fmt(FMT_STRING("size: {}\n"), buffer.size);
response.Fmt(FMT_STRING("size: {}\n"), buffer.size());
if (mime_type != nullptr)
response.Fmt(FMT_STRING("type: {}\n"), mime_type);
buffer.size -= offset;
buffer = buffer.subspan(offset);
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);
if (buffer.size() > binary_limit)
buffer = buffer.first(binary_limit);
response.WriteBinary(buffer);
}

View File

@ -159,10 +159,10 @@ GetMimeType(const AVStream &stream) noexcept
return nullptr;
}
static ConstBuffer<void>
ToConstBuffer(const AVPacket &packet) noexcept
static std::span<const std::byte>
ToSpan(const AVPacket &packet) noexcept
{
return {packet.data, size_t(packet.size)};
return std::as_bytes(std::span{packet.data, size_t(packet.size)});
}
/**
@ -650,7 +650,7 @@ FfmpegScanStream(AVFormatContext &format_context, TagHandler &handler)
const auto *picture_stream = FindPictureStream(format_context);
if (picture_stream != nullptr)
handler.OnPicture(GetMimeType(*picture_stream),
ToConstBuffer(picture_stream->attached_pic));
ToSpan(picture_stream->attached_pic));
}
return true;

View File

@ -111,7 +111,7 @@ Scan(const FLAC__StreamMetadata_Picture &picture, TagHandler &handler) noexcept
return;
handler.OnPicture(picture.mime_type,
{picture.data, picture.data_length});
std::as_bytes(std::span{picture.data, picture.data_length}));
}
void

View File

@ -36,7 +36,7 @@ NullTagHandler::OnPair(StringView, StringView) noexcept
}
void
NullTagHandler::OnPicture(const char *, ConstBuffer<void>) noexcept
NullTagHandler::OnPicture(const char *, std::span<const std::byte>) noexcept
{
}

View File

@ -24,7 +24,9 @@
#include "Chrono.hxx"
#include "util/Compiler.h"
template<typename T> struct ConstBuffer;
#include <cstddef>
#include <span>
struct StringView;
struct AudioFormat;
class TagBuilder;
@ -116,7 +118,7 @@ public:
* invalidated after this method returns
*/
virtual void OnPicture(const char *mime_type,
ConstBuffer<void> buffer) noexcept = 0;
std::span<const std::byte> buffer) noexcept = 0;
};
class NullTagHandler : public TagHandler {
@ -129,7 +131,7 @@ public:
void OnPair(StringView key, StringView value) noexcept override;
void OnAudioFormat(AudioFormat af) noexcept override;
void OnPicture(const char *mime_type,
ConstBuffer<void> buffer) noexcept override;
std::span<const std::byte> buffer) noexcept override;
};
/**

View File

@ -20,37 +20,35 @@
#include "Id3Picture.hxx"
#include "Handler.hxx"
#include "util/ByteOrder.hxx"
#include "util/ConstBuffer.hxx"
#include "util/StringView.hxx"
#include <cstdint>
#include <string>
static StringView
ReadString(ConstBuffer<uint8_t> &src) noexcept
ReadString(std::span<const std::byte> &src) noexcept
{
if (src.size < 4)
if (src.size() < 4)
return nullptr;
const size_t length = *(const PackedBE32 *)src.data;
src.skip_front(4);
const size_t length = *(const PackedBE32 *)(const void *)src.data();
src = src.subspan(4);
if (src.size < length)
if (src.size() < length)
return nullptr;
StringView result((const char *)src.data, length);
src.skip_front(length);
const std::string_view result{(const char *)src.data(), length};
src = src.subspan(length);
return result;
}
void
ScanId3Apic(ConstBuffer<void> _buffer, TagHandler &handler) noexcept
ScanId3Apic(std::span<const std::byte> buffer, TagHandler &handler) noexcept
{
auto buffer = ConstBuffer<uint8_t>::FromVoid(_buffer);
if (buffer.size < 4)
if (buffer.size() < 4)
return;
buffer.skip_front(4); /* picture type */
buffer = buffer.subspan(4); /* picture type */
const auto mime_type = ReadString(buffer);
if (mime_type.IsNull())
@ -60,18 +58,18 @@ ScanId3Apic(ConstBuffer<void> _buffer, TagHandler &handler) noexcept
if (ReadString(buffer).IsNull())
return;
if (buffer.size < 20)
if (buffer.size() < 20)
return;
buffer.skip_front(16);
buffer = buffer.subspan(16);
const size_t image_size = *(const PackedBE32 *)buffer.data;
buffer.skip_front(4);
const size_t image_size = *(const PackedBE32 *)(const void *)buffer.data();
buffer = buffer.subspan(4);
if (buffer.size < image_size)
if (buffer.size() < image_size)
return;
ConstBuffer<void> image(buffer.data, image_size);
const auto image = buffer.first(image_size);
// TODO: don't copy MIME type, pass StringView to TagHandler::OnPicture()
handler.OnPicture(std::string(mime_type.data, mime_type.size).c_str(),

View File

@ -20,13 +20,14 @@
#ifndef MPD_TAG_ID3_PICTURE_HXX
#define MPD_TAG_ID3_PICTURE_HXX
template<typename T> struct ConstBuffer;
#include <span>
class TagHandler;
/**
* Scan an "APIC" value and call TagHandler::OnPicture().
*/
void
ScanId3Apic(ConstBuffer<void> buffer, TagHandler &handler) noexcept;
ScanId3Apic(std::span<const std::byte> buffer, TagHandler &handler) noexcept;
#endif

View File

@ -308,7 +308,8 @@ tag_id3_handle_apic(const struct id3_tag *id3_tag,
if (data == nullptr || size == 0)
continue;
handler.OnPicture(mime_type, {data, size});
handler.OnPicture(mime_type,
std::as_bytes(std::span{data, size}));
}
}

View File

@ -77,8 +77,9 @@ public:
}
void OnPicture(const char *mime_type,
ConstBuffer<void> buffer) noexcept override {
printf("picture mime='%s' size=%zu\n", mime_type, buffer.size);
std::span<const std::byte> buffer) noexcept override {
printf("picture mime='%s' size=%zu\n",
mime_type, buffer.size());
}
};