Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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);
	}
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
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;
}
Пример #7
0
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], &copy)) {
			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;
}
Пример #8
0
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));
}
Пример #9
0
/** 
 * @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));
}
Пример #10
0
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;
}
Пример #11
0
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);
}
Пример #12
0
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);
}
Пример #13
0
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;

}
Пример #14
0
/**
 * 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;
}
Пример #15
0
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;
}
Пример #16
0
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);
}
Пример #17
0
/**
 * 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 ();
}
Пример #18
0
/**
 * 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);
}
Пример #19
0
/* 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, &current))
					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;
}
Пример #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
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);
}
Пример #22
0
bool Dict::contains( const std::string& key ) const
{
    return !!xmmsv_dict_get( value_, key.c_str(), NULL );
}
Пример #23
0
/**
 * 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;
}
Пример #24
0
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);
}
Пример #25
0
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;
}