summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mpdpp.cpp326
-rw-r--r--src/mpdpp.h38
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;