uri: Add new uri API to get media fragments URI as table

As an usecase of URI fragment, it can indicate temporal or spatial
dimension of a media stream. To easily parse key-value pair,
newly added gst_uri_get_media_fragment_table () API will provide
the table of key-value pair likewise URI query.
See also https://www.w3.org/TR/media-frags/

https://bugzilla.gnome.org/show_bug.cgi?id=774830
This commit is contained in:
Seungha Yang 2016-11-22 16:52:46 +09:00 committed by Tim-Philipp Müller
parent 0728b9b59b
commit 0494c173e0
5 changed files with 109 additions and 0 deletions

View file

@ -3452,6 +3452,7 @@ gst_uri_query_has_key
gst_uri_get_query_keys
gst_uri_get_fragment
gst_uri_set_fragment
gst_uri_get_media_fragment_table
<SUBSECTION Standard>
GST_IS_URI
GST_TYPE_URI

View file

@ -2803,3 +2803,34 @@ gst_uri_set_fragment (GstUri * uri, const gchar * fragment)
uri->fragment = g_strdup (fragment);
return TRUE;
}
/**
* gst_uri_get_media_fragment_table:
* @uri: (nullable): The #GstUri to get the fragment table from.
*
* Get the media fragment table from the URI, as defined by "Media Fragments URI 1.0".
* Hash table returned by this API is a list of "key-value" pairs, and the each
* pair is generated by splitting "URI fragment" per "&" sub-delims, then "key"
* and "value" are splitted by "=" sub-delims. The "key" returned by this API may
* be undefined keyword by standard.
* A value may be %NULL to indicate that the key should appear in the fragment
* string in the URI, but does not have a value. Free the returned #GHashTable
* with #g_hash_table_unref() when it is no longer required.
* Modifying this hash table does not affect the fragment in the URI.
*
* See more about Media Fragments URI 1.0 (W3C) at https://www.w3.org/TR/media-frags/
*
* Returns: (transfer full)(element-type gchar* gchar*): The fragment hash table
* from the URI.
*
* Since: 1.12
*/
GHashTable *
gst_uri_get_media_fragment_table (const GstUri * uri)
{
g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
if (!uri->fragment)
return NULL;
return _gst_uri_string_to_table (uri->fragment, "&", "=", TRUE, TRUE);
}

View file

@ -250,6 +250,7 @@ const gchar * gst_uri_get_query_value (const GstUri * uri,
GList * gst_uri_get_query_keys (const GstUri * uri);
const gchar * gst_uri_get_fragment (const GstUri * uri);
gboolean gst_uri_set_fragment (GstUri * uri, const gchar * fragment);
GHashTable * gst_uri_get_media_fragment_table (const GstUri * uri);
/**
* gst_uri_copy:

View file

@ -980,6 +980,80 @@ GST_START_TEST (test_url_get_set)
GST_END_TEST;
GST_START_TEST (test_url_get_media_fragment_table)
{
GstUri *url;
gchar *val;
GHashTable *table;
/* Examples at https://www.w3.org/TR/media-frags/#processing-media-fragment-uri */
/* TEST "t=1" */
url = gst_uri_from_string ("http://foo/var/file#t=1");
table = gst_uri_get_media_fragment_table (url);
fail_unless (table);
fail_unless (g_hash_table_size (table) == 1);
fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
(gpointer) & val));
fail_unless_equals_string ("1", val);
g_hash_table_unref (table);
gst_uri_unref (url);
/* NOTE: Media Fragments URI 1.0 (W3C) is saying that
* "Multiple occurrences of the same dimension: only the last valid occurrence
* of a dimension (e.g. t=10 in #t=2&t=10) is interpreted and all previous
* occurrences (valid or invalid) SHOULD be ignored by the user agent"
*/
/* TEST "t=1&t=2" */
url = gst_uri_from_string ("http://foo/var/file#t=1&t=2");
table = gst_uri_get_media_fragment_table (url);
fail_unless (table);
fail_unless (g_hash_table_size (table) == 1);
fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
(gpointer) & val));
fail_unless_equals_string ("2", val);
g_hash_table_unref (table);
gst_uri_unref (url);
/* TEST "a=b=c" */
url = gst_uri_from_string ("http://foo/var/file#a=b=c");
table = gst_uri_get_media_fragment_table (url);
fail_unless (table);
fail_unless (g_hash_table_size (table) == 1);
fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
(gpointer) & val));
fail_unless_equals_string ("b=c", val);
g_hash_table_unref (table);
gst_uri_unref (url);
/* TEST "a&b=c" */
url = gst_uri_from_string ("http://foo/var/file#a&b=c");
table = gst_uri_get_media_fragment_table (url);
fail_unless (table);
fail_unless (g_hash_table_size (table) == 2);
fail_unless (g_hash_table_lookup_extended (table, "a", NULL,
(gpointer) & val));
fail_unless (val == NULL);
fail_unless (g_hash_table_lookup_extended (table, "b", NULL,
(gpointer) & val));
fail_unless_equals_string ("c", val);
g_hash_table_unref (table);
gst_uri_unref (url);
/* TEST "%74=%6ept%3A%310" */
url = gst_uri_from_string ("http://foo/var/file#%74=%6ept%3A%310");
table = gst_uri_get_media_fragment_table (url);
fail_unless (table);
fail_unless (g_hash_table_size (table) == 1);
fail_unless (g_hash_table_lookup_extended (table, "t", NULL,
(gpointer) & val));
fail_unless_equals_string ("npt:10", val);
g_hash_table_unref (table);
gst_uri_unref (url);
}
GST_END_TEST;
static Suite *
gst_uri_suite (void)
{
@ -1003,6 +1077,7 @@ gst_uri_suite (void)
tcase_add_test (tc_chain, test_url_equality);
tcase_add_test (tc_chain, test_url_constructors);
tcase_add_test (tc_chain, test_url_get_set);
tcase_add_test (tc_chain, test_url_get_media_fragment_table);
return s;
}

View file

@ -1493,6 +1493,7 @@ EXPORTS
gst_uri_get_fragment
gst_uri_get_host
gst_uri_get_location
gst_uri_get_media_fragment_table
gst_uri_get_path
gst_uri_get_path_segments
gst_uri_get_path_string