From 7e8d254b95716f1253577a9a5d7df1760f9f6e47 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 3 Dec 2013 11:27:16 +0100 Subject: Tag: move code from Merge() to TagBuilder::Complement() --- src/tag/Tag.cxx | 44 ++++---------------------------------------- src/tag/TagBuilder.cxx | 19 +++++++++++++++++++ src/tag/TagBuilder.hxx | 6 ++++++ 3 files changed, 29 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx index 0fb7ea93b..7d1da63df 100644 --- a/src/tag/Tag.cxx +++ b/src/tag/Tag.cxx @@ -22,6 +22,7 @@ #include "TagPool.hxx" #include "TagString.hxx" #include "TagSettings.h" +#include "TagBuilder.hxx" #include "util/ASCII.hxx" #include @@ -108,46 +109,9 @@ Tag::Tag(const Tag &other) Tag * Tag::Merge(const Tag &base, const Tag &add) { - unsigned n; - - /* allocate new tag object */ - - Tag *ret = new Tag(); - ret->time = add.time > 0 ? add.time : base.time; - ret->num_items = base.num_items + add.num_items; - ret->items = ret->num_items > 0 - ? (TagItem **)g_malloc(items_size(*ret)) - : nullptr; - - tag_pool_lock.lock(); - - /* copy all items from "add" */ - - for (unsigned i = 0; i < add.num_items; ++i) - ret->items[i] = tag_pool_dup_item(add.items[i]); - - n = add.num_items; - - /* copy additional items from "base" */ - - for (unsigned i = 0; i < base.num_items; ++i) - if (!add.HasType(base.items[i]->type)) - ret->items[n++] = tag_pool_dup_item(base.items[i]); - - tag_pool_lock.unlock(); - - assert(n <= ret->num_items); - - if (n < ret->num_items) { - /* some tags were not copied - shrink ret->items */ - assert(n > 0); - - ret->num_items = n; - ret->items = (TagItem **) - g_realloc(ret->items, items_size(*ret)); - } - - return ret; + TagBuilder builder(base); + builder.Complement(add); + return builder.Commit(); } Tag * diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx index 15e32bb01..6ba8c12db 100644 --- a/src/tag/TagBuilder.cxx +++ b/src/tag/TagBuilder.cxx @@ -109,6 +109,25 @@ TagBuilder::HasType(TagType type) const return false; } +void +TagBuilder::Complement(const Tag &other) +{ + if (time <= 0) + time = other.time; + + has_playlist |= other.has_playlist; + + items.reserve(items.size() + other.num_items); + + tag_pool_lock.lock(); + for (unsigned i = 0, n = other.num_items; i != n; ++i) { + TagItem *item = other.items[i]; + if (!HasType(item->type)) + items.push_back(tag_pool_dup_item(item)); + } + tag_pool_lock.unlock(); +} + inline void TagBuilder::AddItemInternal(TagType type, const char *value, size_t length) { diff --git a/src/tag/TagBuilder.hxx b/src/tag/TagBuilder.hxx index 5804a7940..52ccf466c 100644 --- a/src/tag/TagBuilder.hxx +++ b/src/tag/TagBuilder.hxx @@ -118,6 +118,12 @@ public: gcc_pure bool HasType(TagType type) const; + /** + * Copy attributes and items from the other object that do not + * exist in this object. + */ + void Complement(const Tag &other); + /** * Appends a new tag item. * -- cgit v1.2.3