static gint xmms_browse_list_sortfunc (xmmsv_t **a, xmmsv_t **b) { xmmsv_t *val1, *val2; const gchar *s1, *s2; int r1, r2; g_return_val_if_fail (xmmsv_is_type (*a, XMMSV_TYPE_DICT), 0); g_return_val_if_fail (xmmsv_is_type (*b, XMMSV_TYPE_DICT), 0); r1 = xmmsv_dict_get (*a, "intsort", &val1); r2 = xmmsv_dict_get (*b, "intsort", &val2); if (r1 && r2) { gint i1, i2; if (!xmmsv_get_int (val1, &i1)) return 0; if (!xmmsv_get_int (val2, &i2)) return 0; return i1 > i2; } if (!xmmsv_dict_get (*a, "path", &val1)) return 0; if (!xmmsv_dict_get (*b, "path", &val2)) return 0; if (!xmmsv_get_string (val1, &s1)) return 0; if (!xmmsv_get_string (val2, &s2)) return 0; return xmms_natcmp (s1, s2); }
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; }
static int32_t xmms_visualization_client_set_properties (xmms_visualization_t *vis, int32_t id, xmmsv_t* prop, xmms_error_t *err) { xmms_vis_client_t *c; xmmsv_dict_iter_t *it; const gchar *key, *valstr; xmmsv_t *value; x_fetch_client (id); if (!xmmsv_is_type (prop, XMMSV_TYPE_DICT)) { xmms_error_set (err, XMMS_ERROR_INVAL, "properties must be sent as a dict!"); } else { /* record every pair */ xmmsv_get_dict_iter (prop, &it); while (xmmsv_dict_iter_valid (it)) { if (!xmmsv_dict_iter_pair (it, &key, &value)) { xmms_error_set (err, XMMS_ERROR_INVAL, "key-value property pair could not be read!"); } else if (!xmmsv_get_string (value, &valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property value could not be read!"); } else if (!property_set (&c->prop, key, valstr)) { xmms_error_set (err, XMMS_ERROR_INVAL, "property could not be set!"); } xmmsv_dict_iter_next (it); } /* TODO: propagate new format to xform! */ } x_release_client (); return (++c->format); }
/** * 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 * xmmsv_coll_normalize_order_arguments (xmmsv_t *value) { xmmsv_t *order; const char *key; if (value == NULL) { return NULL; } if (xmmsv_is_type (value, XMMSV_TYPE_DICT)) { return xmmsv_ref (value); } x_api_error_if (!xmmsv_get_string (value, &key), "order entry must be string or dict", NULL); order = xmmsv_new_dict (); if (key[0] == '-') { xmmsv_dict_set_string (order, "direction", "DESC"); key++; } if (strcmp (key, "random") == 0) { xmmsv_dict_set_string (order, "type", "random"); } else if (strcmp (key, "id") == 0) { xmmsv_dict_set_string (order, "type", "id"); } else { xmmsv_dict_set_string (order, "type", "value"); xmmsv_dict_set_string (order, "field", key); } return order; }
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 xmmsv_t * parse_collection (xmmsv_t *dict) { xmmsv_coll_type_t type = 0; xmmsv_t *coll; xmmsv_t *attributes, *operands, *list; const char *name; assert (xmmsv_is_type (dict, XMMSV_TYPE_DICT)); xmmsv_dict_entry_get_string (dict, "type", &name); assert (collection_type_from_string (name, &type)); coll = xmmsv_new_coll (type); if (xmmsv_dict_get (dict, "attributes", &attributes)) parse_attributes (coll, attributes); if (xmmsv_dict_get (dict, "operands", &operands)) parse_operands (coll, operands); if (xmmsv_dict_get (dict, "idlist", &list)) parse_idlist (coll, list); return coll; }
static VALUE coll_get (xmmsv_t *val) { if (!xmmsv_is_type (val, XMMSV_TYPE_COLL)) rb_raise (eValueError, "cannot retrieve value"); return TO_XMMS_CLIENT_COLLECTION (val); }
/** * Retrieve an integer attribute from the given collection. * * @param coll The collection to retrieve the attribute from. * @param key The name of the attribute. * @param value The value of the attribute if found (owned by the collection). * @return 1 if the attribute was found, 0 otherwise */ int xmmsv_coll_attribute_get_int32 (xmmsv_t *coll, const char *key, int32_t *val) { int64_t raw_val; x_return_val_if_fail (xmmsv_is_type (coll, XMMSV_TYPE_COLL), 0); if (xmmsv_dict_entry_get_int (coll->value.coll->attributes, key, &raw_val)) { *val = INT64_TO_INT32 (raw_val); return true; } return false; }
/** * Replace all attributes in the given collection. * * @param coll The collection in which to set the attribute. * @param attributes The new attributes. */ void xmmsv_coll_attributes_set (xmmsv_t *coll, xmmsv_t *attributes) { xmmsv_t *old; x_return_if_fail (coll); x_return_if_fail (attributes); x_return_if_fail (xmmsv_is_type (attributes, XMMSV_TYPE_DICT)); old = coll->value.coll->attributes; coll->value.coll->attributes = xmmsv_ref (attributes); xmmsv_unref (old); }
static void parse_idlist (xmmsv_t *coll, xmmsv_t *list) { xmmsv_list_iter_t *it; int32_t id; assert (xmmsv_is_type (list, XMMSV_TYPE_LIST)); assert (xmmsv_get_list_iter (list, &it)); while (xmmsv_list_iter_entry_int (it, &id)) { assert (xmmsv_coll_idlist_append (coll, id)); xmmsv_list_iter_next (it); } }
static void parse_attributes (xmmsv_t *coll, xmmsv_t *attrs) { xmmsv_dict_iter_t *it; xmmsv_t *entry; const char *key; assert (xmmsv_is_type (attrs, XMMSV_TYPE_DICT)); assert (xmmsv_get_dict_iter (attrs, &it)); while (xmmsv_dict_iter_pair (it, &key, &entry)) { xmmsv_coll_attribute_set_value (coll, key, entry); xmmsv_dict_iter_next (it); } }
static void _sum_len_string_dict (const char *key, xmmsv_t *val, void *userdata) { const char *arg; int *extra = (int *) userdata; if (xmmsv_is_type (val, XMMSV_TYPE_NONE)) { *extra += strlen (key) + 1; /* Leave room for the ampersand. */ } else if (xmmsv_get_string (val, &arg)) { /* Leave room for the equals sign and ampersand. */ *extra += strlen (key) + strlen (arg) + 2; } else { x_api_warning ("with non-string argument"); } }
static void on_collection_changed (xmms_object_t *object, xmmsv_t *val, gpointer udata) { xmms_playlist_t *playlist = (xmms_playlist_t *) udata; const gchar *ns, *name; g_return_if_fail (playlist); g_return_if_fail (xmmsv_is_type (val, XMMSV_TYPE_DICT)); g_return_if_fail (xmmsv_dict_entry_get_string (val, "namespace", &ns)); if (strcmp (ns, XMMS_COLLECTION_NS_PLAYLISTS) != 0) { /* Not a playlist, not our concern... */ return; } g_return_if_fail (xmmsv_dict_entry_get_string (val, "name", &name)); XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_UPDATE, 0, name); }
static void parse_operands (xmmsv_t *coll, xmmsv_t *operands) { xmmsv_list_iter_t *it; xmmsv_t *entry; assert (xmmsv_is_type (operands, XMMSV_TYPE_LIST)); assert (xmmsv_get_list_iter (operands, &it)); while (xmmsv_list_iter_entry (it, &entry)) { xmmsv_t *operand; operand = parse_collection (entry); assert (operand != NULL); xmmsv_coll_add_operand (coll, operand); xmmsv_unref (operand); xmmsv_list_iter_next (it); } }
/** * TODO: Should check for '/' in the key, and set source if found. */ static void populate_medialib (xmms_medialib_t *medialib, xmmsv_t *content) { xmms_medialib_session_t *session; xmms_medialib_entry_t entry = 0; xmmsv_list_iter_t *lit; session = xmms_medialib_session_begin (medialib); xmmsv_get_list_iter (content, &lit); while (xmmsv_list_iter_valid (lit)) { xmmsv_dict_iter_t *dit; xmms_error_t err; xmmsv_t *dict; xmms_error_reset (&err); xmmsv_list_iter_entry (lit, &dict); if (xmmsv_dict_has_key (dict, "url")) { const gchar *url; xmmsv_dict_entry_get_string (dict, "url", &url); entry = xmms_medialib_entry_new (session, url, &err); } else { gchar *url; url = g_strdup_printf ("file://%d.mp3", entry + 1); entry = xmms_medialib_entry_new (session, url, &err); g_free (url); } xmmsv_get_dict_iter (dict, &dit); while (xmmsv_dict_iter_valid (dit)) { const gchar *key, *source; gchar **parts; xmmsv_t *container; xmmsv_dict_iter_pair (dit, &key, &container); parts = g_strsplit (key, "/", 2); key = (parts[1] != NULL) ? parts[1] : key; source = (parts[1] != NULL) ? parts[0] : NULL; if (xmmsv_is_type (container, XMMSV_TYPE_STRING)) { const gchar *value; xmmsv_get_string (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_str_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_str (session, entry, key, value); } } else { gint32 value; xmmsv_get_int (container, &value); if (source != NULL) { xmms_medialib_entry_property_set_int_source (session, entry, key, value, source); } else { xmms_medialib_entry_property_set_int (session, entry, key, value); } } g_strfreev (parts); xmmsv_dict_iter_next (dit); } xmmsv_list_iter_next (lit); } xmms_medialib_session_commit (session); }
/** * Unit test predicate */ static gboolean run_unit_test (xmms_medialib_t *mlib, const gchar *name, xmmsv_t *content, xmmsv_t *coll, xmmsv_t *specification, xmmsv_t *expected, gint format, const gchar *datasetname) { gboolean matches, ordered = FALSE; xmmsv_t *ret, *value; xmms_medialib_t *medialib; xmms_coll_dag_t *dag; gint status; g_debug ("Running test: %s", name); xmms_ipc_init (); xmms_config_init ("memory://"); xmms_config_property_register ("medialib.path", "memory://", NULL, NULL); medialib = xmms_medialib_init (); dag = xmms_collection_init (medialib); populate_medialib (medialib, content); memory_status_calibrate (name); ret = XMMS_IPC_CALL (dag, XMMS_IPC_CMD_QUERY, xmmsv_ref (coll), xmmsv_ref (specification)); status = memory_status_verify (name); xmmsv_dict_get (expected, "result", &value); xmmsv_dict_entry_get_int (expected, "ordered", &ordered); if (!xmmsv_is_type (ret, XMMSV_TYPE_ERROR)) { if (ordered) { matches = xmmsv_compare (ret, value); } else { matches = xmmsv_compare_unordered (ret, value); } } else { matches = FALSE; } if (matches && status == MEMORY_OK) { if (format == FORMAT_CSV) { g_print ("\"%s\", 1\n", name); } else { g_print ("............................................................ Success!"); g_print ("\r%s \n", name); } } else { if (format == FORMAT_CSV) { g_print ("\"%s\", 0\n", name); } else { g_print ("............................................................ Failure!"); if (status & MEMORY_LEAK) { g_print (" Memory Leaks!"); } if (status & MEMORY_ERROR) { g_print (" Memory errors!"); } g_print ("\r%s \n", name); } if (!matches) { g_printerr ("The result:\n"); xmmsv_dump (ret); g_printerr ("Does not equal:\n"); xmmsv_dump (value); } } xmmsv_unref (ret); xmms_object_unref (medialib); xmms_object_unref (dag); xmms_config_shutdown (); xmms_ipc_shutdown (); return matches && status == MEMORY_OK; }
/** * Set an attribute in the given collection. * * @param coll The collection in which to set the attribute. * @param key The name of the attribute to set. * @param value The value of the attribute. */ void xmmsv_coll_attribute_set_value (xmmsv_t *coll, const char *key, xmmsv_t *value) { x_return_if_fail (xmmsv_is_type (coll, XMMSV_TYPE_COLL)); xmmsv_dict_set (coll->value.coll->attributes, key, value); }
/** * Retrieve an attribute from the given collection. * * @param coll The collection to retrieve the attribute from. * @param key The name of the attribute. * @param value The value of the attribute if found (owned by the collection). * @return 1 if the attribute was found, 0 otherwise */ int xmmsv_coll_attribute_get_value (xmmsv_t *coll, const char *key, xmmsv_t **value) { x_return_val_if_fail (xmmsv_is_type (coll, XMMSV_TYPE_COLL), 0); return xmmsv_dict_get (coll->value.coll->attributes, key, value); }
/* Converts the temporary value returned by result_to_xmmsv into the real value */ static xmmsv_t * aggregate_data (xmmsv_t *value, aggregate_function_t aggr_func) { const random_data_t *random_data; const avg_data_t *avg_data; const set_data_t *set_data; gconstpointer data; xmmsv_t *ret; guint len; ret = NULL; data = NULL; if (value != NULL && xmmsv_is_type (value, XMMSV_TYPE_BIN)) xmmsv_get_bin (value, (const guchar **) &data, &len); switch (aggr_func) { case AGGREGATE_FIRST: case AGGREGATE_MIN: case AGGREGATE_MAX: case AGGREGATE_SUM: if (value != NULL) { ret = xmmsv_ref (value); } else { ret = xmmsv_new_none (); } break; case AGGREGATE_LIST: if (value != NULL) { ret = xmmsv_ref (value); } else { ret = xmmsv_new_list (); } break; case AGGREGATE_RANDOM: random_data = data; if (random_data != NULL) { ret = random_data->data; } else { ret = xmmsv_new_none (); } break; case AGGREGATE_SET: set_data = data; if (set_data != NULL) { g_hash_table_destroy (set_data->ht); ret = set_data->list; } else { ret = xmmsv_new_list (); } break; case AGGREGATE_AVG: avg_data = data; if (avg_data != NULL) { ret = xmmsv_new_float (avg_data->n ? avg_data->sum * 1.0 / avg_data->n : 0); } else { ret = xmmsv_new_none (); } break; default: g_assert_not_reached (); } if (value != NULL) { xmmsv_unref (value); } return ret; }