diff options
-rw-r--r-- | src/mpdpp.cpp | 326 | ||||
-rw-r--r-- | src/mpdpp.h | 38 |
2 files changed, 215 insertions, 149 deletions
diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 4bcd5aac..7f7fa358 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -29,7 +29,50 @@ MPD::Connection Mpd; -namespace MPD {// +namespace MPD { + +SongIterator::~SongIterator() +{ + // if iterator wasn't fully traversed, clean up + if (m_connection.get() != nullptr) + mpd_response_finish(m_connection.get()); +} + +Song &SongIterator::operator*() +{ + assert(m_connection.get() != nullptr); + assert(!m_song.empty()); + return m_song; +} + +Song *SongIterator::operator->() +{ + assert(m_connection.get() != nullptr); + assert(!m_song.empty()); + return &m_song; +} + +SongIterator &SongIterator::operator++() +{ + assert(m_connection.get() != nullptr); + mpd_song *s = mpd_recv_song(m_connection.get()); + if (s != nullptr) + m_song = Song(s); + else + { + mpd_response_finish(m_connection.get()); + m_song = Song(); + m_connection = nullptr; + } + return *this; +} + +SongIterator SongIterator::operator++(int) +{ + SongIterator it(*this); + ++*this; + return it; +} Connection::Connection() : m_connection(nullptr), m_command_list_active(false), @@ -40,22 +83,19 @@ Connection::Connection() : m_connection(nullptr), { } -Connection::~Connection() -{ - if (m_connection) - mpd_connection_free(m_connection); -} - void Connection::Connect() { assert(!m_connection); try { - m_connection = mpd_connection_new(m_host.c_str(), m_port, m_timeout * 1000); + m_connection = std::shared_ptr<mpd_connection>( + mpd_connection_new(m_host.c_str(), m_port, m_timeout * 1000), + mpd_connection_free + ); checkErrors(); if (!m_password.empty()) SendPassword(); - m_fd = mpd_connection_get_fd(m_connection); + m_fd = mpd_connection_get_fd(m_connection.get()); checkErrors(); } catch (MPD::ClientError &e) @@ -67,13 +107,11 @@ void Connection::Connect() bool Connection::Connected() const { - return m_connection; + return m_connection.get() != nullptr; } void Connection::Disconnect() { - if (m_connection) - mpd_connection_free(m_connection); m_connection = nullptr; m_command_list_active = false; m_idle = false; @@ -81,7 +119,7 @@ void Connection::Disconnect() unsigned Connection::Version() const { - return m_connection ? mpd_connection_get_server_version(m_connection)[1] : 0; + return m_connection ? mpd_connection_get_server_version(m_connection.get())[1] : 0; } void Connection::SetHostname(const std::string &host) @@ -101,7 +139,7 @@ void Connection::SendPassword() assert(m_connection); noidle(); assert(!m_command_list_active); - mpd_run_password(m_connection, m_password.c_str()); + mpd_run_password(m_connection.get(), m_password.c_str()); checkErrors(); } @@ -110,7 +148,7 @@ void Connection::idle() checkConnection(); if (!m_idle) { - mpd_send_idle(m_connection); + mpd_send_idle(m_connection.get()); checkErrors(); } m_idle = true; @@ -120,11 +158,11 @@ int Connection::noidle() { checkConnection(); int flags = 0; - if (m_idle && mpd_send_noidle(m_connection)) + if (m_idle && mpd_send_noidle(m_connection.get())) { m_idle = false; - flags = mpd_recv_idle(m_connection, true); - mpd_response_finish(m_connection); + flags = mpd_recv_idle(m_connection.get(), true); + mpd_response_finish(m_connection.get()); checkErrors(); } return flags; @@ -133,7 +171,7 @@ int Connection::noidle() Statistics Connection::getStatistics() { prechecks(); - mpd_stats *stats = mpd_run_stats(m_connection); + mpd_stats *stats = mpd_run_stats(m_connection.get()); checkErrors(); return Statistics(stats); } @@ -141,7 +179,7 @@ Statistics Connection::getStatistics() Status Connection::getStatus() { prechecks(); - mpd_status *status = mpd_run_status(m_connection); + mpd_status *status = mpd_run_status(m_connection.get()); checkErrors(); return Status(status); } @@ -149,63 +187,63 @@ Status Connection::getStatus() void Connection::UpdateDirectory(const std::string &path) { prechecksNoCommandsList(); - mpd_run_update(m_connection, path.c_str()); + mpd_run_update(m_connection.get(), path.c_str()); checkErrors(); } void Connection::Play() { prechecksNoCommandsList(); - mpd_run_play(m_connection); + mpd_run_play(m_connection.get()); checkErrors(); } void Connection::Play(int pos) { prechecksNoCommandsList(); - mpd_run_play_pos(m_connection, pos); + mpd_run_play_pos(m_connection.get(), pos); checkErrors(); } void Connection::PlayID(int id) { prechecksNoCommandsList(); - mpd_run_play_id(m_connection, id); + mpd_run_play_id(m_connection.get(), id); checkErrors(); } void Connection::Pause(bool state) { prechecksNoCommandsList(); - mpd_run_pause(m_connection, state); + mpd_run_pause(m_connection.get(), state); checkErrors(); } void Connection::Toggle() { prechecksNoCommandsList(); - mpd_run_toggle_pause(m_connection); + mpd_run_toggle_pause(m_connection.get()); checkErrors(); } void Connection::Stop() { prechecksNoCommandsList(); - mpd_run_stop(m_connection); + mpd_run_stop(m_connection.get()); checkErrors(); } void Connection::Next() { prechecksNoCommandsList(); - mpd_run_next(m_connection); + mpd_run_next(m_connection.get()); checkErrors(); } void Connection::Prev() { prechecksNoCommandsList(); - mpd_run_previous(m_connection); + mpd_run_previous(m_connection.get()); checkErrors(); } @@ -213,10 +251,10 @@ void Connection::Move(unsigned from, unsigned to) { prechecks(); if (m_command_list_active) - mpd_send_move(m_connection, from, to); + mpd_send_move(m_connection.get(), from, to); else { - mpd_run_move(m_connection, from, to); + mpd_run_move(m_connection.get(), from, to); checkErrors(); } } @@ -225,10 +263,10 @@ void Connection::Swap(unsigned from, unsigned to) { prechecks(); if (m_command_list_active) - mpd_send_swap(m_connection, from, to); + mpd_send_swap(m_connection.get(), from, to); else { - mpd_run_swap(m_connection, from, to); + mpd_run_swap(m_connection.get(), from, to); checkErrors(); } } @@ -236,28 +274,28 @@ void Connection::Swap(unsigned from, unsigned to) void Connection::Seek(unsigned pos, unsigned where) { prechecksNoCommandsList(); - mpd_run_seek_pos(m_connection, pos, where); + mpd_run_seek_pos(m_connection.get(), pos, where); checkErrors(); } void Connection::Shuffle() { prechecksNoCommandsList(); - mpd_run_shuffle(m_connection); + mpd_run_shuffle(m_connection.get()); checkErrors(); } void Connection::ClearMainPlaylist() { prechecksNoCommandsList(); - mpd_run_clear(m_connection); + mpd_run_clear(m_connection.get()); checkErrors(); } void Connection::ClearPlaylist(const std::string &playlist) { prechecksNoCommandsList(); - mpd_run_playlist_clear(m_connection, playlist.c_str()); + mpd_run_playlist_clear(m_connection.get(), playlist.c_str()); checkErrors(); } @@ -270,10 +308,10 @@ void Connection::AddToPlaylist(const std::string &path, const std::string &file) { prechecks(); if (m_command_list_active) - mpd_send_playlist_add(m_connection, path.c_str(), file.c_str()); + mpd_send_playlist_add(m_connection.get(), path.c_str(), file.c_str()); else { - mpd_run_playlist_add(m_connection, path.c_str(), file.c_str()); + mpd_run_playlist_add(m_connection.get(), path.c_str(), file.c_str()); checkErrors(); } } @@ -282,11 +320,11 @@ void Connection::PlaylistMove(const std::string &path, int from, int to) { prechecks(); if (m_command_list_active) - mpd_send_playlist_move(m_connection, path.c_str(), from, to); + mpd_send_playlist_move(m_connection.get(), path.c_str(), from, to); else { - mpd_send_playlist_move(m_connection, path.c_str(), from, to); - mpd_response_finish(m_connection); + mpd_send_playlist_move(m_connection.get(), path.c_str(), from, to); + mpd_response_finish(m_connection.get()); checkErrors(); } } @@ -294,26 +332,26 @@ void Connection::PlaylistMove(const std::string &path, int from, int to) void Connection::Rename(const std::string &from, const std::string &to) { prechecksNoCommandsList(); - mpd_run_rename(m_connection, from.c_str(), to.c_str()); + mpd_run_rename(m_connection.get(), from.c_str(), to.c_str()); checkErrors(); } void Connection::GetPlaylistChanges(unsigned version, SongConsumer f) { prechecksNoCommandsList(); - mpd_send_queue_changes_meta(m_connection, version); - while (mpd_song *s = mpd_recv_song(m_connection)) + mpd_send_queue_changes_meta(m_connection.get(), version); + while (mpd_song *s = mpd_recv_song(m_connection.get())) f(Song(s)); - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } Song Connection::GetCurrentSong() { prechecksNoCommandsList(); - mpd_send_current_song(m_connection); - mpd_song *s = mpd_recv_song(m_connection); - mpd_response_finish(m_connection); + mpd_send_current_song(m_connection.get()); + mpd_song *s = mpd_recv_song(m_connection.get()); + mpd_response_finish(m_connection.get()); checkErrors(); return Song(s); } @@ -321,9 +359,9 @@ Song Connection::GetCurrentSong() Song Connection::GetSong(const std::string &path) { prechecksNoCommandsList(); - mpd_send_list_all_meta(m_connection, path.c_str()); - mpd_song *s = mpd_recv_song(m_connection); - mpd_response_finish(m_connection); + mpd_send_list_all_meta(m_connection.get(), path.c_str()); + mpd_song *s = mpd_recv_song(m_connection.get()); + mpd_response_finish(m_connection.get()); checkErrors(); return Song(s); } @@ -331,82 +369,82 @@ Song Connection::GetSong(const std::string &path) void Connection::GetPlaylistContent(const std::string &path, SongConsumer f) { prechecksNoCommandsList(); - mpd_send_list_playlist_meta(m_connection, path.c_str()); - while (mpd_song *s = mpd_recv_song(m_connection)) + mpd_send_list_playlist_meta(m_connection.get(), path.c_str()); + while (mpd_song *s = mpd_recv_song(m_connection.get())) f(Song(s)); - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetPlaylistContentNoInfo(const std::string &path, SongConsumer f) { prechecksNoCommandsList(); - mpd_send_list_playlist(m_connection, path.c_str()); - while (mpd_song *s = mpd_recv_song(m_connection)) + mpd_send_list_playlist(m_connection.get(), path.c_str()); + while (mpd_song *s = mpd_recv_song(m_connection.get())) f(Song(s)); - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetSupportedExtensions(std::set<std::string> &acc) { prechecksNoCommandsList(); - mpd_send_command(m_connection, "decoders", NULL); - while (mpd_pair *pair = mpd_recv_pair_named(m_connection, "suffix")) + mpd_send_command(m_connection.get(), "decoders", NULL); + while (mpd_pair *pair = mpd_recv_pair_named(m_connection.get(), "suffix")) { acc.insert(pair->value); - mpd_return_pair(m_connection, pair); + mpd_return_pair(m_connection.get(), pair); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::SetRepeat(bool mode) { prechecksNoCommandsList(); - mpd_run_repeat(m_connection, mode); + mpd_run_repeat(m_connection.get(), mode); checkErrors(); } void Connection::SetRandom(bool mode) { prechecksNoCommandsList(); - mpd_run_random(m_connection, mode); + mpd_run_random(m_connection.get(), mode); checkErrors(); } void Connection::SetSingle(bool mode) { prechecksNoCommandsList(); - mpd_run_single(m_connection, mode); + mpd_run_single(m_connection.get(), mode); checkErrors(); } void Connection::SetConsume(bool mode) { prechecksNoCommandsList(); - mpd_run_consume(m_connection, mode); + mpd_run_consume(m_connection.get(), mode); checkErrors(); } void Connection::SetVolume(unsigned vol) { prechecksNoCommandsList(); - mpd_run_set_volume(m_connection, vol); + mpd_run_set_volume(m_connection.get(), vol); checkErrors(); } std::string Connection::GetReplayGainMode() { prechecksNoCommandsList(); - mpd_send_command(m_connection, "replay_gain_status", NULL); + mpd_send_command(m_connection.get(), "replay_gain_status", NULL); std::string result; - if (mpd_pair *pair = mpd_recv_pair_named(m_connection, "replay_gain_mode")) + if (mpd_pair *pair = mpd_recv_pair_named(m_connection.get(), "replay_gain_mode")) { result = pair->value; - mpd_return_pair(m_connection, pair); + mpd_return_pair(m_connection.get(), pair); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); return result; } @@ -430,15 +468,15 @@ void Connection::SetReplayGainMode(ReplayGainMode mode) rg_mode = ""; break; } - mpd_send_command(m_connection, "replay_gain_mode", rg_mode, NULL); - mpd_response_finish(m_connection); + mpd_send_command(m_connection.get(), "replay_gain_mode", rg_mode, NULL); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::SetCrossfade(unsigned crossfade) { prechecksNoCommandsList(); - mpd_run_crossfade(m_connection, crossfade); + mpd_run_crossfade(m_connection.get(), crossfade); checkErrors(); } @@ -446,10 +484,10 @@ void Connection::SetPriority(const Song &s, int prio) { prechecks(); if (m_command_list_active) - mpd_send_prio_id(m_connection, prio, s.getID()); + mpd_send_prio_id(m_connection.get(), prio, s.getID()); else { - mpd_run_prio_id(m_connection, prio, s.getID()); + mpd_run_prio_id(m_connection.get(), prio, s.getID()); checkErrors(); } } @@ -459,13 +497,13 @@ int Connection::AddSong(const std::string &path, int pos) prechecks(); int id; if (pos < 0) - mpd_send_add_id(m_connection, path.c_str()); + mpd_send_add_id(m_connection.get(), path.c_str()); else - mpd_send_add_id_to(m_connection, path.c_str(), pos); + mpd_send_add_id_to(m_connection.get(), path.c_str(), pos); if (!m_command_list_active) { - id = mpd_recv_song_id(m_connection); - mpd_response_finish(m_connection); + id = mpd_recv_song_id(m_connection.get()); + mpd_response_finish(m_connection.get()); checkErrors(); } else @@ -482,10 +520,10 @@ void Connection::Add(const std::string &path) { prechecks(); if (m_command_list_active) - mpd_send_add(m_connection, path.c_str()); + mpd_send_add(m_connection.get(), path.c_str()); else { - mpd_run_add(m_connection, path.c_str()); + mpd_run_add(m_connection.get(), path.c_str()); checkErrors(); } } @@ -527,13 +565,13 @@ bool Connection::AddRandomSongs(size_t number) { prechecksNoCommandsList(); StringList files; - mpd_send_list_all(m_connection, "/"); - while (mpd_pair *item = mpd_recv_pair_named(m_connection, "file")) + mpd_send_list_all(m_connection.get(), "/"); + while (mpd_pair *item = mpd_recv_pair_named(m_connection.get(), "file")) { files.push_back(item->value); - mpd_return_pair(m_connection, item); + mpd_return_pair(m_connection.get(), item); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); if (number > files.size()) @@ -557,10 +595,10 @@ bool Connection::AddRandomSongs(size_t number) void Connection::Delete(unsigned pos) { prechecks(); - mpd_send_delete(m_connection, pos); + mpd_send_delete(m_connection.get(), pos); if (!m_command_list_active) { - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } } @@ -568,10 +606,10 @@ void Connection::Delete(unsigned pos) void Connection::PlaylistDelete(const std::string &playlist, unsigned pos) { prechecks(); - mpd_send_playlist_delete(m_connection, playlist.c_str(), pos); + mpd_send_playlist_delete(m_connection.get(), playlist.c_str(), pos); if (!m_command_list_active) { - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } } @@ -579,7 +617,7 @@ void Connection::PlaylistDelete(const std::string &playlist, unsigned pos) void Connection::StartCommandsList() { prechecksNoCommandsList(); - mpd_command_list_begin(m_connection, true); + mpd_command_list_begin(m_connection.get(), true); m_command_list_active = true; checkErrors(); } @@ -588,8 +626,8 @@ void Connection::CommitCommandsList() { prechecks(); assert(m_command_list_active); - mpd_command_list_end(m_connection); - mpd_response_finish(m_connection); + mpd_command_list_end(m_connection.get()); + mpd_response_finish(m_connection.get()); m_command_list_active = false; checkErrors(); } @@ -597,22 +635,22 @@ void Connection::CommitCommandsList() void Connection::DeletePlaylist(const std::string &name) { prechecksNoCommandsList(); - mpd_run_rm(m_connection, name.c_str()); + mpd_run_rm(m_connection.get(), name.c_str()); checkErrors(); } void Connection::LoadPlaylist(const std::string &name) { prechecksNoCommandsList(); - mpd_run_load(m_connection, name.c_str()); + mpd_run_load(m_connection.get(), name.c_str()); checkErrors(); } void Connection::SavePlaylist(const std::string &name) { prechecksNoCommandsList(); - mpd_send_save(m_connection, name.c_str()); - mpd_response_finish(m_connection); + mpd_send_save(m_connection.get(), name.c_str()); + mpd_response_finish(m_connection.get()); checkErrors(); } @@ -627,75 +665,75 @@ void Connection::GetPlaylists(StringConsumer f) void Connection::GetList(mpd_tag_type type, StringConsumer f) { prechecksNoCommandsList(); - mpd_search_db_tags(m_connection, type); - mpd_search_commit(m_connection); - while (mpd_pair *item = mpd_recv_pair_tag(m_connection, type)) + mpd_search_db_tags(m_connection.get(), type); + mpd_search_commit(m_connection.get()); + while (mpd_pair *item = mpd_recv_pair_tag(m_connection.get(), type)) { f(std::string(item->value)); - mpd_return_pair(m_connection, item); + mpd_return_pair(m_connection.get(), item); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::StartSearch(bool exact_match) { prechecksNoCommandsList(); - mpd_search_db_songs(m_connection, exact_match); + mpd_search_db_songs(m_connection.get(), exact_match); } void Connection::StartFieldSearch(mpd_tag_type item) { prechecksNoCommandsList(); - mpd_search_db_tags(m_connection, item); + mpd_search_db_tags(m_connection.get(), item); } void Connection::AddSearch(mpd_tag_type item, const std::string &str) const { checkConnection(); - mpd_search_add_tag_constraint(m_connection, MPD_OPERATOR_DEFAULT, item, str.c_str()); + mpd_search_add_tag_constraint(m_connection.get(), MPD_OPERATOR_DEFAULT, item, str.c_str()); } void Connection::AddSearchAny(const std::string &str) const { checkConnection(); - mpd_search_add_any_tag_constraint(m_connection, MPD_OPERATOR_DEFAULT, str.c_str()); + mpd_search_add_any_tag_constraint(m_connection.get(), MPD_OPERATOR_DEFAULT, str.c_str()); } void Connection::AddSearchURI(const std::string &str) const { checkConnection(); - mpd_search_add_uri_constraint(m_connection, MPD_OPERATOR_DEFAULT, str.c_str()); + mpd_search_add_uri_constraint(m_connection.get(), MPD_OPERATOR_DEFAULT, str.c_str()); } void Connection::CommitSearchSongs(SongConsumer f) { prechecksNoCommandsList(); - mpd_search_commit(m_connection); - while (mpd_song *s = mpd_recv_song(m_connection)) + mpd_search_commit(m_connection.get()); + while (mpd_song *s = mpd_recv_song(m_connection.get())) f(Song(s)); - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::CommitSearchTags(StringConsumer f) { prechecksNoCommandsList(); - mpd_search_commit(m_connection); - while (mpd_pair *tag = mpd_recv_pair_tag(m_connection, m_searched_field)) + mpd_search_commit(m_connection.get()); + while (mpd_pair *tag = mpd_recv_pair_tag(m_connection.get(), m_searched_field)) { f(std::string(tag->value)); - mpd_return_pair(m_connection, tag); + mpd_return_pair(m_connection.get(), tag); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetDirectory(const std::string &directory, ItemConsumer f) { prechecksNoCommandsList(); - mpd_send_list_meta(m_connection, directory.c_str()); - while (mpd_entity *item = mpd_recv_entity(m_connection)) + mpd_send_list_meta(m_connection.get(), directory.c_str()); + while (mpd_entity *item = mpd_recv_entity(m_connection.get())) { Item it; switch (mpd_entity_get_type(item)) @@ -718,83 +756,83 @@ void Connection::GetDirectory(const std::string &directory, ItemConsumer f) mpd_entity_free(item); f(std::move(it)); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetDirectoryRecursive(const std::string &directory, SongConsumer f) { prechecksNoCommandsList(); - mpd_send_list_all_meta(m_connection, directory.c_str()); - while (mpd_entity *e = mpd_recv_entity(m_connection)) { + mpd_send_list_all_meta(m_connection.get(), directory.c_str()); + while (mpd_entity *e = mpd_recv_entity(m_connection.get())) { if (mpd_entity_get_type(e) == MPD_ENTITY_TYPE_SONG) f(Song(mpd_song_dup(mpd_entity_get_song(e)))); mpd_entity_free(e); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetDirectories(const std::string &directory, StringConsumer f) { prechecksNoCommandsList(); - mpd_send_list_meta(m_connection, directory.c_str()); - while (mpd_directory *dir = mpd_recv_directory(m_connection)) + mpd_send_list_meta(m_connection.get(), directory.c_str()); + while (mpd_directory *dir = mpd_recv_directory(m_connection.get())) { f(std::string(mpd_directory_get_path(dir))); mpd_directory_free(dir); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetSongs(const std::string &directory, SongConsumer f) { prechecksNoCommandsList(); - mpd_send_list_meta(m_connection, directory.c_str()); - while (mpd_song *s = mpd_recv_song(m_connection)) + mpd_send_list_meta(m_connection.get(), directory.c_str()); + while (mpd_song *s = mpd_recv_song(m_connection.get())) f(Song(s)); - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::GetOutputs(OutputConsumer f) { prechecksNoCommandsList(); - mpd_send_outputs(m_connection); - while (mpd_output *output = mpd_recv_output(m_connection)) + mpd_send_outputs(m_connection.get()); + while (mpd_output *output = mpd_recv_output(m_connection.get())) { f(Output(mpd_output_get_name(output), mpd_output_get_enabled(output))); mpd_output_free(output); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } void Connection::EnableOutput(int id) { prechecksNoCommandsList(); - mpd_run_enable_output(m_connection, id); + mpd_run_enable_output(m_connection.get(), id); checkErrors(); } void Connection::DisableOutput(int id) { prechecksNoCommandsList(); - mpd_run_disable_output(m_connection, id); + mpd_run_disable_output(m_connection.get(), id); checkErrors(); } void Connection::GetURLHandlers(StringConsumer f) { prechecksNoCommandsList(); - mpd_send_list_url_schemes(m_connection); - while (mpd_pair *handler = mpd_recv_pair_named(m_connection, "handler")) + mpd_send_list_url_schemes(m_connection.get()); + while (mpd_pair *handler = mpd_recv_pair_named(m_connection.get(), "handler")) { f(std::string(handler->value)); - mpd_return_pair(m_connection, handler); + mpd_return_pair(m_connection.get(), handler); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } @@ -802,13 +840,13 @@ void Connection::GetTagTypes(StringConsumer f) { prechecksNoCommandsList(); - mpd_send_list_tag_types(m_connection); - while (mpd_pair *tag_type = mpd_recv_pair_named(m_connection, "tagtype")) + mpd_send_list_tag_types(m_connection.get()); + while (mpd_pair *tag_type = mpd_recv_pair_named(m_connection.get(), "tagtype")) { f(std::string(tag_type->value)); - mpd_return_pair(m_connection, tag_type); + mpd_return_pair(m_connection.get(), tag_type); } - mpd_response_finish(m_connection); + mpd_response_finish(m_connection.get()); checkErrors(); } @@ -832,19 +870,19 @@ void Connection::prechecksNoCommandsList() void Connection::checkErrors() const { - mpd_error code = mpd_connection_get_error(m_connection); + mpd_error code = mpd_connection_get_error(m_connection.get()); if (code != MPD_ERROR_SUCCESS) { - std::string msg = mpd_connection_get_error_message(m_connection); + std::string msg = mpd_connection_get_error_message(m_connection.get()); if (code == MPD_ERROR_SERVER) { - mpd_server_error server_code = mpd_connection_get_server_error(m_connection); - bool clearable = mpd_connection_clear_error(m_connection); + mpd_server_error server_code = mpd_connection_get_server_error(m_connection.get()); + bool clearable = mpd_connection_clear_error(m_connection.get()); throw ServerError(server_code, msg, clearable); } else { - bool clearable = mpd_connection_clear_error(m_connection); + bool clearable = mpd_connection_clear_error(m_connection.get()); throw ClientError(code, msg, clearable); } } diff --git a/src/mpdpp.h b/src/mpdpp.h index d067a191..edee3f63 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -21,6 +21,7 @@ #ifndef NCMPCPP_MPDPP_H #define NCMPCPP_MPDPP_H +#include <boost/noncopyable.hpp> #include <cassert> #include <exception> #include <set> @@ -29,8 +30,8 @@ #include <mpd/client.h> #include "song.h" -namespace MPD {// - +namespace MPD { + enum ItemType { itDirectory, itSong, itPlaylist }; enum PlayerState { psUnknown, psStop, psPlay, psPause }; enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum }; @@ -144,7 +145,35 @@ typedef std::vector<Item> ItemList; typedef std::vector<std::string> StringList; typedef std::vector<Output> OutputList; -class Connection +struct SongIterator : std::iterator<std::forward_iterator_tag, Song> +{ + friend class Connection; + + SongIterator() : m_connection(nullptr) { } + ~SongIterator(); + + Song &operator*(); + Song *operator->(); + + SongIterator &operator++(); + SongIterator operator++(int); + + bool operator==(const SongIterator &rhs) { + return m_connection == rhs.m_connection + && m_song == rhs.m_song; + } + bool operator!=(const SongIterator &rhs) { + return !(*this == rhs); + } + +private: + SongIterator(std::shared_ptr<mpd_connection> conn) : m_connection(std::move(conn)) { } + + std::shared_ptr<mpd_connection> m_connection; + Song m_song; +}; + +class Connection : private boost::noncopyable { typedef void (*ErrorHandler) (Connection *, int, const char *, void *); @@ -155,7 +184,6 @@ class Connection public: Connection(); - ~Connection(); void Connect(); bool Connected() const; @@ -265,7 +293,7 @@ private: void prechecksNoCommandsList(); void checkErrors() const; - mpd_connection *m_connection; + std::shared_ptr<mpd_connection> m_connection; bool m_command_list_active; int m_fd; |