diff options
author | Max Kellermann <max@duempel.org> | 2013-09-05 18:22:39 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-09-05 18:41:49 +0200 |
commit | 0b3e1c4706849be107954ad1b8d6bf82ef3dcc28 (patch) | |
tree | 1e74ebf4807503ca72bbeeb0a022732e9b377062 /src | |
parent | ce08a7a93277d84506a73361583a8a663f60515f (diff) | |
download | mpd-0b3e1c4706849be107954ad1b8d6bf82ef3dcc28.tar.gz mpd-0b3e1c4706849be107954ad1b8d6bf82ef3dcc28.tar.xz mpd-0b3e1c4706849be107954ad1b8d6bf82ef3dcc28.zip |
TagBuilder: new class for constructing Tag objects
Obsoletes Tag::BeginAdd() and the complicated "bulk add" code.
Diffstat (limited to 'src')
-rw-r--r-- | src/tag/TagBuilder.cxx | 108 | ||||
-rw-r--r-- | src/tag/TagBuilder.hxx | 121 |
2 files changed, 229 insertions, 0 deletions
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 <glib.h> + +#include <assert.h> +#include <string.h> + +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)); +} diff --git a/src/tag/TagBuilder.hxx b/src/tag/TagBuilder.hxx new file mode 100644 index 000000000..c882f4d53 --- /dev/null +++ b/src/tag/TagBuilder.hxx @@ -0,0 +1,121 @@ +/* + * 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. + */ + +#ifndef MPD_TAG_BUILDER_HXX +#define MPD_TAG_BUILDER_HXX + +#include "TagType.h" +#include "gcc.h" + +#include <vector> + +#include <stddef.h> + +struct TagItem; +struct Tag; + +/** + * A class that constructs #Tag objects. + */ +class TagBuilder { + /** + * The duration of the song (in seconds). A value of zero + * means that the length is unknown. If the duration is + * really between zero and one second, you should round up to + * 1. + */ + int time; + + /** + * Does this file have an embedded playlist (e.g. embedded CUE + * sheet)? + */ + bool has_playlist; + + /** an array of tag items */ + std::vector<TagItem *> items; + +public: + /** + * Create an empty tag. + */ + TagBuilder() + :time(-1), has_playlist(false) {} + + ~TagBuilder() { + Clear(); + } + + TagBuilder(const TagBuilder &other) = delete; + TagBuilder &operator=(const TagBuilder &other) = delete; + + /** + * Returns true if the object contains any information. + */ + gcc_pure + bool IsDefined() const { + return time >= 0 || has_playlist || !items.empty(); + } + + void Clear(); + + /** + * Create a new #Tag instance from data in this object. The + * returned object is owned by the caller. This object is + * empty afterwards. + */ + Tag *Commit(); + + void SetTime(int _time) { + time = _time; + } + + void SetHasPlaylist(bool _has_playlist) { + has_playlist = _has_playlist; + } + + void Reserve(unsigned n) { + items.reserve(n); + } + + /** + * Appends a new tag item. + * + * @param type the type of the new tag item + * @param value the value of the tag item (not null-terminated) + * @param len the length of #value + */ + gcc_nonnull_all + void AddItem(tag_type type, const char *value, size_t length); + + /** + * Appends a new tag item. + * + * @param type the type of the new tag item + * @param value the value of the tag item (null-terminated) + */ + gcc_nonnull_all + void AddItem(tag_type type, const char *value); + +private: + gcc_nonnull_all + void AddItemInternal(tag_type type, const char *value, size_t length); +}; + +#endif |