aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/PlaylistTag.cxx22
-rw-r--r--src/tag/Tag.cxx20
-rw-r--r--src/tag/Tag.hxx12
-rw-r--r--src/tag/TagBuilder.cxx34
-rw-r--r--src/tag/TagBuilder.hxx10
5 files changed, 54 insertions, 44 deletions
diff --git a/src/PlaylistTag.cxx b/src/PlaylistTag.cxx
index 5813ec1c1..e158018f5 100644
--- a/src/PlaylistTag.cxx
+++ b/src/PlaylistTag.cxx
@@ -28,6 +28,7 @@
#include "PlaylistError.hxx"
#include "Song.hxx"
#include "tag/Tag.hxx"
+#include "tag/TagBuilder.hxx"
#include "util/Error.hxx"
bool
@@ -48,9 +49,15 @@ playlist::AddSongIdTag(unsigned id, TagType tag_type, const char *value,
return false;
}
- if (song.tag == nullptr)
- song.tag = new Tag();
- song.tag->AddItem(tag_type, value);
+ TagBuilder tag;
+ if (song.tag != nullptr) {
+ tag = std::move(*song.tag);
+ delete song.tag;
+ }
+
+ tag.AddItem(tag_type, value);
+ song.tag = tag.Commit();
+
queue.ModifyAtPosition(position);
OnModified();
return true;
@@ -77,10 +84,15 @@ playlist::ClearSongIdTag(unsigned id, TagType tag_type,
if (song.tag == nullptr)
return true;
+ TagBuilder tag(std::move(*song.tag));
+ delete song.tag;
+
if (tag_type == TAG_NUM_OF_ITEM_TYPES)
- song.tag->RemoveAll();
+ tag.RemoveAll();
else
- song.tag->RemoveType(tag_type);
+ tag.RemoveType(tag_type);
+ song.tag = tag.Commit();
+
queue.ModifyAtPosition(position);
OnModified();
return true;
diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx
index 7d1da63df..43ded308a 100644
--- a/src/tag/Tag.cxx
+++ b/src/tag/Tag.cxx
@@ -187,23 +187,3 @@ Tag::AddItem(TagType type, const char *value)
{
AddItem(type, value, strlen(value));
}
-
-void
-Tag::RemoveType(TagType type)
-{
- auto dest = items, src = items, end = items + num_items;
-
- tag_pool_lock.lock();
- while (src != end) {
- TagItem *item = *src++;
- if (item->type == type)
- /* remove it */
- tag_pool_put_item(item);
- else
- /* keep it */
- *dest++ = item;
- }
- tag_pool_lock.unlock();
-
- num_items = dest - items;
-}
diff --git a/src/tag/Tag.hxx b/src/tag/Tag.hxx
index 0e48298a7..e404a4f26 100644
--- a/src/tag/Tag.hxx
+++ b/src/tag/Tag.hxx
@@ -122,18 +122,6 @@ struct Tag {
void AddItem(TagType type, const char *value);
/**
- * Removes all tag items.
- */
- void RemoveAll() {
- num_items = 0;
- }
-
- /**
- * Removes all tag items of the specified type.
- */
- void RemoveType(TagType type);
-
- /**
* Merges the data from two tags. If both tags share data for the
* same TagType, only data from "add" is used.
*
diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx
index 2d3b49eb5..5c7da2a1a 100644
--- a/src/tag/TagBuilder.cxx
+++ b/src/tag/TagBuilder.cxx
@@ -108,13 +108,7 @@ TagBuilder::Clear()
{
time = -1;
has_playlist = false;
-
- tag_pool_lock.lock();
- for (auto i : items)
- tag_pool_put_item(i);
- tag_pool_lock.unlock();
-
- items.clear();
+ RemoveAll();
}
void
@@ -216,3 +210,29 @@ TagBuilder::AddItem(TagType type, const char *value)
AddItem(type, value, strlen(value));
}
+
+void
+TagBuilder::RemoveAll()
+{
+ tag_pool_lock.lock();
+ for (auto i : items)
+ tag_pool_put_item(i);
+ tag_pool_lock.unlock();
+
+ items.clear();
+}
+
+void
+TagBuilder::RemoveType(TagType type)
+{
+ const auto begin = items.begin(), end = items.end();
+
+ items.erase(std::remove_if(begin, end,
+ [type](TagItem *item) {
+ if (item->type != type)
+ return false;
+ tag_pool_put_item(item);
+ return true;
+ }),
+ end);
+}
diff --git a/src/tag/TagBuilder.hxx b/src/tag/TagBuilder.hxx
index cd4fa4e57..fe647db08 100644
--- a/src/tag/TagBuilder.hxx
+++ b/src/tag/TagBuilder.hxx
@@ -147,6 +147,16 @@ public:
gcc_nonnull_all
void AddItem(TagType type, const char *value);
+ /**
+ * Removes all tag items.
+ */
+ void RemoveAll();
+
+ /**
+ * Removes all tag items of the specified type.
+ */
+ void RemoveType(TagType type);
+
private:
gcc_nonnull_all
void AddItemInternal(TagType type, const char *value, size_t length);