예제 #1
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_get_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);
}
예제 #2
0
static bool
_internal_put_on_bb_value_dict (xmmsv_t *bb, xmmsv_t *v)
{
	xmmsv_dict_iter_t *it;
	const char *key;
	xmmsv_t *entry;
	uint32_t ret, offset, count;

	if (!xmmsv_get_dict_iter (v, &it)) {
		return false;
	}

	/* store a dummy value, store the real count once it's known */
	offset = xmmsv_bitbuffer_pos (bb);
	xmmsv_bitbuffer_put_bits (bb, 32, 0);

	count = 0;
	while (xmmsv_dict_iter_valid (it)) {
		xmmsv_dict_iter_pair (it, &key, &entry);
		ret = _internal_put_on_bb_string (bb, key);
		ret = xmmsv_bitbuffer_serialize_value (bb, entry);
		xmmsv_dict_iter_next (it);
		count++;
	}

	/* overwrite with real size */
	xmmsv_bitbuffer_put_bits_at (bb, 32, count, offset);

	return ret;
}
예제 #3
0
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;
}
예제 #4
0
파일: common.c 프로젝트: dreamerc/xmms2
/* dumps a recursive key-source-val dict */
void
print_entry (const gchar *key, xmmsv_t *dict, void *udata)
{
	xmmsv_t *v;
	const gchar *source;
	if (xmmsv_get_type (dict) == XMMSV_TYPE_DICT) {
		xmmsv_dict_iter_t *it;
		xmmsv_get_dict_iter (dict, &it);

		while (xmmsv_dict_iter_valid (it)) {
			xmmsv_dict_iter_pair (it, &source, &v);
			switch (xmmsv_get_type (v)) {
			case XMMSV_TYPE_STRING:
				print_entry_string (v, key, source);
				break;
			case XMMSV_TYPE_INT32:
			{
				gint i;
				xmmsv_get_int (v, &i);
				print_info ("[%s] %s = %d", source, key, i);
				break;
			}
			default:
				print_info ("[%s] %s = (unknown data)", source, key);
				break;
			}
			xmmsv_dict_iter_next (it);
		}
	}
}
/* 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;
}
예제 #6
0
/**
 * Helper function to transform a key-source-value dict-of-dict
 * #xmmsv_t (formerly a propdict) to a regular key-value dict, given a
 * list of source preference.
 *
 * @param propdict A key-source-value dict-of-dict #xmmsv_t.
 * @param src_prefs A list of source names or patterns. Must be
 *                  NULL-terminated. If this argument is NULL, the
 *                  default source preferences is used.
 * @return An #xmmsv_t containing a simple key-value dict. Must be
 *         unreffed manually when done.
 */
xmmsv_t *
xmmsv_propdict_to_dict (xmmsv_t *propdict, const char **src_prefs)
{
	xmmsv_t *dict, *source_dict, *value, *best_value;
	xmmsv_dict_iter_t *key_it, *source_it;
	const char *key, *source;
	const char **local_prefs;
	int match_index, best_index;

	dict = xmmsv_new_dict ();

	local_prefs = src_prefs ? src_prefs : xmmsv_default_source_pref;

	xmmsv_get_dict_iter (propdict, &key_it);
	while (xmmsv_dict_iter_valid (key_it)) {
		xmmsv_dict_iter_pair (key_it, &key, &source_dict);

		best_value = NULL;
		best_index = -1;
		xmmsv_get_dict_iter (source_dict, &source_it);
		while (xmmsv_dict_iter_valid (source_it)) {
			xmmsv_dict_iter_pair (source_it, &source, &value);
			match_index = find_match_index (source, local_prefs);
			/* keep first match or better match */
			if (match_index >= 0 && (best_index < 0 ||
			                         match_index < best_index)) {
				best_value = value;
				best_index = match_index;
			}
			xmmsv_dict_iter_next (source_it);
		}

		/* Note: we do not insert a key-value pair if no source matches */
		if (best_value) {
			xmmsv_dict_set (dict, key, best_value);
		}

		xmmsv_dict_iter_next (key_it);
	}

	return dict;
}
예제 #7
0
파일: xmmsv_copy.c 프로젝트: chrippa/xmms2
xmmsv_coll_t *
xmmsv_coll_copy (xmmsv_coll_t *orig_coll)
{
	xmmsv_coll_t *new_coll, *coll_elem;
	xmmsv_list_iter_t *it;
	xmmsv_dict_iter_t *itd;
	xmmsv_t *v, *list, *dict;
	const char *key;
	int32_t i;
	const char *s;

	new_coll = xmmsv_coll_new (xmmsv_coll_get_type (orig_coll));

	list = xmmsv_coll_idlist_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL);
	while (xmmsv_list_iter_valid (it)) {
		xmmsv_list_iter_entry (it, &v);
		xmmsv_get_int (v, &i);
		xmmsv_coll_idlist_append (new_coll, i);
		xmmsv_list_iter_next (it);
	}
	xmmsv_list_iter_explicit_destroy (it);

	list = xmmsv_coll_operands_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL);
	while (xmmsv_list_iter_valid (it)) {
		xmmsv_list_iter_entry (it, &v);
		xmmsv_get_coll (v, &coll_elem);
		xmmsv_coll_add_operand (new_coll, xmmsv_coll_copy (coll_elem));
		xmmsv_list_iter_next (it);
	}
	xmmsv_list_iter_explicit_destroy (it);

	dict = xmmsv_coll_attributes_get (orig_coll);
	x_return_val_if_fail (xmmsv_get_dict_iter (dict, &itd), NULL);
	while (xmmsv_dict_iter_valid (itd)) {
		xmmsv_dict_iter_pair (itd, &key, &v);
		xmmsv_get_string (v, &s);
		xmmsv_coll_attribute_set (new_coll, key, s);
		xmmsv_dict_iter_next (itd);
	}
	xmmsv_dict_iter_explicit_destroy (itd);
	return new_coll;
}
예제 #8
0
파일: xmmsv_copy.c 프로젝트: chrippa/xmms2
xmmsv_t *
duplicate_dict_value (xmmsv_t *val)
{
	xmmsv_t *dup_val;
	xmmsv_dict_iter_t *it;
	const char *key;
	xmmsv_t *v;
	xmmsv_t *new_elem;

	x_return_val_if_fail (xmmsv_get_dict_iter (val, &it), NULL);
	dup_val = xmmsv_new_dict ();
	while (xmmsv_dict_iter_valid (it)) {
		xmmsv_dict_iter_pair (it, &key, &v);
		new_elem = xmmsv_copy (v);
		xmmsv_dict_set (dup_val, key, new_elem);
		xmmsv_unref (new_elem);
		xmmsv_dict_iter_next (it);
	}

	xmmsv_dict_iter_explicit_destroy (it);

	return dup_val;
}
예제 #9
0
/**
 * 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);
}
예제 #10
0
파일: dict.cpp 프로젝트: chrippa/xmms2
bool
Dict::const_iterator::valid() const
{
    return dict_ && it_ && xmmsv_dict_iter_valid( it_ );
}
예제 #11
0
파일: medialib.c 프로젝트: chrippa/xmms2
/**
 * Encodes an url with arguments stored in dict args.
 *
 * The encoded url is allocated using malloc and has to be freed by the user.
 *
 * @param url The url to encode.
 * @param args The dict with arguments, or NULL.
 * @return The encoded url
 */
char *
xmmsc_medialib_encode_url_full (const char *url, xmmsv_t *args)
{
	static const char hex[16] = "0123456789abcdef";
	int i = 0, j = 0, extra = 0, l;
	char *res;
	xmmsv_dict_iter_t *it;

	x_api_error_if (!url, "with a NULL url", NULL);

	if (args) {
		if (!xmmsv_dict_foreach (args, _sum_len_string_dict, (void *) &extra)) {
			return NULL;
		}
	}

	/* Provide enough room for the worst-case scenario (all characters of the
	   URL must be encoded), the args, and a \0. */
	res = malloc (strlen (url) * 3 + 1 + extra);
	if (!res) {
		return NULL;
	}

	for (i = 0; url[i]; i++) {
		unsigned char chr = url[i];
		if (GOODCHAR (chr)) {
			res[j++] = chr;
		} else if (chr == ' ') {
			res[j++] = '+';
		} else {
			res[j++] = '%';
			res[j++] = hex[((chr & 0xf0) >> 4)];
			res[j++] = hex[(chr & 0x0f)];
		}
	}

	if (args) {
		for (xmmsv_get_dict_iter (args, &it), i = 0;
		     xmmsv_dict_iter_valid (it);
		     xmmsv_dict_iter_next (it), i++) {

			const char *arg, *key;
			xmmsv_t *val;

			xmmsv_dict_iter_pair (it, &key, &val);
			l = strlen (key);
			res[j] = (i == 0) ? '?' : '&';
			j++;
			memcpy (&res[j], key, l);
			j += l;
			if (xmmsv_get_string (val, &arg)) {
				l = strlen (arg);
				res[j] = '=';
				j++;
				memcpy (&res[j], arg, l);
				j += l;
			}
		}
	}

	res[j] = '\0';

	return res;
}
예제 #12
0
static bool
_internal_get_from_bb_collection_alloc (xmmsv_t *bb, xmmsv_coll_t **coll)
{
	int i;
	int32_t type;
	int32_t n_items;
	int id;
	int32_t *idlist = NULL;
	xmmsv_t *dict, *attrs;
	xmmsv_dict_iter_t *it;

	/* Get the type and create the collection */
	if (!_internal_get_from_bb_int32_positive (bb, &type)) {
		return false;
	}

	*coll = xmmsv_coll_new (type);

	/* Get the attributes */
	if (!_internal_get_from_bb_value_dict_alloc (bb, &dict)) {
		return false;
	}

	attrs = xmmsv_coll_attributes_get (*coll);

	xmmsv_get_dict_iter (dict, &it);
	while (xmmsv_dict_iter_valid (it)) {
		const char *key;
		xmmsv_t *value;
		xmmsv_dict_iter_pair (it, &key, &value);
		xmmsv_dict_set (attrs, key, value);
		xmmsv_dict_iter_next (it);
	}

	xmmsv_unref (dict);

	/* Get the idlist */
	if (!_internal_get_from_bb_int32_positive (bb, &n_items)) {
		goto err;
	}

	if (!(idlist = x_new (int32_t, n_items + 1))) {
		goto err;
	}

	for (i = 0; i < n_items; i++) {
		if (!_internal_get_from_bb_int32 (bb, &id)) {
			goto err;
		}

		idlist[i] = id;
	}

	idlist[i] = 0;
	xmmsv_coll_set_idlist (*coll, idlist);
	free (idlist);
	idlist = NULL;

	/* Get the operands */
	if (!_internal_get_from_bb_int32_positive (bb, &n_items)) {
		goto err;
	}

	for (i = 0; i < n_items; i++) {
		xmmsv_coll_t *operand;

		if (!_internal_get_from_bb_int32_positive (bb, &type) ||
		    type != XMMSV_TYPE_COLL ||
		    !_internal_get_from_bb_collection_alloc (bb, &operand)) {
			goto err;
		}

		xmmsv_coll_add_operand (*coll, operand);
		xmmsv_coll_unref (operand);
	}

	return true;

err:
	if (idlist != NULL) {
		free (idlist);
	}

	xmmsv_coll_unref (*coll);

	return false;
}