tag/Handler: pass StringView to OnTag() and OnPair()
Eliminates a number of allocations, because callers don't need to copy the strings to a newly allocated buffer only to null-terminate them. And most callers don't need to have a null-terminated string.
This commit is contained in:
parent
76eb550011
commit
548aa00111
|
@ -21,6 +21,7 @@
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "tag/Settings.hxx"
|
#include "tag/Settings.hxx"
|
||||||
#include "client/Response.hxx"
|
#include "client/Response.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_print_types(Response &r) noexcept
|
tag_print_types(Response &r) noexcept
|
||||||
|
@ -31,6 +32,13 @@ tag_print_types(Response &r) noexcept
|
||||||
r.Format("tagtype: %s\n", tag_item_names[i]);
|
r.Format("tagtype: %s\n", tag_item_names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tag_print(Response &r, TagType type, StringView value) noexcept
|
||||||
|
{
|
||||||
|
r.Format("%s: %.*s\n", tag_item_names[type],
|
||||||
|
int(value.size), value.data);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_print(Response &r, TagType type, const char *value) noexcept
|
tag_print(Response &r, TagType type, const char *value) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,11 +25,15 @@
|
||||||
enum TagType : uint8_t;
|
enum TagType : uint8_t;
|
||||||
|
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
struct StringView;
|
||||||
class Response;
|
class Response;
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_print_types(Response &response) noexcept;
|
tag_print_types(Response &response) noexcept;
|
||||||
|
|
||||||
|
void
|
||||||
|
tag_print(Response &response, TagType type, StringView value) noexcept;
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_print(Response &response, TagType type, const char *value) noexcept;
|
tag_print(Response &response, TagType type, const char *value) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "client/Client.hxx"
|
#include "client/Client.hxx"
|
||||||
#include "client/Response.hxx"
|
#include "client/Response.hxx"
|
||||||
#include "util/CharUtil.hxx"
|
#include "util/CharUtil.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
#include "tag/Generic.hxx"
|
#include "tag/Generic.hxx"
|
||||||
|
@ -110,13 +111,12 @@ handle_listfiles_local(Response &r, Path path_fs)
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
IsValidName(const char *p) noexcept
|
IsValidName(const StringView s) noexcept
|
||||||
{
|
{
|
||||||
if (!IsAlphaASCII(*p))
|
if (s.empty() || !IsAlphaASCII(s.front()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (*++p) {
|
for (const char ch : s) {
|
||||||
const char ch = *p;
|
|
||||||
if (!IsAlphaASCII(ch) && ch != '_' && ch != '-')
|
if (!IsAlphaASCII(ch) && ch != '_' && ch != '-')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,11 +126,9 @@ IsValidName(const char *p) noexcept
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
IsValidValue(const char *p) noexcept
|
IsValidValue(const StringView s) noexcept
|
||||||
{
|
{
|
||||||
while (*p) {
|
for (const char ch : s) {
|
||||||
const char ch = *p++;
|
|
||||||
|
|
||||||
if ((unsigned char)ch < 0x20)
|
if ((unsigned char)ch < 0x20)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -145,9 +143,11 @@ public:
|
||||||
explicit PrintCommentHandler(Response &_response) noexcept
|
explicit PrintCommentHandler(Response &_response) noexcept
|
||||||
:NullTagHandler(WANT_PAIR), response(_response) {}
|
:NullTagHandler(WANT_PAIR), response(_response) {}
|
||||||
|
|
||||||
void OnPair(const char *key, const char *value) noexcept override {
|
void OnPair(StringView key, StringView value) noexcept override {
|
||||||
if (IsValidName(key) && IsValidValue(value))
|
if (IsValidName(key) && IsValidValue(value))
|
||||||
response.Format("%s: %s\n", key, value);
|
response.Format("%.*s: %.*s\n",
|
||||||
|
int(key.size), key.data,
|
||||||
|
int(value.size), value.data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "time/ChronoUtil.hxx"
|
#include "time/ChronoUtil.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/StringAPI.hxx"
|
#include "util/StringAPI.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "Stats.hxx"
|
#include "Stats.hxx"
|
||||||
#include "PlaylistFile.hxx"
|
#include "PlaylistFile.hxx"
|
||||||
|
@ -147,7 +148,7 @@ public:
|
||||||
explicit PrintTagHandler(Response &_response) noexcept
|
explicit PrintTagHandler(Response &_response) noexcept
|
||||||
:NullTagHandler(WANT_TAG), response(_response) {}
|
:NullTagHandler(WANT_TAG), response(_response) {}
|
||||||
|
|
||||||
void OnTag(TagType type, const char *value) noexcept override {
|
void OnTag(TagType type, StringView value) noexcept override {
|
||||||
if (response.GetClient().tag_mask.Test(type))
|
if (response.GetClient().tag_mask.Test(type))
|
||||||
tag_print(response, type, value);
|
tag_print(response, type, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <adplug/adplug.h>
|
#include <adplug/adplug.h>
|
||||||
|
@ -85,7 +86,7 @@ adplug_scan_tag(TagType type, const std::string &value,
|
||||||
TagHandler &handler) noexcept
|
TagHandler &handler) noexcept
|
||||||
{
|
{
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
handler.OnTag(type, value.c_str());
|
handler.OnTag(type, {value.data(), value.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "CheckAudioFormat.hxx"
|
#include "CheckAudioFormat.hxx"
|
||||||
#include "util/bit_reverse.h"
|
#include "util/bit_reverse.h"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/ByteOrder.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
#include "DsdLib.hxx"
|
#include "DsdLib.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
@ -205,15 +206,14 @@ dsdiff_handle_native_tag(DecoderClient *client, InputStream &is,
|
||||||
if (length == 0 || length > MAX_LENGTH)
|
if (length == 0 || length > MAX_LENGTH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char string[MAX_LENGTH + 1];
|
char string[MAX_LENGTH];
|
||||||
char *label;
|
char *label;
|
||||||
label = string;
|
label = string;
|
||||||
|
|
||||||
if (!decoder_read_full(client, is, label, (size_t)length))
|
if (!decoder_read_full(client, is, label, (size_t)length))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string[length] = '\0';
|
handler.OnTag(type, {label, length});
|
||||||
handler.OnTag(type, label);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "tag/Table.hxx"
|
#include "tag/Table.hxx"
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
#include "tag/Id3MusicBrainz.hxx"
|
#include "tag/Id3MusicBrainz.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavutil/dict.h>
|
#include <libavutil/dict.h>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
#include "util/StringFormat.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
@ -220,7 +221,7 @@ ScanGmeInfo(const gme_info_t &info, unsigned song_num, int track_count,
|
||||||
handler.OnDuration(SongTime::FromMS(info.play_length));
|
handler.OnDuration(SongTime::FromMS(info.play_length));
|
||||||
|
|
||||||
if (track_count > 1)
|
if (track_count > 1)
|
||||||
handler.OnTag(TAG_TRACK, StringFormat<16>("%u", song_num + 1));
|
handler.OnTag(TAG_TRACK, StringFormat<16>("%u", song_num + 1).c_str());
|
||||||
|
|
||||||
if (info.song != nullptr) {
|
if (info.song != nullptr) {
|
||||||
if (track_count > 1) {
|
if (track_count > 1) {
|
||||||
|
@ -229,7 +230,7 @@ ScanGmeInfo(const gme_info_t &info, unsigned song_num, int track_count,
|
||||||
StringFormat<1024>("%s (%u/%d)",
|
StringFormat<1024>("%s (%u/%d)",
|
||||||
info.song, song_num + 1,
|
info.song, song_num + 1,
|
||||||
track_count);
|
track_count);
|
||||||
handler.OnTag(TAG_TITLE, tag_title);
|
handler.OnTag(TAG_TITLE, tag_title.c_str());
|
||||||
} else
|
} else
|
||||||
handler.OnTag(TAG_TITLE, info.song);
|
handler.OnTag(TAG_TITLE, info.song);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <mikmod.h>
|
#include <mikmod.h>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "util/WritableBuffer.hxx"
|
#include "util/WritableBuffer.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/RuntimeError.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <libmodplug/modplug.h>
|
#include <libmodplug/modplug.h>
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
#include "util/StringFormat.hxx"
|
#include "util/StringFormat.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/ByteOrder.hxx"
|
#include "util/ByteOrder.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
@ -460,7 +461,7 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks,
|
||||||
const auto tag_title =
|
const auto tag_title =
|
||||||
StringFormat<1024>("%s (%u/%u)",
|
StringFormat<1024>("%s (%u/%u)",
|
||||||
title, track, n_tracks);
|
title, track, n_tracks);
|
||||||
handler.OnTag(TAG_TITLE, tag_title);
|
handler.OnTag(TAG_TITLE, tag_title.c_str());
|
||||||
} else
|
} else
|
||||||
handler.OnTag(TAG_TITLE, title);
|
handler.OnTag(TAG_TITLE, title);
|
||||||
|
|
||||||
|
@ -475,7 +476,7 @@ ScanSidTuneInfo(const SidTuneInfo &info, unsigned track, unsigned n_tracks,
|
||||||
handler.OnTag(TAG_DATE, date);
|
handler.OnTag(TAG_DATE, date);
|
||||||
|
|
||||||
/* track */
|
/* track */
|
||||||
handler.OnTag(TAG_TRACK, StringFormat<16>("%u", track));
|
handler.OnTag(TAG_TRACK, StringFormat<16>("%u", track).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "tag/Handler.hxx"
|
#include "tag/Handler.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "tag/ReplayGain.hxx"
|
#include "tag/ReplayGain.hxx"
|
||||||
#include "tag/MixRamp.hxx"
|
#include "tag/MixRamp.hxx"
|
||||||
#include "ReplayGainInfo.hxx"
|
#include "ReplayGainInfo.hxx"
|
||||||
#include "util/DivideString.hxx"
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@ flac_scan_comment(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
|
||||||
TagHandler &handler) noexcept
|
TagHandler &handler) noexcept
|
||||||
{
|
{
|
||||||
if (handler.WantPair()) {
|
if (handler.WantPair()) {
|
||||||
const char *comment = (const char *)entry->entry;
|
const StringView comment((const char *)entry->entry);
|
||||||
const DivideString split(comment, '=');
|
const auto split = StringView(comment).Split('=');
|
||||||
if (split.IsDefined() && !split.empty())
|
if (!split.first.empty() && !split.second.IsNull())
|
||||||
handler.OnPair(split.GetFirst(), split.GetSecond());
|
handler.OnPair(split.first, split.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const struct tag_table *i = xiph_tags; i->name != nullptr; ++i)
|
for (const struct tag_table *i = xiph_tags; i->name != nullptr; ++i)
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "tag/VorbisComment.hxx"
|
#include "tag/VorbisComment.hxx"
|
||||||
#include "tag/ReplayGain.hxx"
|
#include "tag/ReplayGain.hxx"
|
||||||
#include "ReplayGainInfo.hxx"
|
#include "ReplayGainInfo.hxx"
|
||||||
#include "util/DivideString.hxx"
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments) noexcept
|
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments) noexcept
|
||||||
|
@ -69,9 +69,9 @@ static void
|
||||||
vorbis_scan_comment(const char *comment, TagHandler &handler) noexcept
|
vorbis_scan_comment(const char *comment, TagHandler &handler) noexcept
|
||||||
{
|
{
|
||||||
if (handler.WantPair()) {
|
if (handler.WantPair()) {
|
||||||
const DivideString split(comment, '=');
|
const auto split = StringView(comment).Split('=');
|
||||||
if (split.IsDefined() && !split.empty())
|
if (!split.first.empty() && !split.second.IsNull())
|
||||||
handler.OnPair(split.GetFirst(), split.GetSecond());
|
handler.OnPair(split.first, split.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const struct tag_table *i = xiph_tags; i->name != nullptr; ++i)
|
for (const struct tag_table *i = xiph_tags; i->name != nullptr; ++i)
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "TagFile.hxx"
|
#include "TagFile.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -70,15 +70,14 @@ public:
|
||||||
|
|
||||||
ExtractCuesheetTagHandler() noexcept:NullTagHandler(WANT_PAIR) {}
|
ExtractCuesheetTagHandler() noexcept:NullTagHandler(WANT_PAIR) {}
|
||||||
|
|
||||||
void OnPair(const char *key, const char *value) noexcept override;
|
void OnPair(StringView key, StringView value) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ExtractCuesheetTagHandler::OnPair(const char *name, const char *value) noexcept
|
ExtractCuesheetTagHandler::OnPair(StringView name, StringView value) noexcept
|
||||||
{
|
{
|
||||||
if (cuesheet.empty() &&
|
if (cuesheet.empty() && name.EqualsIgnoreCase("cuesheet"))
|
||||||
StringEqualsCaseASCII(name, "cuesheet"))
|
cuesheet = {value.data, value.size};
|
||||||
cuesheet = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<SongEnumerator>
|
static std::unique_ptr<SongEnumerator>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2003-2018 The Music Player Daemon Project
|
* Copyright 2003-2019 The Music Player Daemon Project
|
||||||
* http://www.musicpd.org
|
* http://www.musicpd.org
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -21,9 +21,20 @@
|
||||||
#include "Builder.hxx"
|
#include "Builder.hxx"
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/StringFormat.hxx"
|
#include "util/CharUtil.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <algorithm>
|
||||||
|
|
||||||
|
void
|
||||||
|
NullTagHandler::OnTag(TagType, StringView) noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NullTagHandler::OnPair(StringView, StringView) noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NullTagHandler::OnAudioFormat(gcc_unused AudioFormat af) noexcept
|
NullTagHandler::OnAudioFormat(gcc_unused AudioFormat af) noexcept
|
||||||
|
@ -36,23 +47,35 @@ AddTagHandler::OnDuration(SongTime duration) noexcept
|
||||||
tag.SetDuration(duration);
|
tag.SetDuration(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip leading zeroes and a non-decimal suffix.
|
||||||
|
*/
|
||||||
|
static StringView
|
||||||
|
NormalizeDecimal(StringView s)
|
||||||
|
{
|
||||||
|
auto start = std::find_if(s.begin(), s.end(),
|
||||||
|
[](char ch){ return ch != '0'; });
|
||||||
|
auto end = std::find_if(start, s.end(),
|
||||||
|
[](char ch){ return !IsDigitASCII(ch); });
|
||||||
|
return {start, end};
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AddTagHandler::OnTag(TagType type, const char *value) noexcept
|
AddTagHandler::OnTag(TagType type, StringView value) noexcept
|
||||||
{
|
{
|
||||||
if (type == TAG_TRACK || type == TAG_DISC) {
|
if (type == TAG_TRACK || type == TAG_DISC) {
|
||||||
/* filter out this extra data and leading zeroes */
|
/* filter out this extra data and leading zeroes */
|
||||||
char *end;
|
|
||||||
unsigned n = strtoul(value, &end, 10);
|
value = NormalizeDecimal(value);
|
||||||
if (value != end)
|
}
|
||||||
tag.AddItem(type, StringFormat<21>("%u", n));
|
|
||||||
} else
|
|
||||||
tag.AddItem(type, value);
|
tag.AddItem(type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FullTagHandler::OnPair(const char *name, gcc_unused const char *value) noexcept
|
FullTagHandler::OnPair(StringView name, StringView) noexcept
|
||||||
{
|
{
|
||||||
if (StringEqualsCaseASCII(name, "cuesheet"))
|
if (name.EqualsIgnoreCase("cuesheet"))
|
||||||
tag.SetHasPlaylist(true);
|
tag.SetHasPlaylist(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2003-2018 The Music Player Daemon Project
|
* Copyright 2003-2019 The Music Player Daemon Project
|
||||||
* http://www.musicpd.org
|
* http://www.musicpd.org
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#include "Chrono.hxx"
|
#include "Chrono.hxx"
|
||||||
#include "util/Compiler.h"
|
#include "util/Compiler.h"
|
||||||
|
|
||||||
|
struct StringView;
|
||||||
struct AudioFormat;
|
struct AudioFormat;
|
||||||
class TagBuilder;
|
class TagBuilder;
|
||||||
|
|
||||||
|
@ -74,13 +75,13 @@ public:
|
||||||
* @param the value of the tag; the pointer will become
|
* @param the value of the tag; the pointer will become
|
||||||
* invalid after returning
|
* invalid after returning
|
||||||
*/
|
*/
|
||||||
virtual void OnTag(TagType type, const char *value) noexcept = 0;
|
virtual void OnTag(TagType type, StringView value) noexcept = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A name-value pair has been read. It is the codec specific
|
* A name-value pair has been read. It is the codec specific
|
||||||
* representation of tags.
|
* representation of tags.
|
||||||
*/
|
*/
|
||||||
virtual void OnPair(const char *key, const char *value) noexcept = 0;
|
virtual void OnPair(StringView key, StringView value) noexcept = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare the audio format of a song.
|
* Declare the audio format of a song.
|
||||||
|
@ -106,10 +107,8 @@ public:
|
||||||
:TagHandler(_want_mask) {}
|
:TagHandler(_want_mask) {}
|
||||||
|
|
||||||
void OnDuration(gcc_unused SongTime duration) noexcept override {}
|
void OnDuration(gcc_unused SongTime duration) noexcept override {}
|
||||||
void OnTag(gcc_unused TagType type,
|
void OnTag(TagType type, StringView value) noexcept override;
|
||||||
gcc_unused const char *value) noexcept override {}
|
void OnPair(StringView key, StringView value) noexcept override;
|
||||||
void OnPair(gcc_unused const char *key,
|
|
||||||
gcc_unused const char *value) noexcept override {}
|
|
||||||
void OnAudioFormat(AudioFormat af) noexcept override;
|
void OnAudioFormat(AudioFormat af) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ public:
|
||||||
:AddTagHandler(0, _builder) {}
|
:AddTagHandler(0, _builder) {}
|
||||||
|
|
||||||
void OnDuration(SongTime duration) noexcept override;
|
void OnDuration(SongTime duration) noexcept override;
|
||||||
void OnTag(TagType type, const char *value) noexcept override;
|
void OnTag(TagType type, StringView value) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +153,7 @@ public:
|
||||||
AudioFormat *_audio_format=nullptr) noexcept
|
AudioFormat *_audio_format=nullptr) noexcept
|
||||||
:FullTagHandler(0, _builder, _audio_format) {}
|
:FullTagHandler(0, _builder, _audio_format) {}
|
||||||
|
|
||||||
void OnPair(const char *key, const char *value) noexcept override;
|
void OnPair(StringView key, StringView value) noexcept override;
|
||||||
void OnAudioFormat(AudioFormat af) noexcept override;
|
void OnAudioFormat(AudioFormat af) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "util/Alloc.hxx"
|
#include "util/Alloc.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
#include "util/StringStrip.hxx"
|
#include "util/StringStrip.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <id3tag.h>
|
#include <id3tag.h>
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
#include "util/StringBuffer.hxx"
|
#include "util/StringBuffer.hxx"
|
||||||
|
#include "util/StringView.hxx"
|
||||||
#include "util/PrintException.hxx"
|
#include "util/PrintException.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -58,13 +59,16 @@ public:
|
||||||
printf("duration=%f\n", duration.ToDoubleS());
|
printf("duration=%f\n", duration.ToDoubleS());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTag(TagType type, const char *value) noexcept override {
|
void OnTag(TagType type, StringView value) noexcept override {
|
||||||
printf("[%s]=%s\n", tag_item_names[type], value);
|
printf("[%s]=%.*s\n", tag_item_names[type],
|
||||||
|
int(value.size), value.data);
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnPair(const char *key, const char *value) noexcept override {
|
void OnPair(StringView key, StringView value) noexcept override {
|
||||||
printf("\"%s\"=%s\n", key, value);
|
printf("\"%.*s\"=%.*s\n",
|
||||||
|
int(key.size), key.data,
|
||||||
|
int(value.size), value.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAudioFormat(AudioFormat af) noexcept override {
|
void OnAudioFormat(AudioFormat af) noexcept override {
|
||||||
|
|
Loading…
Reference in New Issue