tag: added function tag_merge()
tag_merges() merges the data from two tag objects into one.
This commit is contained in:
parent
149f4e10cf
commit
4be479d20c
46
src/tag.c
46
src/tag.c
@ -318,6 +318,52 @@ struct tag *tag_dup(const struct tag *tag)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct tag *
|
||||
tag_merge(const struct tag *base, const struct tag *add)
|
||||
{
|
||||
struct tag *ret;
|
||||
unsigned n;
|
||||
|
||||
assert(base != NULL);
|
||||
assert(add != NULL);
|
||||
|
||||
/* allocate new tag object */
|
||||
|
||||
ret = tag_new();
|
||||
ret->time = add->time > 0 ? add->time : base->time;
|
||||
ret->numOfItems = base->numOfItems + add->numOfItems;
|
||||
ret->items = ret->numOfItems > 0 ? g_malloc(items_size(ret)) : NULL;
|
||||
|
||||
g_mutex_lock(tag_pool_lock);
|
||||
|
||||
/* copy all items from "add" */
|
||||
|
||||
for (unsigned i = 0; i < add->numOfItems; ++i)
|
||||
ret->items[i] = tag_pool_dup_item(add->items[i]);
|
||||
|
||||
n = add->numOfItems;
|
||||
|
||||
/* copy additional items from "base" */
|
||||
|
||||
for (unsigned i = 0; i < base->numOfItems; ++i)
|
||||
if (!tag_has_type(add, base->items[i]->type))
|
||||
ret->items[n++] = tag_pool_dup_item(base->items[i]);
|
||||
|
||||
g_mutex_unlock(tag_pool_lock);
|
||||
|
||||
assert(n <= ret->numOfItems);
|
||||
|
||||
if (n < ret->numOfItems) {
|
||||
/* some tags were not copied - shrink ret->items */
|
||||
assert(n > 0);
|
||||
|
||||
ret->numOfItems = n;
|
||||
ret->items = g_realloc(ret->items, items_size(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool tag_has_type(const struct tag *tag, enum tag_type type)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
|
@ -89,6 +89,15 @@ static inline void tag_add_item(struct tag *tag, enum tag_type itemType,
|
||||
|
||||
struct tag *tag_dup(const struct tag *tag);
|
||||
|
||||
/**
|
||||
* Merges the data from two tags. If both tags share data for the
|
||||
* same tag_type, only data from "add" is used.
|
||||
*
|
||||
* @return a newly allocated tag, which must be freed with tag_free()
|
||||
*/
|
||||
struct tag *
|
||||
tag_merge(const struct tag *base, const struct tag *add);
|
||||
|
||||
/**
|
||||
* Returns true if the tag contains no items. This ignores the "time"
|
||||
* attribute.
|
||||
|
Loading…
Reference in New Issue
Block a user