diff --git a/include/mpd/playlist.h b/include/mpd/playlist.h index 3e3fe4e..c6fa5fa 100644 --- a/include/mpd/playlist.h +++ b/include/mpd/playlist.h @@ -599,6 +599,63 @@ mpd_run_rm(struct mpd_connection *connection, const char *name); bool mpd_send_playlistlength(struct mpd_connection *connection, const char *name); + +/** + * Search for songs in the stored playlist. + * A window may be specified with mpd_playlist_search_add_window(). + * Send the search command with mpd_playlist_search_commit(), and read the + * response items with mpd_recv_song(). + * + * @param connection the connection to MPD + * @param name the name of the stored playlist + * @param expression the expression string; must be enclosed in + * parentheses + * @return true on success, false on error + * + * @since libmpdclient 2.23, MPD 0.24 + */ +bool +mpd_playlist_search_begin(struct mpd_connection *connection, const char *name, + const char *expression); + +/** + * Request only a portion of the result set. + * + * @param connection a #mpd_connection + * @param start the start offset (including) + * @param end the end offset (not including) + * value "UINT_MAX" makes the end of the range open + * @return true on success, false on error + * + * @since libmpdclient 2.23, MPD 0.24 + */ +bool +mpd_playlist_search_add_window(struct mpd_connection *connection, + unsigned start, unsigned end); + +/** + * Starts the real search. + * + * @param connection the connection to MPD + * @return true on success, false on error + * + * @since libmpdclient 2.23, MPD 0.24 + */ +bool +mpd_playlist_search_commit(struct mpd_connection *connection); + +/** + * Cancels the search request before you have called + * mpd_playlist_search_commit(). Call this to clear the current search + * request. + * + * @param connection the connection to MPD + * + * @since libmpdclient 2.23, MPD 0.24 + */ +void +mpd_playlist_search_cancel(struct mpd_connection *connection); + #ifdef __cplusplus } #endif diff --git a/libmpdclient.ld b/libmpdclient.ld index 7a2add0..3ab36c0 100644 --- a/libmpdclient.ld +++ b/libmpdclient.ld @@ -271,6 +271,10 @@ global: mpd_parse_queue_save_mode; mpd_lookup_queue_save_mode; mpd_send_playlistlength; + mpd_playlist_search_begin; + mpd_playlist_search_add_window; + mpd_playlist_search_commit; + mpd_playlist_search_cancel; /* mpd/queue.h */ mpd_send_list_queue_meta; diff --git a/src/cplaylist.c b/src/cplaylist.c index c7d889d..7143e61 100644 --- a/src/cplaylist.c +++ b/src/cplaylist.c @@ -2,12 +2,16 @@ // Copyright The Music Player Daemon Project #include +#include #include #include #include +#include "internal.h" #include "isend.h" +#include "request.h" #include "run.h" +#include #include #include #include @@ -319,3 +323,62 @@ mpd_send_playlistlength(struct mpd_connection *connection, const char *name) { return mpd_send_command(connection, "playlistlength", name, NULL); } + +bool +mpd_playlist_search_begin(struct mpd_connection *connection, const char *name, + const char *expression) +{ + assert(name != NULL); + assert(expression != NULL); + + if (!mpd_request_begin(connection)) + return false; + + char *arg_name = mpd_sanitize_arg(name); + if (arg_name == NULL) { + mpd_error_code(&connection->error, MPD_ERROR_OOM); + return false; + } + + char *arg_expression = mpd_sanitize_arg(expression); + if (arg_expression == NULL) { + mpd_error_code(&connection->error, MPD_ERROR_OOM); + free(arg_name); + return false; + } + + const size_t size = 17 + strlen(arg_name) + 3 + strlen(arg_expression) + 2; + connection->request = malloc(size); + if (connection->request == NULL) { + mpd_error_code(&connection->error, MPD_ERROR_OOM); + free(arg_name); + free(arg_expression); + return false; + } + + snprintf(connection->request, size, "searchplaylist \"%s\" \"%s\"", + arg_name, arg_expression); + + free(arg_name); + free(arg_expression); + return true; +} + +bool +mpd_playlist_search_add_window(struct mpd_connection *connection, + unsigned start, unsigned end) +{ + return mpd_request_add_window(connection, start, end); +} + +bool +mpd_playlist_search_commit(struct mpd_connection *connection) +{ + return mpd_request_commit(connection); +} + +void +mpd_playlist_search_cancel(struct mpd_connection *connection) +{ + mpd_request_cancel(connection); +}