mpd: use unique_ptr for storage of mpd_connection

master
Andrzej Rybczak 12 years ago
parent 72726831ca
commit cb6d8c69cd
  1. 17
      src/mpdpp.cpp
  2. 30
      src/mpdpp.h

@ -45,10 +45,7 @@ void Connection::Connect()
assert(!m_connection); assert(!m_connection);
try try
{ {
m_connection = std::shared_ptr<mpd_connection>( m_connection.reset(mpd_connection_new(m_host.c_str(), m_port, m_timeout * 1000));
mpd_connection_new(m_host.c_str(), m_port, m_timeout * 1000),
mpd_connection_free
);
checkErrors(); checkErrors();
if (!m_password.empty()) if (!m_password.empty())
SendPassword(); SendPassword();
@ -298,7 +295,7 @@ SongIterator Connection::GetPlaylistChanges(unsigned version)
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_send_queue_changes_meta(m_connection.get(), version); mpd_send_queue_changes_meta(m_connection.get(), version);
checkErrors(); checkErrors();
return SongIterator(m_connection, mpd_recv_song); return SongIterator(m_connection.get(), mpd_recv_song);
} }
Song Connection::GetCurrentSong() Song Connection::GetCurrentSong()
@ -325,7 +322,7 @@ SongIterator Connection::GetPlaylistContent(const std::string &path)
{ {
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_send_list_playlist_meta(m_connection.get(), path.c_str()); mpd_send_list_playlist_meta(m_connection.get(), path.c_str());
SongIterator result(m_connection, mpd_recv_song); SongIterator result(m_connection.get(), mpd_recv_song);
checkErrors(); checkErrors();
return result; return result;
} }
@ -334,7 +331,7 @@ SongIterator Connection::GetPlaylistContentNoInfo(const std::string &path)
{ {
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_send_list_playlist(m_connection.get(), path.c_str()); mpd_send_list_playlist(m_connection.get(), path.c_str());
SongIterator result(m_connection, mpd_recv_song); SongIterator result(m_connection.get(), mpd_recv_song);
checkErrors(); checkErrors();
return result; return result;
} }
@ -664,7 +661,7 @@ SongIterator Connection::CommitSearchSongs()
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_search_commit(m_connection.get()); mpd_search_commit(m_connection.get());
checkErrors(); checkErrors();
return SongIterator(m_connection, mpd_recv_song); return SongIterator(m_connection.get(), mpd_recv_song);
} }
void Connection::CommitSearchTags(StringConsumer f) void Connection::CommitSearchTags(StringConsumer f)
@ -742,7 +739,7 @@ SongIterator Connection::GetSongs(const std::string &directory)
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_send_list_meta(m_connection.get(), directory.c_str()); mpd_send_list_meta(m_connection.get(), directory.c_str());
checkErrors(); checkErrors();
return SongIterator(m_connection, mpd_recv_song); return SongIterator(m_connection.get(), mpd_recv_song);
} }
OutputIterator Connection::GetOutputs() OutputIterator Connection::GetOutputs()
@ -750,7 +747,7 @@ OutputIterator Connection::GetOutputs()
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_send_outputs(m_connection.get()); mpd_send_outputs(m_connection.get());
checkErrors(); checkErrors();
return OutputIterator(m_connection, mpd_recv_output); return OutputIterator(m_connection.get(), mpd_recv_output);
} }
void Connection::EnableOutput(int id) void Connection::EnableOutput(int id)

@ -21,7 +21,6 @@
#ifndef NCMPCPP_MPDPP_H #ifndef NCMPCPP_MPDPP_H
#define NCMPCPP_MPDPP_H #define NCMPCPP_MPDPP_H
#include <boost/noncopyable.hpp>
#include <cassert> #include <cassert>
#include <exception> #include <exception>
#include <set> #include <set>
@ -148,7 +147,7 @@ struct Output
return true; return true;
else if (!empty() && !rhs.empty()) else if (!empty() && !rhs.empty())
return id() == rhs.id() return id() == rhs.id()
&& std::strcmp(name(), rhs.name()) == 0 && strcmp(name(), rhs.name()) == 0
&& enabled() == rhs.enabled(); && enabled() == rhs.enabled();
else else
return false; return false;
@ -200,22 +199,22 @@ struct Iterator : std::iterator<std::forward_iterator_tag, DestT>
Iterator() : m_connection(nullptr), m_fetch_source(nullptr) { } Iterator() : m_connection(nullptr), m_fetch_source(nullptr) { }
~Iterator() ~Iterator()
{ {
if (m_connection) if (m_connection != nullptr)
finish(); finish();
} }
void finish() void finish()
{ {
// clean up // clean up
assert(m_connection); assert(m_connection != nullptr);
mpd_response_finish(m_connection.get()); mpd_response_finish(m_connection);
m_object = DestT(); m_object = DestT();
m_connection = nullptr; m_connection = nullptr;
} }
DestT &operator*() const DestT &operator*() const
{ {
assert(m_connection); assert(m_connection != nullptr);
if (m_object.empty()) if (m_object.empty())
throw std::runtime_error("empty object"); throw std::runtime_error("empty object");
return const_cast<DestT &>(m_object); return const_cast<DestT &>(m_object);
@ -227,9 +226,9 @@ struct Iterator : std::iterator<std::forward_iterator_tag, DestT>
Iterator &operator++() Iterator &operator++()
{ {
assert(m_connection); assert(m_connection != nullptr);
assert(m_fetch_source != nullptr); assert(m_fetch_source != nullptr);
auto src = m_fetch_source(m_connection.get()); auto src = m_fetch_source(m_connection);
if (src != nullptr) if (src != nullptr)
m_object = DestT(src); m_object = DestT(src);
else else
@ -254,14 +253,14 @@ struct Iterator : std::iterator<std::forward_iterator_tag, DestT>
} }
private: private:
Iterator(std::shared_ptr<mpd_connection> conn, SourceFetcher fetch_source) Iterator(mpd_connection *connection, SourceFetcher fetch_source)
: m_connection(std::move(conn)), m_fetch_source(fetch_source) : m_connection(connection), m_fetch_source(fetch_source)
{ {
// get the first element // get the first element
++*this; ++*this;
} }
std::shared_ptr<mpd_connection> m_connection; mpd_connection *m_connection;
SourceFetcher m_fetch_source; SourceFetcher m_fetch_source;
DestT m_object; DestT m_object;
}; };
@ -269,7 +268,7 @@ private:
typedef Iterator<Song, mpd_song> SongIterator; typedef Iterator<Song, mpd_song> SongIterator;
typedef Iterator<Output, mpd_output> OutputIterator; typedef Iterator<Output, mpd_output> OutputIterator;
class Connection : private boost::noncopyable class Connection
{ {
typedef std::function<void(Item)> ItemConsumer; typedef std::function<void(Item)> ItemConsumer;
typedef std::function<void(Output)> OutputConsumer; typedef std::function<void(Output)> OutputConsumer;
@ -381,13 +380,18 @@ public:
int noidle(); int noidle();
private: private:
struct ConnectionDeleter {
void operator()(mpd_connection *connection) {
mpd_connection_free(connection);
}
};
void checkConnection() const; void checkConnection() const;
void prechecks(); void prechecks();
void prechecksNoCommandsList(); void prechecksNoCommandsList();
void checkErrors() const; void checkErrors() const;
std::shared_ptr<mpd_connection> m_connection; std::unique_ptr<mpd_connection, ConnectionDeleter> m_connection;
bool m_command_list_active; bool m_command_list_active;
int m_fd; int m_fd;

Loading…
Cancel
Save