aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/DatabaseHelpers.cxx6
-rw-r--r--src/DatabasePlaylist.cxx2
-rw-r--r--src/DatabasePlugin.hxx7
-rw-r--r--src/DatabasePrint.cxx16
-rw-r--r--src/DatabaseQueue.cxx2
-rw-r--r--src/DatabaseSave.cxx2
-rw-r--r--src/DatabaseSelection.cxx2
-rw-r--r--src/DatabaseSelection.hxx4
-rw-r--r--src/DatabaseVisitor.hxx4
-rw-r--r--src/DecoderAPI.cxx2
-rw-r--r--src/DecoderControl.cxx10
-rw-r--r--src/DecoderControl.hxx10
-rw-r--r--src/DecoderThread.cxx14
-rw-r--r--src/Directory.cxx20
-rw-r--r--src/Directory.hxx14
-rw-r--r--src/DirectorySave.cxx6
-rw-r--r--src/Instance.cxx2
-rw-r--r--src/Instance.hxx4
-rw-r--r--src/Mapper.cxx10
-rw-r--r--src/Mapper.hxx4
-rw-r--r--src/OtherCommands.cxx6
-rw-r--r--src/Partition.hxx2
-rw-r--r--src/PlayerControl.cxx16
-rw-r--r--src/PlayerControl.hxx9
-rw-r--r--src/PlayerThread.cxx42
-rw-r--r--src/Playlist.cxx21
-rw-r--r--src/Playlist.hxx11
-rw-r--r--src/PlaylistControl.cxx6
-rw-r--r--src/PlaylistEdit.cxx32
-rw-r--r--src/PlaylistFile.cxx10
-rw-r--r--src/PlaylistFile.hxx4
-rw-r--r--src/PlaylistPlugin.hxx5
-rw-r--r--src/PlaylistPrint.cxx11
-rw-r--r--src/PlaylistQueue.cxx11
-rw-r--r--src/PlaylistSave.cxx8
-rw-r--r--src/PlaylistSave.hxx4
-rw-r--r--src/PlaylistSong.cxx51
-rw-r--r--src/PlaylistSong.hxx6
-rw-r--r--src/Queue.cxx18
-rw-r--r--src/Queue.hxx13
-rw-r--r--src/QueuePrint.cxx4
-rw-r--r--src/QueueSave.cxx16
-rw-r--r--src/Song.cxx97
-rw-r--r--src/Song.hxx147
-rw-r--r--src/SongFilter.cxx8
-rw-r--r--src/SongFilter.hxx6
-rw-r--r--src/SongPointer.hxx12
-rw-r--r--src/SongPrint.cxx8
-rw-r--r--src/SongPrint.hxx6
-rw-r--r--src/SongSave.cxx16
-rw-r--r--src/SongSave.hxx6
-rw-r--r--src/SongSort.cxx6
-rw-r--r--src/SongSticker.cxx62
-rw-r--r--src/SongSticker.hxx14
-rw-r--r--src/SongUpdate.cxx71
-rw-r--r--src/StickerCommands.cxx10
-rw-r--r--src/Tag.cxx2
-rw-r--r--src/TagPrint.cxx2
-rw-r--r--src/TagSave.cxx2
-rw-r--r--src/UpdateArchive.cxx6
-rw-r--r--src/UpdateContainer.cxx4
-rw-r--r--src/UpdateDatabase.cxx10
-rw-r--r--src/UpdateDatabase.hxx4
-rw-r--r--src/UpdateRemove.cxx8
-rw-r--r--src/UpdateRemove.hxx4
-rw-r--r--src/UpdateSong.cxx8
-rw-r--r--src/UpdateWalk.cxx8
-rw-r--r--src/cue/CueParser.cxx14
-rw-r--r--src/cue/CueParser.hxx10
-rw-r--r--src/db/ProxyDatabasePlugin.cxx30
-rw-r--r--src/db/SimpleDatabasePlugin.cxx8
-rw-r--r--src/db/SimpleDatabasePlugin.hxx4
-rw-r--r--src/playlist/AsxPlaylistPlugin.cxx14
-rw-r--r--src/playlist/CuePlaylistPlugin.cxx6
-rw-r--r--src/playlist/DespotifyPlaylistPlugin.cxx6
-rw-r--r--src/playlist/EmbeddedCuePlaylistPlugin.cxx10
-rw-r--r--src/playlist/ExtM3uPlaylistPlugin.cxx8
-rw-r--r--src/playlist/LastFMPlaylistPlugin.cxx4
-rw-r--r--src/playlist/M3uPlaylistPlugin.cxx6
-rw-r--r--src/playlist/MemoryPlaylistProvider.cxx6
-rw-r--r--src/playlist/MemoryPlaylistProvider.hxx4
-rw-r--r--src/playlist/PlsPlaylistPlugin.cxx6
-rw-r--r--src/playlist/RssPlaylistPlugin.cxx14
-rw-r--r--src/playlist/SoundCloudPlaylistPlugin.cxx6
-rw-r--r--src/playlist/XspfPlaylistPlugin.cxx6
-rw-r--r--src/song.h167
-rw-r--r--test/DumpDatabase.cxx4
-rw-r--r--test/FakeSong.cxx6
-rw-r--r--test/dump_playlist.cxx6
-rw-r--r--test/test_queue_priority.cxx12
91 files changed, 643 insertions, 691 deletions
diff --git a/Makefile.am b/Makefile.am
index 442e64609..5df5a1113 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -81,7 +81,6 @@ mpd_headers = \
src/replay_gain_info.h \
src/replay_gain_ape.h \
src/TimePrint.cxx src/TimePrint.hxx \
- src/song.h \
src/stats.h \
src/tag.h \
src/tag_internal.h \
@@ -217,7 +216,7 @@ src_mpd_SOURCES = \
src/ReplayGainConfig.cxx \
src/ReplayGainInfo.cxx \
src/SignalHandlers.cxx src/SignalHandlers.hxx \
- src/Song.cxx \
+ src/Song.cxx src/Song.hxx \
src/SongUpdate.cxx \
src/SongPrint.cxx src/SongPrint.hxx \
src/SongSave.cxx src/SongSave.hxx \
diff --git a/src/DatabaseHelpers.cxx b/src/DatabaseHelpers.cxx
index dc31a4bc2..d6eeb10a1 100644
--- a/src/DatabaseHelpers.cxx
+++ b/src/DatabaseHelpers.cxx
@@ -19,7 +19,7 @@
#include "DatabaseHelpers.hxx"
#include "DatabasePlugin.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <functional>
@@ -37,7 +37,7 @@ struct StringLess {
typedef std::set<const char *, StringLess> StringSet;
static bool
-CollectTags(StringSet &set, enum tag_type tag_type, song &song)
+CollectTags(StringSet &set, enum tag_type tag_type, Song &song)
{
struct tag *tag = song.tag;
if (tag == nullptr)
@@ -104,7 +104,7 @@ StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums,
static bool
StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums,
- song &song)
+ Song &song)
{
++stats.song_count;
diff --git a/src/DatabasePlaylist.cxx b/src/DatabasePlaylist.cxx
index fb477e83b..04d1a490d 100644
--- a/src/DatabasePlaylist.cxx
+++ b/src/DatabasePlaylist.cxx
@@ -28,7 +28,7 @@
static bool
AddSong(const char *playlist_path_utf8,
- song &song, GError **error_r)
+ Song &song, GError **error_r)
{
return spl_append_song(playlist_path_utf8, &song, error_r);
}
diff --git a/src/DatabasePlugin.hxx b/src/DatabasePlugin.hxx
index a175b3cd9..f5406328c 100644
--- a/src/DatabasePlugin.hxx
+++ b/src/DatabasePlugin.hxx
@@ -36,6 +36,7 @@ extern "C" {
struct config_param;
struct DatabaseSelection;
struct db_visitor;
+struct Song;
struct DatabaseStats {
/**
@@ -91,14 +92,14 @@ public:
* @param uri_utf8 the URI of the song within the music
* directory (UTF-8)
*/
- virtual struct song *GetSong(const char *uri_utf8,
- GError **error_r) const = 0;
+ virtual Song *GetSong(const char *uri_utf8,
+ GError **error_r) const = 0;
/**
* Mark the song object as "unused". Call this on objects
* returned by GetSong().
*/
- virtual void ReturnSong(struct song *song) const = 0;
+ virtual void ReturnSong(Song *song) const = 0;
/**
* Visit the selected entities.
diff --git a/src/DatabasePrint.cxx b/src/DatabasePrint.cxx
index 2384d5c14..da427c59f 100644
--- a/src/DatabasePrint.cxx
+++ b/src/DatabasePrint.cxx
@@ -27,11 +27,7 @@
#include "Directory.hxx"
#include "Client.hxx"
#include "tag.h"
-
-extern "C" {
-#include "song.h"
-}
-
+#include "Song.hxx"
#include "DatabaseGlue.hxx"
#include "DatabasePlugin.hxx"
@@ -59,7 +55,7 @@ print_playlist_in_directory(Client *client,
}
static bool
-PrintSongBrief(Client *client, song &song)
+PrintSongBrief(Client *client, Song &song)
{
assert(song.parent != NULL);
@@ -73,7 +69,7 @@ PrintSongBrief(Client *client, song &song)
}
static bool
-PrintSongFull(Client *client, song &song)
+PrintSongFull(Client *client, Song &song)
{
assert(song.parent != NULL);
@@ -142,10 +138,10 @@ static void printSearchStats(Client *client, SearchStats *stats)
}
static bool
-stats_visitor_song(SearchStats &stats, song &song)
+stats_visitor_song(SearchStats &stats, Song &song)
{
stats.numberOfSongs++;
- stats.playTime += song_get_duration(&song);
+ stats.playTime += song.GetDuration();
return true;
}
@@ -191,7 +187,7 @@ printInfoForAllIn(Client *client, const char *uri_utf8,
}
static bool
-PrintSongURIVisitor(Client *client, song &song)
+PrintSongURIVisitor(Client *client, Song &song)
{
song_print_uri(client, &song);
diff --git a/src/DatabaseQueue.cxx b/src/DatabaseQueue.cxx
index e22144c07..67031b730 100644
--- a/src/DatabaseQueue.cxx
+++ b/src/DatabaseQueue.cxx
@@ -27,7 +27,7 @@
#include <functional>
static bool
-AddToQueue(Partition &partition, song &song, GError **error_r)
+AddToQueue(Partition &partition, Song &song, GError **error_r)
{
enum playlist_result result =
partition.playlist.AppendSong(partition.pc, &song, NULL);
diff --git a/src/DatabaseSave.cxx b/src/DatabaseSave.cxx
index dc87c8ddb..fdc2174c0 100644
--- a/src/DatabaseSave.cxx
+++ b/src/DatabaseSave.cxx
@@ -22,7 +22,7 @@
#include "DatabaseLock.hxx"
#include "Directory.hxx"
#include "DirectorySave.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "TextFile.hxx"
#include "TagInternal.hxx"
#include "tag.h"
diff --git a/src/DatabaseSelection.cxx b/src/DatabaseSelection.cxx
index bd756f5f9..a372d5862 100644
--- a/src/DatabaseSelection.cxx
+++ b/src/DatabaseSelection.cxx
@@ -21,7 +21,7 @@
#include "SongFilter.hxx"
bool
-DatabaseSelection::Match(const song &song) const
+DatabaseSelection::Match(const Song &song) const
{
return filter == nullptr || filter->Match(song);
}
diff --git a/src/DatabaseSelection.hxx b/src/DatabaseSelection.hxx
index 3a81c01ec..8ca04a3fc 100644
--- a/src/DatabaseSelection.hxx
+++ b/src/DatabaseSelection.hxx
@@ -26,7 +26,7 @@
#include <stddef.h>
class SongFilter;
-struct song;
+struct Song;
struct DatabaseSelection {
/**
@@ -50,7 +50,7 @@ struct DatabaseSelection {
}
gcc_pure
- bool Match(const song &song) const;
+ bool Match(const Song &song) const;
};
#endif
diff --git a/src/DatabaseVisitor.hxx b/src/DatabaseVisitor.hxx
index c90441415..e36933d7a 100644
--- a/src/DatabaseVisitor.hxx
+++ b/src/DatabaseVisitor.hxx
@@ -25,11 +25,11 @@
#include <functional>
struct Directory;
-struct song;
+struct Song;
struct PlaylistInfo;
typedef std::function<bool(const Directory &, GError **)> VisitDirectory;
-typedef std::function<bool(struct song &, GError **)> VisitSong;
+typedef std::function<bool(struct Song &, GError **)> VisitSong;
typedef std::function<bool(const PlaylistInfo &, const Directory &,
GError **)> VisitPlaylist;
diff --git a/src/DecoderAPI.cxx b/src/DecoderAPI.cxx
index bfadcfd8a..015b11c72 100644
--- a/src/DecoderAPI.cxx
+++ b/src/DecoderAPI.cxx
@@ -26,7 +26,7 @@
#include "MusicPipe.hxx"
#include "DecoderControl.hxx"
#include "DecoderInternal.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "InputStream.hxx"
#include <glib.h>
diff --git a/src/DecoderControl.cxx b/src/DecoderControl.cxx
index c2331105d..a8f41f564 100644
--- a/src/DecoderControl.cxx
+++ b/src/DecoderControl.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "DecoderControl.hxx"
#include "MusicPipe.hxx"
-#include "song.h"
+#include "Song.hxx"
#include <assert.h>
@@ -41,7 +41,7 @@ decoder_control::~decoder_control()
ClearError();
if (song != NULL)
- song_free(song);
+ song->Free();
g_free(mixramp_start);
g_free(mixramp_end);
@@ -84,7 +84,7 @@ dc_command_async(struct decoder_control *dc, enum decoder_command cmd)
}
bool
-decoder_control::IsCurrentSong(const struct song *_song) const
+decoder_control::IsCurrentSong(const Song *_song) const
{
assert(_song != NULL);
@@ -103,7 +103,7 @@ decoder_control::IsCurrentSong(const struct song *_song) const
}
void
-decoder_control::Start(struct song *_song,
+decoder_control::Start(Song *_song,
unsigned _start_ms, unsigned _end_ms,
music_buffer *_buffer, music_pipe *_pipe)
{
@@ -113,7 +113,7 @@ decoder_control::Start(struct song *_song,
assert(music_pipe_empty(_pipe));
if (song != nullptr)
- song_free(song);
+ song->Free();
song = _song;
start_ms = _start_ms;
diff --git a/src/DecoderControl.hxx b/src/DecoderControl.hxx
index 09bf1b834..69de4800c 100644
--- a/src/DecoderControl.hxx
+++ b/src/DecoderControl.hxx
@@ -29,6 +29,8 @@
#include <assert.h>
+struct Song;
+
enum decoder_state {
DECODE_STATE_STOP = 0,
DECODE_STATE_START,
@@ -96,7 +98,7 @@ struct decoder_control {
* This is a duplicate, and must be freed when this attribute
* is cleared.
*/
- struct song *song;
+ Song *song;
/**
* The initial seek position (in milliseconds), e.g. to the
@@ -260,10 +262,10 @@ struct decoder_control {
* Caller must lock the object.
*/
gcc_pure
- bool IsCurrentSong(const struct song *_song) const;
+ bool IsCurrentSong(const Song *_song) const;
gcc_pure
- bool LockIsCurrentSong(const struct song *_song) const {
+ bool LockIsCurrentSong(const Song *_song) const {
Lock();
const bool result = IsCurrentSong(_song);
Unlock();
@@ -280,7 +282,7 @@ struct decoder_control {
* @param pipe the pipe which receives the decoded chunks (owned by
* the caller)
*/
- void Start(struct song *song, unsigned start_ms, unsigned end_ms,
+ void Start(Song *song, unsigned start_ms, unsigned end_ms,
music_buffer *buffer, music_pipe *pipe);
void Stop();
diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx
index 269dbdc1a..f69a5fb3c 100644
--- a/src/DecoderThread.cxx
+++ b/src/DecoderThread.cxx
@@ -23,7 +23,7 @@
#include "DecoderInternal.hxx"
#include "DecoderError.hxx"
#include "DecoderPlugin.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "mpd_error.h"
#include "Mapper.hxx"
#include "fs/Path.hxx"
@@ -380,10 +380,10 @@ decoder_run_file(struct decoder *decoder, const char *path_fs)
static void
decoder_run_song(struct decoder_control *dc,
- const struct song *song, const char *uri)
+ const Song *song, const char *uri)
{
decoder decoder(dc, dc->start_ms > 0,
- song->tag != NULL && song_is_file(song)
+ song->tag != NULL && song->IsFile()
? tag_dup(song->tag) : nullptr);
int ret;
@@ -391,7 +391,7 @@ decoder_run_song(struct decoder_control *dc,
decoder_command_finished_locked(dc);
- ret = song_is_file(song)
+ ret = song->IsFile()
? decoder_run_file(&decoder, uri)
: decoder_run_stream(&decoder, uri);
@@ -427,15 +427,15 @@ decoder_run(struct decoder_control *dc)
{
dc->ClearError();
- const struct song *song = dc->song;
+ const Song *song = dc->song;
char *uri;
assert(song != NULL);
- if (song_is_file(song))
+ if (song->IsFile())
uri = map_song_fs(song).Steal();
else
- uri = song_get_uri(song);
+ uri = song->GetURI();
if (uri == NULL) {
dc->state = DECODE_STATE_ERROR;
diff --git a/src/Directory.cxx b/src/Directory.cxx
index c96ac927d..1c1db386f 100644
--- a/src/Directory.cxx
+++ b/src/Directory.cxx
@@ -23,9 +23,9 @@
#include "PlaylistVector.hxx"
#include "DatabaseLock.hxx"
#include "SongSort.hxx"
+#include "Song.hxx"
extern "C" {
-#include "song.h"
#include "util/list_sort.h"
}
@@ -68,9 +68,9 @@ Directory::Directory(const char *_path)
Directory::~Directory()
{
- struct song *song, *ns;
+ Song *song, *ns;
directory_for_each_song_safe(song, ns, this)
- song_free(song);
+ song->Free();
Directory *child, *n;
directory_for_each_child_safe(child, n, this)
@@ -208,7 +208,7 @@ Directory::LookupDirectory(const char *uri)
}
void
-Directory::AddSong(struct song *song)
+Directory::AddSong(Song *song)
{
assert(holding_db_lock());
assert(song != NULL);
@@ -218,7 +218,7 @@ Directory::AddSong(struct song *song)
}
void
-Directory::RemoveSong(struct song *song)
+Directory::RemoveSong(Song *song)
{
assert(holding_db_lock());
assert(song != NULL);
@@ -227,13 +227,13 @@ Directory::RemoveSong(struct song *song)
list_del(&song->siblings);
}
-const song *
+const Song *
Directory::FindSong(const char *name_utf8) const
{
assert(holding_db_lock());
assert(name_utf8 != NULL);
- struct song *song;
+ Song *song;
directory_for_each_song(song, this) {
assert(song->parent == this);
@@ -244,7 +244,7 @@ Directory::FindSong(const char *name_utf8) const
return NULL;
}
-struct song *
+Song *
Directory::LookupSong(const char *uri)
{
char *duplicated, *base;
@@ -266,7 +266,7 @@ Directory::LookupSong(const char *uri)
} else
base = duplicated;
- struct song *song = d->FindSong(base);
+ Song *song = d->FindSong(base);
assert(song == NULL || song->parent == d);
g_free(duplicated);
@@ -305,7 +305,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
assert(error_r == NULL || *error_r == NULL);
if (visit_song) {
- struct song *song;
+ Song *song;
directory_for_each_song(song, this)
if ((filter == nullptr || filter->Match(*song)) &&
!visit_song(*song, error_r))
diff --git a/src/Directory.hxx b/src/Directory.hxx
index 8fa5c2352..97e4ef32b 100644
--- a/src/Directory.hxx
+++ b/src/Directory.hxx
@@ -45,7 +45,7 @@
#define directory_for_each_song_safe(pos, n, directory) \
list_for_each_entry_safe(pos, n, &directory->songs, siblings)
-struct song;
+struct Song;
struct db_visitor;
class SongFilter;
@@ -202,12 +202,12 @@ public:
* Caller must lock the #db_mutex.
*/
gcc_pure
- const song *FindSong(const char *name_utf8) const;
+ const Song *FindSong(const char *name_utf8) const;
gcc_pure
- song *FindSong(const char *name_utf8) {
+ Song *FindSong(const char *name_utf8) {
const Directory *cthis = this;
- return const_cast<song *>(cthis->FindSong(name_utf8));
+ return const_cast<Song *>(cthis->FindSong(name_utf8));
}
/**
@@ -219,20 +219,20 @@ public:
* @return the song, or NULL if none was found
*/
gcc_pure
- song *LookupSong(const char *uri);
+ Song *LookupSong(const char *uri);
/**
* Add a song object to this directory. Its "parent" attribute must
* be set already.
*/
- void AddSong(song *song);
+ void AddSong(Song *song);
/**
* Remove a song object from this directory (which effectively
* invalidates the song object, because the "parent" attribute becomes
* stale), but does not free it.
*/
- void RemoveSong(song *song);
+ void RemoveSong(Song *song);
/**
* Caller must lock the #db_mutex.
diff --git a/src/DirectorySave.cxx b/src/DirectorySave.cxx
index 6a5efb058..1dcc36dbf 100644
--- a/src/DirectorySave.cxx
+++ b/src/DirectorySave.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "DirectorySave.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "SongSave.hxx"
#include "PlaylistDatabase.hxx"
#include "TextFile.hxx"
@@ -65,7 +65,7 @@ directory_save(FILE *fp, const Directory *directory)
return;
}
- struct song *song;
+ Song *song;
directory_for_each_song(song, directory)
song_save(fp, song);
@@ -143,7 +143,7 @@ directory_load(TextFile &file, Directory *directory, GError **error)
return false;
} else if (g_str_has_prefix(line, SONG_BEGIN)) {
const char *name = line + sizeof(SONG_BEGIN) - 1;
- struct song *song;
+ Song *song;
if (directory->FindSong(name) != nullptr) {
g_set_error(error, directory_quark(), 0,
diff --git a/src/Instance.cxx b/src/Instance.cxx
index 5571155b0..9982e5826 100644
--- a/src/Instance.cxx
+++ b/src/Instance.cxx
@@ -23,7 +23,7 @@
#include "Idle.hxx"
void
-Instance::DeleteSong(const song &song)
+Instance::DeleteSong(const Song &song)
{
partition->DeleteSong(song);
}
diff --git a/src/Instance.hxx b/src/Instance.hxx
index 09d9e4465..896656b10 100644
--- a/src/Instance.hxx
+++ b/src/Instance.hxx
@@ -24,14 +24,14 @@
class ClientList;
struct Partition;
-struct song;
+struct Song;
struct Instance {
ClientList *client_list;
Partition *partition;
- void DeleteSong(const song &song);
+ void DeleteSong(const Song &song);
/**
* The database has been modified. Propagate the change to
diff --git a/src/Mapper.cxx b/src/Mapper.cxx
index 40e762e4b..6f4a9cdcc 100644
--- a/src/Mapper.cxx
+++ b/src/Mapper.cxx
@@ -24,7 +24,7 @@
#include "config.h"
#include "Mapper.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "fs/Path.hxx"
#include "fs/FileSystem.hxx"
#include "fs/DirectoryReader.hxx"
@@ -246,12 +246,12 @@ map_detached_song_fs(const char *uri_utf8)
}
Path
-map_song_fs(const struct song *song)
+map_song_fs(const Song *song)
{
- assert(song_is_file(song));
+ assert(song->IsFile());
- if (song_in_database(song))
- return song_is_detached(song)
+ if (song->IsInDatabase())
+ return song->IsDetached()
? map_detached_song_fs(song->uri)
: map_directory_child_fs(song->parent, song->uri);
else
diff --git a/src/Mapper.hxx b/src/Mapper.hxx
index af6c84cc8..f114f27f0 100644
--- a/src/Mapper.hxx
+++ b/src/Mapper.hxx
@@ -31,7 +31,7 @@
class Path;
struct Directory;
-struct song;
+struct Song;
bool mapper_init(const char *_music_dir, const char *_playlist_dir,
GError **error_r);
@@ -112,7 +112,7 @@ map_directory_child_fs(const Directory *directory, const char *name);
*/
gcc_pure
Path
-map_song_fs(const struct song *song);
+map_song_fs(const Song *song);
/**
* Maps a file system path (relative to the music directory or
diff --git a/src/OtherCommands.cxx b/src/OtherCommands.cxx
index 7f592ee9f..0137cfd57 100644
--- a/src/OtherCommands.cxx
+++ b/src/OtherCommands.cxx
@@ -23,7 +23,7 @@
#include "CommandError.hxx"
#include "UpdateGlue.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "SongPrint.hxx"
#include "TagPrint.hxx"
#include "TimePrint.hxx"
@@ -130,7 +130,7 @@ handle_lsinfo(Client *client, int argc, char *argv[])
if (!client_allow_file(client, path_fs, &error))
return print_error(client, error);
- struct song *song = song_file_load(path_utf8, NULL);
+ Song *song = Song::LoadFile(path_utf8, nullptr);
if (song == NULL) {
command_error(client, ACK_ERROR_NO_EXIST,
"No such file");
@@ -138,7 +138,7 @@ handle_lsinfo(Client *client, int argc, char *argv[])
}
song_print_info(client, song);
- song_free(song);
+ song->Free();
return COMMAND_RETURN_OK;
}
diff --git a/src/Partition.hxx b/src/Partition.hxx
index 6e4230857..0d5017985 100644
--- a/src/Partition.hxx
+++ b/src/Partition.hxx
@@ -76,7 +76,7 @@ struct Partition {
return playlist.DeleteRange(pc, start, end);
}
- void DeleteSong(const song &song) {
+ void DeleteSong(const Song &song) {
playlist.DeleteSong(pc, song);
}
diff --git a/src/PlayerControl.cxx b/src/PlayerControl.cxx
index 790abcd50..357cdfc17 100644
--- a/src/PlayerControl.cxx
+++ b/src/PlayerControl.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "PlayerControl.hxx"
#include "Idle.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "DecoderControl.hxx"
#include "Main.hxx"
@@ -30,7 +30,7 @@
#include <stdio.h>
static void
-pc_enqueue_song_locked(struct player_control *pc, struct song *song);
+pc_enqueue_song_locked(struct player_control *pc, Song *song);
player_control::player_control(unsigned _buffer_chunks,
unsigned _buffered_before_play)
@@ -59,7 +59,7 @@ player_control::player_control(unsigned _buffer_chunks,
player_control::~player_control()
{
if (next_song != nullptr)
- song_free(next_song);
+ next_song->Free();
}
static void
@@ -88,7 +88,7 @@ player_command(struct player_control *pc, enum player_command cmd)
}
void
-player_control::Play(struct song *song)
+player_control::Play(Song *song)
{
assert(song != NULL);
@@ -253,7 +253,7 @@ player_control::GetErrorMessage() const
}
static void
-pc_enqueue_song_locked(struct player_control *pc, struct song *song)
+pc_enqueue_song_locked(struct player_control *pc, Song *song)
{
assert(song != NULL);
assert(pc->next_song == NULL);
@@ -263,7 +263,7 @@ pc_enqueue_song_locked(struct player_control *pc, struct song *song)
}
void
-player_control::EnqueueSong(struct song *song)
+player_control::EnqueueSong(Song *song)
{
assert(song != NULL);
@@ -273,14 +273,14 @@ player_control::EnqueueSong(struct song *song)
}
bool
-player_control::Seek(struct song *song, float seek_time)
+player_control::Seek(Song *song, float seek_time)
{
assert(song != NULL);
Lock();
if (next_song != nullptr)
- song_free(next_song);
+ next_song->Free();
next_song = song;
seek_where = seek_time;
diff --git a/src/PlayerControl.hxx b/src/PlayerControl.hxx
index de05e17ab..ab87f6092 100644
--- a/src/PlayerControl.hxx
+++ b/src/PlayerControl.hxx
@@ -29,6 +29,7 @@
#include <stdint.h>
struct decoder_control;
+struct Song;
enum player_state {
PLAYER_STATE_STOP = 0,
@@ -139,7 +140,7 @@ struct player_control {
* This is a duplicate, and must be freed when this attribute
* is cleared.
*/
- struct song *next_song;
+ Song *next_song;
double seek_where;
float cross_fade_seconds;
@@ -230,7 +231,7 @@ struct player_control {
* @param song the song to be queued; the given instance will
* be owned and freed by the player
*/
- void Play(struct song *song);
+ void Play(Song *song);
/**
* see PLAYER_COMMAND_CANCEL
@@ -287,7 +288,7 @@ struct player_control {
* @param song the song to be queued; the given instance will be owned
* and freed by the player
*/
- void EnqueueSong(struct song *song);
+ void EnqueueSong(Song *song);
/**
* Makes the player thread seek the specified song to a position.
@@ -297,7 +298,7 @@ struct player_control {
* @return true on success, false on failure (e.g. if MPD isn't
* playing currently)
*/
- bool Seek(struct song *song, float seek_time);
+ bool Seek(Song *song, float seek_time);
void SetCrossFade(float cross_fade_seconds);
diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx
index ccf16bb39..3033bce51 100644
--- a/src/PlayerThread.cxx
+++ b/src/PlayerThread.cxx
@@ -24,7 +24,7 @@
#include "MusicPipe.hxx"
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Main.hxx"
#include "mpd_error.h"
#include "CrossFade.hxx"
@@ -86,7 +86,7 @@ struct player {
/**
* the song currently being played
*/
- struct song *song;
+ Song *song;
/**
* is cross fading enabled?
@@ -176,7 +176,7 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
if (pc->command == PLAYER_COMMAND_SEEK)
start_ms += (unsigned)(pc->seek_where * 1000);
- dc->Start(song_dup_detached(pc->next_song),
+ dc->Start(pc->next_song->DupDetached(),
start_ms, pc->next_song->end_ms,
player_buffer, pipe);
}
@@ -254,7 +254,7 @@ player_wait_for_decoder(struct player *player)
pc->Lock();
pc->SetError(PLAYER_ERROR_DECODER, error);
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
pc->Unlock();
@@ -263,7 +263,7 @@ player_wait_for_decoder(struct player *player)
}
if (player->song != NULL)
- song_free(player->song);
+ player->song->Free();
player->song = pc->next_song;
player->elapsed_time = 0.0;
@@ -275,7 +275,7 @@ player_wait_for_decoder(struct player *player)
pc->Lock();
/* update player_control's song information */
- pc->total_time = song_get_duration(pc->next_song);
+ pc->total_time = pc->next_song->GetDuration();
pc->bit_rate = 0;
audio_format_clear(&pc->audio_format);
@@ -295,14 +295,14 @@ player_wait_for_decoder(struct player *player)
* indicated by the decoder plugin.
*/
static double
-real_song_duration(const struct song *song, double decoder_duration)
+real_song_duration(const Song *song, double decoder_duration)
{
assert(song != NULL);
if (decoder_duration <= 0.0)
/* the decoder plugin didn't provide information; fall
- back to song_get_duration() */
- return song_get_duration(song);
+ back to Song::GetDuration() */
+ return song->GetDuration();
if (song->end_ms > 0 && song->end_ms / 1000.0 < decoder_duration)
return (song->end_ms - song->start_ms) / 1000.0;
@@ -407,7 +407,7 @@ player_check_decoder_startup(struct player *player)
player->decoder_starting = false;
if (!player->paused && !player_open_output(player)) {
- char *uri = song_get_uri(dc->song);
+ char *uri = dc->song->GetURI();
g_warning("problems opening audio device "
"while playing \"%s\"", uri);
g_free(uri);
@@ -479,7 +479,7 @@ player_send_silence(struct player *player)
static bool player_seek_decoder(struct player *player)
{
struct player_control *pc = player->pc;
- struct song *song = pc->next_song;
+ Song *song = pc->next_song;
struct decoder_control *dc = player->dc;
assert(pc->next_song != NULL);
@@ -512,7 +512,7 @@ static bool player_seek_decoder(struct player *player)
player->pipe = dc->pipe;
}
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
player->queued = false;
}
@@ -633,7 +633,7 @@ static void player_process_command(struct player *player)
pc->Lock();
}
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
player->queued = false;
player_command_finished_locked(pc);
@@ -656,9 +656,9 @@ static void player_process_command(struct player *player)
}
static void
-update_song_tag(struct song *song, const struct tag *new_tag)
+update_song_tag(Song *song, const struct tag *new_tag)
{
- if (song_is_file(song))
+ if (song->IsFile())
/* don't update tags of local files, only remote
streams may change tags dynamically */
return;
@@ -687,7 +687,7 @@ update_song_tag(struct song *song, const struct tag *new_tag)
*/
static bool
play_chunk(struct player_control *pc,
- struct song *song, struct music_chunk *chunk,
+ Song *song, struct music_chunk *chunk,
const struct audio_format *format,
GError **error_r)
{
@@ -872,7 +872,7 @@ player_song_border(struct player *player)
{
player->xfade = XFADE_UNKNOWN;
- char *uri = song_get_uri(player->song);
+ char *uri = player->song->GetURI();
g_message("played \"%s\"", uri);
g_free(uri);
@@ -1084,13 +1084,13 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
tag_free(player.cross_fade_tag);
if (player.song != NULL)
- song_free(player.song);
+ player.song->Free();
pc->Lock();
if (player.queued) {
assert(pc->next_song != NULL);
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
}
@@ -1133,7 +1133,7 @@ player_task(gpointer arg)
case PLAYER_COMMAND_PAUSE:
if (pc->next_song != NULL) {
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
}
@@ -1178,7 +1178,7 @@ player_task(gpointer arg)
case PLAYER_COMMAND_CANCEL:
if (pc->next_song != NULL) {
- song_free(pc->next_song);
+ pc->next_song->Free();
pc->next_song = NULL;
}
diff --git a/src/Playlist.cxx b/src/Playlist.cxx
index 89bdac637..0fc12f745 100644
--- a/src/Playlist.cxx
+++ b/src/Playlist.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "Playlist.hxx"
#include "PlayerControl.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Idle.hxx"
#include <glib.h>
@@ -62,10 +62,9 @@ playlist_queue_song_order(struct playlist *playlist, struct player_control *pc,
playlist->queued = order;
- struct song *song =
- song_dup_detached(playlist->queue.GetOrder(order));
+ Song *song = playlist->queue.GetOrder(order)->DupDetached();
- uri = song_get_uri(song);
+ uri = song->GetURI();
g_debug("queue song %i:\"%s\"", playlist->queued, uri);
g_free(uri);
@@ -94,7 +93,7 @@ playlist_song_started(struct playlist *playlist, struct player_control *pc)
idle_add(IDLE_PLAYER);
}
-const struct song *
+const Song *
playlist::GetQueuedSong() const
{
return playing && queued >= 0
@@ -103,7 +102,7 @@ playlist::GetQueuedSong() const
}
void
-playlist::UpdateQueuedSong(player_control &pc, const song *prev)
+playlist::UpdateQueuedSong(player_control &pc, const Song *prev)
{
if (!playing)
return;
@@ -130,7 +129,7 @@ playlist::UpdateQueuedSong(player_control &pc, const song *prev)
current = queue.PositionToOrder(current_position);
}
- const struct song *const next_song = next_order >= 0
+ const Song *const next_song = next_order >= 0
? queue.GetOrder(next_order)
: nullptr;
@@ -154,9 +153,9 @@ playlist::PlayOrder(player_control &pc, int order)
playing = true;
queued = -1;
- struct song *song = song_dup_detached(queue.GetOrder(order));
+ Song *song = queue.GetOrder(order)->DupDetached();
- char *uri = song_get_uri(song);
+ char *uri = song->GetURI();
g_debug("play %i:\"%s\"", order, uri);
g_free(uri);
@@ -177,7 +176,7 @@ playlist::SyncWithPlayer(player_control &pc)
pc.Lock();
const player_state pc_state = pc.GetState();
- const song *pc_next_song = pc.next_song;
+ const Song *pc_next_song = pc.next_song;
pc.Unlock();
if (pc_state == PLAYER_STATE_STOP)
@@ -290,7 +289,7 @@ playlist::SetRandom(player_control &pc, bool status)
if (status == queue.random)
return;
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
queue.random = status;
diff --git a/src/Playlist.hxx b/src/Playlist.hxx
index c01813322..c640b78ed 100644
--- a/src/Playlist.hxx
+++ b/src/Playlist.hxx
@@ -26,6 +26,7 @@
#include <stdbool.h>
struct player_control;
+struct Song;
struct playlist {
/**
@@ -99,7 +100,7 @@ struct playlist {
* none if there is none (yet?) or if MPD isn't playing.
*/
gcc_pure
- const struct song *GetQueuedSong() const;
+ const Song *GetQueuedSong() const;
/**
* This is the "PLAYLIST" event handler. It is invoked by the
@@ -124,7 +125,7 @@ protected:
* @param prev the song which was previously queued, as
* determined by playlist_get_queued_song()
*/
- void UpdateQueuedSong(player_control &pc, const song *prev);
+ void UpdateQueuedSong(player_control &pc, const Song *prev);
public:
void Clear(player_control &pc);
@@ -134,7 +135,7 @@ public:
void FullIncrementVersions();
enum playlist_result AppendSong(player_control &pc,
- struct song *song,
+ Song *song,
unsigned *added_id=nullptr);
/**
@@ -153,7 +154,7 @@ public:
protected:
void DeleteInternal(player_control &pc,
- unsigned song, const struct song **queued_p);
+ unsigned song, const Song **queued_p);
public:
enum playlist_result DeletePosition(player_control &pc,
@@ -175,7 +176,7 @@ public:
enum playlist_result DeleteRange(player_control &pc,
unsigned start, unsigned end);
- void DeleteSong(player_control &pc, const song &song);
+ void DeleteSong(player_control &pc, const Song &song);
void Shuffle(player_control &pc, unsigned start, unsigned end);
diff --git a/src/PlaylistControl.cxx b/src/PlaylistControl.cxx
index 3db61cc7c..5b33486e3 100644
--- a/src/PlaylistControl.cxx
+++ b/src/PlaylistControl.cxx
@@ -25,7 +25,7 @@
#include "config.h"
#include "Playlist.hxx"
#include "PlayerControl.hxx"
-#include "song.h"
+#include "Song.hxx"
#include <glib.h>
@@ -198,7 +198,7 @@ playlist::SeekSongPosition(player_control &pc, unsigned song, float seek_time)
if (!queue.IsValidPosition(song))
return PLAYLIST_RESULT_BAD_RANGE;
- const struct song *queued_song = GetQueuedSong();
+ const Song *queued_song = GetQueuedSong();
unsigned i = queue.random
? queue.PositionToOrder(song)
@@ -218,7 +218,7 @@ playlist::SeekSongPosition(player_control &pc, unsigned song, float seek_time)
queued_song = nullptr;
}
- struct song *the_song = song_dup_detached(queue.GetOrder(i));
+ Song *the_song = queue.GetOrder(i)->DupDetached();
if (!pc.Seek(the_song, seek_time)) {
UpdateQueuedSong(pc, queued_song);
diff --git a/src/PlaylistEdit.cxx b/src/PlaylistEdit.cxx
index 9ccc8c46d..e3d3eac25 100644
--- a/src/PlaylistEdit.cxx
+++ b/src/PlaylistEdit.cxx
@@ -27,11 +27,7 @@
#include "Playlist.hxx"
#include "PlayerControl.hxx"
#include "util/UriUtil.hxx"
-
-extern "C" {
-#include "song.h"
-}
-
+#include "Song.hxx"
#include "Idle.hxx"
#include "DatabaseGlue.hxx"
#include "DatabasePlugin.hxx"
@@ -61,7 +57,7 @@ enum playlist_result
playlist::AppendFile(struct player_control &pc,
const char *path_utf8, unsigned *added_id)
{
- struct song *song = song_file_load(path_utf8, NULL);
+ Song *song = Song::LoadFile(path_utf8, nullptr);
if (song == NULL)
return PLAYLIST_RESULT_NO_SUCH_SONG;
@@ -70,14 +66,14 @@ playlist::AppendFile(struct player_control &pc,
enum playlist_result
playlist::AppendSong(struct player_control &pc,
- struct song *song, unsigned *added_id)
+ Song *song, unsigned *added_id)
{
unsigned id;
if (queue.IsFull())
return PLAYLIST_RESULT_TOO_LARGE;
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
id = queue.Append(song, 0);
@@ -110,9 +106,9 @@ playlist::AppendURI(struct player_control &pc,
g_debug("add to playlist: %s", uri);
const Database *db = nullptr;
- struct song *song;
+ Song *song;
if (uri_has_scheme(uri)) {
- song = song_remote_new(uri);
+ song = Song::NewRemote(uri);
} else {
db = GetDatabase(nullptr);
if (db == nullptr)
@@ -136,7 +132,7 @@ playlist::SwapPositions(player_control &pc, unsigned song1, unsigned song2)
if (!queue.IsValidPosition(song1) || !queue.IsValidPosition(song2))
return PLAYLIST_RESULT_BAD_RANGE;
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
queue.SwapPositions(song1, song2);
@@ -190,7 +186,7 @@ playlist::SetPriorityRange(player_control &pc,
/* remember "current" and "queued" */
const int current_position = GetCurrentPosition();
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
/* apply the priority changes */
@@ -222,7 +218,7 @@ playlist::SetPriorityId(struct player_control &pc,
void
playlist::DeleteInternal(player_control &pc,
- unsigned song, const struct song **queued_p)
+ unsigned song, const Song **queued_p)
{
assert(song < GetLength());
@@ -272,7 +268,7 @@ playlist::DeletePosition(struct player_control &pc, unsigned song)
if (song >= queue.GetLength())
return PLAYLIST_RESULT_BAD_RANGE;
- const struct song *queued_song = GetQueuedSong();
+ const Song *queued_song = GetQueuedSong();
DeleteInternal(pc, song, &queued_song);
@@ -294,7 +290,7 @@ playlist::DeleteRange(struct player_control &pc, unsigned start, unsigned end)
if (start >= end)
return PLAYLIST_RESULT_SUCCESS;
- const struct song *queued_song = GetQueuedSong();
+ const Song *queued_song = GetQueuedSong();
do {
DeleteInternal(pc, --end, &queued_song);
@@ -317,7 +313,7 @@ playlist::DeleteId(struct player_control &pc, unsigned id)
}
void
-playlist::DeleteSong(struct player_control &pc, const struct song &song)
+playlist::DeleteSong(struct player_control &pc, const struct Song &song)
{
for (int i = queue.GetLength() - 1; i >= 0; --i)
// TODO: compare URI instead of pointer
@@ -339,7 +335,7 @@ playlist::MoveRange(player_control &pc, unsigned start, unsigned end, int to)
/* nothing happens */
return PLAYLIST_RESULT_SUCCESS;
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
/*
* (to < 0) => move to offset from current song
@@ -394,7 +390,7 @@ playlist::Shuffle(player_control &pc, unsigned start, unsigned end)
/* needs at least two entries. */
return;
- const struct song *const queued_song = GetQueuedSong();
+ const Song *const queued_song = GetQueuedSong();
if (playing && current >= 0) {
unsigned current_position = queue.OrderToPosition(current);
diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx
index 8cc009e0c..6541e6598 100644
--- a/src/PlaylistFile.cxx
+++ b/src/PlaylistFile.cxx
@@ -24,7 +24,7 @@
#include "PlaylistVector.hxx"
#include "DatabasePlugin.hxx"
#include "DatabaseGlue.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "io_error.h"
#include "Mapper.hxx"
#include "TextFile.hxx"
@@ -360,7 +360,7 @@ spl_remove_index(const char *utf8path, unsigned pos, GError **error_r)
}
bool
-spl_append_song(const char *utf8path, struct song *song, GError **error_r)
+spl_append_song(const char *utf8path, Song *song, GError **error_r)
{
if (spl_map(error_r).IsNull())
return false;
@@ -402,16 +402,16 @@ bool
spl_append_uri(const char *url, const char *utf8file, GError **error_r)
{
if (uri_has_scheme(url)) {
- struct song *song = song_remote_new(url);
+ Song *song = Song::NewRemote(url);
bool success = spl_append_song(utf8file, song, error_r);
- song_free(song);
+ song->Free();
return success;
} else {
const Database *db = GetDatabase(error_r);
if (db == nullptr)
return false;
- song *song = db->GetSong(url, error_r);
+ Song *song = db->GetSong(url, error_r);
if (song == nullptr)
return false;
diff --git a/src/PlaylistFile.hxx b/src/PlaylistFile.hxx
index a9aeaa237..4fcecc8da 100644
--- a/src/PlaylistFile.hxx
+++ b/src/PlaylistFile.hxx
@@ -25,7 +25,7 @@
#include <vector>
#include <string>
-struct song;
+struct Song;
struct PlaylistInfo;
class PlaylistVector;
@@ -72,7 +72,7 @@ bool
spl_remove_index(const char *utf8path, unsigned pos, GError **error_r);
bool
-spl_append_song(const char *utf8path, struct song *song, GError **error_r);
+spl_append_song(const char *utf8path, Song *song, GError **error_r);
bool
spl_append_uri(const char *file, const char *utf8file, GError **error_r);
diff --git a/src/PlaylistPlugin.hxx b/src/PlaylistPlugin.hxx
index d422106bb..56adceedc 100644
--- a/src/PlaylistPlugin.hxx
+++ b/src/PlaylistPlugin.hxx
@@ -28,6 +28,7 @@
struct config_param;
struct input_stream;
struct tag;
+struct Song;
/**
* An object which provides the contents of a playlist.
@@ -78,7 +79,7 @@ struct playlist_plugin {
void (*close)(struct playlist_provider *playlist);
- struct song *(*read)(struct playlist_provider *playlist);
+ Song *(*read)(struct playlist_provider *playlist);
const char *const*schemes;
const char *const*suffixes;
@@ -132,7 +133,7 @@ playlist_plugin_close(struct playlist_provider *playlist)
playlist->plugin->close(playlist);
}
-static inline struct song *
+static inline Song *
playlist_plugin_read(struct playlist_provider *playlist)
{
return playlist->plugin->read(playlist);
diff --git a/src/PlaylistPrint.cxx b/src/PlaylistPrint.cxx
index e79e87732..35498eeba 100644
--- a/src/PlaylistPrint.cxx
+++ b/src/PlaylistPrint.cxx
@@ -31,10 +31,7 @@
#include "DatabasePlugin.hxx"
#include "Client.hxx"
#include "input_stream.h"
-
-extern "C" {
-#include "song.h"
-}
+#include "Song.hxx"
void
playlist_print_uris(Client *client, const struct playlist *playlist)
@@ -119,7 +116,7 @@ PrintSongDetails(Client *client, const char *uri_utf8)
if (db == nullptr)
return false;
- song *song = db->GetSong(uri_utf8, nullptr);
+ Song *song = db->GetSong(uri_utf8, nullptr);
if (song == nullptr)
return false;
@@ -152,7 +149,7 @@ static void
playlist_provider_print(Client *client, const char *uri,
struct playlist_provider *playlist, bool detail)
{
- struct song *song;
+ Song *song;
char *base_uri = uri != NULL ? g_path_get_dirname(uri) : NULL;
while ((song = playlist_plugin_read(playlist)) != NULL) {
@@ -165,7 +162,7 @@ playlist_provider_print(Client *client, const char *uri,
else
song_print_uri(client, song);
- song_free(song);
+ song->Free();
}
g_free(base_uri);
diff --git a/src/PlaylistQueue.cxx b/src/PlaylistQueue.cxx
index c52f49a91..c7b6c21fb 100644
--- a/src/PlaylistQueue.cxx
+++ b/src/PlaylistQueue.cxx
@@ -24,10 +24,7 @@
#include "PlaylistSong.hxx"
#include "Playlist.hxx"
#include "input_stream.h"
-
-extern "C" {
-#include "song.h"
-}
+#include "Song.hxx"
enum playlist_result
playlist_load_into_queue(const char *uri, struct playlist_provider *source,
@@ -36,7 +33,7 @@ playlist_load_into_queue(const char *uri, struct playlist_provider *source,
bool secure)
{
enum playlist_result result;
- struct song *song;
+ Song *song;
char *base_uri = uri != NULL ? g_path_get_dirname(uri) : NULL;
for (unsigned i = 0;
@@ -44,7 +41,7 @@ playlist_load_into_queue(const char *uri, struct playlist_provider *source,
++i) {
if (i < start_index) {
/* skip songs before the start index */
- song_free(song);
+ song->Free();
continue;
}
@@ -53,7 +50,7 @@ playlist_load_into_queue(const char *uri, struct playlist_provider *source,
continue;
result = dest->AppendSong(*pc, song);
- song_free(song);
+ song->Free();
if (result != PLAYLIST_RESULT_SUCCESS) {
g_free(base_uri);
return result;
diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx
index 473713d5d..b259b1f3d 100644
--- a/src/PlaylistSave.cxx
+++ b/src/PlaylistSave.cxx
@@ -21,7 +21,7 @@
#include "PlaylistSave.hxx"
#include "PlaylistFile.hxx"
#include "Playlist.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Mapper.hxx"
#include "Idle.hxx"
#include "fs/Path.hxx"
@@ -31,14 +31,14 @@
#include <glib.h>
void
-playlist_print_song(FILE *file, const struct song *song)
+playlist_print_song(FILE *file, const Song *song)
{
- if (playlist_saveAbsolutePaths && song_in_database(song)) {
+ if (playlist_saveAbsolutePaths && song->IsInDatabase()) {
const Path path = map_song_fs(song);
if (!path.IsNull())
fprintf(file, "%s\n", path.c_str());
} else {
- char *uri = song_get_uri(song);
+ char *uri = song->GetURI();
const Path uri_fs = Path::FromUTF8(uri);
g_free(uri);
diff --git a/src/PlaylistSave.hxx b/src/PlaylistSave.hxx
index ff5f0c494..382df1b19 100644
--- a/src/PlaylistSave.hxx
+++ b/src/PlaylistSave.hxx
@@ -24,13 +24,13 @@
#include <stdio.h>
-struct song;
+struct Song;
struct queue;
struct playlist;
struct player_control;
void
-playlist_print_song(FILE *fp, const struct song *song);
+playlist_print_song(FILE *fp, const Song *song);
void
playlist_print_uri(FILE *fp, const char *uri);
diff --git a/src/PlaylistSong.cxx b/src/PlaylistSong.cxx
index 4ca955240..510124215 100644
--- a/src/PlaylistSong.cxx
+++ b/src/PlaylistSong.cxx
@@ -26,10 +26,7 @@
#include "tag.h"
#include "fs/Path.hxx"
#include "util/UriUtil.hxx"
-
-extern "C" {
-#include "song.h"
-}
+#include "Song.hxx"
#include <glib.h>
@@ -37,8 +34,8 @@ extern "C" {
#include <string.h>
static void
-merge_song_metadata(struct song *dest, const struct song *base,
- const struct song *add)
+merge_song_metadata(Song *dest, const Song *base,
+ const Song *add)
{
dest->tag = base->tag != NULL
? (add->tag != NULL
@@ -53,10 +50,10 @@ merge_song_metadata(struct song *dest, const struct song *base,
dest->end_ms = add->end_ms;
}
-static struct song *
-apply_song_metadata(struct song *dest, const struct song *src)
+static Song *
+apply_song_metadata(Song *dest, const Song *src)
{
- struct song *tmp;
+ Song *tmp;
assert(dest != NULL);
assert(src != NULL);
@@ -64,7 +61,7 @@ apply_song_metadata(struct song *dest, const struct song *src)
if (src->tag == NULL && src->start_ms == 0 && src->end_ms == 0)
return dest;
- if (song_in_database(dest)) {
+ if (dest->IsInDatabase()) {
const Path &path_fs = map_song_fs(dest);
if (path_fs.IsNull())
return dest;
@@ -73,11 +70,11 @@ apply_song_metadata(struct song *dest, const struct song *src)
if (path_utf8.empty())
path_utf8 = path_fs.c_str();
- tmp = song_file_new(path_utf8.c_str(), NULL);
+ tmp = Song::NewFile(path_utf8.c_str(), NULL);
merge_song_metadata(tmp, dest, src);
} else {
- tmp = song_file_new(dest->uri, NULL);
+ tmp = Song::NewFile(dest->uri, NULL);
merge_song_metadata(tmp, dest, src);
}
@@ -89,19 +86,19 @@ apply_song_metadata(struct song *dest, const struct song *src)
(e.g. last track on a CUE file); fix it up here */
tmp->tag->time = dest->tag->time - src->start_ms / 1000;
- song_free(dest);
+ dest->Free();
return tmp;
}
-static struct song *
-playlist_check_load_song(const struct song *song, const char *uri, bool secure)
+static Song *
+playlist_check_load_song(const Song *song, const char *uri, bool secure)
{
- struct song *dest;
+ Song *dest;
if (uri_has_scheme(uri)) {
- dest = song_remote_new(uri);
+ dest = Song::NewRemote(uri);
} else if (g_path_is_absolute(uri) && secure) {
- dest = song_file_load(uri, NULL);
+ dest = Song::LoadFile(uri, nullptr);
if (dest == NULL)
return NULL;
} else {
@@ -109,23 +106,23 @@ playlist_check_load_song(const struct song *song, const char *uri, bool secure)
if (db == nullptr)
return nullptr;
- struct song *tmp = db->GetSong(uri, nullptr);
+ Song *tmp = db->GetSong(uri, nullptr);
if (tmp == NULL)
/* not found in database */
return NULL;
- dest = song_dup_detached(tmp);
+ dest = tmp->DupDetached();
db->ReturnSong(tmp);
}
return apply_song_metadata(dest, song);
}
-struct song *
-playlist_check_translate_song(struct song *song, const char *base_uri,
+Song *
+playlist_check_translate_song(Song *song, const char *base_uri,
bool secure)
{
- if (song_in_database(song))
+ if (song->IsInDatabase())
/* already ok */
return song;
@@ -137,7 +134,7 @@ playlist_check_translate_song(struct song *song, const char *base_uri,
return song;
else {
/* unsupported remote song */
- song_free(song);
+ song->Free();
return NULL;
}
}
@@ -159,7 +156,7 @@ playlist_check_translate_song(struct song *song, const char *base_uri,
else if (!secure) {
/* local files must be relative to the music
directory when "secure" is enabled */
- song_free(song);
+ song->Free();
return NULL;
}
@@ -170,8 +167,8 @@ playlist_check_translate_song(struct song *song, const char *base_uri,
if (base_uri != NULL)
uri = allocated = g_build_filename(base_uri, uri, NULL);
- struct song *dest = playlist_check_load_song(song, uri, secure);
- song_free(song);
+ Song *dest = playlist_check_load_song(song, uri, secure);
+ song->Free();
g_free(allocated);
return dest;
}
diff --git a/src/PlaylistSong.hxx b/src/PlaylistSong.hxx
index 117ee1338..68c99c4ec 100644
--- a/src/PlaylistSong.hxx
+++ b/src/PlaylistSong.hxx
@@ -20,6 +20,8 @@
#ifndef MPD_PLAYLIST_SONG_HXX
#define MPD_PLAYLIST_SONG_HXX
+struct Song;
+
/**
* Verifies the song, returns NULL if it is unsafe. Translate the
* song to a new song object within the database, if it is a local
@@ -28,8 +30,8 @@
* @param secure if true, then local files are only allowed if they
* are relative to base_uri
*/
-struct song *
-playlist_check_translate_song(struct song *song, const char *base_uri,
+Song *
+playlist_check_translate_song(Song *song, const char *base_uri,
bool secure);
#endif
diff --git a/src/Queue.cxx b/src/Queue.cxx
index 3fdb9ed1e..6bb8175a1 100644
--- a/src/Queue.cxx
+++ b/src/Queue.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "Queue.hxx"
-#include "song.h"
+#include "Song.hxx"
#include <stdlib.h>
@@ -97,7 +97,7 @@ queue::ModifyAll()
}
unsigned
-queue::Append(struct song *song, uint8_t priority)
+queue::Append(Song *song, uint8_t priority)
{
assert(!IsFull());
@@ -105,7 +105,7 @@ queue::Append(struct song *song, uint8_t priority)
const unsigned id = id_table.Insert(position);
auto &item = items[position];
- item.song = song_dup_detached(song);
+ item.song = song->DupDetached();
item.id = id;
item.version = version;
item.priority = priority;
@@ -232,9 +232,9 @@ queue::DeletePosition(unsigned position)
{
assert(position < length);
- struct song *song = Get(position);
- assert(!song_in_database(song) || song_is_detached(song));
- song_free(song);
+ Song *song = Get(position);
+ assert(!song->IsInDatabase() || song->IsDetached());
+ song->Free();
const unsigned id = PositionToId(position);
const unsigned _order = PositionToOrder(position);
@@ -268,9 +268,9 @@ queue::Clear()
for (unsigned i = 0; i < length; i++) {
Item *item = &items[i];
- assert(!song_in_database(item->song) ||
- song_is_detached(item->song));
- song_free(item->song);
+ assert(!item->song->IsInDatabase() ||
+ item->song->IsDetached());
+ item->song->Free();
id_table.Erase(item->id);
}
diff --git a/src/Queue.hxx b/src/Queue.hxx
index 6e7786bcd..d8eeb271e 100644
--- a/src/Queue.hxx
+++ b/src/Queue.hxx
@@ -29,6 +29,8 @@
#include <assert.h>
#include <stdint.h>
+struct Song;
+
/**
* A queue of songs. This is the backend of the playlist: it contains
* an ordered list of songs.
@@ -51,7 +53,7 @@ struct queue {
* information attached.
*/
struct Item {
- struct song *song;
+ Song *song;
/** the unique id of this item in the queue */
unsigned id;
@@ -198,7 +200,7 @@ struct queue {
/**
* Returns the song at the specified position.
*/
- struct song *Get(unsigned position) const {
+ Song *Get(unsigned position) const {
assert(position < length);
return items[position].song;
@@ -207,7 +209,7 @@ struct queue {
/**
* Returns the song at the specified order number.
*/
- struct song *GetOrder(unsigned _order) const {
+ Song *GetOrder(unsigned _order) const {
return Get(OrderToPosition(_order));
}
@@ -254,11 +256,12 @@ struct queue {
* that, the caller must check if the queue is already full.
*
* If a song is not in the database (determined by
- * song_in_database()), it is freed when removed from the queue.
+ * Song::IsInDatabase()), it is freed when removed from the
+ * queue.
*
* @param priority the priority of this new queue item
*/
- unsigned Append(struct song *song, uint8_t priority);
+ unsigned Append(Song *song, uint8_t priority);
/**
* Swaps two songs, addressed by their position.
diff --git a/src/QueuePrint.cxx b/src/QueuePrint.cxx
index 28abc5a8c..d8d94d3b0 100644
--- a/src/QueuePrint.cxx
+++ b/src/QueuePrint.cxx
@@ -26,7 +26,7 @@
#include "Client.hxx"
extern "C" {
-#include "song.h"
+#include "Song.hxx"
}
/**
@@ -99,7 +99,7 @@ queue_find(Client *client, const struct queue *queue,
const SongFilter &filter)
{
for (unsigned i = 0; i < queue->GetLength(); i++) {
- const struct song *song = queue->Get(i);
+ const Song *song = queue->Get(i);
if (filter.Match(*song))
queue_print_song_info(client, queue, i);
diff --git a/src/QueueSave.cxx b/src/QueueSave.cxx
index 6311201e9..fd00009b1 100644
--- a/src/QueueSave.cxx
+++ b/src/QueueSave.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "QueueSave.hxx"
#include "Playlist.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "SongSave.hxx"
#include "DatabasePlugin.hxx"
#include "DatabaseGlue.hxx"
@@ -32,24 +32,24 @@
#define PRIO_LABEL "Prio: "
static void
-queue_save_database_song(FILE *fp, int idx, const struct song *song)
+queue_save_database_song(FILE *fp, int idx, const Song *song)
{
- char *uri = song_get_uri(song);
+ char *uri = song->GetURI();
fprintf(fp, "%i:%s\n", idx, uri);
g_free(uri);
}
static void
-queue_save_full_song(FILE *fp, const struct song *song)
+queue_save_full_song(FILE *fp, const Song *song)
{
song_save(fp, song);
}
static void
-queue_save_song(FILE *fp, int idx, const struct song *song)
+queue_save_song(FILE *fp, int idx, const Song *song)
{
- if (song_in_database(song))
+ if (song->IsInDatabase())
queue_save_database_song(fp, idx, song);
else
queue_save_full_song(fp, song);
@@ -83,7 +83,7 @@ queue_load_song(TextFile &file, const char *line, queue *queue)
}
const Database *db = nullptr;
- struct song *song;
+ Song *song;
if (g_str_has_prefix(line, SONG_BEGIN)) {
const char *uri = line + sizeof(SONG_BEGIN) - 1;
@@ -108,7 +108,7 @@ queue_load_song(TextFile &file, const char *line, queue *queue)
const char *uri = endptr + 1;
if (uri_has_scheme(uri)) {
- song = song_remote_new(uri);
+ song = Song::NewRemote(uri);
} else {
db = GetDatabase(nullptr);
if (db == nullptr)
diff --git a/src/Song.cxx b/src/Song.cxx
index 4c820c3f8..90ddcf518 100644
--- a/src/Song.cxx
+++ b/src/Song.cxx
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "song.h"
+#include "Song.hxx"
#include "Directory.hxx"
#include "tag.h"
@@ -28,7 +28,7 @@
Directory detached_root;
-static struct song *
+static Song *
song_alloc(const char *uri, Directory *parent)
{
size_t uri_length;
@@ -37,7 +37,7 @@ song_alloc(const char *uri, Directory *parent)
uri_length = strlen(uri);
assert(uri_length);
- struct song *song = (struct song *)
+ Song *song = (Song *)
g_malloc(sizeof(*song) - sizeof(song->uri) + uri_length + 1);
song->tag = nullptr;
@@ -49,67 +49,65 @@ song_alloc(const char *uri, Directory *parent)
return song;
}
-struct song *
-song_remote_new(const char *uri)
+Song *
+Song::NewRemote(const char *uri)
{
return song_alloc(uri, nullptr);
}
-struct song *
-song_file_new(const char *path, Directory *parent)
+Song *
+Song::NewFile(const char *path, Directory *parent)
{
assert((parent == nullptr) == (*path == '/'));
return song_alloc(path, parent);
}
-struct song *
-song_replace_uri(struct song *old_song, const char *uri)
+Song *
+Song::ReplaceURI(const char *new_uri)
{
- struct song *new_song = song_alloc(uri, old_song->parent);
- new_song->tag = old_song->tag;
- new_song->mtime = old_song->mtime;
- new_song->start_ms = old_song->start_ms;
- new_song->end_ms = old_song->end_ms;
- g_free(old_song);
+ Song *new_song = song_alloc(new_uri, parent);
+ new_song->tag = tag;
+ new_song->mtime = mtime;
+ new_song->start_ms = start_ms;
+ new_song->end_ms = end_ms;
+ g_free(this);
return new_song;
}
-struct song *
-song_detached_new(const char *uri)
+Song *
+Song::NewDetached(const char *uri)
{
assert(uri != nullptr);
return song_alloc(uri, &detached_root);
}
-struct song *
-song_dup_detached(const struct song *src)
+Song *
+Song::DupDetached() const
{
- assert(src != nullptr);
-
- struct song *song;
- if (song_in_database(src)) {
- char *uri = song_get_uri(src);
- song = song_detached_new(uri);
- g_free(uri);
+ Song *song;
+ if (IsInDatabase()) {
+ char *new_uri = GetURI();
+ song = NewDetached(new_uri);
+ g_free(new_uri);
} else
- song = song_alloc(src->uri, nullptr);
+ song = song_alloc(uri, nullptr);
- song->tag = tag_dup(src->tag);
- song->mtime = src->mtime;
- song->start_ms = src->start_ms;
- song->end_ms = src->end_ms;
+ song->tag = tag_dup(tag);
+ song->mtime = mtime;
+ song->start_ms = start_ms;
+ song->end_ms = end_ms;
return song;
}
void
-song_free(struct song *song)
+Song::Free()
{
- if (song->tag)
- tag_free(song->tag);
- g_free(song);
+ if (tag != nullptr)
+ tag_free(tag);
+ g_free(this);
}
gcc_pure
@@ -130,7 +128,7 @@ directory_is_same(const Directory *a, const Directory *b)
}
bool
-song_equals(const struct song *a, const struct song *b)
+song_equals(const Song *a, const Song *b)
{
assert(a != nullptr);
assert(b != nullptr);
@@ -140,8 +138,8 @@ song_equals(const struct song *a, const struct song *b)
(a->parent == &detached_root || b->parent == &detached_root)) {
/* must compare the full URI if one of the objects is
"detached" */
- char *au = song_get_uri(a);
- char *bu = song_get_uri(b);
+ char *au = a->GetURI();
+ char *bu = b->GetURI();
const bool result = strcmp(au, bu) == 0;
g_free(bu);
g_free(au);
@@ -153,26 +151,25 @@ song_equals(const struct song *a, const struct song *b)
}
char *
-song_get_uri(const struct song *song)
+Song::GetURI() const
{
- assert(song != nullptr);
- assert(*song->uri);
+ assert(*uri);
- if (!song_in_database(song) || song->parent->IsRoot())
- return g_strdup(song->uri);
+ if (!IsInDatabase() || parent->IsRoot())
+ return g_strdup(uri);
else
- return g_strconcat(song->parent->GetPath(),
- "/", song->uri, nullptr);
+ return g_strconcat(parent->GetPath(),
+ "/", uri, nullptr);
}
double
-song_get_duration(const struct song *song)
+Song::GetDuration() const
{
- if (song->end_ms > 0)
- return (song->end_ms - song->start_ms) / 1000.0;
+ if (end_ms > 0)
+ return (end_ms - start_ms) / 1000.0;
- if (song->tag == nullptr)
+ if (tag == nullptr)
return 0;
- return song->tag->time - song->start_ms / 1000.0;
+ return tag->time - start_ms / 1000.0;
}
diff --git a/src/Song.hxx b/src/Song.hxx
new file mode 100644
index 000000000..f7ded6c04
--- /dev/null
+++ b/src/Song.hxx
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_SONG_HXX
+#define MPD_SONG_HXX
+
+#include "util/list.h"
+#include "gcc.h"
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <sys/time.h>
+
+#define SONG_FILE "file: "
+#define SONG_TIME "Time: "
+
+/**
+ * A dummy #directory instance that is used for "detached" song
+ * copies.
+ */
+extern struct Directory detached_root;
+
+struct Song {
+ /**
+ * Pointers to the siblings of this directory within the
+ * parent directory. It is unused (undefined) if this song is
+ * not in the database.
+ *
+ * This attribute is protected with the global #db_mutex.
+ * Read access in the update thread does not need protection.
+ */
+ struct list_head siblings;
+
+ struct tag *tag;
+ Directory *parent;
+ time_t mtime;
+
+ /**
+ * Start of this sub-song within the file in milliseconds.
+ */
+ unsigned start_ms;
+
+ /**
+ * End of this sub-song within the file in milliseconds.
+ * Unused if zero.
+ */
+ unsigned end_ms;
+
+ char uri[sizeof(int)];
+
+ /** allocate a new song with a remote URL */
+ gcc_malloc
+ static Song *NewRemote(const char *uri);
+
+ /** allocate a new song with a local file name */
+ gcc_malloc
+ static Song *NewFile(const char *path_utf8, Directory *parent);
+
+ /**
+ * allocate a new song structure with a local file name and attempt to
+ * load its metadata. If all decoder plugin fail to read its meta
+ * data, nullptr is returned.
+ */
+ gcc_malloc
+ static Song *LoadFile(const char *path_utf8, Directory *parent);
+
+ /**
+ * Replaces the URI of a song object. The given song object
+ * is destroyed, and a newly allocated one is returned. It
+ * does not update the reference within the parent directory;
+ * the caller is responsible for doing that.
+ */
+ gcc_malloc
+ Song *ReplaceURI(const char *uri);
+
+ /**
+ * Creates a "detached" song object.
+ */
+ gcc_malloc
+ static Song *NewDetached(const char *uri);
+
+ /**
+ * Creates a duplicate of the song object. If the object is
+ * in the database, it creates a "detached" copy of this song,
+ * see Song::IsDetached().
+ */
+ gcc_malloc
+ Song *DupDetached() const;
+
+ void Free();
+
+ bool IsInDatabase() const {
+ return parent != nullptr;
+ }
+
+ bool IsFile() const {
+ return IsInDatabase() || uri[0] == '/';
+ }
+
+ bool IsDetached() const {
+ assert(IsInDatabase());
+
+ return parent == &detached_root;
+ }
+
+ bool UpdateFile();
+ bool UpdateFileInArchive();
+
+ /**
+ * Returns the URI of the song in UTF-8 encoding, including its
+ * location within the music directory.
+ *
+ * The return value is allocated on the heap, and must be freed by the
+ * caller.
+ */
+ gcc_malloc
+ char *GetURI() const;
+
+ gcc_pure
+ double GetDuration() const;
+};
+
+/**
+ * Returns true if both objects refer to the same physical song.
+ */
+gcc_pure
+bool
+song_equals(const Song *a, const Song *b);
+
+#endif
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index 0e138386b..ce9cea246 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "SongFilter.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -107,10 +107,10 @@ SongFilter::Item::Match(const struct tag &_tag) const
}
bool
-SongFilter::Item::Match(const song &song) const
+SongFilter::Item::Match(const Song &song) const
{
if (tag == LOCATE_TAG_FILE_TYPE || tag == LOCATE_TAG_ANY_TYPE) {
- char *uri = song_get_uri(&song);
+ char *uri = song.GetURI();
const bool result = StringMatch(uri);
g_free(uri);
@@ -156,7 +156,7 @@ SongFilter::Parse(unsigned argc, char *argv[], bool fold_case)
}
bool
-SongFilter::Match(const song &song) const
+SongFilter::Match(const Song &song) const
{
for (const auto &i : items)
if (!i.Match(song))
diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx
index afec81300..2b53d4524 100644
--- a/src/SongFilter.hxx
+++ b/src/SongFilter.hxx
@@ -31,7 +31,7 @@
struct tag;
struct tag_item;
-struct song;
+struct Song;
class SongFilter {
class Item {
@@ -71,7 +71,7 @@ class SongFilter {
bool Match(const struct tag &tag) const;
gcc_pure
- bool Match(const song &song) const;
+ bool Match(const Song &song) const;
};
std::list<Item> items;
@@ -94,7 +94,7 @@ public:
bool Match(const tag &tag) const;
gcc_pure
- bool Match(const song &song) const;
+ bool Match(const Song &song) const;
};
/**
diff --git a/src/SongPointer.hxx b/src/SongPointer.hxx
index c80f96f4d..ded3b3e1d 100644
--- a/src/SongPointer.hxx
+++ b/src/SongPointer.hxx
@@ -20,15 +20,15 @@
#ifndef MPD_SONG_POINTER_HXX
#define MPD_SONG_POINTER_HXX
-#include "song.h"
+#include "Song.hxx"
#include <utility>
class SongPointer {
- struct song *song;
+ Song *song;
public:
- explicit SongPointer(struct song *_song)
+ explicit SongPointer(Song *_song)
:song(_song) {}
SongPointer(const SongPointer &) = delete;
@@ -39,7 +39,7 @@ public:
~SongPointer() {
if (song != nullptr)
- song_free(song);
+ song->Free();
}
SongPointer &operator=(const SongPointer &) = delete;
@@ -49,11 +49,11 @@ public:
return *this;
}
- operator const struct song *() const {
+ operator const Song *() const {
return song;
}
- struct song *Steal() {
+ Song *Steal() {
auto result = song;
song = nullptr;
return result;
diff --git a/src/SongPrint.cxx b/src/SongPrint.cxx
index 331f3912d..b6b66e1f6 100644
--- a/src/SongPrint.cxx
+++ b/src/SongPrint.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "SongPrint.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Directory.hxx"
#include "TimePrint.hxx"
#include "TagPrint.hxx"
@@ -30,9 +30,9 @@
#include <glib.h>
void
-song_print_uri(Client *client, struct song *song)
+song_print_uri(Client *client, Song *song)
{
- if (song_in_database(song) && !song->parent->IsRoot()) {
+ if (song->IsInDatabase() && !song->parent->IsRoot()) {
client_printf(client, "%s%s/%s\n", SONG_FILE,
song->parent->GetPath(), song->uri);
} else {
@@ -51,7 +51,7 @@ song_print_uri(Client *client, struct song *song)
}
void
-song_print_info(Client *client, struct song *song)
+song_print_info(Client *client, Song *song)
{
song_print_uri(client, song);
diff --git a/src/SongPrint.hxx b/src/SongPrint.hxx
index 49f9478be..a82b54cfe 100644
--- a/src/SongPrint.hxx
+++ b/src/SongPrint.hxx
@@ -20,13 +20,13 @@
#ifndef MPD_SONG_PRINT_HXX
#define MPD_SONG_PRINT_HXX
-struct song;
+struct Song;
class Client;
void
-song_print_info(Client *client, struct song *song);
+song_print_info(Client *client, Song *song);
void
-song_print_uri(Client *client, struct song *song);
+song_print_uri(Client *client, Song *song);
#endif
diff --git a/src/SongSave.cxx b/src/SongSave.cxx
index c3796235b..d6860d1b0 100644
--- a/src/SongSave.cxx
+++ b/src/SongSave.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "SongSave.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "TagSave.hxx"
#include "Directory.hxx"
#include "TextFile.hxx"
@@ -43,7 +43,7 @@ song_save_quark(void)
}
void
-song_save(FILE *fp, const struct song *song)
+song_save(FILE *fp, const Song *song)
{
fprintf(fp, SONG_BEGIN "%s\n", song->uri);
@@ -59,13 +59,13 @@ song_save(FILE *fp, const struct song *song)
fprintf(fp, SONG_END "\n");
}
-struct song *
+Song *
song_load(TextFile &file, Directory *parent, const char *uri,
GError **error_r)
{
- struct song *song = parent != NULL
- ? song_file_new(uri, parent)
- : song_remote_new(uri);
+ Song *song = parent != NULL
+ ? Song::NewFile(uri, parent)
+ : Song::NewRemote(uri);
char *line, *colon;
enum tag_type type;
const char *value;
@@ -76,7 +76,7 @@ song_load(TextFile &file, Directory *parent, const char *uri,
if (colon == NULL || colon == line) {
if (song->tag != NULL)
tag_end_add(song->tag);
- song_free(song);
+ song->Free();
g_set_error(error_r, song_save_quark(), 0,
"unknown line in db: %s", line);
@@ -118,7 +118,7 @@ song_load(TextFile &file, Directory *parent, const char *uri,
} else {
if (song->tag != NULL)
tag_end_add(song->tag);
- song_free(song);
+ song->Free();
g_set_error(error_r, song_save_quark(), 0,
"unknown line in db: %s", line);
diff --git a/src/SongSave.hxx b/src/SongSave.hxx
index 3b0c3319c..9fd6ba86c 100644
--- a/src/SongSave.hxx
+++ b/src/SongSave.hxx
@@ -26,12 +26,12 @@
#define SONG_BEGIN "song_begin: "
-struct song;
+struct Song;
struct Directory;
class TextFile;
void
-song_save(FILE *fp, const struct song *song);
+song_save(FILE *fp, const Song *song);
/**
* Loads a song from the input file. Reading stops after the
@@ -41,7 +41,7 @@ song_save(FILE *fp, const struct song *song);
* ignore errors
* @return true on success, false on error
*/
-struct song *
+Song *
song_load(TextFile &file, Directory *parent, const char *uri,
GError **error_r);
diff --git a/src/SongSort.cxx b/src/SongSort.cxx
index 8728614e0..299a72042 100644
--- a/src/SongSort.cxx
+++ b/src/SongSort.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "SongSort.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "util/list.h"
#include "tag.h"
@@ -94,8 +94,8 @@ compare_tag_item(const struct tag *a, const struct tag *b, enum tag_type type)
static int
song_cmp(G_GNUC_UNUSED void *priv, struct list_head *_a, struct list_head *_b)
{
- const struct song *a = (const struct song *)_a;
- const struct song *b = (const struct song *)_b;
+ const Song *a = (const Song *)_a;
+ const Song *b = (const Song *)_b;
int ret;
/* first sort by album */
diff --git a/src/SongSticker.cxx b/src/SongSticker.cxx
index 86385fc33..589bc2a4a 100644
--- a/src/SongSticker.cxx
+++ b/src/SongSticker.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "SongSticker.hxx"
#include "StickerDatabase.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Directory.hxx"
#include <glib.h>
@@ -29,80 +29,66 @@
#include <string.h>
char *
-sticker_song_get_value(const struct song *song, const char *name)
+sticker_song_get_value(const Song *song, const char *name)
{
- char *uri, *value;
-
assert(song != NULL);
- assert(song_in_database(song));
+ assert(song->IsInDatabase());
- uri = song_get_uri(song);
- value = sticker_load_value("song", uri, name);
+ char *uri = song->GetURI();
+ char *value = sticker_load_value("song", uri, name);
g_free(uri);
return value;
}
bool
-sticker_song_set_value(const struct song *song,
+sticker_song_set_value(const Song *song,
const char *name, const char *value)
{
- char *uri;
- bool ret;
-
assert(song != NULL);
- assert(song_in_database(song));
+ assert(song->IsInDatabase());
- uri = song_get_uri(song);
- ret = sticker_store_value("song", uri, name, value);
+ char *uri = song->GetURI();
+ bool ret = sticker_store_value("song", uri, name, value);
g_free(uri);
return ret;
}
bool
-sticker_song_delete(const struct song *song)
+sticker_song_delete(const Song *song)
{
- char *uri;
- bool ret;
-
assert(song != NULL);
- assert(song_in_database(song));
+ assert(song->IsInDatabase());
- uri = song_get_uri(song);
- ret = sticker_delete("song", uri);
+ char *uri = song->GetURI();
+ bool ret = sticker_delete("song", uri);
g_free(uri);
return ret;
}
bool
-sticker_song_delete_value(const struct song *song, const char *name)
+sticker_song_delete_value(const Song *song, const char *name)
{
- char *uri;
- bool success;
-
assert(song != NULL);
- assert(song_in_database(song));
+ assert(song->IsInDatabase());
- uri = song_get_uri(song);
- success = sticker_delete_value("song", uri, name);
+ char *uri = song->GetURI();
+ bool success = sticker_delete_value("song", uri, name);
g_free(uri);
return success;
}
struct sticker *
-sticker_song_get(const struct song *song)
+sticker_song_get(const Song *song)
{
- char *uri;
- struct sticker *sticker;
-
assert(song != NULL);
- assert(song_in_database(song));
+ assert(song->IsInDatabase());
- uri = song_get_uri(song);
- sticker = sticker_load("song", uri);
+ char *uri = song->GetURI();
+ struct sticker *sticker = sticker_load("song", uri);
g_free(uri);
return sticker;
@@ -113,7 +99,7 @@ struct sticker_song_find_data {
const char *base_uri;
size_t base_uri_length;
- void (*func)(struct song *song, const char *value,
+ void (*func)(Song *song, const char *value,
void *user_data);
void *user_data;
};
@@ -128,14 +114,14 @@ sticker_song_find_cb(const char *uri, const char *value, void *user_data)
/* should not happen, ignore silently */
return;
- song *song = data->directory->LookupSong(uri + data->base_uri_length);
+ Song *song = data->directory->LookupSong(uri + data->base_uri_length);
if (song != NULL)
data->func(song, value, data->user_data);
}
bool
sticker_song_find(Directory *directory, const char *name,
- void (*func)(struct song *song, const char *value,
+ void (*func)(Song *song, const char *value,
void *user_data),
void *user_data)
{
diff --git a/src/SongSticker.hxx b/src/SongSticker.hxx
index 07539b400..385aa59dc 100644
--- a/src/SongSticker.hxx
+++ b/src/SongSticker.hxx
@@ -22,7 +22,7 @@
#include "gerror.h"
-struct song;
+struct Song;
struct Directory;
struct sticker;
@@ -31,28 +31,28 @@ struct sticker;
* free the return value with g_free().
*/
char *
-sticker_song_get_value(const struct song *song, const char *name);
+sticker_song_get_value(const Song *song, const char *name);
/**
* Sets a sticker value in the specified song. Overwrites existing
* values.
*/
bool
-sticker_song_set_value(const struct song *song,
+sticker_song_set_value(const Song *song,
const char *name, const char *value);
/**
* Deletes a sticker from the database. All values are deleted.
*/
bool
-sticker_song_delete(const struct song *song);
+sticker_song_delete(const Song *song);
/**
* Deletes a sticker value. Does nothing if the sticker did not
* exist.
*/
bool
-sticker_song_delete_value(const struct song *song, const char *name);
+sticker_song_delete_value(const Song *song, const char *name);
/**
* Loads the sticker for the specified song.
@@ -61,7 +61,7 @@ sticker_song_delete_value(const struct song *song, const char *name);
* @return a sticker object, or NULL on error or if there is no sticker
*/
struct sticker *
-sticker_song_get(const struct song *song);
+sticker_song_get(const Song *song);
/**
* Finds stickers with the specified name below the specified
@@ -76,7 +76,7 @@ sticker_song_get(const struct song *song);
*/
bool
sticker_song_find(Directory *directory, const char *name,
- void (*func)(struct song *song, const char *value,
+ void (*func)(Song *song, const char *value,
void *user_data),
void *user_data);
diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx
index a7666b47d..6752386be 100644
--- a/src/SongUpdate.cxx
+++ b/src/SongUpdate.cxx
@@ -18,11 +18,7 @@
*/
#include "config.h" /* must be first for large file support */
-
-extern "C" {
-#include "song.h"
-}
-
+#include "Song.hxx"
#include "util/UriUtil.hxx"
#include "Directory.hxx"
#include "Mapper.hxx"
@@ -46,26 +42,26 @@ extern "C" {
#include <sys/stat.h>
#include <stdio.h>
-struct song *
-song_file_load(const char *path_utf8, Directory *parent)
+Song *
+Song::LoadFile(const char *path_utf8, Directory *parent)
{
- struct song *song;
+ Song *song;
bool ret;
assert((parent == NULL) == g_path_is_absolute(path_utf8));
assert(!uri_has_scheme(path_utf8));
assert(strchr(path_utf8, '\n') == NULL);
- song = song_file_new(path_utf8, parent);
+ song = NewFile(path_utf8, parent);
//in archive ?
if (parent != NULL && parent->device == DEVICE_INARCHIVE) {
- ret = song_file_update_inarchive(song);
+ ret = song->UpdateFileInArchive();
} else {
- ret = song_file_update(song);
+ ret = song->UpdateFile();
}
if (!ret) {
- song_free(song);
+ song->Free();
return NULL;
}
@@ -84,18 +80,18 @@ tag_scan_fallback(const char *path,
}
bool
-song_file_update(struct song *song)
+Song::UpdateFile()
{
const char *suffix;
const struct decoder_plugin *plugin;
struct stat st;
struct input_stream *is = NULL;
- assert(song_is_file(song));
+ assert(IsFile());
/* check if there's a suffix and a plugin */
- suffix = uri_get_suffix(song->uri);
+ suffix = uri_get_suffix(uri);
if (suffix == NULL)
return false;
@@ -103,33 +99,33 @@ song_file_update(struct song *song)
if (plugin == NULL)
return false;
- const Path path_fs = map_song_fs(song);
+ const Path path_fs = map_song_fs(this);
if (path_fs.IsNull())
return false;
- if (song->tag != NULL) {
- tag_free(song->tag);
- song->tag = NULL;
+ if (tag != NULL) {
+ tag_free(tag);
+ tag = NULL;
}
if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode)) {
return false;
}
- song->mtime = st.st_mtime;
+ mtime = st.st_mtime;
Mutex mutex;
Cond cond;
do {
/* load file tag */
- song->tag = tag_new();
+ tag = tag_new();
if (decoder_plugin_scan_file(plugin, path_fs.c_str(),
- &full_tag_handler, song->tag))
+ &full_tag_handler, tag))
break;
- tag_free(song->tag);
- song->tag = NULL;
+ tag_free(tag);
+ tag = nullptr;
/* fall back to stream tag */
if (plugin->scan_stream != NULL) {
@@ -143,14 +139,14 @@ song_file_update(struct song *song)
/* now try the stream_tag() method */
if (is != NULL) {
- song->tag = tag_new();
+ tag = tag_new();
if (decoder_plugin_scan_stream(plugin, is,
&full_tag_handler,
- song->tag))
+ tag))
break;
- tag_free(song->tag);
- song->tag = NULL;
+ tag_free(tag);
+ tag = nullptr;
input_stream_lock_seek(is, 0, SEEK_SET, NULL);
}
@@ -162,24 +158,23 @@ song_file_update(struct song *song)
if (is != NULL)
input_stream_close(is);
- if (song->tag != NULL && tag_is_empty(song->tag))
- tag_scan_fallback(path_fs.c_str(), &full_tag_handler,
- song->tag);
+ if (tag != nullptr && tag_is_empty(tag))
+ tag_scan_fallback(path_fs.c_str(), &full_tag_handler, tag);
- return song->tag != NULL;
+ return tag != nullptr;
}
bool
-song_file_update_inarchive(struct song *song)
+Song::UpdateFileInArchive()
{
const char *suffix;
const struct decoder_plugin *plugin;
- assert(song_is_file(song));
+ assert(IsFile());
/* check if there's a suffix and a plugin */
- suffix = uri_get_suffix(song->uri);
+ suffix = uri_get_suffix(uri);
if (suffix == NULL)
return false;
@@ -187,13 +182,13 @@ song_file_update_inarchive(struct song *song)
if (plugin == NULL)
return false;
- if (song->tag != NULL)
- tag_free(song->tag);
+ if (tag != nullptr)
+ tag_free(tag);
//accept every file that has music suffix
//because we don't support tag reading through
//input streams
- song->tag = tag_new();
+ tag = tag_new();
return true;
}
diff --git a/src/StickerCommands.cxx b/src/StickerCommands.cxx
index d13647c33..5cbb7e984 100644
--- a/src/StickerCommands.cxx
+++ b/src/StickerCommands.cxx
@@ -38,7 +38,7 @@ struct sticker_song_find_data {
};
static void
-sticker_song_find_print_cb(struct song *song, const char *value,
+sticker_song_find_print_cb(Song *song, const char *value,
gpointer user_data)
{
struct sticker_song_find_data *data =
@@ -58,7 +58,7 @@ handle_sticker_song(Client *client, int argc, char *argv[])
/* get song song_id key */
if (argc == 5 && strcmp(argv[1], "get") == 0) {
- song *song = db->GetSong(argv[3], &error);
+ Song *song = db->GetSong(argv[3], &error);
if (song == nullptr)
return print_error(client, error);
@@ -76,7 +76,7 @@ handle_sticker_song(Client *client, int argc, char *argv[])
return COMMAND_RETURN_OK;
/* list song song_id */
} else if (argc == 4 && strcmp(argv[1], "list") == 0) {
- song *song = db->GetSong(argv[3], &error);
+ Song *song = db->GetSong(argv[3], &error);
if (song == nullptr)
return print_error(client, error);
@@ -90,7 +90,7 @@ handle_sticker_song(Client *client, int argc, char *argv[])
return COMMAND_RETURN_OK;
/* set song song_id id key */
} else if (argc == 6 && strcmp(argv[1], "set") == 0) {
- song *song = db->GetSong(argv[3], &error);
+ Song *song = db->GetSong(argv[3], &error);
if (song == nullptr)
return print_error(client, error);
@@ -106,7 +106,7 @@ handle_sticker_song(Client *client, int argc, char *argv[])
/* delete song song_id [key] */
} else if ((argc == 4 || argc == 5) &&
strcmp(argv[1], "delete") == 0) {
- song *song = db->GetSong(argv[3], &error);
+ Song *song = db->GetSong(argv[3], &error);
if (song == nullptr)
return print_error(client, error);
diff --git a/src/Tag.cxx b/src/Tag.cxx
index afdeb0558..0cf9c32c7 100644
--- a/src/Tag.cxx
+++ b/src/Tag.cxx
@@ -22,7 +22,7 @@
#include "TagInternal.hxx"
#include "TagPool.hxx"
#include "conf.h"
-#include "song.h"
+#include "Song.hxx"
#include "mpd_error.h"
#include <glib.h>
diff --git a/src/TagPrint.cxx b/src/TagPrint.cxx
index b3ad07df4..acbb14e8c 100644
--- a/src/TagPrint.cxx
+++ b/src/TagPrint.cxx
@@ -21,7 +21,7 @@
#include "TagPrint.hxx"
#include "tag.h"
#include "TagInternal.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Client.hxx"
void tag_print_types(Client *client)
diff --git a/src/TagSave.cxx b/src/TagSave.cxx
index 15da9fc4b..51ae53444 100644
--- a/src/TagSave.cxx
+++ b/src/TagSave.cxx
@@ -21,7 +21,7 @@
#include "TagSave.hxx"
#include "tag.h"
#include "TagInternal.hxx"
-#include "song.h"
+#include "Song.hxx"
void tag_save(FILE *file, const struct tag *tag)
{
diff --git a/src/UpdateArchive.cxx b/src/UpdateArchive.cxx
index 133dfd476..ab174fa53 100644
--- a/src/UpdateArchive.cxx
+++ b/src/UpdateArchive.cxx
@@ -22,7 +22,7 @@
#include "UpdateInternal.hxx"
#include "DatabaseLock.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Mapper.hxx"
#include "fs/Path.hxx"
#include "ArchiveList.hxx"
@@ -58,10 +58,10 @@ update_archive_tree(Directory *directory, const char *name)
//add file
db_lock();
- struct song *song = directory->FindSong(name);
+ Song *song = directory->FindSong(name);
db_unlock();
if (song == NULL) {
- song = song_file_load(name, directory);
+ song = Song::LoadFile(name, directory);
if (song != NULL) {
db_lock();
directory->AddSong(song);
diff --git a/src/UpdateContainer.cxx b/src/UpdateContainer.cxx
index f090cf0f1..92b727ce7 100644
--- a/src/UpdateContainer.cxx
+++ b/src/UpdateContainer.cxx
@@ -23,7 +23,7 @@
#include "UpdateDatabase.hxx"
#include "DatabaseLock.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "DecoderPlugin.hxx"
#include "Mapper.hxx"
#include "fs/Path.hxx"
@@ -89,7 +89,7 @@ update_container_file(Directory *directory,
char *vtrack;
unsigned int tnum = 0;
while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != NULL) {
- struct song *song = song_file_new(vtrack, contdir);
+ Song *song = Song::NewFile(vtrack, contdir);
// shouldn't be necessary but it's there..
song->mtime = st->st_mtime;
diff --git a/src/UpdateDatabase.cxx b/src/UpdateDatabase.cxx
index 984fb1be8..9d2fa9017 100644
--- a/src/UpdateDatabase.cxx
+++ b/src/UpdateDatabase.cxx
@@ -22,14 +22,14 @@
#include "UpdateRemove.hxx"
#include "PlaylistVector.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "DatabaseLock.hxx"
#include <glib.h>
#include <assert.h>
void
-delete_song(Directory *dir, struct song *del)
+delete_song(Directory *dir, Song *del)
{
assert(del->parent == dir);
@@ -42,7 +42,7 @@ delete_song(Directory *dir, struct song *del)
update_remove_song(del);
/* finally, all possible references gone, free it */
- song_free(del);
+ del->Free();
db_lock();
}
@@ -60,7 +60,7 @@ clear_directory(Directory *directory)
directory_for_each_child_safe(child, n, directory)
delete_directory(child);
- struct song *song, *ns;
+ Song *song, *ns;
directory_for_each_song_safe(song, ns, directory) {
assert(song->parent == directory);
delete_song(directory, song);
@@ -90,7 +90,7 @@ delete_name_in(Directory *parent, const char *name)
modified = true;
}
- struct song *song = parent->FindSong(name);
+ Song *song = parent->FindSong(name);
if (song != NULL) {
delete_song(parent, song);
modified = true;
diff --git a/src/UpdateDatabase.hxx b/src/UpdateDatabase.hxx
index 7b55ce95d..ab8f7ec26 100644
--- a/src/UpdateDatabase.hxx
+++ b/src/UpdateDatabase.hxx
@@ -23,13 +23,13 @@
#include "check.h"
struct Directory;
-struct song;
+struct Song;
/**
* Caller must lock the #db_mutex.
*/
void
-delete_song(Directory *parent, struct song *song);
+delete_song(Directory *parent, Song *song);
/**
* Recursively free a directory and all its contents.
diff --git a/src/UpdateRemove.cxx b/src/UpdateRemove.cxx
index fa4c8e764..f9f6994b0 100644
--- a/src/UpdateRemove.cxx
+++ b/src/UpdateRemove.cxx
@@ -24,7 +24,7 @@
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Main.hxx"
#include "Instance.hxx"
@@ -37,7 +37,7 @@
#include <assert.h>
-static const struct song *removed_song;
+static const Song *removed_song;
static Mutex remove_mutex;
static Cond remove_cond;
@@ -53,7 +53,7 @@ song_remove_event(void)
assert(removed_song != NULL);
- uri = song_get_uri(removed_song);
+ uri = removed_song->GetURI();
g_message("removing %s", uri);
g_free(uri);
@@ -79,7 +79,7 @@ update_remove_global_init(void)
}
void
-update_remove_song(const struct song *song)
+update_remove_song(const Song *song)
{
assert(removed_song == NULL);
diff --git a/src/UpdateRemove.hxx b/src/UpdateRemove.hxx
index a83e14ae1..bef27d766 100644
--- a/src/UpdateRemove.hxx
+++ b/src/UpdateRemove.hxx
@@ -22,7 +22,7 @@
#include "check.h"
-struct song;
+struct Song;
void
update_remove_global_init(void);
@@ -33,6 +33,6 @@ update_remove_global_init(void);
* serialized access is implemented to avoid excessive locking.
*/
void
-update_remove_song(const struct song *song);
+update_remove_song(const Song *song);
#endif
diff --git a/src/UpdateSong.cxx b/src/UpdateSong.cxx
index 0c2f2fb54..b1f8cac4d 100644
--- a/src/UpdateSong.cxx
+++ b/src/UpdateSong.cxx
@@ -25,7 +25,7 @@
#include "UpdateContainer.hxx"
#include "DatabaseLock.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "DecoderPlugin.hxx"
#include "DecoderList.hxx"
@@ -39,7 +39,7 @@ update_song_file2(Directory *directory,
const struct decoder_plugin *plugin)
{
db_lock();
- struct song *song = directory->FindSong(name);
+ Song *song = directory->FindSong(name);
db_unlock();
if (!directory_child_access(directory, name, R_OK)) {
@@ -68,7 +68,7 @@ update_song_file2(Directory *directory,
if (song == NULL) {
g_debug("reading %s/%s", directory->GetPath(), name);
- song = song_file_load(name, directory);
+ song = Song::LoadFile(name, directory);
if (song == NULL) {
g_debug("ignoring unrecognized file %s/%s",
directory->GetPath(), name);
@@ -85,7 +85,7 @@ update_song_file2(Directory *directory,
} else if (st->st_mtime != song->mtime || walk_discard) {
g_message("updating %s/%s",
directory->GetPath(), name);
- if (!song_file_update(song)) {
+ if (!song->UpdateFile()) {
g_debug("deleting unrecognized file %s/%s",
directory->GetPath(), name);
db_lock();
diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx
index 4b415895e..cc2b5743e 100644
--- a/src/UpdateWalk.cxx
+++ b/src/UpdateWalk.cxx
@@ -26,7 +26,7 @@
#include "DatabaseLock.hxx"
#include "DatabaseSimple.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "PlaylistVector.hxx"
#include "PlaylistRegistry.hxx"
#include "Mapper.hxx"
@@ -109,7 +109,7 @@ remove_excluded_from_directory(Directory *directory,
}
}
- struct song *song, *ns;
+ Song *song, *ns;
directory_for_each_song_safe(song, ns, directory) {
assert(song->parent == directory);
@@ -138,7 +138,7 @@ purge_deleted_from_directory(Directory *directory)
modified = true;
}
- struct song *song, *ns;
+ Song *song, *ns;
directory_for_each_song_safe(song, ns, directory) {
const Path path = map_song_fs(song);
if (path.IsNull() || !FileExists(path)) {
@@ -414,7 +414,7 @@ directory_make_child_checked(Directory *parent, const char *name_utf8)
/* if we're adding directory paths, make sure to delete filenames
with potentially the same name */
db_lock();
- struct song *conflicting = parent->FindSong(name_utf8);
+ Song *conflicting = parent->FindSong(name_utf8);
if (conflicting)
delete_song(parent, conflicting);
diff --git a/src/cue/CueParser.cxx b/src/cue/CueParser.cxx
index 915499f44..ae1445abc 100644
--- a/src/cue/CueParser.cxx
+++ b/src/cue/CueParser.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "CueParser.hxx"
#include "util/StringUtil.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -42,13 +42,13 @@ CueParser::~CueParser()
g_free(filename);
if (current != nullptr)
- song_free(current);
+ current->Free();
if (previous != nullptr)
- song_free(previous);
+ previous->Free();
if (finished != nullptr)
- song_free(finished);
+ finished->Free();
}
static const char *
@@ -250,7 +250,7 @@ CueParser::Feed2(char *p)
}
state = TRACK;
- current = song_remote_new(filename);
+ current = Song::NewRemote(filename);
assert(current->tag == nullptr);
current->tag = tag_dup(tag);
tag_add_item(current->tag, TAG_TRACK, nr);
@@ -304,7 +304,7 @@ CueParser::Finish()
end = true;
}
-struct song *
+Song *
CueParser::Get()
{
if (finished == nullptr && end) {
@@ -316,7 +316,7 @@ CueParser::Get()
previous = nullptr;
}
- struct song *song = finished;
+ Song *song = finished;
finished = nullptr;
return song;
}
diff --git a/src/cue/CueParser.hxx b/src/cue/CueParser.hxx
index 1266f1a6f..ad2a6f34c 100644
--- a/src/cue/CueParser.hxx
+++ b/src/cue/CueParser.hxx
@@ -23,6 +23,8 @@
#include "check.h"
#include "gcc.h"
+struct Song;
+
class CueParser {
enum {
/**
@@ -58,19 +60,19 @@ class CueParser {
/**
* The song currently being edited.
*/
- struct song *current;
+ Song *current;
/**
* The previous song. It is remembered because its end_time
* will be set to the current song's start time.
*/
- struct song *previous;
+ Song *previous;
/**
* A song that is completely finished and can be returned to
* the caller via cue_parser_get().
*/
- struct song *finished;
+ Song *finished;
/**
* Set to true after previous.end_time has been updated to the
@@ -109,7 +111,7 @@ public:
* @return a song object that must be freed by the caller, or NULL if
* no song was finished at this time
*/
- struct song *Get();
+ Song *Get();
private:
gcc_pure
diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx
index efaaffeba..6f39eeea7 100644
--- a/src/db/ProxyDatabasePlugin.cxx
+++ b/src/db/ProxyDatabasePlugin.cxx
@@ -23,12 +23,12 @@
#include "DatabaseSelection.hxx"
#include "PlaylistVector.hxx"
#include "Directory.hxx"
+#include "Song.hxx"
#include "gcc.h"
#include "conf.h"
extern "C" {
#include "db_error.h"
-#include "song.h"
}
#undef MPD_DIRECTORY_H
@@ -52,9 +52,9 @@ public:
virtual bool Open(GError **error_r) override;
virtual void Close() override;
- virtual struct song *GetSong(const char *uri_utf8,
+ virtual Song *GetSong(const char *uri_utf8,
GError **error_r) const override;
- virtual void ReturnSong(struct song *song) const;
+ virtual void ReturnSong(Song *song) const;
virtual bool Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory,
@@ -181,10 +181,10 @@ ProxyDatabase::Close()
mpd_connection_free(connection);
}
-static song *
+static Song *
Convert(const struct mpd_song *song);
-struct song *
+Song *
ProxyDatabase::GetSong(const char *uri, GError **error_r) const
{
// TODO: implement
@@ -196,13 +196,13 @@ ProxyDatabase::GetSong(const char *uri, GError **error_r) const
}
struct mpd_song *song = mpd_recv_song(connection);
- struct song *song2 = song != nullptr
+ Song *song2 = song != nullptr
? Convert(song)
: nullptr;
mpd_song_free(song);
if (!mpd_response_finish(connection)) {
if (song2 != nullptr)
- song_free(song2);
+ song2->Free();
CheckError(connection, error_r);
return nullptr;
@@ -216,13 +216,13 @@ ProxyDatabase::GetSong(const char *uri, GError **error_r) const
}
void
-ProxyDatabase::ReturnSong(struct song *song) const
+ProxyDatabase::ReturnSong(Song *song) const
{
assert(song != nullptr);
- assert(song_in_database(song));
- assert(song_is_detached(song));
+ assert(song->IsInDatabase());
+ assert(song->IsDetached());
- song_free(song);
+ song->Free();
}
static bool
@@ -268,10 +268,10 @@ Copy(struct tag *tag, enum tag_type d_tag,
}
}
-static song *
+static Song *
Convert(const struct mpd_song *song)
{
- struct song *s = song_detached_new(mpd_song_get_uri(song));
+ Song *s = Song::NewDetached(mpd_song_get_uri(song));
s->mtime = mpd_song_get_last_modified(song);
s->start_ms = mpd_song_get_start(song) * 1000;
@@ -297,9 +297,9 @@ Visit(const struct mpd_song *song,
if (!visit_song)
return true;
- struct song *s = Convert(song);
+ Song *s = Convert(song);
bool success = visit_song(*s, error_r);
- song_free(s);
+ s->Free();
return success;
}
diff --git a/src/db/SimpleDatabasePlugin.cxx b/src/db/SimpleDatabasePlugin.cxx
index 2b720c41f..f8a176fe1 100644
--- a/src/db/SimpleDatabasePlugin.cxx
+++ b/src/db/SimpleDatabasePlugin.cxx
@@ -211,13 +211,13 @@ SimpleDatabase::Close()
root->Free();
}
-struct song *
+Song *
SimpleDatabase::GetSong(const char *uri, GError **error_r) const
{
assert(root != NULL);
db_lock();
- song *song = root->LookupSong(uri);
+ Song *song = root->LookupSong(uri);
db_unlock();
if (song == NULL)
g_set_error(error_r, db_quark(), DB_NOT_FOUND,
@@ -231,7 +231,7 @@ SimpleDatabase::GetSong(const char *uri, GError **error_r) const
}
void
-SimpleDatabase::ReturnSong(gcc_unused struct song *song) const
+SimpleDatabase::ReturnSong(gcc_unused Song *song) const
{
assert(song != nullptr);
@@ -264,7 +264,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
const Directory *directory = root->LookupDirectory(selection.uri);
if (directory == NULL) {
if (visit_song) {
- song *song = root->LookupSong(selection.uri);
+ Song *song = root->LookupSong(selection.uri);
if (song != nullptr)
return !selection.Match(*song) ||
visit_song(*song, error_r);
diff --git a/src/db/SimpleDatabasePlugin.hxx b/src/db/SimpleDatabasePlugin.hxx
index 525e854db..8f0ed214c 100644
--- a/src/db/SimpleDatabasePlugin.hxx
+++ b/src/db/SimpleDatabasePlugin.hxx
@@ -66,9 +66,9 @@ public:
virtual bool Open(GError **error_r) override;
virtual void Close() override;
- virtual struct song *GetSong(const char *uri_utf8,
+ virtual Song *GetSong(const char *uri_utf8,
GError **error_r) const override;
- virtual void ReturnSong(struct song *song) const;
+ virtual void ReturnSong(Song *song) const;
virtual bool Visit(const DatabaseSelection &selection,
VisitDirectory visit_directory,
diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx
index 25319ca6b..198b1d581 100644
--- a/src/playlist/AsxPlaylistPlugin.cxx
+++ b/src/playlist/AsxPlaylistPlugin.cxx
@@ -21,7 +21,7 @@
#include "AsxPlaylistPlugin.hxx"
#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -60,7 +60,7 @@ struct AsxParser {
* The current song. It is allocated after the "location"
* element.
*/
- struct song *song;
+ Song *song;
AsxParser()
:state(ROOT) {}
@@ -91,7 +91,7 @@ asx_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
case AsxParser::ROOT:
if (g_ascii_strcasecmp(element_name, "entry") == 0) {
parser->state = AsxParser::ENTRY;
- parser->song = song_remote_new("asx:");
+ parser->song = Song::NewRemote("asx:");
parser->tag = TAG_NUM_OF_ITEM_TYPES;
}
@@ -108,12 +108,12 @@ asx_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
replace the existing song's URI,
because that attribute is
immutable */
- struct song *song = song_remote_new(href);
+ Song *song = Song::NewRemote(href);
if (parser->song != NULL) {
song->tag = parser->song->tag;
parser->song->tag = NULL;
- song_free(parser->song);
+ parser->song->Free();
}
parser->song = song;
@@ -145,7 +145,7 @@ asx_end_element(G_GNUC_UNUSED GMarkupParseContext *context,
if (strcmp(parser->song->uri, "asx:") != 0)
parser->songs.emplace_front(parser->song);
else
- song_free(parser->song);
+ parser->song->Free();
parser->state = AsxParser::ROOT;
} else
@@ -192,7 +192,7 @@ asx_parser_destroy(gpointer data)
AsxParser *parser = (AsxParser *)data;
if (parser->state >= AsxParser::ENTRY)
- song_free(parser->song);
+ parser->song->Free();
}
/*
diff --git a/src/playlist/CuePlaylistPlugin.cxx b/src/playlist/CuePlaylistPlugin.cxx
index 3d8098672..23f2aa82a 100644
--- a/src/playlist/CuePlaylistPlugin.cxx
+++ b/src/playlist/CuePlaylistPlugin.cxx
@@ -21,7 +21,7 @@
#include "CuePlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
#include "tag.h"
-#include "song.h"
+#include "Song.hxx"
#include "input_stream.h"
#include "cue/CueParser.hxx"
#include "TextInputStream.hxx"
@@ -63,12 +63,12 @@ cue_playlist_close(struct playlist_provider *_playlist)
delete playlist;
}
-static struct song *
+static Song *
cue_playlist_read(struct playlist_provider *_playlist)
{
CuePlaylist *playlist = (CuePlaylist *)_playlist;
- struct song *song = playlist->parser.Get();
+ Song *song = playlist->parser.Get();
if (song != NULL)
return song;
diff --git a/src/playlist/DespotifyPlaylistPlugin.cxx b/src/playlist/DespotifyPlaylistPlugin.cxx
index 25f12785a..444a41a13 100644
--- a/src/playlist/DespotifyPlaylistPlugin.cxx
+++ b/src/playlist/DespotifyPlaylistPlugin.cxx
@@ -22,7 +22,7 @@
#include "DespotifyUtils.hxx"
#include "MemoryPlaylistProvider.hxx"
#include "tag.h"
-#include "song.h"
+#include "Song.hxx"
extern "C" {
#include <despotify.h>
@@ -37,7 +37,7 @@ static void
add_song(std::forward_list<SongPointer> &songs, struct ds_track *track)
{
const char *dsp_scheme = despotify_playlist_plugin.schemes[0];
- struct song *song;
+ Song *song;
char uri[128];
char *ds_uri;
@@ -51,7 +51,7 @@ add_song(std::forward_list<SongPointer> &songs, struct ds_track *track)
return;
}
- song = song_remote_new(uri);
+ song = Song::NewRemote(uri);
song->tag = mpd_despotify_tag_from_track(track);
songs.emplace_front(song);
diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
index eaedc738f..b88e4ae8c 100644
--- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx
+++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx
@@ -28,7 +28,7 @@
#include "PlaylistPlugin.hxx"
#include "tag.h"
#include "tag_handler.h"
-#include "song.h"
+#include "Song.hxx"
#include "TagFile.hxx"
#include "cue/CueParser.hxx"
@@ -128,12 +128,12 @@ embcue_playlist_close(struct playlist_provider *_playlist)
g_free(playlist);
}
-static struct song *
+static Song *
embcue_playlist_read(struct playlist_provider *_playlist)
{
struct embcue_playlist *playlist = (struct embcue_playlist *)_playlist;
- struct song *song = playlist->parser->Get();
+ Song *song = playlist->parser->Get();
if (song != NULL)
return song;
@@ -152,13 +152,13 @@ embcue_playlist_read(struct playlist_provider *_playlist)
playlist->parser->Feed(line);
song = playlist->parser->Get();
if (song != NULL)
- return song_replace_uri(song, playlist->filename);
+ return song->ReplaceURI(playlist->filename);
}
playlist->parser->Finish();
song = playlist->parser->Get();
if (song != NULL)
- song = song_replace_uri(song, playlist->filename);
+ song = song->ReplaceURI(playlist->filename);
return song;
}
diff --git a/src/playlist/ExtM3uPlaylistPlugin.cxx b/src/playlist/ExtM3uPlaylistPlugin.cxx
index 923536ea9..72be308a1 100644
--- a/src/playlist/ExtM3uPlaylistPlugin.cxx
+++ b/src/playlist/ExtM3uPlaylistPlugin.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "ExtM3uPlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include "util/StringUtil.hxx"
#include "TextInputStream.hxx"
@@ -105,14 +105,14 @@ extm3u_parse_tag(const char *line)
return tag;
}
-static struct song *
+static Song *
extm3u_read(struct playlist_provider *_playlist)
{
ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
struct tag *tag = NULL;
std::string line;
const char *line_s;
- struct song *song;
+ Song *song;
do {
if (!playlist->tis->ReadLine(line)) {
@@ -134,7 +134,7 @@ extm3u_read(struct playlist_provider *_playlist)
++line_s;
} while (line_s[0] == '#' || *line_s == 0);
- song = song_remote_new(line_s);
+ song = Song::NewRemote(line_s);
song->tag = tag;
return song;
}
diff --git a/src/playlist/LastFMPlaylistPlugin.cxx b/src/playlist/LastFMPlaylistPlugin.cxx
index 496388407..b4933e6a3 100644
--- a/src/playlist/LastFMPlaylistPlugin.cxx
+++ b/src/playlist/LastFMPlaylistPlugin.cxx
@@ -22,7 +22,7 @@
#include "PlaylistPlugin.hxx"
#include "PlaylistRegistry.hxx"
#include "conf.h"
-#include "song.h"
+#include "Song.hxx"
#include "input_stream.h"
#include <glib.h>
@@ -268,7 +268,7 @@ lastfm_close(struct playlist_provider *_playlist)
g_free(playlist);
}
-static struct song *
+static Song *
lastfm_read(struct playlist_provider *_playlist)
{
struct lastfm_playlist *playlist = (struct lastfm_playlist *)_playlist;
diff --git a/src/playlist/M3uPlaylistPlugin.cxx b/src/playlist/M3uPlaylistPlugin.cxx
index e1e0a803b..ee61baa7b 100644
--- a/src/playlist/M3uPlaylistPlugin.cxx
+++ b/src/playlist/M3uPlaylistPlugin.cxx
@@ -20,7 +20,7 @@
#include "config.h"
#include "M3uPlaylistPlugin.hxx"
#include "PlaylistPlugin.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "TextInputStream.hxx"
#include <glib.h>
@@ -51,7 +51,7 @@ m3u_close(struct playlist_provider *_playlist)
g_free(playlist);
}
-static struct song *
+static Song *
m3u_read(struct playlist_provider *_playlist)
{
M3uPlaylist *playlist = (M3uPlaylist *)_playlist;
@@ -68,7 +68,7 @@ m3u_read(struct playlist_provider *_playlist)
++line_s;
} while (line_s[0] == '#' || *line_s == 0);
- return song_remote_new(line_s);
+ return Song::NewRemote(line_s);
}
static const char *const m3u_suffixes[] = {
diff --git a/src/playlist/MemoryPlaylistProvider.cxx b/src/playlist/MemoryPlaylistProvider.cxx
index 4fe3d6cef..c2b6d9312 100644
--- a/src/playlist/MemoryPlaylistProvider.cxx
+++ b/src/playlist/MemoryPlaylistProvider.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "MemoryPlaylistProvider.hxx"
-#include "song.h"
+#include "Song.hxx"
static void
memory_playlist_close(struct playlist_provider *_playlist)
@@ -29,7 +29,7 @@ memory_playlist_close(struct playlist_provider *_playlist)
delete playlist;
}
-static struct song *
+static Song *
memory_playlist_read(struct playlist_provider *_playlist)
{
MemoryPlaylistProvider *playlist = (MemoryPlaylistProvider *)_playlist;
@@ -57,7 +57,7 @@ MemoryPlaylistProvider::MemoryPlaylistProvider(std::forward_list<SongPointer> &&
playlist_provider_init(this, &memory_playlist_plugin);
}
-inline song *
+inline Song *
MemoryPlaylistProvider::Read()
{
if (songs.empty())
diff --git a/src/playlist/MemoryPlaylistProvider.hxx b/src/playlist/MemoryPlaylistProvider.hxx
index 246ffd10a..efbc46fe1 100644
--- a/src/playlist/MemoryPlaylistProvider.hxx
+++ b/src/playlist/MemoryPlaylistProvider.hxx
@@ -25,7 +25,7 @@
#include <forward_list>
-struct song;
+struct Song;
class MemoryPlaylistProvider : public playlist_provider {
std::forward_list<SongPointer> songs;
@@ -33,7 +33,7 @@ class MemoryPlaylistProvider : public playlist_provider {
public:
MemoryPlaylistProvider(std::forward_list<SongPointer> &&_songs);
- song *Read();
+ Song *Read();
};
#endif
diff --git a/src/playlist/PlsPlaylistPlugin.cxx b/src/playlist/PlsPlaylistPlugin.cxx
index faa7212f3..268211b59 100644
--- a/src/playlist/PlsPlaylistPlugin.cxx
+++ b/src/playlist/PlsPlaylistPlugin.cxx
@@ -21,7 +21,7 @@
#include "PlsPlaylistPlugin.hxx"
#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -50,7 +50,7 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
}
while (num_entries > 0) {
- struct song *song;
+ Song *song;
key = g_strdup_printf("File%i", num_entries);
value = g_key_file_get_string(keyfile, "playlist", key,
&error);
@@ -62,7 +62,7 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
}
g_free(key);
- song = song_remote_new(value);
+ song = Song::NewRemote(value);
g_free(value);
key = g_strdup_printf("Title%i", num_entries);
diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx
index 3b69202e6..f96b54ae3 100644
--- a/src/playlist/RssPlaylistPlugin.cxx
+++ b/src/playlist/RssPlaylistPlugin.cxx
@@ -21,7 +21,7 @@
#include "RssPlaylistPlugin.hxx"
#include "MemoryPlaylistProvider.hxx"
#include "input_stream.h"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -60,7 +60,7 @@ struct RssParser {
* The current song. It is allocated after the "location"
* element.
*/
- struct song *song;
+ Song *song;
RssParser()
:state(ROOT) {}
@@ -90,7 +90,7 @@ rss_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
case RssParser::ROOT:
if (g_ascii_strcasecmp(element_name, "item") == 0) {
parser->state = RssParser::ITEM;
- parser->song = song_remote_new("rss:");
+ parser->song = Song::NewRemote("rss:");
parser->tag = TAG_NUM_OF_ITEM_TYPES;
}
@@ -107,12 +107,12 @@ rss_start_element(G_GNUC_UNUSED GMarkupParseContext *context,
replace the existing song's URI,
because that attribute is
immutable */
- struct song *song = song_remote_new(href);
+ Song *song = Song::NewRemote(href);
if (parser->song != NULL) {
song->tag = parser->song->tag;
parser->song->tag = NULL;
- song_free(parser->song);
+ parser->song->Free();
}
parser->song = song;
@@ -142,7 +142,7 @@ rss_end_element(G_GNUC_UNUSED GMarkupParseContext *context,
if (strcmp(parser->song->uri, "rss:") != 0)
parser->songs.emplace_front(parser->song);
else
- song_free(parser->song);
+ parser->song->Free();
parser->state = RssParser::ROOT;
} else
@@ -189,7 +189,7 @@ rss_parser_destroy(gpointer data)
RssParser *parser = (RssParser *)data;
if (parser->state >= RssParser::ITEM)
- song_free(parser->song);
+ parser->song->Free();
}
/*
diff --git a/src/playlist/SoundCloudPlaylistPlugin.cxx b/src/playlist/SoundCloudPlaylistPlugin.cxx
index 5a258865c..7c93a57b3 100644
--- a/src/playlist/SoundCloudPlaylistPlugin.cxx
+++ b/src/playlist/SoundCloudPlaylistPlugin.cxx
@@ -22,7 +22,7 @@
#include "MemoryPlaylistProvider.hxx"
#include "conf.h"
#include "input_stream.h"
-#include "song.h"
+#include "Song.hxx"
#include "tag.h"
#include <glib.h>
@@ -203,12 +203,12 @@ static int handle_end_map(void *ctx)
/* got_url == 1, track finished, make it into a song */
data->got_url = 0;
- struct song *s;
+ Song *s;
struct tag *t;
char *u;
u = g_strconcat(data->stream_url, "?client_id=", soundcloud_config.apikey, NULL);
- s = song_remote_new(u);
+ s = Song::NewRemote(u);
g_free(u);
t = tag_new();
t->time = data->duration / 1000;
diff --git a/src/playlist/XspfPlaylistPlugin.cxx b/src/playlist/XspfPlaylistPlugin.cxx
index 0484246e3..a0bb33f1c 100644
--- a/src/playlist/XspfPlaylistPlugin.cxx
+++ b/src/playlist/XspfPlaylistPlugin.cxx
@@ -60,7 +60,7 @@ struct XspfParser {
* The current song. It is allocated after the "location"
* element.
*/
- struct song *song;
+ Song *song;
XspfParser()
:state(ROOT) {}
@@ -187,7 +187,7 @@ xspf_text(G_GNUC_UNUSED GMarkupParseContext *context,
case XspfParser::LOCATION:
if (parser->song == NULL) {
char *uri = g_strndup(text, text_len);
- parser->song = song_remote_new(uri);
+ parser->song = Song::NewRemote(uri);
g_free(uri);
}
@@ -209,7 +209,7 @@ xspf_parser_destroy(gpointer data)
XspfParser *parser = (XspfParser *)data;
if (parser->state >= XspfParser::TRACK && parser->song != NULL)
- song_free(parser->song);
+ parser->song->Free();
}
/*
diff --git a/src/song.h b/src/song.h
deleted file mode 100644
index 4095317f6..000000000
--- a/src/song.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
- * http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPD_SONG_H
-#define MPD_SONG_H
-
-#include "util/list.h"
-#include "gcc.h"
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <sys/time.h>
-
-#define SONG_FILE "file: "
-#define SONG_TIME "Time: "
-
-struct song {
- /**
- * Pointers to the siblings of this directory within the
- * parent directory. It is unused (undefined) if this song is
- * not in the database.
- *
- * This attribute is protected with the global #db_mutex.
- * Read access in the update thread does not need protection.
- */
- struct list_head siblings;
-
- struct tag *tag;
- struct Directory *parent;
- time_t mtime;
-
- /**
- * Start of this sub-song within the file in milliseconds.
- */
- unsigned start_ms;
-
- /**
- * End of this sub-song within the file in milliseconds.
- * Unused if zero.
- */
- unsigned end_ms;
-
- char uri[sizeof(int)];
-};
-
-/**
- * A dummy #directory instance that is used for "detached" song
- * copies.
- */
-extern struct Directory detached_root;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** allocate a new song with a remote URL */
-struct song *
-song_remote_new(const char *uri);
-
-/** allocate a new song with a local file name */
-struct song *
-song_file_new(const char *path_utf8, struct Directory *parent);
-
-/**
- * allocate a new song structure with a local file name and attempt to
- * load its metadata. If all decoder plugin fail to read its meta
- * data, NULL is returned.
- */
-struct song *
-song_file_load(const char *path_utf8, struct Directory *parent);
-
-/**
- * Replaces the URI of a song object. The given song object is
- * destroyed, and a newly allocated one is returned. It does not
- * update the reference within the parent directory; the caller is
- * responsible for doing that.
- */
-struct song *
-song_replace_uri(struct song *song, const char *uri);
-
-/**
- * Creates a "detached" song object.
- */
-struct song *
-song_detached_new(const char *uri);
-
-/**
- * Creates a duplicate of the song object. If the object is in the
- * database, it creates a "detached" copy of this song, see
- * song_is_detached().
- */
-gcc_malloc
-struct song *
-song_dup_detached(const struct song *src);
-
-void
-song_free(struct song *song);
-
-static inline bool
-song_in_database(const struct song *song)
-{
- return song->parent != NULL;
-}
-
-static inline bool
-song_is_file(const struct song *song)
-{
- return song_in_database(song) || song->uri[0] == '/';
-}
-
-static inline bool
-song_is_detached(const struct song *song)
-{
- assert(song != NULL);
- assert(song_in_database(song));
-
- return song->parent == &detached_root;
-}
-
-/**
- * Returns true if both objects refer to the same physical song.
- */
-gcc_pure
-bool
-song_equals(const struct song *a, const struct song *b);
-
-bool
-song_file_update(struct song *song);
-
-bool
-song_file_update_inarchive(struct song *song);
-
-/**
- * Returns the URI of the song in UTF-8 encoding, including its
- * location within the music directory.
- *
- * The return value is allocated on the heap, and must be freed by the
- * caller.
- */
-char *
-song_get_uri(const struct song *song);
-
-double
-song_get_duration(const struct song *song);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/test/DumpDatabase.cxx b/test/DumpDatabase.cxx
index ddafd626c..e917ec831 100644
--- a/test/DumpDatabase.cxx
+++ b/test/DumpDatabase.cxx
@@ -22,7 +22,7 @@
#include "DatabasePlugin.hxx"
#include "DatabaseSelection.hxx"
#include "Directory.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "PlaylistVector.hxx"
#include "conf.h"
#include "tag.h"
@@ -53,7 +53,7 @@ DumpDirectory(const Directory &directory, GError **)
}
static bool
-DumpSong(song &song, GError **)
+DumpSong(Song &song, GError **)
{
cout << "S " << song.parent->path << "/" << song.uri << endl;
return true;
diff --git a/test/FakeSong.cxx b/test/FakeSong.cxx
index 927a07652..ef7879f1b 100644
--- a/test/FakeSong.cxx
+++ b/test/FakeSong.cxx
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "song.h"
+#include "Song.hxx"
#include "directory.h"
#include "gcc.h"
@@ -26,8 +26,8 @@
struct directory detached_root;
-struct song *
-song_dup_detached(gcc_unused const struct song *src)
+Song *
+song_dup_detached(gcc_unused const Song *src)
{
abort();
}
diff --git a/test/dump_playlist.cxx b/test/dump_playlist.cxx
index 74486cd98..8eb1d6078 100644
--- a/test/dump_playlist.cxx
+++ b/test/dump_playlist.cxx
@@ -19,7 +19,7 @@
#include "config.h"
#include "TagSave.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Directory.hxx"
#include "input_stream.h"
#include "conf.h"
@@ -141,7 +141,7 @@ int main(int argc, char **argv)
struct input_stream *is = NULL;
GError *error = NULL;
struct playlist_provider *playlist;
- struct song *song;
+ Song *song;
if (argc != 3) {
g_printerr("Usage: dump_playlist CONFIG URI\n");
@@ -234,7 +234,7 @@ int main(int argc, char **argv)
if (song->tag != NULL)
tag_save(stdout, song->tag);
- song_free(song);
+ song->Free();
}
/* deinitialize everything */
diff --git a/test/test_queue_priority.cxx b/test/test_queue_priority.cxx
index 8dd1c3f5f..2e544253d 100644
--- a/test/test_queue_priority.cxx
+++ b/test/test_queue_priority.cxx
@@ -1,6 +1,6 @@
#include "config.h"
#include "Queue.hxx"
-#include "song.h"
+#include "Song.hxx"
#include "Directory.hxx"
#include <glib.h>
@@ -10,14 +10,14 @@ Directory detached_root;
Directory::Directory() {}
Directory::~Directory() {}
-struct song *
-song_dup_detached(const struct song *src)
+Song *
+Song::DupDetached() const
{
- return const_cast<song *>(src);
+ return const_cast<Song *>(this);
}
void
-song_free(gcc_unused struct song *song)
+Song::Free()
{
}
@@ -50,7 +50,7 @@ check_descending_priority(const struct queue *queue,
int
main(gcc_unused int argc, gcc_unused char **argv)
{
- static struct song songs[16];
+ static Song songs[16];
struct queue queue(32);