int mpd_put_current_song(char *buffer) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_song *song; song = mpd_run_current_song(mpd.conn); if(song == NULL) return 0; cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"song_change\", \"data\":{\"pos\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); if(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) != NULL) { cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)); } if(mpd_song_get_tag(song, MPD_TAG_ALBUM, 0) != NULL) { cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)); } cur += json_emit_raw_str(cur, end - cur, "}}"); mpd_song_free(song); mpd_response_finish(mpd.conn); return cur - buffer; }
int mpd_put_queue(char *buffer, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset+MAX_ELEMENTS_PER_PAGE)) RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"queue\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"id\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_id(song)); cur += json_emit_raw_str(cur, end - cur, ",\"pos\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); } mpd_entity_free(entity); } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
int mpd_search(char *buffer, char *searchstr) { int i = 0; char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_song *song; if(mpd_search_db_songs(mpd.conn, false) == false) RETURN_ERROR_AND_RECOVER("mpd_search_db_songs"); else if(mpd_search_add_any_tag_constraint(mpd.conn, MPD_OPERATOR_DEFAULT, searchstr) == false) RETURN_ERROR_AND_RECOVER("mpd_search_add_any_tag_constraint"); else if(mpd_search_commit(mpd.conn) == false) RETURN_ERROR_AND_RECOVER("mpd_search_commit"); else { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"search\",\"data\":[ "); while((song = mpd_recv_song(mpd.conn)) != NULL) { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); mpd_song_free(song); /* Maximum results */ if(i++ >= 300) { cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\"},"); break; } } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); } return cur - buffer; }
static const char *test_emit(void) { char buf[1000], *p = buf; const char *s5 = "{\"foo\":[-123,1.23,true]}"; p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, "{"); p += json_emit_quoted_str(p, &buf[sizeof(buf)] - p, "foo"); p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, ":["); p += json_emit_int(p, &buf[sizeof(buf)] - p, -123); p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, ","); p += json_emit_double(p, &buf[sizeof(buf)] - p, 1.23); p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, ","); p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, "true"); p += json_emit_raw_str(p, &buf[sizeof(buf)] - p, "]}"); ASSERT(strcmp(buf, s5) == 0); ASSERT(p < &buf[sizeof(buf)]); return NULL; }
int mpd_put_browse(char *buffer, char *path, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; unsigned int entity_count = 0; if (!mpd_send_list_meta(mpd.conn, path)) RETURN_ERROR_AND_RECOVER("mpd_send_list_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; if(offset > entity_count) { mpd_entity_free(entity); entity_count++; continue; } else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count) { mpd_entity_free(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":"); cur += json_emit_int(cur, end - cur, entity_count); cur += json_emit_raw_str(cur, end - cur, "} "); break; } switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl)); cur += json_emit_raw_str(cur, end - cur, "},"); break; } mpd_entity_free(entity); entity_count++; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { fprintf(stderr, "MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return 0; } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }