From 548aa00111e781c6b31e9a2486306d607081b1ec Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 6 Jun 2019 12:02:55 +0200 Subject: 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. --- src/tag/Handler.cxx | 47 +++++++++++++++++++++++++++++++++++------------ src/tag/Handler.hxx | 17 ++++++++--------- src/tag/Id3Scan.cxx | 1 + 3 files changed, 44 insertions(+), 21 deletions(-) (limited to 'src/tag') diff --git a/src/tag/Handler.cxx b/src/tag/Handler.cxx index fb328fda6..9731a7878 100644 --- a/src/tag/Handler.cxx +++ b/src/tag/Handler.cxx @@ -1,5 +1,5 @@ /* - * Copyright 2003-2018 The Music Player Daemon Project + * Copyright 2003-2019 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,9 +21,20 @@ #include "Builder.hxx" #include "AudioFormat.hxx" #include "util/ASCII.hxx" -#include "util/StringFormat.hxx" +#include "util/CharUtil.hxx" +#include "util/StringView.hxx" -#include +#include + +void +NullTagHandler::OnTag(TagType, StringView) noexcept +{ +} + +void +NullTagHandler::OnPair(StringView, StringView) noexcept +{ +} void NullTagHandler::OnAudioFormat(gcc_unused AudioFormat af) noexcept @@ -36,23 +47,35 @@ AddTagHandler::OnDuration(SongTime duration) noexcept 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 -AddTagHandler::OnTag(TagType type, const char *value) noexcept +AddTagHandler::OnTag(TagType type, StringView value) noexcept { if (type == TAG_TRACK || type == TAG_DISC) { /* filter out this extra data and leading zeroes */ - char *end; - unsigned n = strtoul(value, &end, 10); - if (value != end) - tag.AddItem(type, StringFormat<21>("%u", n)); - } else - tag.AddItem(type, value); + + value = NormalizeDecimal(value); + } + + tag.AddItem(type, value); } 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); } diff --git a/src/tag/Handler.hxx b/src/tag/Handler.hxx index f03ac4af8..4b5118f1b 100644 --- a/src/tag/Handler.hxx +++ b/src/tag/Handler.hxx @@ -1,5 +1,5 @@ /* - * Copyright 2003-2018 The Music Player Daemon Project + * Copyright 2003-2019 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include "Chrono.hxx" #include "util/Compiler.h" +struct StringView; struct AudioFormat; class TagBuilder; @@ -74,13 +75,13 @@ public: * @param the value of the tag; the pointer will become * 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 * 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. @@ -106,10 +107,8 @@ public: :TagHandler(_want_mask) {} void OnDuration(gcc_unused SongTime duration) noexcept override {} - void OnTag(gcc_unused TagType type, - gcc_unused const char *value) noexcept override {} - void OnPair(gcc_unused const char *key, - gcc_unused const char *value) noexcept override {} + void OnTag(TagType type, StringView value) noexcept override; + void OnPair(StringView key, StringView value) noexcept override; void OnAudioFormat(AudioFormat af) noexcept override; }; @@ -130,7 +129,7 @@ public: :AddTagHandler(0, _builder) {} 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 :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; }; diff --git a/src/tag/Id3Scan.cxx b/src/tag/Id3Scan.cxx index faf98cc00..823e175b5 100644 --- a/src/tag/Id3Scan.cxx +++ b/src/tag/Id3Scan.cxx @@ -27,6 +27,7 @@ #include "util/Alloc.hxx" #include "util/ScopeExit.hxx" #include "util/StringStrip.hxx" +#include "util/StringView.hxx" #include "Log.hxx" #include -- cgit v1.2.3