summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ceee392)
raw | patch | inline | side by side (parent: ceee392)
author | Max Kellermann <max@duempel.org> | |
Wed, 30 Sep 2009 21:55:38 +0000 (23:55 +0200) | ||
committer | Max Kellermann <max@duempel.org> | |
Wed, 30 Sep 2009 21:55:38 +0000 (23:55 +0200) |
MPD 0.16 supports "delete" with a range argument.
src/mpdclient.c | patch | blob | history | |
src/mpdclient.h | patch | blob | history |
diff --git a/src/mpdclient.c b/src/mpdclient.c
index 33f50184a90e52062d5482abbbd5ab75ff795cca..d60436946a378753538c1711cb653d0ce4bc9c16 100644 (file)
--- a/src/mpdclient.c
+++ b/src/mpdclient.c
return 0;
}
+/**
+ * Fallback for mpdclient_cmd_delete_range() on MPD older than 0.16.
+ * It emulates the "delete range" command with a list of simple
+ * "delete" commands.
+ */
+static gint
+mpdclient_cmd_delete_range_fallback(struct mpdclient *c,
+ unsigned start, unsigned end)
+{
+ if (!mpd_command_list_begin(c->connection, false))
+ return mpdclient_handle_error(c);
+
+ for (; start < end; --end)
+ mpd_send_delete(c->connection, start);
+
+ if (!mpd_command_list_end(c->connection) ||
+ !mpd_response_finish(c->connection))
+ return mpdclient_handle_error(c);
+
+ return 0;
+}
+
+gint
+mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end)
+{
+ struct mpd_status *status;
+
+ if (MPD_ERROR(c))
+ return -1;
+
+ if (mpd_connection_cmp_server_version(c->connection, 0, 16, 0) < 0)
+ return mpdclient_cmd_delete_range_fallback(c, start, end);
+
+ /* MPD 0.16 supports "delete" with a range argument */
+
+ /* send the delete command to mpd; at the same time, get the
+ new status (to verify the playlist id) */
+
+ if (!mpd_command_list_begin(c->connection, false) ||
+ !mpd_send_delete_range(c->connection, start, end) ||
+ !mpd_send_status(c->connection) ||
+ !mpd_command_list_end(c->connection))
+ return mpdclient_handle_error(c);
+
+ c->events |= MPD_IDLE_PLAYLIST;
+
+ status = mpd_recv_status(c->connection);
+ if (status != NULL) {
+ if (c->status != NULL)
+ mpd_status_free(c->status);
+ c->status = status;
+ }
+
+ if (!mpd_response_finish(c->connection))
+ return mpdclient_handle_error(c);
+
+ if (mpd_status_get_queue_length(status) == playlist_length(&c->playlist) - (end - start) &&
+ mpd_status_get_queue_version(status) == c->playlist.version + 1) {
+ /* the cheap route: match on the new playlist length
+ and its version, we can keep our local playlist
+ copy in sync */
+ c->playlist.version = mpd_status_get_queue_version(status);
+
+ /* remove the song from the local playlist */
+ while (end > start) {
+ --end;
+
+ /* remove references to the song */
+ if (c->song == playlist_get(&c->playlist, end))
+ c->song = NULL;
+
+ playlist_remove(&c->playlist, end);
+ }
+ }
+
+ return 0;
+}
+
gint
mpdclient_cmd_move(struct mpdclient *c, gint old_index, gint new_index)
{
diff --git a/src/mpdclient.h b/src/mpdclient.h
index f363aa9d2a05c297dfcfe5b262453b27eed7dd6d..b06c7a042679d97dde9e6e059057cfb8bb5b4c7f 100644 (file)
--- a/src/mpdclient.h
+++ b/src/mpdclient.h
gint mpdclient_cmd_add(struct mpdclient *c, const struct mpd_song *song);
gint mpdclient_cmd_delete(struct mpdclient *c, gint index);
+
+gint
+mpdclient_cmd_delete_range(struct mpdclient *c, unsigned start, unsigned end);
+
gint mpdclient_cmd_move(struct mpdclient *c, gint old_index, gint new_index);
gint mpdclient_cmd_save_playlist(struct mpdclient *c, const gchar *filename);