PaylistTag: use class TagBuilder
This commit is contained in:
		| @@ -28,6 +28,7 @@ | |||||||
| #include "PlaylistError.hxx" | #include "PlaylistError.hxx" | ||||||
| #include "Song.hxx" | #include "Song.hxx" | ||||||
| #include "tag/Tag.hxx" | #include "tag/Tag.hxx" | ||||||
|  | #include "tag/TagBuilder.hxx" | ||||||
| #include "util/Error.hxx" | #include "util/Error.hxx" | ||||||
|  |  | ||||||
| bool | bool | ||||||
| @@ -48,9 +49,15 @@ playlist::AddSongIdTag(unsigned id, TagType tag_type, const char *value, | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (song.tag == nullptr) | 	TagBuilder tag; | ||||||
| 		song.tag = new Tag(); | 	if (song.tag != nullptr) { | ||||||
| 	song.tag->AddItem(tag_type, value); | 		tag = std::move(*song.tag); | ||||||
|  | 		delete song.tag; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tag.AddItem(tag_type, value); | ||||||
|  | 	song.tag = tag.Commit(); | ||||||
|  |  | ||||||
| 	queue.ModifyAtPosition(position); | 	queue.ModifyAtPosition(position); | ||||||
| 	OnModified(); | 	OnModified(); | ||||||
| 	return true; | 	return true; | ||||||
| @@ -77,10 +84,15 @@ playlist::ClearSongIdTag(unsigned id, TagType tag_type, | |||||||
| 	if (song.tag == nullptr) | 	if (song.tag == nullptr) | ||||||
| 		return true; | 		return true; | ||||||
|  |  | ||||||
|  | 	TagBuilder tag(std::move(*song.tag)); | ||||||
|  | 	delete song.tag; | ||||||
|  |  | ||||||
| 	if (tag_type == TAG_NUM_OF_ITEM_TYPES) | 	if (tag_type == TAG_NUM_OF_ITEM_TYPES) | ||||||
| 		song.tag->RemoveAll(); | 		tag.RemoveAll(); | ||||||
| 	else | 	else | ||||||
| 		song.tag->RemoveType(tag_type); | 		tag.RemoveType(tag_type); | ||||||
|  | 	song.tag = tag.Commit(); | ||||||
|  |  | ||||||
| 	queue.ModifyAtPosition(position); | 	queue.ModifyAtPosition(position); | ||||||
| 	OnModified(); | 	OnModified(); | ||||||
| 	return true; | 	return true; | ||||||
|   | |||||||
| @@ -187,23 +187,3 @@ Tag::AddItem(TagType type, const char *value) | |||||||
| { | { | ||||||
| 	AddItem(type, value, strlen(value)); | 	AddItem(type, value, strlen(value)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void |  | ||||||
| Tag::RemoveType(TagType type) |  | ||||||
| { |  | ||||||
| 	auto dest = items, src = items, end = items + num_items; |  | ||||||
|  |  | ||||||
| 	tag_pool_lock.lock(); |  | ||||||
| 	while (src != end) { |  | ||||||
| 		TagItem *item = *src++; |  | ||||||
| 		if (item->type == type) |  | ||||||
| 			/* remove it */ |  | ||||||
| 			tag_pool_put_item(item); |  | ||||||
| 		else |  | ||||||
| 			/* keep it */ |  | ||||||
| 			*dest++ = item; |  | ||||||
| 	} |  | ||||||
| 	tag_pool_lock.unlock(); |  | ||||||
|  |  | ||||||
| 	num_items = dest - items; |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -121,18 +121,6 @@ struct Tag { | |||||||
| 	 */ | 	 */ | ||||||
| 	void AddItem(TagType type, const char *value); | 	void AddItem(TagType type, const char *value); | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Removes all tag items. |  | ||||||
| 	 */ |  | ||||||
| 	void RemoveAll() { |  | ||||||
| 		num_items = 0; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Removes all tag items of the specified type. |  | ||||||
| 	 */ |  | ||||||
| 	void RemoveType(TagType type); |  | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Merges the data from two tags.  If both tags share data for the | 	 * Merges the data from two tags.  If both tags share data for the | ||||||
| 	 * same TagType, only data from "add" is used. | 	 * same TagType, only data from "add" is used. | ||||||
|   | |||||||
| @@ -108,13 +108,7 @@ TagBuilder::Clear() | |||||||
| { | { | ||||||
| 	time = -1; | 	time = -1; | ||||||
| 	has_playlist = false; | 	has_playlist = false; | ||||||
|  | 	RemoveAll(); | ||||||
| 	tag_pool_lock.lock(); |  | ||||||
| 	for (auto i : items) |  | ||||||
| 		tag_pool_put_item(i); |  | ||||||
| 	tag_pool_lock.unlock(); |  | ||||||
|  |  | ||||||
| 	items.clear(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -216,3 +210,29 @@ TagBuilder::AddItem(TagType type, const char *value) | |||||||
|  |  | ||||||
| 	AddItem(type, value, strlen(value)); | 	AddItem(type, value, strlen(value)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | TagBuilder::RemoveAll() | ||||||
|  | { | ||||||
|  | 	tag_pool_lock.lock(); | ||||||
|  | 	for (auto i : items) | ||||||
|  | 		tag_pool_put_item(i); | ||||||
|  | 	tag_pool_lock.unlock(); | ||||||
|  |  | ||||||
|  | 	items.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | TagBuilder::RemoveType(TagType type) | ||||||
|  | { | ||||||
|  | 	const auto begin = items.begin(), end = items.end(); | ||||||
|  |  | ||||||
|  | 	items.erase(std::remove_if(begin, end, | ||||||
|  | 				   [type](TagItem *item) { | ||||||
|  | 					   if (item->type != type) | ||||||
|  | 						   return false; | ||||||
|  | 					   tag_pool_put_item(item); | ||||||
|  | 					   return true; | ||||||
|  | 				   }), | ||||||
|  | 		    end); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -147,6 +147,16 @@ public: | |||||||
| 	gcc_nonnull_all | 	gcc_nonnull_all | ||||||
| 	void AddItem(TagType type, const char *value); | 	void AddItem(TagType type, const char *value); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Removes all tag items. | ||||||
|  | 	 */ | ||||||
|  | 	void RemoveAll(); | ||||||
|  |  | ||||||
|  | 	/** | ||||||
|  | 	 * Removes all tag items of the specified type. | ||||||
|  | 	 */ | ||||||
|  | 	void RemoveType(TagType type); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	gcc_nonnull_all | 	gcc_nonnull_all | ||||||
| 	void AddItemInternal(TagType type, const char *value, size_t length); | 	void AddItemInternal(TagType type, const char *value, size_t length); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann