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;
}
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;
}
예제 #3
0
void
xmms_xform_auxdata_set_bin (xmms_xform_t *xform, const gchar *key,
                            gpointer data, gssize len)
{
	xmmsv_t *val;

	val = xmmsv_new_bin (data, len);
	xmms_xform_auxdata_set_val (xform, g_strdup (key), val);
}
예제 #4
0
/**
 * Decode an URL-encoded string.
 *
 * Some strings (currently only the url of media) has no known
 * encoding, and must be encoded in an UTF-8 clean way. This is done
 * similar to the url encoding web browsers do. This functions decodes
 * a string encoded in that way. OBSERVE that the decoded string HAS
 * NO KNOWN ENCODING and you cannot display it on screen in a 100%
 * guaranteed correct way (a good heuristic is to try to validate the
 * decoded string as UTF-8, and if it validates assume that it is an
 * UTF-8 encoded string, and otherwise fall back to some other
 * encoding).
 *
 * Do not use this function if you don't understand the
 * implications. The best thing is not to try to display the url at
 * all.
 *
 * Note that the fact that the string has NO KNOWN ENCODING and CAN
 * NOT BE DISPLAYED does not stop you from open the file if it is a
 * local file (if it starts with "file://").
 *
 * @param url the #xmmsv_t containing a url-encoded string
 * @return a new #xmmsv_t containing the decoded string as a XMMSV_BIN or NULL on failure
 *
 */
xmmsv_t *
xmmsv_decode_url (const xmmsv_t *inv)
{
	int i = 0, j = 0;
	const char *ins;
	unsigned char *url;
	xmmsv_t *ret;

	if (!xmmsv_get_string (inv, &ins)) {
		return NULL;
	}

	url = x_malloc (strlen (ins));
	if (!url) {
		x_oom ();
		return NULL;
	}

	while (ins[i]) {
		unsigned char chr = ins[i++];

		if (chr == '+') {
			chr = ' ';
		} else if (chr == '%') {
			char ts[3];
			char *t;

			ts[0] = ins[i++];
			if (!ts[0])
				goto err;
			ts[1] = ins[i++];
			if (!ts[1])
				goto err;
			ts[2] = '\0';

			chr = strtoul (ts, &t, 16);

			if (t != &ts[2])
				goto err;
		}

		url[j++] = chr;
	}

	ret = xmmsv_new_bin (url, j);
	free (url);

	return ret;

err:
	free (url);
	return NULL;
}
예제 #5
0
/**
 * Return a new value object which is a deep copy of the input value
 *
 * @param val #xmmsv_t to copy.
 * @return 1 the address to the new copy of the value.
 */
xmmsv_t *
xmmsv_copy (xmmsv_t *val)
{
	xmmsv_t *cur_val = NULL;
	xmmsv_type_t type;
	int64_t i;
	const char *s;
	float f;

	x_return_val_if_fail (val, 0);
	type = xmmsv_get_type (val);
	switch (type) {
		case XMMSV_TYPE_DICT:
			cur_val = duplicate_dict_value (val);
			break;
		case XMMSV_TYPE_LIST:
			cur_val = duplicate_list_value (val);
			break;
		case XMMSV_TYPE_INT64:
			xmmsv_get_int (val, &i);
			cur_val = xmmsv_new_int (i);
			break;
		case XMMSV_TYPE_FLOAT:
			xmmsv_get_float (val, &f);
			cur_val = xmmsv_new_float (f);
			break;
		case XMMSV_TYPE_STRING:
			xmmsv_get_string (val, &s);
			cur_val = xmmsv_new_string (s);
			break;
		case XMMSV_TYPE_ERROR:
			xmmsv_get_error (val, &s);
			cur_val = xmmsv_new_error (s);
			break;
		case XMMSV_TYPE_COLL:
			cur_val = duplicate_coll_value (val);
			break;
		case XMMSV_TYPE_BIN:
			cur_val = xmmsv_new_bin (val->value.bin.data, val->value.bin.len);
			break;
		case XMMSV_TYPE_BITBUFFER:
			cur_val = xmmsv_new_bitbuffer ();
			xmmsv_bitbuffer_put_data (cur_val, val->value.bit.buf, val->value.bit.len / 8);
			xmmsv_bitbuffer_goto (cur_val, xmmsv_bitbuffer_pos (val));
			break;
		default:
			cur_val = xmmsv_new_none ();
			break;
	}
	assert (cur_val);
	return cur_val;
}
예제 #6
0
/** 
 * Add binary data to the servers bindata directory.
 */
xmmsc_result_t *
xmmsc_bindata_add (xmmsc_connection_t *c,
                   const unsigned char *data,
                   unsigned int len)
{
	xmmsv_t *bin;

	x_check_conn (c, NULL);

	bin = xmmsv_new_bin (data, len);

	return xmmsc_send_cmd (c, XMMS_IPC_OBJECT_BINDATA, XMMS_IPC_CMD_ADD_DATA,
	                       XMMSV_LIST_ENTRY (bin), XMMSV_LIST_END);
}
static xmmsv_t *
aggregate_average (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	avg_data_t *data;
	guint length;

	if (current == NULL) {
		avg_data_t init = { 0 };
		current = xmmsv_new_bin ((guchar *) &init, sizeof (avg_data_t));
	}

	xmmsv_get_bin (current, (const guchar **) &data, &length);

	if (str_value == NULL) {
		data->n++;
		data->sum += int_value;
	}

	return current;
}
xmmsv_t *
xmmsv_serialize (xmmsv_t *v)
{
	xmmsv_t *bb;

	if (!v)
		return NULL;

	bb = xmmsv_bitbuffer_new ();

	if (!xmmsv_bitbuffer_serialize_value (bb, v)) {
		xmmsv_unref (bb);
		return NULL;
	}

	/* this is internally in xmmsv implementation,
	   so we could just switch the type,
	   but thats for later */
	return xmmsv_new_bin (xmmsv_bitbuffer_buffer (bb), xmmsv_bitbuffer_len (bb) / 8);
}
예제 #9
0
static bool
_internal_get_from_bb_value_of_type_alloc (xmmsv_t *bb, xmmsv_type_t type,
                                           xmmsv_t **val)
{
	int32_t i;
	uint32_t len;
	char *s;
	xmmsv_coll_t *c;
	unsigned char *d;

	switch (type) {
		case XMMSV_TYPE_ERROR:
			if (!_internal_get_from_bb_error_alloc (bb, &s, &len)) {
				return false;
			}
			*val = xmmsv_new_error (s);
			free (s);
			break;
		case XMMSV_TYPE_INT32:
			if (!_internal_get_from_bb_int32 (bb, &i)) {
				return false;
			}
			*val = xmmsv_new_int (i);
			break;
		case XMMSV_TYPE_STRING:
			if (!_internal_get_from_bb_string_alloc (bb, &s, &len)) {
				return false;
			}
			*val = xmmsv_new_string (s);
			free (s);
			break;
		case XMMSV_TYPE_DICT:
			if (!xmmsc_deserialize_dict (bb, val)) {
				return false;
			}
			break;

		case XMMSV_TYPE_LIST :
			if (!xmmsc_deserialize_list (bb, val)) {
				return false;
			}
			break;

		case XMMSV_TYPE_COLL:
			if (!_internal_get_from_bb_collection_alloc (bb, &c)) {
				return false;
			}
			*val = xmmsv_new_coll (c);
			xmmsv_coll_unref (c);
			break;

		case XMMSV_TYPE_BIN:
			if (!_internal_get_from_bb_bin_alloc (bb, &d, &len)) {
				return false;
			}
			*val = xmmsv_new_bin (d, len);
			free (d);
			break;

		case XMMSV_TYPE_NONE:
			*val = xmmsv_new_none ();
			break;
		default:
			x_internal_error ("Got message of unknown type!");
			return false;
	}

	return true;
}