DictListResult Collection::queryInfos( const Coll::Coll& coll, const std::list< std::string >& fetch, const std::list< std::string >& order, int limit_len, int limit_start, const std::list< std::string >& group ) const { assertNonEmptyFetchList( fetch ); xmmsv_t *xorder, *xfetch, *xgroup; xorder = makeStringList( order ); xfetch = makeStringList( fetch ); xgroup = makeStringList( group ); xmmsc_result_t* res = call( connected_, boost::bind( xmmsc_coll_query_infos, conn_, coll.coll_, xorder, limit_start, limit_len, xfetch, xgroup ) ); xmmsv_unref( xorder ); xmmsv_unref( xfetch ); xmmsv_unref( xgroup ); return DictListResult( res, ml_ ); }
xmmsv_t * xmmsv_build_dict_va (const char *firstkey, va_list ap) { const char *key; xmmsv_t *val, *res; res = xmmsv_new_dict (); if (!res) return NULL; key = firstkey; do { val = va_arg (ap, xmmsv_t *); if (!xmmsv_dict_set (res, key, val)) { xmmsv_unref (res); res = NULL; break; } xmmsv_unref (val); key = va_arg (ap, const char *); } while (key); return res; }
static void filter_testcase (const gchar *path, xmmsv_t *list) { gchar *content, *filename; xmmsv_t *dict, *data, *coll; g_assert (g_file_get_contents (path, &content, NULL, NULL)); dict = xmmsv_from_json (content); if (dict == NULL) { g_error ("Could not parse '%s'!\n", path); g_assert_not_reached (); } g_free (content); g_assert (xmmsv_dict_has_key (dict, "medialib")); g_assert (xmmsv_dict_has_key (dict, "collection")); g_assert (xmmsv_dict_has_key (dict, "specification")); g_assert (xmmsv_dict_has_key (dict, "expected")); g_assert (xmmsv_dict_get (dict, "collection", &data)); g_assert (xmmsv_is_type (data, XMMSV_TYPE_DICT)); coll = xmmsv_coll_from_dict (data); xmmsv_dict_set (dict, "collection", coll); xmmsv_unref (coll); filename = g_path_get_basename (path); xmmsv_dict_set_string (dict, "name", filename); g_free (filename); xmmsv_list_append (list, dict); xmmsv_unref (dict); }
/* * call-seq: * Xmms.decode_url(url) -> String * * Decodes a url-encoded string _url_ and returns it in UNKNOWN ENCODING. * Use with caution. */ static VALUE m_decode_url (VALUE self, VALUE str) { const unsigned char *burl; unsigned int blen; xmmsv_t *strv, *decoded; VALUE url = Qnil; strv = xmmsv_new_string (StringValuePtr (str)); decoded = xmmsv_decode_url (strv); if (!decoded) goto out; if (!xmmsv_get_bin (decoded, &burl, &blen)) goto out; url = rb_str_new ((char *) burl, blen); out: if (decoded) xmmsv_unref (decoded); xmmsv_unref (strv); return url; }
static int xmmsc_deserialize_list (xmmsv_t *bb, xmmsv_t **val) { xmmsv_t *list; int32_t len; list = xmmsv_new_list (); if (!_internal_get_from_bb_int32_positive (bb, &len)) { goto err; } while (len--) { xmmsv_t *v; if (xmmsv_bitbuffer_deserialize_value (bb, &v)) { xmmsv_list_append (list, v); } else { goto err; } xmmsv_unref (v); } *val = list; return true; err: x_internal_error ("Message from server did not parse correctly!"); xmmsv_unref (list); return false; }
static void updater_remove_directory (updater_t *updater, GFile *file) { xmmsc_result_t *res; xmmsv_t *univ, *coll; gchar *path, *pattern, *encoded; path = g_file_get_path (file); encoded = xmmsv_encode_url (path); g_free (path); pattern = g_strdup_printf ("file://%s/*", encoded); g_free (encoded); univ = xmmsv_new_coll (XMMS_COLLECTION_TYPE_UNIVERSE); coll = xmmsv_new_coll (XMMS_COLLECTION_TYPE_MATCH); xmmsv_coll_add_operand (coll, univ); xmmsv_coll_attribute_set_string (coll, "field", "url"); xmmsv_coll_attribute_set_string (coll, "value", pattern); xmmsv_coll_attribute_set_string (coll, "case-sensitive", "true"); g_debug ("remove '%s' from mlib", pattern); res = xmmsc_coll_query_ids (updater->conn, coll, NULL, 0, 0); xmmsc_result_notifier_set (res, updater_remove_directory_by_id, updater); xmmsc_result_unref (res); xmmsv_unref (coll); xmmsv_unref (univ); g_free (pattern); }
xmmsv_t * xmmsv_build_list_va (xmmsv_t *first_entry, va_list ap) { xmmsv_t *val, *res; res = xmmsv_new_list (); if (!res) return NULL; val = first_entry; while (val) { if (!xmmsv_list_append (res, val)) { xmmsv_unref (res); res = NULL; break; } xmmsv_unref (val); val = va_arg (ap, xmmsv_t *); } return res; }
static xmmsv_t * convert_ghashtable_to_xmmsv (GHashTable *table, xmms_fetch_spec_t *spec) { GHashTableIter iter; s4_resultset_t *value; const gchar *key; xmmsv_t *ret; g_hash_table_iter_init (&iter, table); ret = xmmsv_new_dict (); while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) { xmmsv_t *converted; if (value == NULL) { continue; } converted = xmms_medialib_query_to_xmmsv (value, spec); xmmsv_dict_set (ret, key, converted); xmmsv_unref (converted); } if (xmmsv_dict_get_size (ret) == 0) { xmmsv_unref (ret); ret = NULL; } return ret; }
/** * Creates a cluster-dict fetch specification. * * @param cluster_by A list of attributes to cluster by * @param cluster_data The fetch specifcation to use when filling the list * @return A cluster-list fetch specification */ xmmsv_t *xmmsv_build_cluster_dict (xmmsv_t *cluster_by, xmmsv_t *cluster_field, xmmsv_t *cluster_data) { xmmsv_t *res = xmmsv_new_dict (); if (res == NULL) return NULL; xmmsv_dict_set_string (res, "type", "cluster-dict"); if (cluster_by != NULL) { xmmsv_dict_set (res, "cluster-by", cluster_by); xmmsv_unref (cluster_by); } if (cluster_field != NULL) { xmmsv_dict_set (res, "cluster-field", cluster_field); xmmsv_unref (cluster_field); } if (cluster_data != NULL) { xmmsv_dict_set (res, "data", cluster_data); xmmsv_unref (cluster_data); } return res; }
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; }
/** * Free the memory owned by the collection. * You probably want to use #xmmsv_coll_unref instead, which handles * reference counting. * * @param coll the collection to free. */ void _xmmsv_coll_free (xmmsv_coll_internal_t *coll) { x_return_if_fail (coll); /* Unref all the operands and attributes */ xmmsv_unref (coll->operands); xmmsv_unref (coll->attributes); xmmsv_unref (coll->idlist); free (coll); }
/* Converts an S4 resultset into an xmmsv_t, based on the fetch specification */ xmmsv_t * xmms_medialib_query_to_xmmsv (s4_resultset_t *set, xmms_fetch_spec_t *spec) { GHashTable *set_table; GList *sets; xmmsv_t *val, *ret = NULL; gint i; switch (spec->type) { case FETCH_COUNT: ret = xmmsv_new_int (s4_resultset_get_rowcount (set)); break; case FETCH_METADATA: ret = metadata_to_xmmsv (set, spec); break; case FETCH_ORGANIZE: ret = xmmsv_new_dict (); for (i = 0; i < spec->data.organize.count; i++) { val = xmms_medialib_query_to_xmmsv (set, spec->data.organize.data[i]); if (val != NULL) { xmmsv_dict_set (ret, spec->data.organize.keys[i], val); xmmsv_unref (val); } } break; case FETCH_CLUSTER_LIST: sets = cluster_list (set, spec); ret = xmmsv_new_list (); for (; sets != NULL; sets = g_list_delete_link (sets, sets)) { set = sets->data; val = xmms_medialib_query_to_xmmsv (set, spec->data.cluster.data); if (val != NULL) { xmmsv_list_append (ret, val); xmmsv_unref (val); } s4_resultset_free (set); } break; case FETCH_CLUSTER_DICT: set_table = cluster_dict (set, spec); ret = convert_ghashtable_to_xmmsv (set_table, spec->data.cluster.data); g_hash_table_destroy (set_table); break; default: g_assert_not_reached (); } return ret; }
static xmmsv_t * xmms_medialib_entry_to_tree (xmms_medialib_session_t *session, xmms_medialib_entry_t entry) { s4_resultset_t *set; s4_val_t *song_id; xmmsv_t *ret, *id; gint i; song_id = s4_val_new_int (entry); set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT, NULL, NULL, S4_FETCH_PARENT | S4_FETCH_DATA); s4_val_free (song_id); ret = xmmsv_new_dict (); for (i = 0; i < s4_resultset_get_rowcount (set); i++) { const s4_result_t *res; res = s4_resultset_get_result (set, 0, 0); while (res != NULL) { xmmsv_t *v_entry = NULL; const s4_val_t *val; const char *s; gint32 i; val = s4_result_get_val (res); if (s4_val_get_str (val, &s)) { v_entry = xmmsv_new_string (s); } else if (s4_val_get_int (val, &i)) { v_entry = xmmsv_new_int (i); } xmms_medialib_tree_add_tuple (ret, s4_result_get_key (res), s4_result_get_src (res), v_entry); xmmsv_unref (v_entry); res = s4_result_next (res); } } s4_resultset_free (set); id = xmmsv_new_int (entry); xmms_medialib_tree_add_tuple (ret, "id", "server", id); xmmsv_unref (id); return ret; }
/** * 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 c_dict_free (RbDict *dict) { xmmsv_unref (dict->real); free (dict); }
static int operator_callback (void *userdata, int cols, char **col_strs, char **col_names) { struct db_info *info = userdata; xmmsv_t *coll = info->coll; xmmsv_t *op; int i; gint id; gint type; for (i = 0; i < cols; i++) { if (!strcmp (col_names[i], "id")) { id = atoi (col_strs[i]); } else if (!strcmp (col_names[i], "type")) { type = atoi (col_strs[i]); } } op = xmms_collection_dbread_operator (info->db, id, type); xmmsv_coll_add_operand (coll, op); xmmsv_unref (op); return 0; }
static gboolean ol_player_xmms2_get_music_length (int *len) { /* ol_log_func (); */ ol_assert_ret (len != NULL, FALSE); if (!ol_player_xmms2_ensure_connection ()) return FALSE; *len = 0; int32_t id = ol_player_xmms2_get_currend_id (); if (id > 0) { xmmsc_result_t *result = xmmsc_medialib_get_info (connection, id); xmmsc_result_wait (result); xmmsv_t *return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value)) { ol_error ("Get music info from XMMS2 failed."); } else { xmmsv_t *dict = xmmsv_propdict_to_dict (return_value, NULL); *len = ol_player_xmms2_get_dict_int (return_value, "duration"); xmmsv_unref (dict); } xmmsc_result_unref (result); } return TRUE; }
static gboolean type_and_msg_to_arg (xmmsv_type_t expected_type, xmmsv_t *argument_list, xmms_object_cmd_arg_t *arg, gint i) { xmmsv_t *arg_value; xmmsv_type_t actual_type; if (argument_list && xmmsv_list_get (argument_list, i, &arg_value)) { xmmsv_ref (arg_value); } else { arg_value = xmmsv_new_none (); } actual_type = xmmsv_get_type (arg_value); if (actual_type != expected_type) { XMMS_DBG ("Expected type %i, but got type %i", expected_type, actual_type); xmmsv_unref (arg_value); return FALSE; } else { arg->values[i] = arg_value; return TRUE; } }
static xmmsv_t * aggregate_random (xmmsv_t *current, gint int_value, const gchar *str_value) { random_data_t *data; guint length; if (current == NULL) { random_data_t init = { 0 }; current = xmmsv_new_bin ((guchar *) &init, sizeof (random_data_t)); } xmmsv_get_bin (current, (const guchar **) &data, &length); data->n++; if (g_random_int_range (0, data->n) == 0) { if (data->data != NULL) { xmmsv_unref (data->data); } if (str_value != NULL) { data->data = xmmsv_new_string (str_value); } else { data->data = xmmsv_new_int (int_value); } } return current; }
/** * Return a collection with several order-operators added. * * @param coll the original collection * @param order list of ordering strings or dicts. * * @return coll with order-operators added */ xmmsv_t * xmmsv_coll_add_order_operators (xmmsv_t *coll, xmmsv_t *order) { xmmsv_list_iter_t *it; xmmsv_t *current, *value; x_api_error_if (coll == NULL, "with a NULL coll", NULL); xmmsv_ref (coll); if (!order) { return coll; } x_api_error_if (!xmmsv_is_type (order, XMMSV_TYPE_LIST), "with a non list order", coll); current = coll; xmmsv_get_list_iter (order, &it); xmmsv_list_iter_last (it); while (xmmsv_list_iter_entry (it, &value)) { xmmsv_t *ordered; ordered = xmmsv_coll_add_order_operator (current, value); xmmsv_unref (current); current = ordered; xmmsv_list_iter_prev (it); } return current; }
static xmmsv_t * aggregate_set (xmmsv_t *current, gint int_value, const gchar *str_value) { set_data_t *data; xmmsv_t *value; gpointer key; guint length; if (current == NULL) { set_data_t init = { .ht = g_hash_table_new (NULL, NULL), .list = xmmsv_new_list () }; current = xmmsv_new_bin ((guchar *) &init, sizeof (set_data_t)); } xmmsv_get_bin (current, (const guchar **) &data, &length); if (str_value != NULL) { value = xmmsv_new_string (str_value); key = (gpointer) str_value; } else { value = xmmsv_new_int (int_value); key = GINT_TO_POINTER (int_value); } if (g_hash_table_lookup (data->ht, key) == NULL) { g_hash_table_insert (data->ht, key, value); xmmsv_list_append (data->list, value); } xmmsv_unref (value); return current; }
/** * List the ids of all media matched by the given collection. * A list of ordering properties can be specified, as well as offsets * to only retrieve part of the result set. * * @param conn The connection to the server. * @param coll The collection used to query. * @param order The list of properties to order by, passed as an #xmmsv_t list of strings. * @param limit_start The offset at which to start retrieving results (0 to disable). * @param limit_len The maximum number of entries to retrieve (0 to disable). */ xmmsc_result_t* xmmsc_coll_query_ids (xmmsc_connection_t *conn, xmmsv_coll_t *coll, xmmsv_t *order, int limit_start, int limit_len) { xmms_ipc_msg_t *msg; x_check_conn (conn, NULL); x_api_error_if (!coll, "with a NULL collection", NULL); /* default to empty ordering */ if (!order) { order = xmmsv_new_list (); } else { xmmsv_ref (order); } msg = xmms_ipc_msg_new (XMMS_IPC_OBJECT_COLLECTION, XMMS_IPC_CMD_QUERY_IDS); xmms_ipc_msg_put_collection (msg, coll); xmms_ipc_msg_put_int32 (msg, limit_start); xmms_ipc_msg_put_int32 (msg, limit_len); xmms_ipc_msg_put_value_list (msg, order); /* purposedly skip typing */ xmmsv_unref (order); return xmmsc_send_msg (conn, msg); }
gboolean cli_jump (cli_context_t *ctx, command_t *cmd) { xmmsc_connection_t *conn = cli_context_xmms_sync (ctx); xmmsv_t *query; gboolean backward = FALSE; playlist_positions_t *positions; command_flag_boolean_get (cmd, "backward", &backward); /* Select by positions */ if (command_arg_positions_get (cmd, 0, &positions, cli_context_current_position (ctx))) { gint pos; if (playlist_positions_get_single (positions, &pos)) { XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_playlist_set_next, conn, pos), XMMS_CALL_P (xmmsc_playback_tickle, conn)); } else { g_printf (_("Cannot jump to several positions!\n")); } playlist_positions_free (positions); /* Select by pattern */ } else if (command_arg_pattern_get (cmd, 0, &query, TRUE)) { query = xmmsv_coll_intersect_with_playlist (query, XMMS_ACTIVE_PLAYLIST); XMMS_CALL_CHAIN (XMMS_CALL_P (xmmsc_coll_query_ids, conn, query, NULL, 0, 0), FUNC_CALL_P (cli_jump_relative, ctx, (backward ? -1 : 1), XMMS_PREV_VALUE)); xmmsv_unref (query); } return FALSE; }
static void xmms_playlist_client_insert_collection (xmms_playlist_t *playlist, const gchar *plname, gint32 pos, xmmsv_coll_t *coll, xmmsv_t *order, xmms_error_t *err) { xmmsv_list_iter_t *it; xmmsv_t *list; list = xmms_collection_query_ids (playlist->colldag, coll, 0, 0, order, err); if (xmms_error_iserror (err)) { return; } xmmsv_get_list_iter (list, &it); xmmsv_list_iter_last (it); while (xmmsv_list_iter_valid (it)) { xmms_medialib_entry_t mid; xmmsv_t *entry; xmmsv_list_iter_entry (it, &entry); xmmsv_get_int (entry, &mid); xmms_playlist_insert_entry (playlist, plname, pos, mid, err); xmmsv_list_iter_prev (it); } xmmsv_unref (list); }
/* Applies an aggregation function to the leafs in an xmmsv dict tree */ static xmmsv_t * aggregate_result (xmmsv_t *val, gint depth, aggregate_function_t aggr_func) { xmmsv_dict_iter_t *it; if (depth == 0) { return aggregate_data (val, aggr_func); } if (val == NULL && depth > 0) { return xmmsv_new_dict(); } /* If it's a dict we call this function recursively on all its values */ xmmsv_get_dict_iter (val, &it); while (xmmsv_dict_iter_valid (it)) { xmmsv_t *entry; xmmsv_dict_iter_pair (it, NULL, &entry); xmmsv_ref (entry); entry = aggregate_result (entry, depth - 1, aggr_func); xmmsv_dict_iter_set (it, entry); xmmsv_unref (entry); xmmsv_dict_iter_next (it); } return val; }
static void currently_playing_update_info (currently_playing_t *entry, xmmsv_t *value) { const gchar *noinfo_fields[] = { "playback_status", "playtime", "position"}; const gchar *time_fields[] = { "duration"}; xmmsv_t *info; gint i; info = xmmsv_propdict_to_dict (value, NULL); enrich_mediainfo (info); /* copy over fields that are not from metadata */ for (i = 0; i < G_N_ELEMENTS (noinfo_fields); i++) { xmmsv_t *copy; if (xmmsv_dict_get (entry->data, noinfo_fields[i], ©)) { xmmsv_dict_set (info, noinfo_fields[i], copy); } } /* pretty format time fields */ for (i = 0; i < G_N_ELEMENTS (time_fields); i++) { gint32 tim; if (xmmsv_dict_entry_get_int (info, time_fields[i], &tim)) { gchar *p = format_time (tim, FALSE); xmmsv_dict_set_string (info, time_fields[i], p); g_free (p); } } xmmsv_unref (entry->data); entry->data = info; }
static void c_free (RbCollection *coll) { xmmsv_unref (coll->real); free (coll); }
void cmd_sort (xmmsc_connection_t *conn, gint argc, gchar **argv) { gchar *playlist; xmmsv_t *sortby; xmmsc_result_t *res; if (argc < 3) { print_error ("Sort needs a property to sort on"); } else if (argc == 3) { playlist = NULL; sortby = xmmsv_make_stringlist (&argv[2], argc - 2); } else { playlist = argv[2]; sortby = xmmsv_make_stringlist (&argv[3], argc - 3); } res = xmmsc_playlist_sort (conn, playlist, sortby); xmmsc_result_wait (res); if (xmmsc_result_iserror (res)) { print_error ("%s", xmmsc_result_get_error (res)); } xmmsc_result_unref (res); xmmsv_unref (sortby); }
void xmms_ipc_msg_destroy (xmms_ipc_msg_t *msg) { x_return_if_fail (msg); xmmsv_unref (msg->bb); free (msg); }
void Dict::setValue( xmmsv_t *newval ) { if( value_ ) { xmmsv_unref( value_ ); } value_ = newval; xmmsv_ref( value_ ); }