Tag: move code from Merge() to TagBuilder::Complement()

This commit is contained in:
Max Kellermann 2013-12-03 11:27:16 +01:00
parent 6325c3f14a
commit 7e8d254b95
3 changed files with 29 additions and 40 deletions

View File

@ -22,6 +22,7 @@
#include "TagPool.hxx"
#include "TagString.hxx"
#include "TagSettings.h"
#include "TagBuilder.hxx"
#include "util/ASCII.hxx"
#include <glib.h>
@ -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 *

View File

@ -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)
{

View File

@ -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.
*