Пример #1
0
/*
 * call-seq:
 *  Xmms.decode_url(url) -> String
 *
 * Decodes a url-encoded string _url_ and returns it in UNKNOWN ENCODING.
 * Use with caution.
 */
static VALUE
m_decode_url (VALUE self, VALUE str)
{
	const unsigned char *burl;
	unsigned int blen;
	xmmsv_t *strv, *decoded;
	VALUE url = Qnil;

	strv = xmmsv_new_string (StringValuePtr (str));

	decoded = xmmsv_decode_url (strv);

	if (!decoded)
		goto out;

	if (!xmmsv_get_bin (decoded, &burl, &blen))
		goto out;

	url = rb_str_new ((char *) burl, blen);

out:
	if (decoded)
		xmmsv_unref (decoded);

	xmmsv_unref (strv);

	return url;
}
Пример #2
0
static void
xmms_playlist_client_load (xmms_playlist_t *playlist, const gchar *name, xmms_error_t *err)
{
	xmmsv_coll_t *plcoll, *active_coll;

	if (strcmp (name, XMMS_ACTIVE_PLAYLIST) == 0) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "invalid playlist to load");
		return;
	}

	active_coll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err);
	if (active_coll == NULL) {
		xmms_error_set (err, XMMS_ERROR_GENERIC, "no active playlist");
		return;
	}

	plcoll = xmms_playlist_get_coll (playlist, name, err);
	if (plcoll == NULL) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist");
		return;
	}

	if (active_coll == plcoll) {
		XMMS_DBG ("Not loading %s playlist, already active!", name);
		return;
	}

	XMMS_DBG ("Loading new playlist! %s", name);
	xmms_collection_update_pointer (playlist->colldag, XMMS_ACTIVE_PLAYLIST,
	                                XMMS_COLLECTION_NSID_PLAYLISTS, plcoll);

	xmms_object_emit (XMMS_OBJECT (playlist),
	                  XMMS_IPC_SIGNAL_PLAYLIST_LOADED,
	                  xmmsv_new_string (name));
}
Пример #3
0
static xmms_xspf_track_attr_t *
xmms_xspf_track_attr_from_node (const xmms_xspf_track_prop_t *prop, xmlNodePtr node)
{
	xmmsv_t *value;
	xmms_xspf_track_attr_t *attr;

	switch (prop->attr_type) {
		case XMMS_XSPF_TRACK_ATTR_TYPE_STRING:
			value = xmmsv_new_string ((char *)node->children->content);
			break;
		case XMMS_XSPF_TRACK_ATTR_TYPE_INT32: {
			/* TODO: check for errors */
			gint32 val = strtol ((char *)node->children->content, (char **)NULL, 10);
			value = xmmsv_new_int (val);
			break;
		}
	}

	if (!value) {
		return NULL;
	}

	attr = g_new0 (xmms_xspf_track_attr_t, 1);
	attr->key = prop->name;
	attr->value = value;

	return attr;
}
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;
}
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;
}
Пример #6
0
void
xmms_xform_browse_add_entry_property_str (xmms_xform_t *xform,
                                          const gchar *key,
                                          const gchar *value)
{
	xmmsv_t *val = xmmsv_new_string (value);
	xmms_xform_browse_add_entry_property (xform, key, val);
	xmmsv_unref (val);
}
Пример #7
0
xmmsv_t *
xmms_convert_and_kill_string (gchar *str)
{
	xmmsv_t *v = NULL;

	if (str) {
		v = xmmsv_new_string (str);
		g_free (str);
	}

	return v;
}
Пример #8
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;
}
Пример #9
0
static xmmsv_t *
xmms_medialib_entry_to_tree (xmms_medialib_session_t *session,
                             xmms_medialib_entry_t entry)
{
	s4_resultset_t *set;
	s4_val_t *song_id;
	xmmsv_t *ret, *id;
	gint i;

	song_id = s4_val_new_int (entry);
	set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT,
	                            NULL, NULL, S4_FETCH_PARENT | S4_FETCH_DATA);
	s4_val_free (song_id);

	ret = xmmsv_new_dict ();

	for (i = 0; i < s4_resultset_get_rowcount (set); i++) {
		const s4_result_t *res;

		res = s4_resultset_get_result (set, 0, 0);
		while (res != NULL) {
			xmmsv_t *v_entry = NULL;
			const s4_val_t *val;
			const char *s;
			gint32 i;

			val = s4_result_get_val (res);
			if (s4_val_get_str (val, &s)) {
				v_entry = xmmsv_new_string (s);
			} else if (s4_val_get_int (val, &i)) {
				v_entry = xmmsv_new_int (i);
			}

			xmms_medialib_tree_add_tuple (ret, s4_result_get_key (res),
			                              s4_result_get_src (res), v_entry);
			xmmsv_unref (v_entry);

			res = s4_result_next (res);
		}
	}

	s4_resultset_free (set);

	id = xmmsv_new_int (entry);
	xmms_medialib_tree_add_tuple (ret, "id", "server", id);
	xmmsv_unref (id);

	return ret;
}
Пример #10
0
static xmmsv_t *
aggregate_first (xmmsv_t *current, gint int_value, const gchar *str_value)
{
	if (current != NULL) {
		return current;
	}

	if (str_value != NULL) {
		current = xmmsv_new_string (str_value);
	} else {
		current = xmmsv_new_int (int_value);
	}

	return current;
}
Пример #11
0
void
xmms_xform_auxdata_set_str (xmms_xform_t *xform, const gchar *key,
                            const gchar *strval)
{
	xmmsv_t *val;
	const char *old;

	if (xmms_xform_auxdata_get_str (xform, key, &old)) {
		if (strcmp (old, strval) == 0) {
			return;
		}
	}

	val = xmmsv_new_string (strval);
	xmms_xform_auxdata_set_val (xform, g_strdup (key), val);
}
Пример #12
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;
}
Пример #13
0
/**
 * This returns the main stats for the server
 */
static GTree *
xmms_main_client_stats (xmms_object_t *object, xmms_error_t *error)
{
	GTree *ret;
	gint starttime;

	ret = g_tree_new_full ((GCompareDataFunc) strcmp, NULL,
	                       NULL, (GDestroyNotify) xmmsv_unref);

	starttime = ((xmms_main_t*)object)->starttime;

	g_tree_insert (ret, (gpointer) "version",
	               xmmsv_new_string (XMMS_VERSION));
	g_tree_insert (ret, (gpointer) "uptime",
	               xmmsv_new_int (time (NULL) - starttime));

	return ret;
}
Пример #14
0
static xmmsv_t *
create_data (int type, const char *data, uint32_t len)
{
	switch (type) {
		case JSON_STRING:
			return xmmsv_new_string (data);
		case JSON_INT:
			return xmmsv_new_int (atoi(data));
		case JSON_FLOAT:
			return xmmsv_new_float (strtof (data, NULL));
		case JSON_NULL:
			return xmmsv_new_none ();
		case JSON_TRUE:
			return xmmsv_new_int (1);
		case JSON_FALSE:
			return xmmsv_new_int (0);
		default:
			return xmmsv_new_error ("Unknown data type.");
	}
}
Пример #15
0
	/** Decode an URL-encoded string.
	 *
	 * Some strings (currently only the url of media) have no known
	 * encoding, and must be encoded in an UTF-8 clean way. This is done
	 * similarly 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 encoded_url the url-encoded string
	 * @return the decoded string in an unknown encoding
	 *
	 */
	std::string decodeUrl( const std::string& encoded_url )
	{
		xmmsv_t *encoded, *decoded;
		const unsigned char *url;
		unsigned int len;
		std::string dec_str;

		encoded = xmmsv_new_string( encoded_url.c_str() );
		decoded = xmmsv_decode_url( encoded );
		if( !xmmsv_get_bin( decoded, &url, &len ) ) {
			throw invalid_url( "The given URL cannot be decoded." );
		}

		dec_str = std::string( reinterpret_cast< const char* >( url ), len );

		xmmsv_unref( encoded );
		xmmsv_unref( decoded );

		return dec_str;
	}
Пример #16
0
void
xmms_xform_metadata_set_str (xmms_xform_t *xform, const char *key,
                             const char *val)
{
	const char *old;

	if (!g_utf8_validate (val, -1, NULL)) {
		xmms_log_error ("xform '%s' tried to set property '%s' to a NON UTF-8 string!", xmms_xform_shortname (xform), key);
		return;
	}

	if (xmms_xform_metadata_get_str (xform, key, &old)) {
		if (strcmp (old, val) == 0) {
			return;
		}
	}

	g_hash_table_insert (xform->metadata, g_strdup (key),
	                     xmmsv_new_string (val));

	xform->metadata_changed = TRUE;
}
Пример #17
0
static xmmsv_t *
args_to_dict (gchar **argv, gint argc)
{
	xmmsv_t *dict;
	gint i;

	dict = xmmsv_new_dict ();
	if (!dict) {
		return NULL;
	}

	for (i = 0; i < argc; i++) {
		gchar **tuple;
		xmmsv_t *val;

		/* Split the string into arg and value. */
		tuple = g_strsplit (argv[i], "=", 2);
		if (tuple[0] && tuple[1]) {
			val = xmmsv_new_string (tuple[1]);
		} else if (tuple[0]) {
			val = xmmsv_new_none ();
		} else {
			g_strfreev (tuple);
			continue; /* Empty tuple, means empty string. */
		}
		if (!val) {
			xmmsv_unref (dict);
			return NULL;
		}

		xmmsv_dict_set (dict, tuple[0], val);

		g_strfreev (tuple);
		xmmsv_unref (val);
	}

	return dict;
}
Пример #18
0
char *decode_url(const char *url) {
	xmmsv_t *url_str;
	xmmsv_t *decoded_url;
	char *new_url = NULL;
	const unsigned char *url_tmp;
	unsigned int url_len;

	url_str = xmmsv_new_string(url);

	if (url_str) {
		decoded_url = xmmsv_decode_url(url_str);
		if (decoded_url) {
			if (xmmsv_get_bin(decoded_url, &url_tmp, &url_len)) {
				new_url = (char*) malloc( sizeof(char)*(url_len+1) );
				snprintf(new_url, url_len+1, "%s", url_tmp);
			}
		}
		xmmsv_unref(decoded_url);
	}

	xmmsv_unref(url_str);
	return new_url;
}
Пример #19
0
xmmsv_t *
xmms_medialib_entry_property_get_value (xmms_medialib_session_t *session,
                                        xmms_medialib_entry_t id_num,
                                        const gchar *property)
{
	xmmsv_t *ret = NULL;
	s4_val_t *prop;
	const gchar *s;
	gint32 i;

	prop = xmms_medialib_entry_property_get (session, id_num, property);
	if (prop == NULL)
		return NULL;

	if (s4_val_get_str (prop, &s)) {
		ret = xmmsv_new_string (s);
	} else if (s4_val_get_int (prop, &i)) {
		ret = xmmsv_new_int (i);
	}

	s4_val_free (prop);

	return ret;
}
Пример #20
0
/**
 * 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;
}
Пример #21
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;
}