static void __int_xmms_cmd_add (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 1) { XMMS_DBG ("Wrong number of arguments to add (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to add"); return; } GString * argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in add"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in add"); return; } if (!xmms_bin_to_gstring (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in add"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in add"); return; } gchar * retval = xmms_bindata_client_add ((xmms_bindata_t *) object, argval0, &arg->error); if (retval != NULL) { arg->retval = xmms_convert_and_kill_string (retval); } }
static void __int_xmms_cmd_remove (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 1) { XMMS_DBG ("Wrong number of arguments to remove (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to remove"); return; } const char * argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in remove"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in remove"); return; } if (!xmmsv_get_string (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in remove"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in remove"); return; } xmms_bindata_client_remove ((xmms_bindata_t *) object, argval0, &arg->error); arg->retval = xmmsv_new_none (); }
static void __int_xmms_cmd_rehash (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 1) { XMMS_DBG ("Wrong number of arguments to rehash (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to rehash"); return; } gint32 argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in rehash"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in rehash"); return; } if (!xmmsv_get_int (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in rehash"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in rehash"); return; } xmms_medialib_client_rehash ((xmms_medialib_t *) object, argval0, &arg->error); arg->retval = xmmsv_new_none (); }
/* Generate a query string from a query structure. */ static GString* xmms_collection_gen_query (coll_query_t *query) { GString *qstring; /* If no alias base yet (m0), select the default base property */ if (query->alias_base == NULL) { query_make_alias (query, XMMS_COLLQUERY_DEFAULT_BASE, FALSE); } else { /* We are actually interested in the property of m0... Let's make sure it comes from a good source. */ if (query->conditions->len > 0) { g_string_append (query->conditions, " AND "); } g_string_append_printf (query->conditions, "xmms_source_pref (m0.source) = " "(SELECT MIN (xmms_source_pref (n.source)) FROM Media AS n " "WHERE n.id = m0.id AND n.key = '%s')", query->alias_base); } /* Append select and joins */ qstring = g_string_new ("SELECT DISTINCT "); query_string_append_fetch (query, qstring); g_string_append (qstring, " FROM Media AS m0"); g_hash_table_foreach (query->aliases, query_string_append_joins, qstring); /* Append conditions */ g_string_append_printf (qstring, " WHERE m0.key='%s'", query->alias_base); if (query->conditions->len > 0) { g_string_append_printf (qstring, " AND %s", query->conditions->str); } /* Append grouping */ if (xmmsv_list_get_size (query->params->group) > 0) { g_string_append (qstring, " GROUP BY "); query_string_append_alias_list (query, qstring, query->params->group); } /* Append ordering */ /* FIXME: Ordering is Teh Broken (source?) */ if (xmmsv_list_get_size (query->params->order) > 0) { g_string_append (qstring, " ORDER BY "); query_string_append_alias_list (query, qstring, query->params->order); } /* Append limit */ if (query->params->limit_len != 0) { if (query->params->limit_start ) { g_string_append_printf (qstring, " LIMIT %u,%u", query->params->limit_start, query->params->limit_len); } else { g_string_append_printf (qstring, " LIMIT %u", query->params->limit_len); } } return qstring; }
static void __int_xmms_cmd_set_property_int (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 4) { XMMS_DBG ("Wrong number of arguments to set_property_int (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to set_property_int"); return; } gint32 argval0; const char * argval1; const char * argval2; gint32 argval3; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in set_property_int"); return; } if (!xmmsv_get_int (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 1, &t)) { XMMS_DBG ("Missing arg 1 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 1 in set_property_int"); return; } if (!xmmsv_get_string (t, &argval1)) { XMMS_DBG ("Error parsing arg 1 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 1 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 2, &t)) { XMMS_DBG ("Missing arg 2 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 2 in set_property_int"); return; } if (!xmmsv_get_string (t, &argval2)) { XMMS_DBG ("Error parsing arg 2 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 2 in set_property_int"); return; } if (!xmmsv_list_get (arg->args, 3, &t)) { XMMS_DBG ("Missing arg 3 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 3 in set_property_int"); return; } if (!xmmsv_get_int (t, &argval3)) { XMMS_DBG ("Error parsing arg 3 in set_property_int"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 3 in set_property_int"); return; } xmms_medialib_client_set_property_int ((xmms_medialib_t *) object, argval0, argval1, argval2, argval3, &arg->error); arg->retval = xmmsv_new_none (); }
static void __int_xmms_cmd_list (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { if (xmmsv_list_get_size (arg->args) != 0) { XMMS_DBG ("Wrong number of arguments to list (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to list"); return; } arg->retval = xmms_bindata_client_list ((xmms_bindata_t *) object, &arg->error); }
static void __int_xmms_cmd_sync (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { if (xmmsv_list_get_size (arg->args) != 0) { XMMS_DBG ("Wrong number of arguments to sync (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to sync"); return; } xmms_coll_sync_client_sync ((xmms_coll_sync_t *) object, &arg->error); arg->retval = xmmsv_new_none (); }
/** * Get the size of the idlist. * @param coll The collection to update. * @return The size of the idlist. */ int xmmsv_coll_idlist_get_size (xmmsv_t *coll) { x_return_val_if_fail (coll, 0); return xmmsv_list_get_size (coll->value.coll->idlist); }
static xmms_fetch_spec_t * xmms_fetch_spec_new_metadata (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *ret = NULL; s4_sourcepref_t *sp; const gchar *key; xmmsv_t *gets, *fields; gint i, size, aggregate, get; aggregate = normalize_aggregate_function (fetch, err); if (xmms_error_iserror (err)) { return NULL; } fields = normalize_metadata_fields (fetch, err); if (xmms_error_iserror (err)) { return NULL; } gets = normalize_metadata_get (fetch, err); if (xmms_error_iserror (err)) { return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { xmmsv_unref (gets); return NULL; } ret = g_new0 (xmms_fetch_spec_t, 1); ret->type = FETCH_METADATA; ret->data.metadata.aggr_func = aggregate; for (i = 0; i < 4 && xmmsv_list_get_int (gets, i, &get); i++) { ret->data.metadata.get[i] = get; } ret->data.metadata.get_size = i; if (fields != NULL) { size = xmmsv_list_get_size (fields); ret->data.metadata.col_count = size; ret->data.metadata.cols = g_new (gint32, size); for (i = 0; xmmsv_list_get_string (fields, i, &key); i++) { ret->data.metadata.cols[i] = xmms_fetch_info_add_key (info, fetch, key, sp); } } else { /* No fields requested, fetching all available */ ret->data.metadata.col_count = 1; ret->data.metadata.cols = g_new0 (gint32, 1); ret->data.metadata.cols[0] = xmms_fetch_info_add_key (info, fetch, NULL, sp); } s4_sourcepref_unref (sp); xmmsv_unref (gets); return ret; }
void positions_print_list (xmmsc_result_t *res, playlist_positions_t *positions, column_display_t *coldisp, gboolean is_search) { cli_infos_t *infos = column_display_infos_get (coldisp); pl_pos_udata_t udata = { infos, coldisp, NULL, NULL, 0, 0}; xmmsv_t *val; GArray *entries; guint id; const gchar *err; /* FIXME: separate function or merge with list_print_row (lot of if(positions))? */ val = xmmsc_result_get_value (res); if (!xmmsv_get_error (val, &err)) { xmmsv_list_iter_t *it; column_display_prepare (coldisp); if (is_search) { column_display_print_header (coldisp); } entries = g_array_sized_new (FALSE, FALSE, sizeof (guint), xmmsv_list_get_size (val)); for (xmmsv_get_list_iter (val, &it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); if (xmmsv_get_uint (entry, &id)) { g_array_append_val (entries, id); } } udata.entries = entries; playlist_positions_foreach (positions, pos_print_row_cb, TRUE, &udata); } else { g_printf (_("Server error: %s\n"), err); } if (is_search) { column_display_print_footer (coldisp); } else { g_printf ("\n"); column_display_print_footer_totaltime (coldisp); } column_display_free (coldisp); g_array_free (entries, TRUE); cli_infos_loop_resume (infos); xmmsc_result_unref (res); }
static xmmsv_t * normalize_metadata_fields (xmmsv_t *fetch, xmms_error_t *err) { gpointer SENTINEL = GINT_TO_POINTER (0x31337); GHashTable *table; xmmsv_list_iter_t *it; xmmsv_t *fields; if (!xmmsv_dict_get (fetch, "fields", &fields)) { /* No fields means that we should fetch all fields */ return NULL; } if (xmmsv_get_type (fields) != XMMSV_TYPE_LIST) { const gchar *message = "'fields' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (xmmsv_list_get_size (fields) < 1) { /* No fields means that we should fetch all fields */ return NULL; } table = g_hash_table_new (g_str_hash, g_str_equal); xmmsv_get_list_iter (fields, &it); while (xmmsv_list_iter_valid (it)) { const gchar *value = NULL; if (!xmmsv_list_iter_entry_string (it, &value)) { const gchar *message = "'fields' entries must be of string type."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_hash_table_unref (table); return NULL; } if (g_hash_table_lookup (table, (gpointer) value) == SENTINEL) { const gchar *message = "'fields' entries must be unique."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_hash_table_unref (table); return NULL; } g_hash_table_insert (table, (gpointer) value, SENTINEL); xmmsv_list_iter_next (it); } g_hash_table_unref (table); return fields; }
static void _xmms_coll_dump (xmmsv_t *coll, int indent) { xmmsv_t *attributes, *operands, *idlist; const char *type_str; printf ("/* collection */ {\n"); type_str = collection_type_string (xmmsv_coll_get_type (coll)); _xmmsv_coll_dump_indent (indent + 1); printf ("'type': '%s'", type_str); attributes = xmmsv_coll_attributes_get (coll); if (xmmsv_dict_get_size (attributes)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'attributes': "); xmmsv_dump_indented (attributes, indent + 1); } operands = xmmsv_coll_operands_get (coll); if (xmmsv_list_get_size (operands)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'operands': "); xmmsv_dump_indented (operands, indent + 1); } idlist = xmmsv_coll_idlist_get (coll); if (xmmsv_list_get_size (idlist)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'idlist': "); xmmsv_dump_indented (idlist, indent + 1); } printf ("\n"); _xmmsv_coll_dump_indent (indent); printf ("}"); }
/** * Sanitize the 'get' property of a 'metadata' fetch specification. */ static xmmsv_t * normalize_metadata_get (xmmsv_t *fetch, xmms_error_t *err) { xmmsv_list_iter_t *it; xmmsv_t *get, *list; guint32 values; if (!xmmsv_dict_get (fetch, "get", &get) || xmmsv_get_type (get) != XMMSV_TYPE_LIST || xmmsv_list_get_size (get) < 1) { const gchar *message = "'get' must be a non-empty list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } list = xmmsv_new_list (); values = 0; /* Scan for duplicates or invalid values */ xmmsv_get_list_iter (get, &it); while (xmmsv_list_iter_valid (it)) { const gchar *value = NULL; guint32 get_as_int, mask; xmmsv_list_iter_entry_string (it, &value); if (!metadata_value_from_string (value, &get_as_int)) { const gchar *message = "'get' entries must be 'id', 'field', 'value' or 'source'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); xmmsv_unref (list); return NULL; } mask = 1 << (get_as_int + 1); if (values & mask) { const gchar *message = "'get' entries must be unique."; xmms_error_set (err, XMMS_ERROR_INVAL, message); xmmsv_unref (list); return NULL; } values |= mask; xmmsv_list_append_int (list, get_as_int); xmmsv_list_iter_next (it); } return list; }
static void __int_xmms_cmd_move_entry (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 2) { XMMS_DBG ("Wrong number of arguments to move_entry (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to move_entry"); return; } gint32 argval0; const char * argval1; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in move_entry"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in move_entry"); return; } if (!xmmsv_get_int (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in move_entry"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in move_entry"); return; } if (!xmmsv_list_get (arg->args, 1, &t)) { XMMS_DBG ("Missing arg 1 in move_entry"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 1 in move_entry"); return; } if (!xmmsv_get_string (t, &argval1)) { XMMS_DBG ("Error parsing arg 1 in move_entry"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 1 in move_entry"); return; } xmms_medialib_client_move_entry ((xmms_medialib_t *) object, argval0, argval1, &arg->error); arg->retval = xmmsv_new_none (); }
static void __int_xmms_cmd_get_id (xmms_object_t *object, xmms_object_cmd_arg_t *arg) { xmmsv_t *t; if (xmmsv_list_get_size (arg->args) != 1) { XMMS_DBG ("Wrong number of arguments to get_id (%d)", xmmsv_list_get_size (arg->args)); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Wrong number of arguments to get_id"); return; } const char * argval0; if (!xmmsv_list_get (arg->args, 0, &t)) { XMMS_DBG ("Missing arg 0 in get_id"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Missing arg 0 in get_id"); return; } if (!xmmsv_get_string (t, &argval0)) { XMMS_DBG ("Error parsing arg 0 in get_id"); xmms_error_set (&arg->error, XMMS_ERROR_INVAL, "Error parsing arg 0 in get_id"); return; } arg->retval = xmmsv_new_int (xmms_medialib_client_get_id ((xmms_medialib_t *) object, argval0, &arg->error)); }
static s4_sourcepref_t * normalize_source_preferences (xmmsv_t *fetch, s4_sourcepref_t *prefs, xmms_error_t *err) { s4_sourcepref_t *sp; xmmsv_list_iter_t *it; const char **strv; const gchar *str; xmmsv_t *list; gint length, idx; if (!xmmsv_dict_get (fetch, "source-preference", &list)) { return s4_sourcepref_ref (prefs); } if (xmmsv_get_type (list) != XMMSV_TYPE_LIST) { const gchar *message = "'source-preference' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } length = xmmsv_list_get_size (list); if (length == 0) { return s4_sourcepref_ref (prefs); } strv = g_new0 (const char *, length + 1); idx = 0; xmmsv_get_list_iter (list, &it); while (xmmsv_list_iter_valid (it)) { if (!xmmsv_list_iter_entry_string (it, &str)) { const gchar *message = "'source-preference' must be a list of strings."; xmms_error_set (err, XMMS_ERROR_INVAL, message); g_free (strv); return NULL; } strv[idx++] = str; xmmsv_list_iter_next (it); } sp = s4_sourcepref_create (strv); g_free (strv); return sp; }
static void cli_list_print_positions_row (gint pos, void *udata) { cli_list_positions_t *pack = (cli_list_positions_t *) udata; gint id; if (pos >= xmmsv_list_get_size (pack->entries)) { return; } if (xmmsv_list_get_int (pack->entries, pos, &id)) { column_display_set_position (pack->coldisp, pos); XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_medialib_get_info, pack->sync, id), FUNC_CALL_P (cli_list_print_row, pack->coldisp, XMMS_PREV_VALUE)); } }
/* Get length of @playlist or of active playlist if @playlist == NULL. */ static gboolean playlist_length_get (cli_context_t *ctx, const gchar *playlist, gint *length) { xmmsc_connection_t *conn = cli_context_xmms_sync (ctx); *length = -1; if (playlist) { XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_coll_get, conn, playlist, XMMS_COLLECTION_NS_PLAYLISTS), FUNC_CALL_P (playlist_coll_idlist_get_size, XMMS_PREV_VALUE, length)); } else { xmmsv_t *entries = cli_context_active_playlist (ctx); *length = xmmsv_list_get_size (entries); } return *length >= 0; }
static void cli_jump_relative (cli_context_t *ctx, gint inc, xmmsv_t *value) { xmmsc_connection_t *conn = cli_context_xmms_sync (ctx); xmmsv_list_iter_t *it; gint i, plid, id, currpos, plsize; xmmsv_t *playlist; currpos = cli_context_current_position (ctx); playlist = cli_context_active_playlist (ctx); plsize = xmmsv_list_get_size (playlist); /* If no currpos, start jump from beginning */ if (currpos < 0) { currpos = 0; } /* magic trick so we can loop in either direction */ inc += plsize; xmmsv_get_list_iter (value, &it); /* Loop on the playlist */ for (i = (currpos + inc) % plsize; i != currpos; i = (i + inc) % plsize) { xmmsv_list_iter_first (it); xmmsv_list_get_int (playlist, i, &plid); /* Loop on the matched media */ while (xmmsv_list_iter_entry_int (it, &id)) { /* If both match, jump! */ if (plid == id) { XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_playlist_set_next, conn, i), XMMS_CALL_P (xmmsc_playback_tickle, conn)); return; } xmmsv_list_iter_next (it); } } /* No matching media found, don't jump */ g_printf (_("No media matching the pattern in the playlist!\n")); }
/** Sorts the playlist by properties. * * This will sort the list. * @param playlist The playlist to sort. * @param properties Tells xmms_playlist_sort which properties it * should use when sorting. * @param err An #xmms_error_t - needed since xmms_playlist_sort is an ipc * method handler. */ static void xmms_playlist_client_sort (xmms_playlist_t *playlist, const gchar *plname, xmmsv_t *properties, xmms_error_t *err) { xmmsv_t *tmp, *idlist, *val, *spec, *metadata, *get; xmmsv_coll_t *plcoll, *ordered; gint currpos, pos; xmms_medialib_entry_t currid; g_return_if_fail (playlist); g_return_if_fail (properties); if (xmmsv_list_get_size (properties) < 1) { xmms_error_set (err, XMMS_ERROR_NOENT, "need at least one property to sort"); return; } g_mutex_lock (playlist->mutex); plcoll = xmms_playlist_get_coll (playlist, plname, err); if (plcoll == NULL) { xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist!"); g_mutex_unlock (playlist->mutex); return; } currpos = xmms_playlist_coll_get_currpos (plcoll); xmmsv_coll_idlist_get_index (plcoll, currpos, &currid); get = xmmsv_new_list (); xmmsv_list_append_string (get, "id"); metadata = xmmsv_new_dict (); xmmsv_dict_set_string (metadata, "type", "metadata"); xmmsv_dict_set_string (metadata, "aggregate", "first"); xmmsv_dict_set (metadata, "get", get); xmmsv_unref (get); spec = xmmsv_new_dict (); xmmsv_dict_set_string (spec, "type", "cluster-list"); xmmsv_dict_set_string (spec, "cluster-by", "position"); xmmsv_dict_set (spec, "data", metadata); xmmsv_unref (metadata); ordered = xmmsv_coll_add_order_operators (plcoll, properties); MEDIALIB_BEGIN (playlist->medialib); tmp = xmms_medialib_query (session, ordered, spec, err); MEDIALIB_COMMIT (); xmmsv_coll_unref (ordered); xmmsv_unref (spec); if (tmp == NULL) { g_mutex_unlock (playlist->mutex); return; } idlist = xmmsv_coll_idlist_get (plcoll); xmmsv_list_clear (idlist); for (pos = 0; xmmsv_list_get (tmp, pos, &val); pos++) { xmms_medialib_entry_t id; xmmsv_get_int (val, &id); xmmsv_list_append (idlist, val); if (id == currid) { xmms_collection_set_int_attr (plcoll, "position", pos); currpos = pos; } } xmmsv_unref (tmp); XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_SORT, 0, plname); XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname); g_mutex_unlock (playlist->mutex); }
static bool _internal_put_on_bb_collection (xmmsv_t *bb, xmmsv_coll_t *coll) { xmmsv_list_iter_t *it; xmmsv_t *v, *attrs; int n; uint32_t ret; int32_t entry; xmmsv_coll_t *op; if (!bb || !coll) { return false; } /* push type */ if (!xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_get_type (coll))) return false; /* attribute counter and values */ attrs = xmmsv_coll_attributes_get (coll); n = 0; xmmsv_dict_foreach (attrs, _internal_put_on_bb_count_coll_attr, &n); if (!xmmsv_bitbuffer_put_bits (bb, 32, n)) return false; /* needs error checking! */ xmmsv_dict_foreach (attrs, _internal_put_on_bb_append_coll_attr, bb); attrs = NULL; /* no unref needed. */ /* idlist counter and content */ xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_idlist_get_size (coll)); xmmsv_get_list_iter (xmmsv_coll_idlist_get (coll), &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { if (!xmmsv_list_iter_entry_int (it, &entry)) { x_api_error ("Non integer in idlist", 0); } xmmsv_bitbuffer_put_bits (bb, 32, entry); } xmmsv_list_iter_explicit_destroy (it); /* operands counter and objects */ n = 0; if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) { n = xmmsv_list_get_size (xmmsv_coll_operands_get (coll)); } ret = xmmsv_bitbuffer_pos (bb); xmmsv_bitbuffer_put_bits (bb, 32, n); if (n > 0) { xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &it); while (xmmsv_list_iter_entry (it, &v)) { if (!xmmsv_get_coll (v, &op)) { x_api_error ("Non collection operand", 0); } _internal_put_on_bb_int32 (bb, XMMSV_TYPE_COLL); ret = _internal_put_on_bb_collection (bb, op); xmmsv_list_iter_next (it); } } return ret; }