gstpad: Probes that return HANDLED can reset the data info field
[platform/upstream/gstreamer.git] / gst / gsturi.c
index b13dbca..a5b7190 100644 (file)
 
 /**
  * SECTION:gsturihandler
+ * @title: GstUriHandler
  * @short_description: Interface to ease URI handling in plugins.
  *
- * The URIHandler is an interface that is implemented by Source and Sink
- * #GstElement to simplify then handling of URI.
+ * The #GstURIHandler is an interface that is implemented by Source and Sink
+ * #GstElement to unify handling of URI.
  *
  * An application can use the following functions to quickly get an element
  * that handles the given URI for reading or writing
@@ -118,25 +119,6 @@ _gst_ascii_strcasestr (const gchar * s, const gchar * find)
 }
 #endif
 
-#if !GLIB_CHECK_VERSION (2, 33, 4)
-#define g_list_copy_deep gst_g_list_copy_deep
-static GList *
-gst_g_list_copy_deep (GList * list, GCopyFunc func, gpointer user_data)
-{
-  list = g_list_copy (list);
-
-  if (func != NULL) {
-    GList *l;
-
-    for (l = list; l != NULL; l = l->next) {
-      l->data = func (l->data, user_data);
-    }
-  }
-
-  return list;
-}
-#endif
-
 GType
 gst_uri_handler_get_type (void)
 {
@@ -173,6 +155,9 @@ gst_uri_error_quark (void)
   return g_quark_from_static_string ("gst-uri-error-quark");
 }
 
+#define HEX_ESCAPE '%'
+
+#ifndef GST_REMOVE_DEPRECATED
 static const guchar acceptable[96] = {  /* X0   X1   X2   X3   X4   X5   X6   X7   X8   X9   XA   XB   XC   XD   XE   XF */
   0x00, 0x3F, 0x20, 0x20, 0x20, 0x00, 0x2C, 0x3F, 0x3F, 0x3F, 0x3F, 0x22, 0x20, 0x3F, 0x3F, 0x1C,       /* 2X  !"#$%&'()*+,-./   */
   0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x20, 0x20, 0x2C, 0x20, 0x2C,       /* 3X 0123456789:;<=>?   */
@@ -192,8 +177,6 @@ typedef enum
   UNSAFE_SLASHES = 0x20         /* Allows all characters except for '/' and '%' */
 } UnsafeCharacterSet;
 
-#define HEX_ESCAPE '%'
-
 /*  Escape undesirable characters using %
  *  -------------------------------------
  *
@@ -266,21 +249,7 @@ escape_string_internal (const gchar * string, UnsafeCharacterSet mask)
 
   return result;
 }
-
-/* escape_string:
- * @string: string to be escaped
- *
- * Escapes @string, replacing any and all special characters
- * with equivalent escape sequences.
- *
- * Return value: a newly allocated string equivalent to @string
- * but with all special characters escaped
- **/
-static gchar *
-escape_string (const gchar * string)
-{
-  return escape_string_internal (string, UNSAFE_ALL);
-}
+#endif
 
 static int
 hex_to_int (gchar c)
@@ -428,7 +397,7 @@ gst_uri_is_valid (const gchar * uri)
  * Extracts the protocol out of a given valid URI. The returned string must be
  * freed using g_free().
  *
- * Returns: The protocol for this URI.
+ * Returns: (nullable): The protocol for this URI.
  */
 gchar *
 gst_uri_get_protocol (const gchar * uri)
@@ -480,9 +449,9 @@ gst_uri_has_protocol (const gchar * uri, const gchar * protocol)
  *
  * Free-function: g_free
  *
- * Returns: (transfer full): the location for this URI. Returns %NULL if the
- *     URI isn't valid. If the URI does not contain a location, an empty
- *     string is returned.
+ * Returns: (transfer full) (nullable): the location for this URI. Returns
+ *     %NULL if the URI isn't valid. If the URI does not contain a location, an
+ *     empty string is returned.
  */
 gchar *
 gst_uri_get_location (const gchar * uri)
@@ -529,7 +498,10 @@ gst_uri_get_location (const gchar * uri)
  *
  * Returns: (transfer full): a new string for this URI. Returns %NULL if the
  *     given URI protocol is not valid, or the given location is %NULL.
+ *
+ * Deprecated: Use GstURI instead.
  */
+#ifndef GST_REMOVE_DEPRECATED
 gchar *
 gst_uri_construct (const gchar * protocol, const gchar * location)
 {
@@ -540,13 +512,14 @@ gst_uri_construct (const gchar * protocol, const gchar * location)
   g_return_val_if_fail (location != NULL, NULL);
 
   proto_lowercase = g_ascii_strdown (protocol, -1);
-  escaped = escape_string (location);
+  escaped = escape_string_internal (location, UNSAFE_PATH);
   retval = g_strdup_printf ("%s://%s", proto_lowercase, escaped);
   g_free (escaped);
   g_free (proto_lowercase);
 
   return retval;
 }
+#endif
 
 typedef struct
 {
@@ -645,7 +618,8 @@ gst_uri_protocol_is_supported (const GstURIType type, const gchar * protocol)
  *
  * Creates an element for handling the given URI.
  *
- * Returns: (transfer floating): a new element or %NULL if none could be created
+ * Returns: (transfer floating) (nullable): a new element or %NULL if none
+ * could be created
  */
 GstElement *
 gst_element_make_from_uri (const GstURIType type, const gchar * uri,
@@ -918,7 +892,7 @@ file_path_contains_relatives (const gchar * path)
 
 /**
  * gst_filename_to_uri:
- * @filename: absolute or relative file name path
+ * @filename: (type filename): absolute or relative file name path
  * @error: pointer to error, or %NULL
  *
  * Similar to g_filename_to_uri(), but attempts to handle relative file paths
@@ -979,10 +953,11 @@ beach:
 
 /**
  * SECTION:gsturi
+ * @title: GstUri
  * @short_description: URI parsing and manipulation.
  *
  * A #GstUri object can be used to parse and split a URI string into its
- * constituant parts. Two #GstUri objects can be joined to make a new #GstUri
+ * constituent parts. Two #GstUri objects can be joined to make a new #GstUri
  * using the algorithm described in RFC3986.
  */
 
@@ -1013,6 +988,9 @@ static GstUri *
 _gst_uri_new (void)
 {
   GstUri *uri;
+
+  g_return_val_if_fail (gst_is_initialized (), NULL);
+
   uri = GST_URI_CAST (g_slice_new0 (GstUri));
 
   if (uri)
@@ -1036,6 +1014,10 @@ _gst_uri_free (GstUri * uri)
     g_hash_table_unref (uri->query);
   g_free (uri->fragment);
 
+#ifdef USE_POISONING
+  memset (uri, 0xff, sizeof (*uri));
+#endif
+
   g_slice_free1 (sizeof (*uri), uri);
 }
 
@@ -1238,7 +1220,12 @@ _remove_dot_segments (GList * path)
         out = g_list_delete_link (out, prev);
       }
       g_free (elem->data);
-      out = g_list_delete_link (out, elem);
+      if (next != NULL) {
+        out = g_list_delete_link (out, elem);
+      } else {
+        /* path ends in '/..' We need to keep the last '/' */
+        elem->data = NULL;
+      }
     }
   }
 
@@ -1517,7 +1504,7 @@ gst_uri_new_with_base (GstUri * base, const gchar * scheme,
  * Parses a URI string into a new #GstUri object. Will return NULL if the URI
  * cannot be parsed.
  *
- * Returns: (transfer full)(nullable): A new #GstUri object, or NULL.
+ * Returns: (transfer full) (nullable): A new #GstUri object, or NULL.
  *
  * Since: 1.6
  */
@@ -1567,7 +1554,7 @@ gst_uri_from_string (const gchar * uri)
         if (eoh == NULL || eoh > eoa) {
           GST_DEBUG ("Unable to parse the host part of the URI '%s'.",
               orig_uri);
-          _gst_uri_free (uri_obj);
+          gst_uri_unref (uri_obj);
           return NULL;
         }
         reoh = eoh + 1;
@@ -1587,7 +1574,7 @@ gst_uri_from_string (const gchar * uri)
         if (uri[0] != ':' || strspn (uri + 1, "0123456789") != eoa - uri - 1) {
           GST_DEBUG ("Unable to parse host/port part of the URI '%s'.",
               orig_uri);
-          _gst_uri_free (uri_obj);
+          gst_uri_unref (uri_obj);
           return NULL;
         }
         /* otherwise treat port as unsigned decimal number */
@@ -1779,16 +1766,16 @@ gst_uri_equal (const GstUri * first, const GstUri * second)
 
 /**
  * gst_uri_join:
- * @base_uri: (transfer none)(nullable): The base URI to join another to.
- * @ref_uri: (transfer none)(nullable): The reference URI to join onto the
- *                                        base URI.
+ * @base_uri: (transfer none) (nullable): The base URI to join another to.
+ * @ref_uri: (transfer none) (nullable): The reference URI to join onto the
+ *                                       base URI.
  *
  * Join a reference URI onto a base URI using the method from RFC 3986.
  * If either URI is %NULL then the other URI will be returned with the ref count
  * increased.
  *
- * Returns: (transfer full): A #GstUri which represents the base with the
- *                           reference URI joined on.
+ * Returns: (transfer full) (nullable): A #GstUri which represents the base
+ *                                      with the reference URI joined on.
  *
  * Since: 1.6
  */
@@ -1946,7 +1933,7 @@ gst_uri_make_writable (GstUri * uri)
  *
  * Convert the URI to a string.
  *
- * Returns the URI as held in this object as a gchar* %NULL terminated string.
+ * Returns the URI as held in this object as a #gchar* nul-terminated string.
  * The caller should g_free() the string once they are finished with it.
  * The string is put together as described in RFC 3986.
  *
@@ -2096,7 +2083,7 @@ gst_uri_normalize (GstUri * uri)
  * Get the scheme name from the URI or %NULL if it doesn't exist.
  * If @uri is %NULL then returns %NULL.
  *
- * Returns: The scheme from the #GstUri object or %NULL.
+ * Returns: (nullable): The scheme from the #GstUri object or %NULL.
  */
 const gchar *
 gst_uri_get_scheme (const GstUri * uri)
@@ -2136,7 +2123,7 @@ gst_uri_set_scheme (GstUri * uri, const gchar * scheme)
  * Get the userinfo (usually in the form "username:password") from the URI
  * or %NULL if it doesn't exist. If @uri is %NULL then returns %NULL.
  *
- * Returns: The userinfo from the #GstUri object or %NULL.
+ * Returns: (nullable): The userinfo from the #GstUri object or %NULL.
  *
  * Since: 1.6
  */
@@ -2178,7 +2165,7 @@ gst_uri_set_userinfo (GstUri * uri, const gchar * userinfo)
  * Get the host name from the URI or %NULL if it doesn't exist.
  * If @uri is %NULL then returns %NULL.
  *
- * Returns: The host name from the #GstUri object or %NULL.
+ * Returns: (nullable): The host name from the #GstUri object or %NULL.
  *
  * Since: 1.6
  */
@@ -2260,8 +2247,8 @@ gst_uri_set_port (GstUri * uri, guint port)
  *
  * Extract the path string from the URI object.
  *
- * Returns: (transfer full): The path from the URI. Once finished with the
- *                           string should be g_free()'d.
+ * Returns: (transfer full) (nullable): The path from the URI. Once finished
+ *                                      with the string should be g_free()'d.
  *
  * Since: 1.6
  */
@@ -2294,7 +2281,7 @@ gst_uri_get_path (const GstUri * uri)
 
 /**
  * gst_uri_set_path:
- * @uri: (transfer none)(nullable): The #GstUri to modify.
+ * @uri: (transfer none) (nullable): The #GstUri to modify.
  * @path: The new path to set with path segments separated by '/', or use %NULL
  *        to unset the path.
  *
@@ -2323,8 +2310,8 @@ gst_uri_set_path (GstUri * uri, const gchar * path)
  *
  * Extract the path string from the URI object as a percent encoded URI path.
  *
- * Returns: (transfer full): The path from the URI. Once finished with the
- *                           string should be g_free()'d.
+ * Returns: (transfer full) (nullable): The path from the URI. Once finished
+ *                                      with the string should be g_free()'d.
  *
  * Since: 1.6
  */
@@ -2388,7 +2375,7 @@ gst_uri_set_path_string (GstUri * uri, const gchar * path)
  *
  * Get a list of path segments from the URI.
  *
- * Returns: (transfer full)(element-type gchar*): A #GList of path segment
+ * Returns: (transfer full) (element-type gchar*): A #GList of path segment
  *          strings or %NULL if no path segments are available. Free the list
  *          when no longer needed with g_list_free_full(list, g_free).
  *
@@ -2510,8 +2497,8 @@ gst_uri_append_path_segment (GstUri * uri, const gchar * path_segment)
  *
  * Get a percent encoded URI query string from the @uri.
  *
- * Returns: (transfer full): A percent encoded query string. Use g_free() when
- *          no longer needed.
+ * Returns: (transfer full) (nullable): A percent encoded query string. Use
+ *                                      g_free() when no longer needed.
  *
  * Since: 1.6
  */
@@ -2586,8 +2573,8 @@ gst_uri_set_query_string (GstUri * uri, const gchar * query)
  * no longer required. Modifying this hash table will modify the query in the
  * URI.
  *
- * Returns: (transfer full)(element-type gchar* gchar*): The query hash table
- *          from the URI.
+ * Returns: (transfer full) (element-type gchar* gchar*) (nullable): The query
+ *          hash table from the URI.
  *
  * Since: 1.6
  */
@@ -2613,7 +2600,7 @@ gst_uri_get_query_table (const GstUri * uri)
  * reference to the new one is used instead. A value if %NULL for @query_table
  * will remove the query string from the URI.
  *
- * Returns: %TRUE if the new table was sucessfully used for the query table.
+ * Returns: %TRUE if the new table was successfully used for the query table.
  *
  * Since: 1.6
  */
@@ -2647,7 +2634,7 @@ gst_uri_set_query_table (GstUri * uri, GHashTable * query_table)
  * indicates that the key has no associated value, but will still be present in
  * the query string.
  *
- * Returns: %TRUE if the query table was sucessfully updated.
+ * Returns: %TRUE if the query table was successfully updated.
  *
  * Since: 1.6
  */
@@ -2734,7 +2721,7 @@ gst_uri_query_has_key (const GstUri * uri, const gchar * query_key)
  * use gst_uri_query_has_key() to determine if a key is present in the URI
  * query.
  *
- * Returns: The value for the given key, or %NULL if not found.
+ * Returns: (nullable): The value for the given key, or %NULL if not found.
  *
  * Since: 1.6
  */
@@ -2756,7 +2743,7 @@ gst_uri_get_query_value (const GstUri * uri, const gchar * query_key)
  *
  * Get a list of the query keys from the URI.
  *
- * Returns: (transfer container)(element-type gchar*): A list of keys from
+ * Returns: (transfer container) (element-type gchar*): A list of keys from
  *          the URI query. Free the list with g_list_free().
  *
  * Since: 1.6
@@ -2780,7 +2767,7 @@ gst_uri_get_query_keys (const GstUri * uri)
  * Get the fragment name from the URI or %NULL if it doesn't exist.
  * If @uri is %NULL then returns %NULL.
  *
- * Returns: The host name from the #GstUri object or %NULL.
+ * Returns: (nullable): The host name from the #GstUri object or %NULL.
  *
  * Since: 1.6
  */
@@ -2814,3 +2801,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 split 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*) (nullable): 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);
+}