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 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 void run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate, gint format, const gchar *datasetname) { xmmsv_list_iter_t *it; xmmsv_get_list_iter (testcases, &it); while (xmmsv_list_iter_valid (it)) { xmmsv_t *dict, *content, *specification, *holder, *expected; xmmsv_coll_t *coll; const gchar *name; dict = NULL; g_assert (xmmsv_list_iter_entry (it, &dict)); xmmsv_dict_entry_get_string (dict, "name", &name); xmmsv_dict_get (dict, "medialib", &content); xmmsv_dict_get (dict, "specification", &specification); xmmsv_dict_get (dict, "collection", &holder); xmmsv_dict_get (dict, "expected", &expected); xmmsv_get_coll (holder, &coll); predicate (medialib, name, content, coll, specification, expected, format, datasetname); xmmsv_list_iter_next (it); } }
static gboolean run_tests (xmms_medialib_t *medialib, xmmsv_t *testcases, xmms_test_predicate predicate, gint format, const gchar *datasetname) { xmmsv_list_iter_t *it; xmmsv_t *dict; gboolean result = TRUE; xmmsv_get_list_iter (testcases, &it); while (xmmsv_list_iter_entry (it, &dict)) { xmmsv_t *content, *specification, *expected, *coll; const gchar *name; xmmsv_dict_entry_get_string (dict, "name", &name); xmmsv_dict_get (dict, "medialib", &content); xmmsv_dict_get (dict, "specification", &specification); xmmsv_dict_get (dict, "collection", &coll); xmmsv_dict_get (dict, "expected", &expected); result &= predicate (medialib, name, content, coll, specification, expected, format, datasetname); xmmsv_list_iter_next (it); } return result; }
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 xmms_fetch_spec_t * xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmms_fetch_spec_t *spec; xmmsv_dict_iter_t *it; s4_sourcepref_t *sp; xmmsv_t *org_data; gint org_idx; if (!xmmsv_dict_get (fetch, "data", &org_data)) { xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize."); return NULL; } if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) { xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict."); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->type = FETCH_ORGANIZE; spec->data.organize.count = xmmsv_dict_get_size (org_data); spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count); spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count); org_idx = 0; xmmsv_get_dict_iter (org_data, &it); while (xmmsv_dict_iter_valid (it)) { xmms_fetch_spec_t *orgee; const gchar *str; xmmsv_t *entry; xmmsv_dict_iter_pair (it, &str, &entry); orgee = xmms_fetch_spec_new (entry, info, sp, err); if (xmms_error_iserror (err)) { xmms_fetch_spec_free (spec); spec = NULL; break; } spec->data.organize.keys[org_idx] = str; spec->data.organize.data[org_idx] = orgee; org_idx++; xmmsv_dict_iter_next (it); } xmmsv_dict_iter_explicit_destroy (it); s4_sourcepref_unref (sp); return spec; }
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 int xmmsv_dict_get_int (xmmsv_t *dict, const char *key, int32_t *val) { xmmsv_t *dict_entry; return (xmmsv_dict_get (dict, key, &dict_entry) && xmmsv_get_int (dict_entry, val)); }
/** * @brief Play the music relative to the current one * * @param rel The relative position, can be negative * * @return TRUE if succeeded */ static gboolean ol_player_xmms2_go_rel (int rel); static const char *_get_icon_path (void); #if XMMS_IPC_PROTOCOL_VERSION < 13 /* Before xmmsv_t introduced */ typedef xmmsc_result_t xmmsv_t; xmmsv_t * xmmsc_result_get_value (xmmsc_result_t *result) { return result; } int xmmsv_is_error (xmmsv_t *val) { return xmmsc_result_iserror (val); } int xmmsv_get_int (xmmsv_t *val, int32_t *r) { return xmmsc_result_get_int (val, r); } int xmmsv_get_string (xmmsv_t *val, const char **r) { return xmmsc_result_get_string (val, r); } struct TargetInt { const char *key; int val; int succeed; }; static void xmmsv_propdict_get_int (const void *key, xmmsc_result_value_type_t type, const void *value, const char *source, void *user_data) { struct TargetInt *target = (struct TargetInt *) user_data; if (type != XMMSC_RESULT_VALUE_TYPE_INT32) { return; } if (strcmp (key, target->key) == 0) { target->val = XPOINTER_TO_INT (value); target->succeed = 1; } } static int xmmsv_dict_get_int (xmmsv_t *dictv, const char *key, int32_t *val) { ol_assert_ret (dictv != NULL, 0); ol_assert_ret (key != NULL, 0); ol_assert_ret (val != NULL, 0); struct TargetInt target; target.key = key; target.val = 0; target.succeed = 0; if (!xmmsc_result_propdict_foreach (dictv, xmmsv_propdict_get_int, &target)) return 0; if (target.succeed) *val = target.val; return target.succeed; } struct TargetString { const char *key; char *val; int succeed; }; static void xmmsv_propdict_get_string (const void *key, xmmsc_result_value_type_t type, const void *value, const char *source, void *user_data) { struct TargetString *target = (struct TargetString *) user_data; if (type != XMMSC_RESULT_VALUE_TYPE_STRING) { return; } if (strcmp (key, target->key) == 0) { target->val = g_strdup (value); target->succeed = 1; } } static int xmmsv_dict_get_string (xmmsv_t *dictv, const char *key, const char **val) { ol_assert_ret (dictv != NULL, 0); ol_assert_ret (key != NULL, 0); ol_assert_ret (val != NULL, 0); struct TargetString target; target.key = key; target.val = NULL; target.succeed = 0; if (!xmmsc_result_propdict_foreach (dictv, xmmsv_propdict_get_string, &target)) return 0; if (target.succeed) *val = target.val; return target.succeed; } static xmmsv_t * xmmsv_propdict_to_dict (xmmsv_t *propdict, const char **src_prefs) { xmmsv_ref (propdict); return propdict; } #else /* We have xmmsv_t, so things are easy */ static int xmmsv_dict_get_string (xmmsv_t *dict, const char *key, const char **val) { xmmsv_t *dict_entry; return (xmmsv_dict_get (dict, key, &dict_entry) && xmmsv_get_string (dict_entry, val)); }
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 gint xmms_browse_list_sortfunc (gconstpointer a, gconstpointer b) { int r1, r2; xmmsv_t *val1, *val2, *tmp1, *tmp2; const gchar *s1, *s2; val1 = (xmmsv_t *) a; val2 = (xmmsv_t *) b; g_return_val_if_fail (xmmsv_get_type (val1) == XMMSV_TYPE_DICT, 0); g_return_val_if_fail (xmmsv_get_type (val2) == XMMSV_TYPE_DICT, 0); r1 = xmmsv_dict_get (val1, "intsort", &tmp1); r2 = xmmsv_dict_get (val2, "intsort", &tmp2); if (r1 && r2) { gint i1, i2; if (!xmmsv_get_int (tmp1, &i1)) return 0; if (!xmmsv_get_int (tmp2, &i2)) return 0; return i1 > i2; } if (!xmmsv_dict_get (val1, "path", &tmp1)) return 0; if (!xmmsv_dict_get (val2, "path", &tmp2)) return 0; if (!xmmsv_get_string (tmp1, &s1)) return 0; if (!xmmsv_get_string (tmp2, &s2)) return 0; return xmms_natcmp (s1, s2); }
static void cli_info_print (xmmsv_t *propdict) { xmmsv_t *properties, *sourcedict, *sources, *value; xmmsv_list_iter_t *pit, *sit; const gchar *source, *property; gint source_width; GString *sb; if (!xmmsv_propdict_lengths (propdict, NULL, &source_width)) { return; } sb = g_string_sized_new (source_width); xmmsv_dict_keys (propdict, &properties); xmmsv_list_sort (properties, xmmsv_strcmp); xmmsv_get_list_iter (properties, &pit); while (xmmsv_list_iter_entry_string (pit, &property)) { if (xmmsv_dict_get (propdict, property, &sourcedict)) { xmmsv_dict_keys (sourcedict, &sources); xmmsv_list_sort (sources, xmmsv_strcmp); xmmsv_get_list_iter (sources, &sit); while (xmmsv_list_iter_entry_string (sit, &source)) { if (xmmsv_dict_get (sourcedict, source, &value)) { cli_info_pad_source (sb, source_width, source); xmmsv_print_value (sb->str, property, value); } xmmsv_list_iter_next (sit); } } xmmsv_list_iter_next (pit); } g_string_free (sb, TRUE); }
Dict::Variant Dict::operator[]( const std::string& key ) const { Dict::Variant value; xmmsv_t *elem; if( !xmmsv_dict_get( value_, key.c_str(), &elem ) ) { throw no_such_key_error( "No such key: " + key ); } getValue( value, elem ); return value; }
/** * 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 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 xmms_medialib_tree_add_tuple (xmmsv_t *dict, const char *key, const char *source, xmmsv_t *value) { xmmsv_t *entry; if (key == NULL || source == NULL || value == NULL) { return; } /* Find (or insert) subtree matching the prop key */ if (!xmmsv_dict_get (dict, key, &entry)) { entry = xmmsv_new_dict (); xmmsv_dict_set (dict, key, entry); xmmsv_unref (entry); } /* Replace (or insert) value matching the prop source */ xmmsv_dict_set (entry, source, value); }
/** * Unit test predicate */ static void run_unit_test (xmms_medialib_t *mlib, const gchar *name, xmmsv_t *content, xmmsv_coll_t *coll, xmmsv_t *specification, xmmsv_t *expected, gint format, const gchar *datasetname) { gboolean matches, ordered = FALSE; xmmsv_t *ret, *value; xmms_error_t err; xmms_medialib_t *medialib; xmms_medialib_session_t *session; 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 (); populate_medialib (medialib, content); session = xmms_medialib_session_begin (medialib); ret = xmms_medialib_query (session, coll, specification, &err); xmms_medialib_session_commit (session); xmmsv_dict_get (expected, "result", &value); xmmsv_dict_entry_get_int (expected, "ordered", &ordered); if (ordered) { matches = xmmsv_compare (ret, value); } else { matches = xmmsv_compare_unordered (ret, value); } if (matches) { 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!"); g_print ("\r%s \n", name); } g_printerr ("The result: "); xmmsv_dump (ret); g_printerr ("Does not equal: "); xmmsv_dump (value); } xmmsv_unref (ret); xmms_object_unref (medialib); xmms_config_shutdown (); xmms_ipc_shutdown (); }
/** * 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 an S4 result (a column) into an xmmsv values */ static void * result_to_xmmsv (xmmsv_t *ret, gint32 id, const s4_result_t *res, xmms_fetch_spec_t *spec) { static xmmsv_t * (*aggregate_functions[AGGREGATE_END])(xmmsv_t *c, gint i, const gchar *s) = { aggregate_first, aggregate_sum, aggregate_max, aggregate_min, aggregate_set, aggregate_list, aggregate_random, aggregate_average }; const s4_val_t *val; xmmsv_t *dict, *current; const gchar *str_value, *key = NULL; gint32 i, int_value; xmmsv_t *newval; g_return_val_if_fail (spec->data.metadata.get_size > 0, ret); g_return_val_if_fail (spec->data.metadata.get_size <= METADATA_END, ret); g_return_val_if_fail (spec->data.metadata.aggr_func >= 0, ret); g_return_val_if_fail (spec->data.metadata.aggr_func < AGGREGATE_END, ret); /* Loop through all the values the column has */ while (res != NULL) { dict = ret; current = ret; /* Loop through the list of what to get ("key", "source", ..) */ for (i = 0; i < spec->data.metadata.get_size; i++) { str_value = NULL; int_value = 0; /* Fill str_value with the correct value if it is a string * or int_value if it is an integer */ switch (spec->data.metadata.get[i]) { case METADATA_KEY: str_value = s4_result_get_key (res); break; case METADATA_SOURCE: str_value = s4_result_get_src (res); if (str_value == NULL) str_value = "server"; break; case METADATA_ID: int_value = id; break; case METADATA_VALUE: val = s4_result_get_val (res); if (!s4_val_get_int (val, &int_value)) { s4_val_get_str (val, &str_value); } break; default: g_assert_not_reached (); } /* If this is not the last property to get we use this property * as a key in a dict */ if (i < (spec->data.metadata.get_size - 1)) { /* Convert integers to strings */ if (str_value == NULL) { /* Big enough to hold 2^32 with minus sign */ gchar buf[12]; g_sprintf (buf, "%i", int_value); key = buf; } else { key = str_value; } /* Make sure the root dict exists */ if (dict == NULL) { ret = dict = xmmsv_new_dict (); } /* If this dict contains dicts we have to create a new * dict if one does not exists for the key yet */ if (!xmmsv_dict_get (dict, key, ¤t)) current = NULL; if (i < (spec->data.metadata.get_size - 2)) { if (current == NULL) { current = xmmsv_new_dict (); xmmsv_dict_set (dict, key, current); xmmsv_unref (current); } dict = current; } } } newval = aggregate_functions[spec->data.metadata.aggr_func](current, int_value, str_value); /* Update the previous dict (if there is one) */ if (newval != current) { if (i > 1) { xmmsv_dict_set (dict, key, newval); xmmsv_unref (newval); } else { ret = newval; if (current != NULL) { xmmsv_unref (current); } } } res = s4_result_next (res); } return ret; }
/** * Decodes a cluster fetch specification from a dictionary. * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set * to 'value', then an additional 'cluster-field' will be used to specify * which meta data attribute to cluster on. */ static xmms_fetch_spec_t * xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info, s4_sourcepref_t *prefs, xmms_error_t *err) { xmmsv_t *cluster_by, *cluster_field, *cluster_data; xmms_fetch_spec_t *data, *spec = NULL; s4_sourcepref_t *sp; const gchar *value = NULL; const gchar *field = NULL; const gchar *fallback = NULL; gint cluster_type; if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) { cluster_by = xmmsv_new_string ("value"); xmmsv_dict_set (fetch, "cluster-by", cluster_by); xmmsv_unref (cluster_by); } if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) { const gchar *message = "'cluster-by' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } xmmsv_get_string (cluster_by, &value); if (!cluster_by_from_string (value, &cluster_type)) { const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (cluster_type == CLUSTER_BY_VALUE) { if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) { const gchar *message = "'cluster-field' must if 'cluster-by' is 'value'."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } } if (!xmmsv_dict_get (fetch, "data", &cluster_data)) { const gchar *message = "Required field 'data' not set in cluster."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) { fallback = NULL; } else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) { const gchar *message = "Optional field 'default' must be a string."; xmms_error_set (err, XMMS_ERROR_INVAL, message); return NULL; } sp = normalize_source_preferences (fetch, prefs, err); if (xmms_error_iserror (err)) { return NULL; } data = xmms_fetch_spec_new (cluster_data, info, sp, err); if (xmms_error_iserror (err)) { s4_sourcepref_unref (sp); return NULL; } spec = g_new0 (xmms_fetch_spec_t, 1); spec->data.cluster.data = data; spec->data.cluster.type = cluster_type; spec->data.cluster.fallback = fallback; switch (spec->data.cluster.type) { case CLUSTER_BY_ID: spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field); break; case CLUSTER_BY_VALUE: xmmsv_dict_get (fetch, "cluster-field", &cluster_field); spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field, field, sp); break; case CLUSTER_BY_POSITION: /* do nothing */ break; default: g_assert_not_reached (); } s4_sourcepref_unref (sp); return spec; }
void media_info_get (xmmsv_t *value, media_info *info) { xmmsv_t *infos, *dict_entry; const char *artist, *album, *title, *url, *comment, *genre, *date; assert(value); assert(info); infos = xmmsv_propdict_to_dict(value, NULL); if (!xmmsv_dict_get (infos, "id", &dict_entry) || !xmmsv_get_int (dict_entry, &info->id)) { info->id = 0; } if (!xmmsv_dict_get (infos, "artist", &dict_entry) || !xmmsv_get_string (dict_entry, &artist)) { artist = "[Unknown Artist]"; } if (!xmmsv_dict_get (infos, "album", &dict_entry) || !xmmsv_get_string (dict_entry, &album)) { album = "[Unknown Album]"; } if (!xmmsv_dict_get (infos, "url", &dict_entry) || !xmmsv_get_string (dict_entry, &url)) { url = "[Unknown URL]"; } if (!xmmsv_dict_get (infos, "title", &dict_entry) || !xmmsv_get_string (dict_entry, &title)) { title = ecore_file_file_get(url); } if (!xmmsv_dict_get (infos, "comment", &dict_entry) || !xmmsv_get_string (dict_entry, &comment)) { comment = ""; } if (!xmmsv_dict_get (infos, "genre", &dict_entry) || !xmmsv_get_string (dict_entry, &genre)) { genre = "[Unknown Genre]"; } if (!xmmsv_dict_get (infos, "date", &dict_entry) || !xmmsv_get_string (dict_entry, &date)) { date = ""; } if (!xmmsv_dict_get (infos, "duration", &dict_entry) || !xmmsv_get_int (dict_entry, &info->duration)) { info->duration = 0; } if (!xmmsv_dict_get (infos, "bitrate", &dict_entry) || !xmmsv_get_int (dict_entry, &info->bitrate)) { info->bitrate = 0; } if (!xmmsv_dict_get (infos, "tracknr", &dict_entry) || !xmmsv_get_int (dict_entry, &info->tracknr)) { info->tracknr = 0; } info->artist = strdup(artist); info->album = strdup(album); info->title = decode_url(title); info->url = decode_url(url); info->comment = strdup(comment); info->genre = strdup(genre); info->date = strdup(date); xmmsv_unref(infos); }
bool Dict::contains( const std::string& key ) const { return !!xmmsv_dict_get( value_, key.c_str(), NULL ); }
/** * 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; }
int main (int argc, char **argv) { /* * The first part of this program is * commented on in tut1.c and tut2.c */ xmmsc_connection_t *connection; xmmsc_result_t *result; xmmsv_t *return_value; const char *err_buf; /* * Variables that we'll need later */ const char *val; int intval; int id; xmmsv_t *dict_entry; xmmsv_t *infos; connection = xmmsc_init ("tutorial3"); if (!connection) { fprintf (stderr, "OOM!\n"); exit (EXIT_FAILURE); } if (!xmmsc_connect (connection, getenv ("XMMS_PATH"))) { fprintf (stderr, "Connection failed: %s\n", xmmsc_get_last_error (connection)); exit (EXIT_FAILURE); } /* * Ok, let' do the same thing as we did in * tut2.c and retrieve the current playing * entry. We need that to get information * about the song. */ result = xmmsc_playback_current_id (connection); xmmsc_result_wait (result); return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value) && xmmsv_get_error (return_value, &err_buf)) { fprintf (stderr, "playback current id returns error, %s\n", err_buf); } if (!xmmsv_get_int (return_value, &id)) { fprintf (stderr, "xmmsc_playback_current_id didn't " "return int as expected\n"); /* Fake id (ids are >= 1) used as an error flag. */ id = 0; } /* Print the value */ printf ("Currently playing id is %d\n", id); /* * Same drill as before. Release memory * so that we can reuse it in the next * clientlib call. * */ xmmsc_result_unref (result); /* * Something about the medialib and xmms2. All * entries that are played, put into playlists * have to be in the medialib. A song's metadata * will be added to the medialib the first time * you do "xmms2 add" or equivalent. * * When we request information for an entry, it will * be requested from the medialib, not the playlist * or the playback. The playlist and playback only * know the unique id of the entry. All other * information must be retrieved in subsequent calls. * * Entry 0 is non valid. Only 1-inf is valid. * So let's check for 0 and don't ask medialib for it. */ if (id == 0) { fprintf (stderr, "Nothing is playing.\n"); exit (EXIT_FAILURE); } /* * And now for something about return types from * clientlib. The clientlib will always return * an xmmsc_result_t that will eventually contain the * return value as a xmmsv_t struct. * The value can contain an int and string as * base type. It can also contain more complex * types like lists and dicts. * A list is a sequence of values, each of them * wrapped in its own xmmsv_t struct (of any type). * A dict is a key<->value representation where key * is always a string but the value is again wrapped * in its own xmmsv_t struct (of any type). * * When retrieving an entry from the medialib, you * get a dict as return. Let's print out some * entries from it and then traverse the dict. */ result = xmmsc_medialib_get_info (connection, id); /* And waaait for it .. */ xmmsc_result_wait (result); /* Let's reuse the previous return_value pointer, it * was invalidated as soon as we freed the result that * contained it anyway. */ return_value = xmmsc_result_get_value (result); if (xmmsv_is_error (return_value) && xmmsv_get_error (return_value, &err_buf)) { /* * This can return error if the id * is not in the medialib */ fprintf (stderr, "medialib get info returns error, %s\n", err_buf); exit (EXIT_FAILURE); } /* * Because of the nature of the dict returned by * xmmsc_medialib_get_info, we need to convert it to * a simpler dict using xmmsv_propdict_to_dict. * Let's not worry about that for now and accept it * as a fact of life. * * See tut5 for a discussion about dicts and propdicts. * * Note that xmmsv_propdict_to_dict creates a new * xmmsv_t struct, which we will need to free manually * when we're done with it. */ infos = xmmsv_propdict_to_dict (return_value, NULL); /* * We must first retrieve the xmmsv_t struct * corresponding to the "artist" key in the dict, * and then extract the string from that struct. */ if (!xmmsv_dict_get (infos, "artist", &dict_entry) || !xmmsv_get_string (dict_entry, &val)) { /* * if we end up here it means that the key "artist" wasn't * in the dict or that the value for "artist" wasn't a * string. * * You can check the type of the entry (if there is one) with * xmmsv_get_type (dict_entry). It will return an * xmmsv_type_t enum describing the type. * * Actually this is no disaster, it might just mean that * we don't have an artist tag on this entry. Let's * call it "No Artist" for now. */ val = "No Artist"; } /* print the value */ printf ("artist = %s\n", val); if (!xmmsv_dict_get (infos, "title", &dict_entry) || !xmmsv_get_string (dict_entry, &val)) { val = "No Title"; } printf ("title = %s\n", val); /* * Let's extract an integer as well */ if (!xmmsv_dict_get (infos, "bitrate", &dict_entry) || !xmmsv_get_int (dict_entry, &intval)) { intval = 0; } printf ("bitrate = %i\n", intval); /* * We need to free infos manually here, else we will leak. */ xmmsv_unref (infos); /* * !!Important!! * * When unreffing the result here we will free * the memory that we have extracted from the dict, * and that includes all the string pointers of the * dict entries! So if you want to keep strings * somewhere you need to copy that memory! Very * important otherwise you will get undefined behaviour. */ xmmsc_result_unref (result); xmmsc_unref (connection); return (EXIT_SUCCESS); }
int show_xmmsinfo_c(lua_State *L) { xmmsc_connection_t *connection; xmmsc_result_t *state; xmmsv_t *state_value; const char *err_buf; int32_t status; // string containing the current xmms2 state char *state_str; // initialize the Info struct struct Info i; // initialize the connection connection = xmmsc_init("xmmsinfo"); if (!connection) { fprintf(stderr, "No connection!\n"); return(EXIT_FAILURE); } // try to connect if (!xmmsc_connect(connection, getenv("XMMS_PATH"))) { fprintf(stderr, "Connection failed, %s\n", xmmsc_get_last_error(connection)); return(EXIT_FAILURE); } // get current xmms2 status state = xmmsc_playback_status(connection); xmmsc_result_wait(state); state_value = xmmsc_result_get_value(state); if(xmmsv_get_error(state_value, &err_buf)) { fprintf(stderr, "Error while asking for the connection status, %s\n", err_buf); } if(!xmmsv_get_int(state_value, &status)) { fprintf(stderr, "Couldn't get connection status, %d\n", status); } // 0 == stopped; 1 == playing; 2 == paused if(status == XMMS_PLAYBACK_STATUS_PLAY) { state_str = "playing"; } else if (status == XMMS_PLAYBACK_STATUS_PAUSE) { state_str = "paused"; } else { state_str = "stopped"; } i.state = state_str; // get current position in the playlist xmmsc_result_t *current_id; xmmsv_t *current_id_value; int32_t cur_id; current_id = xmmsc_playback_current_id(connection); xmmsc_result_wait(current_id); current_id_value = xmmsc_result_get_value(current_id); xmmsv_get_int(current_id_value, &cur_id); // initialize variables for the song info xmmsc_result_t *result; xmmsv_t *return_value; xmmsv_t *dict_entry; xmmsv_t *infos; const char *val; result = xmmsc_medialib_get_info(connection, cur_id); xmmsc_result_wait(result); return_value = xmmsc_result_get_value(result); if(xmmsv_get_error(return_value, &err_buf)) { fprintf(stderr, "Medialib returns error, %s\n", err_buf); return(EXIT_FAILURE); } infos = xmmsv_propdict_to_dict(return_value, NULL); if(!xmmsv_dict_get(infos, "artist", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Artist"; } i.artist = val; if(!xmmsv_dict_get(infos, "album", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Album"; } i.album = val; if(!xmmsv_dict_get(infos, "title", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = "No Title"; } i.song = val; i.id = cur_id; if(!xmmsv_dict_get(infos, "url", &dict_entry) || !xmmsv_get_string(dict_entry, &val)) { val = NULL; } i.uri = val; // push everything to lua lua_pushstring(L, i.state); lua_pushstring(L, i.artist); lua_pushstring(L, i.album); lua_pushstring(L, i.song); lua_pushinteger(L, i.id); lua_pushstring(L, i.uri); // clean up xmmsv_unref(infos); xmmsc_result_unref(result); xmmsc_result_unref(state); xmmsc_result_unref(current_id); xmmsc_unref(connection); return 6; }