diff options
Diffstat (limited to 'src/playlist')
-rw-r--r-- | src/playlist/AsxPlaylistPlugin.cxx | 38 | ||||
-rw-r--r-- | src/playlist/CuePlaylistPlugin.cxx | 5 | ||||
-rw-r--r-- | src/playlist/EmbeddedCuePlaylistPlugin.cxx | 6 | ||||
-rw-r--r-- | src/playlist/ExtM3uPlaylistPlugin.cxx | 14 | ||||
-rw-r--r-- | src/playlist/PlsPlaylistPlugin.cxx | 23 | ||||
-rw-r--r-- | src/playlist/RssPlaylistPlugin.cxx | 38 | ||||
-rw-r--r-- | src/playlist/SoundCloudPlaylistPlugin.cxx | 15 | ||||
-rw-r--r-- | src/playlist/XspfPlaylistPlugin.cxx | 34 |
8 files changed, 81 insertions, 92 deletions
diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx index 94198b8c3..47983358a 100644 --- a/src/playlist/AsxPlaylistPlugin.cxx +++ b/src/playlist/AsxPlaylistPlugin.cxx @@ -23,7 +23,7 @@ #include "MemorySongEnumerator.hxx" #include "InputStream.hxx" #include "Song.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -31,7 +31,6 @@ #include <glib.h> -#include <assert.h> #include <string.h> static constexpr Domain asx_domain("asx"); @@ -58,7 +57,7 @@ struct AsxParser { * valid if state==ENTRY. TAG_NUM_OF_ITEM_TYPES means there * is no (known) tag. */ - TagType tag; + TagType tag_type; /** * The current song. It is allocated after the "location" @@ -66,6 +65,8 @@ struct AsxParser { */ Song *song; + TagBuilder tag_builder; + AsxParser() :state(ROOT) {} @@ -96,7 +97,7 @@ asx_start_element(gcc_unused GMarkupParseContext *context, if (StringEqualsCaseASCII(element_name, "entry")) { parser->state = AsxParser::ENTRY; parser->song = Song::NewRemote("asx:"); - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } break; @@ -107,27 +108,22 @@ asx_start_element(gcc_unused GMarkupParseContext *context, attribute_values, "href"); if (href != nullptr) { - /* create new song object, and copy - the existing tag over; we cannot + /* create new song object; we cannot replace the existing song's URI, because that attribute is immutable */ Song *song = Song::NewRemote(href); - - if (parser->song != nullptr) { - song->tag = parser->song->tag; - parser->song->tag = nullptr; + if (parser->song != nullptr) parser->song->Free(); - } parser->song = song; } } else if (StringEqualsCaseASCII(element_name, "author")) /* is that correct? or should it be COMPOSER or PERFORMER? */ - parser->tag = TAG_ARTIST; + parser->tag_type = TAG_ARTIST; else if (StringEqualsCaseASCII(element_name, "title")) - parser->tag = TAG_TITLE; + parser->tag_type = TAG_TITLE; break; } @@ -146,14 +142,16 @@ asx_end_element(gcc_unused GMarkupParseContext *context, case AsxParser::ENTRY: if (StringEqualsCaseASCII(element_name, "entry")) { - if (strcmp(parser->song->uri, "asx:") != 0) + if (strcmp(parser->song->uri, "asx:") != 0) { + assert(parser->song->tag == nullptr); + parser->song->tag = parser->tag_builder.Commit(); parser->songs.emplace_front(parser->song); - else + } else parser->song->Free(); parser->state = AsxParser::ROOT; } else - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; break; } @@ -171,11 +169,9 @@ asx_text(gcc_unused GMarkupParseContext *context, break; case AsxParser::ENTRY: - if (parser->tag != TAG_NUM_OF_ITEM_TYPES) { - if (parser->song->tag == nullptr) - parser->song->tag = new Tag(); - parser->song->tag->AddItem(parser->tag, - text, text_len); + if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) { + parser->tag_builder.AddItem(parser->tag_type, + text, text_len); } break; diff --git a/src/playlist/CuePlaylistPlugin.cxx b/src/playlist/CuePlaylistPlugin.cxx index 42a43bbad..00aa758b0 100644 --- a/src/playlist/CuePlaylistPlugin.cxx +++ b/src/playlist/CuePlaylistPlugin.cxx @@ -21,13 +21,10 @@ #include "CuePlaylistPlugin.hxx" #include "PlaylistPlugin.hxx" #include "SongEnumerator.hxx" -#include "tag/Tag.hxx" -#include "Song.hxx" #include "cue/CueParser.hxx" #include "TextInputStream.hxx" -#include <assert.h> -#include <string.h> +#include <string> class CuePlaylist final : public SongEnumerator { InputStream &is; diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx index d758650eb..96d83b968 100644 --- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx +++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx @@ -27,7 +27,6 @@ #include "EmbeddedCuePlaylistPlugin.hxx" #include "PlaylistPlugin.hxx" #include "SongEnumerator.hxx" -#include "tag/Tag.hxx" #include "tag/TagHandler.hxx" #include "tag/TagId3.hxx" #include "tag/ApeTag.hxx" @@ -38,7 +37,6 @@ #include "fs/AllocatedPath.hxx" #include "util/ASCII.hxx" -#include <assert.h> #include <string.h> class EmbeddedCuePlaylist final : public SongEnumerator { @@ -95,7 +93,7 @@ embcue_playlist_open_uri(const char *uri, gcc_unused Mutex &mutex, gcc_unused Cond &cond) { - if (!PathTraits::IsAbsoluteUTF8(uri)) + if (!PathTraitsUTF8::IsAbsolute(uri)) /* only local files supported */ return nullptr; @@ -118,7 +116,7 @@ embcue_playlist_open_uri(const char *uri, return nullptr; } - playlist->filename = PathTraits::GetBaseUTF8(uri); + playlist->filename = PathTraitsUTF8::GetBase(uri); playlist->next = &playlist->cuesheet[0]; playlist->parser = new CueParser(); diff --git a/src/playlist/ExtM3uPlaylistPlugin.cxx b/src/playlist/ExtM3uPlaylistPlugin.cxx index 8d260fec7..d48db1ed2 100644 --- a/src/playlist/ExtM3uPlaylistPlugin.cxx +++ b/src/playlist/ExtM3uPlaylistPlugin.cxx @@ -23,11 +23,10 @@ #include "SongEnumerator.hxx" #include "Song.hxx" #include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "util/StringUtil.hxx" #include "TextInputStream.hxx" -#include <glib.h> - #include <string.h> #include <stdlib.h> @@ -74,7 +73,6 @@ extm3u_parse_tag(const char *line) long duration; char *endptr; const char *name; - Tag *tag; duration = strtol(line, &endptr, 10); if (endptr[0] != ',') @@ -91,16 +89,16 @@ extm3u_parse_tag(const char *line) object */ return NULL; - tag = new Tag(); - tag->time = duration; + TagBuilder tag; + tag.SetTime(duration); /* unfortunately, there is no real specification for the EXTM3U format, so we must assume that the string after the comma is opaque, and is just the song name*/ if (*name != 0) - tag->AddItem(TAG_NAME, name); + tag.AddItem(TAG_NAME, name); - return tag; + return tag.Commit(); } Song * @@ -119,7 +117,7 @@ ExtM3uPlaylist::NextSong() line_s = line.c_str(); - if (g_str_has_prefix(line_s, "#EXTINF:")) { + if (StringStartsWith(line_s, "#EXTINF:")) { delete tag; tag = extm3u_parse_tag(line_s + 8); continue; diff --git a/src/playlist/PlsPlaylistPlugin.cxx b/src/playlist/PlsPlaylistPlugin.cxx index d44a34cdf..329bd8bfb 100644 --- a/src/playlist/PlsPlaylistPlugin.cxx +++ b/src/playlist/PlsPlaylistPlugin.cxx @@ -23,7 +23,7 @@ #include "MemorySongEnumerator.hxx" #include "InputStream.hxx" #include "Song.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -32,6 +32,8 @@ #include <string> +#include <stdio.h> + static constexpr Domain pls_domain("pls"); static void @@ -75,14 +77,14 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) song = Song::NewRemote(value); g_free(value); + TagBuilder tag; + sprintf(key, "Title%u", num_entries); value = g_key_file_get_string(keyfile, "playlist", key, &error); - if(error == nullptr && value){ - if (song->tag == nullptr) - song->tag = new Tag(); - song->tag->AddItem(TAG_TITLE, value); - } + if (error == nullptr && value != nullptr) + tag.AddItem(TAG_TITLE, value); + /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = nullptr; @@ -91,15 +93,14 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) sprintf(key, "Length%u", num_entries); length = g_key_file_get_integer(keyfile, "playlist", key, &error); - if(error == nullptr && length > 0){ - if (song->tag == nullptr) - song->tag = new Tag(); - song->tag->time = length; - } + if (error == nullptr && length > 0) + tag.SetTime(length); + /* Ignore errors? Most likely value not present */ if(error) g_error_free(error); error = nullptr; + song->tag = tag.Commit(); songs.emplace_front(song); num_entries--; } diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx index e2a44bfd3..62f636126 100644 --- a/src/playlist/RssPlaylistPlugin.cxx +++ b/src/playlist/RssPlaylistPlugin.cxx @@ -23,7 +23,7 @@ #include "MemorySongEnumerator.hxx" #include "InputStream.hxx" #include "Song.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -31,7 +31,6 @@ #include <glib.h> -#include <assert.h> #include <string.h> static constexpr Domain rss_domain("rss"); @@ -58,7 +57,7 @@ struct RssParser { * valid if state==ITEM. TAG_NUM_OF_ITEM_TYPES means there * is no (known) tag. */ - TagType tag; + TagType tag_type; /** * The current song. It is allocated after the "location" @@ -66,6 +65,8 @@ struct RssParser { */ Song *song; + TagBuilder tag_builder; + RssParser() :state(ROOT) {} }; @@ -95,7 +96,7 @@ rss_start_element(gcc_unused GMarkupParseContext *context, if (StringEqualsCaseASCII(element_name, "item")) { parser->state = RssParser::ITEM; parser->song = Song::NewRemote("rss:"); - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } break; @@ -106,25 +107,21 @@ rss_start_element(gcc_unused GMarkupParseContext *context, attribute_values, "url"); if (href != nullptr) { - /* create new song object, and copy - the existing tag over; we cannot + /* create new song object; we cannot replace the existing song's URI, because that attribute is immutable */ Song *song = Song::NewRemote(href); - if (parser->song != nullptr) { - song->tag = parser->song->tag; - parser->song->tag = nullptr; + if (parser->song != nullptr) parser->song->Free(); - } parser->song = song; } } else if (StringEqualsCaseASCII(element_name, "title")) - parser->tag = TAG_TITLE; + parser->tag_type = TAG_TITLE; else if (StringEqualsCaseASCII(element_name, "itunes:author")) - parser->tag = TAG_ARTIST; + parser->tag_type = TAG_ARTIST; break; } @@ -143,14 +140,16 @@ rss_end_element(gcc_unused GMarkupParseContext *context, case RssParser::ITEM: if (StringEqualsCaseASCII(element_name, "item")) { - if (strcmp(parser->song->uri, "rss:") != 0) + if (strcmp(parser->song->uri, "rss:") != 0) { + assert(parser->song->tag == nullptr); + parser->song->tag = parser->tag_builder.Commit(); parser->songs.emplace_front(parser->song); - else + } else parser->song->Free(); parser->state = RssParser::ROOT; } else - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; break; } @@ -168,12 +167,9 @@ rss_text(gcc_unused GMarkupParseContext *context, break; case RssParser::ITEM: - if (parser->tag != TAG_NUM_OF_ITEM_TYPES) { - if (parser->song->tag == nullptr) - parser->song->tag = new Tag(); - parser->song->tag->AddItem(parser->tag, - text, text_len); - } + if (parser->tag_type != TAG_NUM_OF_ITEM_TYPES) + parser->tag_builder.AddItem(parser->tag_type, + text, text_len); break; } diff --git a/src/playlist/SoundCloudPlaylistPlugin.cxx b/src/playlist/SoundCloudPlaylistPlugin.cxx index f6797b14d..f058b596b 100644 --- a/src/playlist/SoundCloudPlaylistPlugin.cxx +++ b/src/playlist/SoundCloudPlaylistPlugin.cxx @@ -24,7 +24,8 @@ #include "ConfigData.hxx" #include "InputStream.hxx" #include "Song.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" +#include "util/StringUtil.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -65,9 +66,9 @@ static char * soundcloud_resolve(const char* uri) { char *u, *ru; - if (g_str_has_prefix(uri, "http://")) { + if (StringStartsWith(uri, "http://")) { u = g_strdup(uri); - } else if (g_str_has_prefix(uri, "soundcloud.com")) { + } else if (StringStartsWith(uri, "soundcloud.com")) { u = g_strconcat("http://", uri, nullptr); } else { /* assume it's just a path on soundcloud.com */ @@ -214,11 +215,11 @@ static int handle_end_map(void *ctx) s = Song::NewRemote(u); g_free(u); - Tag *t = new Tag(); - t->time = data->duration / 1000; + TagBuilder tag; + tag.SetTime(data->duration / 1000); if (data->title != nullptr) - t->AddItem(TAG_NAME, data->title); - s->tag = t; + tag.AddItem(TAG_NAME, data->title); + s->tag = tag.Commit(); data->songs.emplace_front(s); diff --git a/src/playlist/XspfPlaylistPlugin.cxx b/src/playlist/XspfPlaylistPlugin.cxx index dcfab5a80..2935225e4 100644 --- a/src/playlist/XspfPlaylistPlugin.cxx +++ b/src/playlist/XspfPlaylistPlugin.cxx @@ -22,14 +22,13 @@ #include "PlaylistPlugin.hxx" #include "MemorySongEnumerator.hxx" #include "InputStream.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" #include <glib.h> -#include <assert.h> #include <string.h> static constexpr Domain xspf_domain("xspf"); @@ -57,7 +56,7 @@ struct XspfParser { * valid if state==TRACK. TAG_NUM_OF_ITEM_TYPES means there * is no (known) tag. */ - TagType tag; + TagType tag_type; /** * The current song. It is allocated after the "location" @@ -65,6 +64,8 @@ struct XspfParser { */ Song *song; + TagBuilder tag_builder; + XspfParser() :state(ROOT) {} }; @@ -95,7 +96,7 @@ xspf_start_element(gcc_unused GMarkupParseContext *context, if (strcmp(element_name, "track") == 0) { parser->state = XspfParser::TRACK; parser->song = nullptr; - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } break; @@ -104,17 +105,17 @@ xspf_start_element(gcc_unused GMarkupParseContext *context, if (strcmp(element_name, "location") == 0) parser->state = XspfParser::LOCATION; else if (strcmp(element_name, "title") == 0) - parser->tag = TAG_TITLE; + parser->tag_type = TAG_TITLE; else if (strcmp(element_name, "creator") == 0) /* TAG_COMPOSER would be more correct according to the XSPF spec */ - parser->tag = TAG_ARTIST; + parser->tag_type = TAG_ARTIST; else if (strcmp(element_name, "annotation") == 0) - parser->tag = TAG_COMMENT; + parser->tag_type = TAG_COMMENT; else if (strcmp(element_name, "album") == 0) - parser->tag = TAG_ALBUM; + parser->tag_type = TAG_ALBUM; else if (strcmp(element_name, "trackNum") == 0) - parser->tag = TAG_TRACK; + parser->tag_type = TAG_TRACK; break; @@ -148,12 +149,15 @@ xspf_end_element(gcc_unused GMarkupParseContext *context, case XspfParser::TRACK: if (strcmp(element_name, "track") == 0) { - if (parser->song != nullptr) + if (parser->song != nullptr) { + assert(parser->song->tag == nullptr); + parser->song->tag = parser->tag_builder.Commit(); parser->songs.emplace_front(parser->song); + } parser->state = XspfParser::TRACKLIST; } else - parser->tag = TAG_NUM_OF_ITEM_TYPES; + parser->tag_type = TAG_NUM_OF_ITEM_TYPES; break; @@ -178,11 +182,9 @@ xspf_text(gcc_unused GMarkupParseContext *context, case XspfParser::TRACK: if (parser->song != nullptr && - parser->tag != TAG_NUM_OF_ITEM_TYPES) { - if (parser->song->tag == nullptr) - parser->song->tag = new Tag(); - parser->song->tag->AddItem(parser->tag, text, text_len); - } + parser->tag_type != TAG_NUM_OF_ITEM_TYPES) + parser->tag_builder.AddItem(parser->tag_type, + text, text_len); break; |