diff options
author | Max Kellermann <max@musicpd.org> | 2018-10-22 11:35:22 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-10-22 13:08:24 +0200 |
commit | db27bb76e280c69d70bc14f0b0161e89d496a3c8 (patch) | |
tree | 6efdf274058eea88b99ac92155aae1d7e83e03c6 /src/tag | |
parent | 7cfe929c3692e74f4e6073960eaf0e08a9989811 (diff) |
db: fix broken command "list ... group"
Grouping in the "list" command was completely broken from the start,
unlike "count group". I have no idea what I have been thinking when I
wrote commit ae178c77bdc47c954fd9a4b32ffc07fe6c4a8a49, but it didn't
make any sense.
This commit is a rewrite of the feature.
For clients to be able to detect this feature, this commit also
increments the protocol version.
Diffstat (limited to 'src/tag')
-rw-r--r-- | src/tag/Set.cxx | 117 | ||||
-rw-r--r-- | src/tag/Set.hxx | 73 |
2 files changed, 0 insertions, 190 deletions
diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx deleted file mode 100644 index d52d517aa..000000000 --- a/src/tag/Set.cxx +++ /dev/null @@ -1,117 +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 "Fallback.hxx" -#include "TagBuilder.hxx" -#include "util/StringView.hxx" - -#include <functional> - -#include <assert.h> - -/** - * Copy all tag items of the specified type. - */ -static bool -CopyTagItem2(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) -{ - ApplyTagWithFallback(type, - std::bind(CopyTagItem2, std::ref(dest), type, - std::cref(src), std::placeholders::_1)); -} - -/** - * Copy all tag items of the types in the mask. - */ -static void -CopyTagMask(TagBuilder &dest, const Tag &src, tag_mask_t mask) -{ - for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) - if ((mask & (tag_mask_t(1) << i)) != 0) - CopyTagItem(dest, src, TagType(i)); -} - -void -TagSet::InsertUnique(const Tag &src, TagType type, const char *value, - tag_mask_t group_mask) noexcept -{ - TagBuilder builder; - builder.AddItemUnchecked(type, value); - CopyTagMask(builder, src, group_mask); -#if CLANG_OR_GCC_VERSION(4,8) - emplace(builder.Commit()); -#else - insert(builder.Commit()); -#endif -} - -bool -TagSet::CheckUnique(TagType dest_type, - const Tag &tag, TagType src_type, - tag_mask_t 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, tag_mask_t group_mask) noexcept -{ - static_assert(sizeof(group_mask) * 8 >= TAG_NUM_OF_ITEM_TYPES, - "Mask is too small"); - - assert((group_mask & (tag_mask_t(1) << unsigned(type))) == 0); - - if (!ApplyTagWithFallback(type, - std::bind(&TagSet::CheckUnique, this, - type, std::cref(tag), - std::placeholders::_1, - group_mask))) - InsertUnique(tag, type, "", group_mask); -} diff --git a/src/tag/Set.hxx b/src/tag/Set.hxx deleted file mode 100644 index 8e19b7ca2..000000000 --- a/src/tag/Set.hxx +++ /dev/null @@ -1,73 +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 "Compiler.h" -#include "Tag.hxx" -#include "Mask.hxx" - -#include <set> - -#include <string.h> - -/** - * 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, tag_mask_t group_mask) noexcept; - -private: - void InsertUnique(const Tag &src, TagType type, const char *value, - tag_mask_t group_mask) noexcept; - - bool CheckUnique(TagType dest_type, - const Tag &tag, TagType src_type, - tag_mask_t group_mask) noexcept; -}; - -#endif |