diff options
author | Max Kellermann <max@duempel.org> | 2014-01-07 21:39:47 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-01-09 09:05:58 +0100 |
commit | 322b0616322760dc162447563d8f4da7e024ca90 (patch) | |
tree | 2f87cb3ce061556161797aba9f57ee08de5b9e21 /src/playlist | |
parent | 43847f2244a34064af24704aac4cfad4a3c76f7d (diff) |
DetachedSong: fork of struct Song
From now on, struct Song will be used by the database only, and
DetachedSong will be used by everybody else. DetachedSong is easier
to use, but Song has lower overhead.
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); |