diff options
author | Max Kellermann <max@musicpd.org> | 2018-10-22 18:19:04 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-10-22 18:20:29 +0200 |
commit | 66ab2de5785755594b300b933083a0e5892d05fc (patch) | |
tree | a0e1dfa192d357a3749acf53dfc04876fcfcf4ef /src/tag | |
parent | e28d1e0f65fb47f452934bc5d70fdb40bdc4c62e (diff) | |
parent | db27bb76e280c69d70bc14f0b0161e89d496a3c8 (diff) |
Merge branch 'v0.20.x'
Diffstat (limited to 'src/tag')
-rw-r--r-- | src/tag/Builder.cxx | 29 | ||||
-rw-r--r-- | src/tag/Builder.hxx | 6 | ||||
-rw-r--r-- | src/tag/Fallback.hxx | 53 | ||||
-rw-r--r-- | src/tag/Set.cxx | 114 | ||||
-rw-r--r-- | src/tag/Set.hxx | 74 | ||||
-rw-r--r-- | src/tag/VisitFallback.hxx | 60 | ||||
-rw-r--r-- | src/tag/meson.build | 1 |
7 files changed, 134 insertions, 203 deletions
diff --git a/src/tag/Builder.cxx b/src/tag/Builder.cxx index 1bcdb5bda..85a77131b 100644 --- a/src/tag/Builder.cxx +++ b/src/tag/Builder.cxx @@ -186,6 +186,19 @@ TagBuilder::Complement(const Tag &other) noexcept } } +void +TagBuilder::AddItemUnchecked(TagType type, StringView value) noexcept +{ + TagItem *i; + + { + const std::lock_guard<Mutex> protect(tag_pool_lock); + i = tag_pool_get_item(type, value); + } + + items.push_back(i); +} + inline void TagBuilder::AddItemInternal(TagType type, StringView value) noexcept { @@ -195,15 +208,9 @@ TagBuilder::AddItemInternal(TagType type, StringView value) noexcept if (!f.IsNull()) value = { f.data, f.size }; - TagItem *i; - { - const std::lock_guard<Mutex> protect(tag_pool_lock); - i = tag_pool_get_item(type, value); - } + AddItemUnchecked(type, value); free(f.data); - - items.push_back(i); } void @@ -229,13 +236,7 @@ TagBuilder::AddItem(TagType type, const char *value) noexcept void TagBuilder::AddEmptyItem(TagType type) noexcept { - TagItem *i; - { - const std::lock_guard<Mutex> protect(tag_pool_lock); - i = tag_pool_get_item(type, ""); - } - - items.push_back(i); + AddItemUnchecked(type, ""); } void diff --git a/src/tag/Builder.hxx b/src/tag/Builder.hxx index 136e0e745..dbf4cddb8 100644 --- a/src/tag/Builder.hxx +++ b/src/tag/Builder.hxx @@ -133,6 +133,12 @@ public: void Complement(const Tag &other) noexcept; /** + * A variant of AddItem() which does not attempt to fix up the + * value and does not check whether the tag type is disabled. + */ + void AddItemUnchecked(TagType type, StringView value) noexcept; + + /** * Appends a new tag item. * * @param type the type of the new tag item diff --git a/src/tag/Fallback.hxx b/src/tag/Fallback.hxx new file mode 100644 index 000000000..08e4dc80a --- /dev/null +++ b/src/tag/Fallback.hxx @@ -0,0 +1,53 @@ +/* + * Copyright 2003-2018 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_TAG_FALLBACK_HXX +#define MPD_TAG_FALLBACK_HXX + +#include <utility> + +template<typename F> +bool +ApplyTagFallback(TagType type, F &&f) noexcept +{ + if (type == TAG_ALBUM_ARTIST_SORT) { + /* fall back to "AlbumArtist", "ArtistSort" and + "Artist" if no "AlbumArtistSort" was found */ + if (f(TAG_ALBUM_ARTIST)) + return true; + + return ApplyTagFallback(TAG_ARTIST_SORT, std::forward<F>(f)); + } + + if (type == TAG_ALBUM_ARTIST || type == TAG_ARTIST_SORT) + /* fall back to "Artist" if no + "AlbumArtist"/"ArtistSort" was found */ + return f(TAG_ARTIST); + + return false; +} + +template<typename F> +bool +ApplyTagWithFallback(TagType type, F &&f) noexcept +{ + return f(type) || ApplyTagFallback(type, std::forward<F>(f)); +} + +#endif diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx deleted file mode 100644 index 0009173bb..000000000 --- a/src/tag/Set.cxx +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2003-2017 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. - */ - -#include "Set.hxx" -#include "Builder.hxx" -#include "Mask.hxx" -#include "Settings.hxx" - -#include <assert.h> - -/** - * Copy all tag items of the specified type. - */ -static bool -CopyTagItem(TagBuilder &dest, TagType dest_type, - const Tag &src, TagType src_type) -{ - bool found = false; - - for (const auto &item : src) { - if (item.type == src_type) { - dest.AddItem(dest_type, item.value); - found = true; - } - } - - return found; -} - -/** - * Copy all tag items of the specified type. Fall back to "Artist" if - * there is no "AlbumArtist". - */ -static void -CopyTagItem(TagBuilder &dest, const Tag &src, TagType type) -{ - if (!CopyTagItem(dest, type, src, type) && - type == TAG_ALBUM_ARTIST) - CopyTagItem(dest, type, src, TAG_ARTIST); -} - -/** - * Copy all tag items of the types in the mask. - */ -static void -CopyTagMask(TagBuilder &dest, const Tag &src, TagMask mask) -{ - for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) - if (mask.Test(TagType(i))) - CopyTagItem(dest, src, TagType(i)); -} - -void -TagSet::InsertUnique(const Tag &src, TagType type, const char *value, - TagMask group_mask) noexcept -{ - TagBuilder builder; - if (value == nullptr) - builder.AddEmptyItem(type); - else - builder.AddItem(type, value); - CopyTagMask(builder, src, group_mask); - emplace(builder.Commit()); -} - -bool -TagSet::CheckUnique(TagType dest_type, - const Tag &tag, TagType src_type, - TagMask group_mask) noexcept -{ - bool found = false; - - for (const auto &item : tag) { - if (item.type == src_type) { - InsertUnique(tag, dest_type, item.value, group_mask); - found = true; - } - } - - return found; -} - -void -TagSet::InsertUnique(const Tag &tag, - TagType type, TagMask group_mask) noexcept -{ - static_assert(sizeof(group_mask) * 8 >= TAG_NUM_OF_ITEM_TYPES, - "Mask is too small"); - - assert(!group_mask.Test(type)); - - if (!CheckUnique(type, tag, type, group_mask) && - (type != TAG_ALBUM_ARTIST || - !IsTagEnabled(TAG_ALBUM_ARTIST) || - /* fall back to "Artist" if no "AlbumArtist" was found */ - !CheckUnique(type, tag, TAG_ARTIST, group_mask))) - InsertUnique(tag, type, nullptr, group_mask); -} diff --git a/src/tag/Set.hxx b/src/tag/Set.hxx deleted file mode 100644 index e74d145f4..000000000 --- a/src/tag/Set.hxx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2003-2017 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_TAG_SET_HXX -#define MPD_TAG_SET_HXX - -#include "util/Compiler.h" -#include "Tag.hxx" - -#include <set> - -#include <string.h> - -class TagMask; - -/** - * Helper class for #TagSet which compares two #Tag objects. - */ -struct TagLess { - gcc_pure - bool operator()(const Tag &a, const Tag &b) const noexcept { - if (a.num_items != b.num_items) - return a.num_items < b.num_items; - - const unsigned n = a.num_items; - for (unsigned i = 0; i < n; ++i) { - const TagItem &ai = *a.items[i]; - const TagItem &bi = *b.items[i]; - if (ai.type != bi.type) - return unsigned(ai.type) < unsigned(bi.type); - - const int cmp = strcmp(ai.value, bi.value); - if (cmp != 0) - return cmp < 0; - } - - return false; - } -}; - -/** - * A set of #Tag objects. - */ -class TagSet : public std::set<Tag, TagLess> { -public: - void InsertUnique(const Tag &tag, - TagType type, TagMask group_mask) noexcept; - -private: - void InsertUnique(const Tag &src, TagType type, const char *value, - TagMask group_mask) noexcept; - - bool CheckUnique(TagType dest_type, - const Tag &tag, TagType src_type, - TagMask group_mask) noexcept; -}; - -#endif diff --git a/src/tag/VisitFallback.hxx b/src/tag/VisitFallback.hxx new file mode 100644 index 000000000..23992d44b --- /dev/null +++ b/src/tag/VisitFallback.hxx @@ -0,0 +1,60 @@ +/* + * Copyright 2003-2018 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_TAG_VISIT_FALLBACK_HXX +#define MPD_TAG_VISIT_FALLBACK_HXX + +#include "Fallback.hxx" +#include "Tag.hxx" + +template<typename F> +bool +VisitTagType(const Tag &tag, TagType type, F &&f) noexcept +{ + bool found = false; + + for (const auto &item : tag) { + if (item.type == type) { + found = true; + f(item.value); + } + } + + return found; +} + +template<typename F> +bool +VisitTagWithFallback(const Tag &tag, TagType type, F &&f) noexcept +{ + return ApplyTagWithFallback(type, + [&](TagType type2) { + return VisitTagType(tag, type2, f); + }); +} + +template<typename F> +void +VisitTagWithFallbackOrEmpty(const Tag &tag, TagType type, F &&f) noexcept +{ + if (!VisitTagWithFallback(tag, type, f)) + f(""); +} + +#endif diff --git a/src/tag/meson.build b/src/tag/meson.build index b0121a71d..c423417d1 100644 --- a/src/tag/meson.build +++ b/src/tag/meson.build @@ -9,7 +9,6 @@ tag_sources = [ 'FixString.cxx', 'Pool.cxx', 'Table.cxx', - 'Set.cxx', 'Format.cxx', 'VorbisComment.cxx', 'ReplayGain.cxx', |