From 0b3e1c4706849be107954ad1b8d6bf82ef3dcc28 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 5 Sep 2013 18:22:39 +0200 Subject: TagBuilder: new class for constructing Tag objects Obsoletes Tag::BeginAdd() and the complicated "bulk add" code. --- src/tag/TagBuilder.cxx | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/tag/TagBuilder.cxx (limited to 'src/tag/TagBuilder.cxx') diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx new file mode 100644 index 000000000..d1babdadb --- /dev/null +++ b/src/tag/TagBuilder.cxx @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2003-2013 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 "config.h" +#include "TagBuilder.hxx" +#include "TagSettings.h" +#include "TagPool.hxx" +#include "TagString.hxx" +#include "Tag.hxx" + +#include + +#include +#include + +void +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(); +} + +Tag * +TagBuilder::Commit() +{ + Tag *tag = new Tag(); + tag->time = time; + tag->has_playlist = has_playlist; + + /* move all TagItem pointers to the new Tag object without + touching the TagPool reference counters; the + vector::clear() call is important to detach them from this + object */ + const unsigned n_items = items.size(); + tag->num_items = n_items; + tag->items = g_new(TagItem *, n_items); + std::copy_n(items.begin(), n_items, tag->items); + items.clear(); + + /* now ensure that this object is fresh (will not delete any + items because we've already moved them out) */ + Clear(); + + return tag; +} + +inline void +TagBuilder::AddItemInternal(tag_type type, const char *value, size_t length) +{ + assert(value != nullptr); + assert(length > 0); + + char *p = FixTagString(value, length); + if (p != nullptr) { + value = p; + length = strlen(value); + } + + tag_pool_lock.lock(); + auto i = tag_pool_get_item(type, value, length); + tag_pool_lock.unlock(); + + g_free(p); + + items.push_back(i); +} + +void +TagBuilder::AddItem(tag_type type, const char *value, size_t length) +{ + assert(value != nullptr); + + if (length == 0 || ignore_tag_items[type]) + return; + + AddItemInternal(type, value, length); +} + +void +TagBuilder::AddItem(tag_type type, const char *value) +{ + assert(value != nullptr); + + AddItem(type, value, strlen(value)); +} -- cgit v1.2.3