diff options
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); |