aboutsummaryrefslogtreecommitdiffstats
path: root/src/playlist
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/playlist/AsxPlaylistPlugin.cxx38
-rw-r--r--src/playlist/CuePlaylistPlugin.cxx5
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.cxx6
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.cxx14
-rw-r--r--src/playlist/PlsPlaylistPlugin.cxx23
-rw-r--r--src/playlist/RssPlaylistPlugin.cxx38
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.cxx15
-rw-r--r--src/playlist/XspfPlaylistPlugin.cxx34
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;