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); }
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 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; }
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; }
void xmms_medialib_session_track_garbage (xmms_medialib_session_t *session, xmmsv_t *data) { if (session->vals == NULL) session->vals = xmmsv_new_list (); xmmsv_list_append (session->vals, data); }
/* 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 void create_xmmsv_list_foreach (gpointer data, gpointer userdata) { xmmsv_t *v = (xmmsv_t *) data; xmmsv_t *l = (xmmsv_t *) userdata; xmmsv_list_append (l, v); /* Transfer ownership of 'v' from the GList to the * xmmsv list. */ xmmsv_unref (v); }
/** * Creates a metadata fetch specification. * * @param fields A list of fields to fetch, or NULL to fetch everything * @param get A list of what to get ("id", "key", "value", "source") * @param aggregate The aggregation function to use * @param sourcepref A list of sources, first one has the highest priority * @return A metadata fetch specification */ xmmsv_t *xmmsv_build_metadata (xmmsv_t *fields, xmmsv_t *get, const char *aggregate, xmmsv_t *sourcepref) { xmmsv_t *res = xmmsv_new_dict (); if (res == NULL) return NULL; xmmsv_dict_set_string (res, "type", "metadata"); if (fields != NULL) { if (xmmsv_get_type (fields) == XMMSV_TYPE_STRING) { xmmsv_t *list = xmmsv_new_list (); xmmsv_list_append (list, fields); xmmsv_unref (fields); fields = list; } xmmsv_dict_set (res, "fields", fields); xmmsv_unref (fields); } if (get != NULL) { if (xmmsv_get_type (get) == XMMSV_TYPE_STRING) { xmmsv_t *list = xmmsv_new_list (); xmmsv_list_append (list, get); xmmsv_unref (get); get = list; } xmmsv_dict_set (res, "get", get); xmmsv_unref (get); } if (sourcepref != NULL) { xmmsv_dict_set (res, "source-preference", sourcepref); xmmsv_unref (sourcepref); } if (aggregate != NULL) { xmmsv_dict_set_string (res, "aggregate", aggregate); } return res; }
static int append (xmmsv_t *obj, const char *key, uint32_t key_len, xmmsv_t *value) { if (xmmsv_is_type (obj, XMMSV_TYPE_LIST)) { xmmsv_list_append (obj, value); } else if (xmmsv_is_type (obj, XMMSV_TYPE_DICT) && key) { xmmsv_dict_set (obj, key, value); } else { /* Should never be reached */ assert (0); } xmmsv_unref (value); return 0; }
/** * Helper function to build a list #xmmsv_t containing the * strings from the input array. * * @param array An array of C strings. Must be NULL-terminated if num * is -1. * @param num The optional number of elements to read from the array. Set to * -1 if the array is NULL-terminated. * @return An #xmmsv_t containing the list of strings. Must be * unreffed manually when done. */ xmmsv_t * xmmsv_make_stringlist (char *array[], int num) { xmmsv_t *list, *elem; int i; list = xmmsv_new_list (); if (array) { for (i = 0; (num >= 0 && i < num) || array[i]; i++) { elem = xmmsv_new_string (array[i]); xmmsv_list_append (list, elem); xmmsv_unref (elem); } } return list; }
void xmms_xform_browse_add_entry (xmms_xform_t *xform, const gchar *filename, guint32 flags) { const gchar *url; gchar *efile, *eurl, *t; gint l, isdir; g_return_if_fail (filename); t = strchr (filename, '/'); g_return_if_fail (!t); /* filenames can't contain '/', can they? */ url = xmms_xform_get_url (xform); g_return_if_fail (url); xform->browse_dict = xmmsv_new_dict (); eurl = xmms_medialib_url_encode (url); efile = xmms_medialib_url_encode (filename); /* can't use g_build_filename as we need to preserve slashes stuff like file:/// */ l = strlen (url); if (l && url[l - 1] == '/') { t = g_strdup_printf ("%s%s", eurl, efile); } else { t = g_strdup_printf ("%s/%s", eurl, efile); } isdir = !!(flags & XMMS_XFORM_BROWSE_FLAG_DIR); xmms_xform_browse_add_entry_property_str (xform, "path", t); xmms_xform_browse_add_entry_property_int (xform, "isdir", isdir); if (xform->browse_list == NULL) { xform->browse_list = xmmsv_new_list (); } xmmsv_list_append (xform->browse_list, xform->browse_dict); xmmsv_unref (xform->browse_dict); g_free (t); g_free (efile); g_free (eurl); }
static gboolean xmms_main_client_list_foreach (xmms_plugin_t *plugin, gpointer data) { xmmsv_t *list, *dict; list = (xmmsv_t *) data; dict = xmmsv_build_dict ( XMMSV_DICT_ENTRY_STR ("name", xmms_plugin_name_get (plugin)), XMMSV_DICT_ENTRY_STR ("shortname", xmms_plugin_shortname_get (plugin)), XMMSV_DICT_ENTRY_STR ("version", xmms_plugin_version_get (plugin)), XMMSV_DICT_ENTRY_STR ("description", xmms_plugin_description_get (plugin)), XMMSV_DICT_ENTRY_INT ("type", xmms_plugin_type_get (plugin)), XMMSV_DICT_END); xmmsv_list_append (list, dict); xmmsv_unref (dict); return TRUE; }
/** * Add the operand to the given collection. * @param coll The collection to add the operand to. * @param op The operand to add. */ void xmmsv_coll_add_operand (xmmsv_t *coll, xmmsv_t *op) { xmmsv_list_iter_t *it; x_return_if_fail (coll); x_return_if_fail (op); /* we used to check if it already existed here before */ if (!xmmsv_get_list_iter (coll->value.coll->operands, &it)) return; if (_xmmsv_coll_operand_find (it, op)) { x_api_warning ("with an operand already in operand list"); xmmsv_list_iter_explicit_destroy (it); return; } xmmsv_list_iter_explicit_destroy (it); xmmsv_list_append (coll->value.coll->operands, op); }
xmmsv_t * duplicate_list_value (xmmsv_t *val) { xmmsv_t *dup_val; xmmsv_list_iter_t *it; xmmsv_t *v; xmmsv_t *new_elem; x_return_val_if_fail (xmmsv_get_list_iter (val, &it), NULL); dup_val = xmmsv_new_list (); while (xmmsv_list_iter_entry (it, &v)) { new_elem = xmmsv_copy (v); xmmsv_list_append (dup_val, new_elem); xmmsv_unref (new_elem); xmmsv_list_iter_next (it); } xmmsv_list_iter_explicit_destroy (it); return dup_val; }
/** 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); }