diff options
Diffstat (limited to 'src/playlist')
-rw-r--r-- | src/playlist/AsxPlaylistPlugin.cxx | 42 | ||||
-rw-r--r-- | src/playlist/CuePlaylistPlugin.cxx | 6 | ||||
-rw-r--r-- | src/playlist/DespotifyPlaylistPlugin.cxx | 16 | ||||
-rw-r--r-- | src/playlist/EmbeddedCuePlaylistPlugin.cxx | 16 | ||||
-rw-r--r-- | src/playlist/ExtM3uPlaylistPlugin.cxx | 13 | ||||
-rw-r--r-- | src/playlist/M3uPlaylistPlugin.cxx | 8 | ||||
-rw-r--r-- | src/playlist/PlsPlaylistPlugin.cxx | 17 | ||||
-rw-r--r-- | src/playlist/RssPlaylistPlugin.cxx | 42 | ||||
-rw-r--r-- | src/playlist/SoundCloudPlaylistPlugin.cxx | 8 | ||||
-rw-r--r-- | src/playlist/XspfPlaylistPlugin.cxx | 37 |
10 files changed, 69 insertions, 136 deletions
diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx index ccd98a711..11bdc93d6 100644 --- a/src/playlist/AsxPlaylistPlugin.cxx +++ b/src/playlist/AsxPlaylistPlugin.cxx @@ -43,7 +43,7 @@ struct AsxParser { * The list of songs (in reverse order because that's faster * while adding). */ - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; /** * The current position in the XML file. @@ -60,10 +60,9 @@ struct AsxParser { TagType tag_type; /** - * The current song. It is allocated after the "location" - * element. + * The current song URI. It is set by the "ref" element. */ - Song *song; + std::string location; TagBuilder tag_builder; @@ -96,7 +95,7 @@ asx_start_element(gcc_unused GMarkupParseContext *context, case AsxParser::ROOT: if (StringEqualsCaseASCII(element_name, "entry")) { parser->state = AsxParser::ENTRY; - parser->song = Song::NewRemote("asx:"); + parser->location.clear(); parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } @@ -107,17 +106,8 @@ asx_start_element(gcc_unused GMarkupParseContext *context, const gchar *href = get_attribute(attribute_names, attribute_values, "href"); - if (href != nullptr) { - /* 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) - parser->song->Free(); - - parser->song = song; - } + if (href != nullptr) + parser->location = href; } else if (StringEqualsCaseASCII(element_name, "author")) /* is that correct? or should it be COMPOSER or PERFORMER? */ @@ -142,12 +132,9 @@ asx_end_element(gcc_unused GMarkupParseContext *context, case AsxParser::ENTRY: if (StringEqualsCaseASCII(element_name, "entry")) { - if (strcmp(parser->song->uri, "asx:") != 0) { - assert(parser->song->tag == nullptr); - parser->song->tag = parser->tag_builder.CommitNew(); - parser->songs.emplace_front(parser->song); - } else - parser->song->Free(); + if (!parser->location.empty()) + parser->songs.emplace_front(std::move(parser->location), + parser->tag_builder.Commit()); parser->state = AsxParser::ROOT; } else @@ -186,15 +173,6 @@ static const GMarkupParser asx_parser = { nullptr, }; -static void -asx_parser_destroy(gpointer data) -{ - AsxParser *parser = (AsxParser *)data; - - if (parser->state >= AsxParser::ENTRY) - parser->song->Free(); -} - /* * The playlist object * @@ -215,7 +193,7 @@ asx_open_stream(InputStream &is) context = g_markup_parse_context_new(&asx_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, - &parser, asx_parser_destroy); + &parser, nullptr); while (true) { nbytes = is.LockRead(buffer, sizeof(buffer), error2); diff --git a/src/playlist/CuePlaylistPlugin.cxx b/src/playlist/CuePlaylistPlugin.cxx index 00aa758b0..1da76d372 100644 --- a/src/playlist/CuePlaylistPlugin.cxx +++ b/src/playlist/CuePlaylistPlugin.cxx @@ -36,7 +36,7 @@ class CuePlaylist final : public SongEnumerator { :is(_is), tis(is) { } - virtual Song *NextSong() override; + virtual DetachedSong *NextSong() override; }; static SongEnumerator * @@ -45,10 +45,10 @@ cue_playlist_open_stream(InputStream &is) return new CuePlaylist(is); } -Song * +DetachedSong * CuePlaylist::NextSong() { - Song *song = parser.Get(); + DetachedSong *song = parser.Get(); if (song != nullptr) return song; diff --git a/src/playlist/DespotifyPlaylistPlugin.cxx b/src/playlist/DespotifyPlaylistPlugin.cxx index 67400e20a..d73c7fe72 100644 --- a/src/playlist/DespotifyPlaylistPlugin.cxx +++ b/src/playlist/DespotifyPlaylistPlugin.cxx @@ -23,7 +23,7 @@ #include "PlaylistPlugin.hxx" #include "MemorySongEnumerator.hxx" #include "tag/Tag.hxx" -#include "Song.hxx" +#include "DetachedSong.hxx" #include "Log.hxx" extern "C" { @@ -34,10 +34,9 @@ extern "C" { #include <stdlib.h> static void -add_song(std::forward_list<SongPointer> &songs, ds_track &track) +add_song(std::forward_list<DetachedSong> &songs, ds_track &track) { const char *dsp_scheme = despotify_playlist_plugin.schemes[0]; - Song *song; char uri[128]; char *ds_uri; @@ -52,15 +51,12 @@ add_song(std::forward_list<SongPointer> &songs, ds_track &track) return; } - song = Song::NewRemote(uri); - song->tag = new Tag(mpd_despotify_tag_from_track(track)); - - songs.emplace_front(song); + songs.emplace_front(uri, mpd_despotify_tag_from_track(track)); } static bool parse_track(struct despotify_session *session, - std::forward_list<SongPointer> &songs, + std::forward_list<DetachedSong> &songs, struct ds_link *link) { struct ds_track *track = despotify_link_get_track(session, link); @@ -73,7 +69,7 @@ parse_track(struct despotify_session *session, static bool parse_playlist(struct despotify_session *session, - std::forward_list<SongPointer> &songs, + std::forward_list<DetachedSong> &songs, struct ds_link *link) { ds_playlist *playlist = despotify_link_get_playlist(session, link); @@ -103,7 +99,7 @@ despotify_playlist_open_uri(const char *url, return nullptr; } - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; bool parse_result; switch (link->type) { diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx index 9dfecbf46..77df51778 100644 --- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx +++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx @@ -30,7 +30,7 @@ #include "tag/TagHandler.hxx" #include "tag/TagId3.hxx" #include "tag/ApeTag.hxx" -#include "Song.hxx" +#include "DetachedSong.hxx" #include "TagFile.hxx" #include "cue/CueParser.hxx" #include "fs/Traits.hxx" @@ -69,7 +69,7 @@ public: delete parser; } - virtual Song *NextSong() override; + virtual DetachedSong *NextSong() override; }; static void @@ -124,10 +124,10 @@ embcue_playlist_open_uri(const char *uri, return playlist; } -Song * +DetachedSong * EmbeddedCuePlaylist::NextSong() { - Song *song = parser->Get(); + DetachedSong *song = parser->Get(); if (song != nullptr) return song; @@ -145,14 +145,16 @@ EmbeddedCuePlaylist::NextSong() parser->Feed(line); song = parser->Get(); - if (song != nullptr) - return song->ReplaceURI(filename.c_str()); + if (song != nullptr) { + song->SetURI(filename); + return song; + } } parser->Finish(); song = parser->Get(); if (song != nullptr) - song = song->ReplaceURI(filename.c_str()); + song->SetURI(filename); return song; } diff --git a/src/playlist/ExtM3uPlaylistPlugin.cxx b/src/playlist/ExtM3uPlaylistPlugin.cxx index 4f0c111ad..51211988c 100644 --- a/src/playlist/ExtM3uPlaylistPlugin.cxx +++ b/src/playlist/ExtM3uPlaylistPlugin.cxx @@ -21,7 +21,7 @@ #include "ExtM3uPlaylistPlugin.hxx" #include "PlaylistPlugin.hxx" #include "SongEnumerator.hxx" -#include "Song.hxx" +#include "DetachedSong.hxx" #include "tag/Tag.hxx" #include "tag/TagBuilder.hxx" #include "util/StringUtil.hxx" @@ -44,7 +44,7 @@ public: strcmp(line.c_str(), "#EXTM3U") == 0; } - virtual Song *NextSong() override; + virtual DetachedSong *NextSong() override; }; static SongEnumerator * @@ -101,20 +101,19 @@ extm3u_parse_tag(const char *line) return tag.CommitNew(); } -Song * +DetachedSong * ExtM3uPlaylist::NextSong() { Tag *tag = NULL; std::string line; const char *line_s; - Song *song; do { if (!tis.ReadLine(line)) { delete tag; return NULL; } - + line_s = line.c_str(); if (StringStartsWith(line_s, "#EXTINF:")) { @@ -126,8 +125,8 @@ ExtM3uPlaylist::NextSong() line_s = strchug_fast(line_s); } while (line_s[0] == '#' || *line_s == 0); - song = Song::NewRemote(line_s); - song->tag = tag; + DetachedSong *song = new DetachedSong(line_s, std::move(*tag)); + delete tag; return song; } diff --git a/src/playlist/M3uPlaylistPlugin.cxx b/src/playlist/M3uPlaylistPlugin.cxx index 3f99bdfdf..09f2c91cb 100644 --- a/src/playlist/M3uPlaylistPlugin.cxx +++ b/src/playlist/M3uPlaylistPlugin.cxx @@ -21,7 +21,7 @@ #include "M3uPlaylistPlugin.hxx" #include "PlaylistPlugin.hxx" #include "SongEnumerator.hxx" -#include "Song.hxx" +#include "DetachedSong.hxx" #include "util/StringUtil.hxx" #include "TextInputStream.hxx" @@ -33,7 +33,7 @@ public: :tis(is) { } - virtual Song *NextSong() override; + virtual DetachedSong *NextSong() override; }; static SongEnumerator * @@ -42,7 +42,7 @@ m3u_open_stream(InputStream &is) return new M3uPlaylist(is); } -Song * +DetachedSong * M3uPlaylist::NextSong() { std::string line; @@ -56,7 +56,7 @@ M3uPlaylist::NextSong() line_s = strchug_fast(line_s); } while (line_s[0] == '#' || *line_s == 0); - return Song::NewRemote(line_s); + return new DetachedSong(line_s); } static const char *const m3u_suffixes[] = { diff --git a/src/playlist/PlsPlaylistPlugin.cxx b/src/playlist/PlsPlaylistPlugin.cxx index 3fd420d89..103451dfe 100644 --- a/src/playlist/PlsPlaylistPlugin.cxx +++ b/src/playlist/PlsPlaylistPlugin.cxx @@ -22,7 +22,7 @@ #include "PlaylistPlugin.hxx" #include "MemorySongEnumerator.hxx" #include "InputStream.hxx" -#include "Song.hxx" +#include "DetachedSong.hxx" #include "tag/TagBuilder.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -37,7 +37,7 @@ static constexpr Domain pls_domain("pls"); static void -pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) +pls_parser(GKeyFile *keyfile, std::forward_list<DetachedSong> &songs) { gchar *value; GError *error = nullptr; @@ -61,8 +61,8 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) for (; num_entries > 0; --num_entries) { char key[64]; sprintf(key, "File%u", num_entries); - value = g_key_file_get_string(keyfile, "playlist", key, - &error); + char *uri = g_key_file_get_string(keyfile, "playlist", key, + &error); if(error) { FormatError(pls_domain, "Invalid PLS entry %s: '%s'", key, error->message); @@ -70,9 +70,6 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) return; } - Song *song = Song::NewRemote(value); - g_free(value); - TagBuilder tag; sprintf(key, "Title%u", num_entries); @@ -89,8 +86,8 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs) if (length > 0) tag.SetTime(length); - song->tag = tag.CommitNew(); - songs.emplace_front(song); + songs.emplace_front(uri, tag.Commit()); + g_free(uri); } } @@ -135,7 +132,7 @@ pls_open_stream(InputStream &is) return nullptr; } - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; pls_parser(keyfile, songs); g_key_file_free(keyfile); diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx index c4dd2f8c3..558c74619 100644 --- a/src/playlist/RssPlaylistPlugin.cxx +++ b/src/playlist/RssPlaylistPlugin.cxx @@ -43,7 +43,7 @@ struct RssParser { * The list of songs (in reverse order because that's faster * while adding). */ - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; /** * The current position in the XML file. @@ -60,10 +60,10 @@ struct RssParser { TagType tag_type; /** - * The current song. It is allocated after the "location" + * The current song URI. It is set by the "enclosure" * element. */ - Song *song; + std::string location; TagBuilder tag_builder; @@ -95,7 +95,7 @@ rss_start_element(gcc_unused GMarkupParseContext *context, case RssParser::ROOT: if (StringEqualsCaseASCII(element_name, "item")) { parser->state = RssParser::ITEM; - parser->song = Song::NewRemote("rss:"); + parser->location.clear(); parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } @@ -106,18 +106,8 @@ rss_start_element(gcc_unused GMarkupParseContext *context, const gchar *href = get_attribute(attribute_names, attribute_values, "url"); - if (href != nullptr) { - /* 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) - parser->song->Free(); - - parser->song = song; - } + if (href != nullptr) + parser->location = href; } else if (StringEqualsCaseASCII(element_name, "title")) parser->tag_type = TAG_TITLE; else if (StringEqualsCaseASCII(element_name, "itunes:author")) @@ -140,12 +130,9 @@ rss_end_element(gcc_unused GMarkupParseContext *context, case RssParser::ITEM: if (StringEqualsCaseASCII(element_name, "item")) { - if (strcmp(parser->song->uri, "rss:") != 0) { - assert(parser->song->tag == nullptr); - parser->song->tag = parser->tag_builder.CommitNew(); - parser->songs.emplace_front(parser->song); - } else - parser->song->Free(); + if (!parser->location.empty()) + parser->songs.emplace_front(std::move(parser->location), + parser->tag_builder.Commit()); parser->state = RssParser::ROOT; } else @@ -183,15 +170,6 @@ static const GMarkupParser rss_parser = { nullptr, }; -static void -rss_parser_destroy(gpointer data) -{ - RssParser *parser = (RssParser *)data; - - if (parser->state >= RssParser::ITEM) - parser->song->Free(); -} - /* * The playlist object * @@ -212,7 +190,7 @@ rss_open_stream(InputStream &is) context = g_markup_parse_context_new(&rss_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, - &parser, rss_parser_destroy); + &parser, nullptr); while (true) { nbytes = is.LockRead(buffer, sizeof(buffer), error2); diff --git a/src/playlist/SoundCloudPlaylistPlugin.cxx b/src/playlist/SoundCloudPlaylistPlugin.cxx index cfbd0e8b5..50a9cb214 100644 --- a/src/playlist/SoundCloudPlaylistPlugin.cxx +++ b/src/playlist/SoundCloudPlaylistPlugin.cxx @@ -108,7 +108,7 @@ struct parse_data { char* title; int got_url; /* nesting level of last stream_url */ - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; }; static int @@ -214,16 +214,14 @@ handle_end_map(void *ctx) char *u = g_strconcat(data->stream_url, "?client_id=", soundcloud_config.apikey.c_str(), nullptr); - Song *s = Song::NewRemote(u); - g_free(u); TagBuilder tag; tag.SetTime(data->duration / 1000); if (data->title != nullptr) tag.AddItem(TAG_NAME, data->title); - s->tag = tag.CommitNew(); - data->songs.emplace_front(s); + data->songs.emplace_front(u, tag.Commit()); + g_free(u); return 1; } diff --git a/src/playlist/XspfPlaylistPlugin.cxx b/src/playlist/XspfPlaylistPlugin.cxx index 08fe49191..7c20df57d 100644 --- a/src/playlist/XspfPlaylistPlugin.cxx +++ b/src/playlist/XspfPlaylistPlugin.cxx @@ -21,6 +21,7 @@ #include "XspfPlaylistPlugin.hxx" #include "PlaylistPlugin.hxx" #include "MemorySongEnumerator.hxx" +#include "DetachedSong.hxx" #include "InputStream.hxx" #include "tag/TagBuilder.hxx" #include "util/Error.hxx" @@ -41,7 +42,7 @@ struct XspfParser { * The list of songs (in reverse order because that's faster * while adding). */ - std::forward_list<SongPointer> songs; + std::forward_list<DetachedSong> songs; /** * The current position in the XML file. @@ -59,10 +60,9 @@ struct XspfParser { TagType tag_type; /** - * The current song. It is allocated after the "location" - * element. + * The current song URI. It is set by the "location" element. */ - Song *song; + std::string location; TagBuilder tag_builder; @@ -95,7 +95,7 @@ xspf_start_element(gcc_unused GMarkupParseContext *context, case XspfParser::TRACKLIST: if (strcmp(element_name, "track") == 0) { parser->state = XspfParser::TRACK; - parser->song = nullptr; + parser->location.clear(); parser->tag_type = TAG_NUM_OF_ITEM_TYPES; } @@ -149,11 +149,9 @@ xspf_end_element(gcc_unused GMarkupParseContext *context, case XspfParser::TRACK: if (strcmp(element_name, "track") == 0) { - if (parser->song != nullptr) { - assert(parser->song->tag == nullptr); - parser->song->tag = parser->tag_builder.CommitNew(); - parser->songs.emplace_front(parser->song); - } + if (!parser->location.empty()) + parser->songs.emplace_front(std::move(parser->location), + parser->tag_builder.Commit()); parser->state = XspfParser::TRACKLIST; } else @@ -181,7 +179,7 @@ xspf_text(gcc_unused GMarkupParseContext *context, break; case XspfParser::TRACK: - if (parser->song != nullptr && + if (!parser->location.empty() && parser->tag_type != TAG_NUM_OF_ITEM_TYPES) parser->tag_builder.AddItem(parser->tag_type, text, text_len); @@ -189,11 +187,7 @@ xspf_text(gcc_unused GMarkupParseContext *context, break; case XspfParser::LOCATION: - if (parser->song == nullptr) { - char *uri = g_strndup(text, text_len); - parser->song = Song::NewRemote(uri); - g_free(uri); - } + parser->location.assign(text, text_len); break; } @@ -207,15 +201,6 @@ static const GMarkupParser xspf_parser = { nullptr, }; -static void -xspf_parser_destroy(gpointer data) -{ - XspfParser *parser = (XspfParser *)data; - - if (parser->state >= XspfParser::TRACK && parser->song != nullptr) - parser->song->Free(); -} - /* * The playlist object * @@ -236,7 +221,7 @@ xspf_open_stream(InputStream &is) context = g_markup_parse_context_new(&xspf_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, - &parser, xspf_parser_destroy); + &parser, nullptr); while (true) { nbytes = is.LockRead(buffer, sizeof(buffer), error2); |