/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 * Copyright (C) 2011 Tim-Philipp Müller <tim centricular net>
 * Copyright (C) 2014 David Waring, British Broadcasting Corporation
 *                        <david.waring@rd.bbc.co.uk>
 *
 * gsturi.c: register URI handlers and IETF RFC 3986 URI manipulations.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION: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.
 *
 * An application can use the following functions to quickly get an element
 * that handles the given URI for reading or writing
 * (gst_element_make_from_uri()).
 *
 * Source and Sink plugins should implement this interface when possible.
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "gst_private.h"
#include "gst.h"
#include "gsturi.h"
#include "gstinfo.h"
#include "gstregistry.h"

#include "gst-i18n-lib.h"

#include <string.h>
#include <glib.h>
#include <glib/gprintf.h>

GST_DEBUG_CATEGORY_STATIC (gst_uri_handler_debug);
#define GST_CAT_DEFAULT gst_uri_handler_debug

#ifndef HAVE_STRCASESTR
#define strcasestr _gst_ascii_strcasestr

/* From https://github.com/freebsd/freebsd/blob/master/contrib/file/src/strcasestr.c
 * Updated to use GLib types and GLib string functions
 *
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Chris Torek.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Find the first occurrence of find in s, ignore case.
 */

static gchar *
_gst_ascii_strcasestr (const gchar * s, const gchar * find)
{
  gchar c, sc;
  gsize len;

  if ((c = *find++) != 0) {
    c = g_ascii_tolower (c);
    len = strlen (find);
    do {
      do {
        if ((sc = *s++) == 0)
          return (NULL);
      } while (g_ascii_tolower (sc) != c);
    } while (g_ascii_strncasecmp (s, find, len) != 0);
    s--;
  }
  return (gchar *) (gintptr) (s);
}
#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)
{
  static volatile gsize urihandler_type = 0;

  if (g_once_init_enter (&urihandler_type)) {
    GType _type;
    static const GTypeInfo urihandler_info = {
      sizeof (GstURIHandlerInterface),
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      0,
      0,
      NULL,
      NULL
    };

    _type = g_type_register_static (G_TYPE_INTERFACE,
        "GstURIHandler", &urihandler_info, 0);

    GST_DEBUG_CATEGORY_INIT (gst_uri_handler_debug, "GST_URI", GST_DEBUG_BOLD,
        "handling of URIs");
    g_once_init_leave (&urihandler_type, _type);
  }
  return urihandler_type;
}

GQuark
gst_uri_error_quark (void)
{
  return g_quark_from_static_string ("gst-uri-error-quark");
}

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:;<=>?   */
  0x30, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,       /* 4X @ABCDEFGHIJKLMNO   */
  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x3F,       /* 5X PQRSTUVWXYZ[\]^_   */
  0x20, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,       /* 6X `abcdefghijklmno   */
  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x3F, 0x20        /* 7X pqrstuvwxyz{|}~DEL */
};

typedef enum
{
  UNSAFE_ALL = 0x1,             /* Escape all unsafe characters   */
  UNSAFE_ALLOW_PLUS = 0x2,      /* Allows '+'  */
  UNSAFE_PATH = 0x4,            /* Allows '/' and '?' and '&' and '='  */
  UNSAFE_DOS_PATH = 0x8,        /* Allows '/' and '?' and '&' and '=' and ':' */
  UNSAFE_HOST = 0x10,           /* Allows '/' and ':' and '@' */
  UNSAFE_SLASHES = 0x20         /* Allows all characters except for '/' and '%' */
} UnsafeCharacterSet;

#define HEX_ESCAPE '%'

/*  Escape undesirable characters using %
 *  -------------------------------------
 *
 * This function takes a pointer to a string in which
 * some characters may be unacceptable unescaped.
 * It returns a string which has these characters
 * represented by a '%' character followed by two hex digits.
 *
 * This routine returns a g_malloced string.
 */

static const gchar hex[16] = "0123456789ABCDEF";

static gchar *
escape_string_internal (const gchar * string, UnsafeCharacterSet mask)
{
#define ACCEPTABLE_CHAR(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))

  const gchar *p;
  gchar *q;
  gchar *result;
  guchar c;
  gint unacceptable;
  UnsafeCharacterSet use_mask;

  g_return_val_if_fail (mask == UNSAFE_ALL
      || mask == UNSAFE_ALLOW_PLUS
      || mask == UNSAFE_PATH
      || mask == UNSAFE_DOS_PATH
      || mask == UNSAFE_HOST || mask == UNSAFE_SLASHES, NULL);

  if (string == NULL) {
    return NULL;
  }

  unacceptable = 0;
  use_mask = mask;
  for (p = string; *p != '\0'; p++) {
    c = *p;
    if (!ACCEPTABLE_CHAR (c)) {
      unacceptable++;
    }
    if ((use_mask == UNSAFE_HOST) && (unacceptable || (c == '/'))) {
      /* when escaping a host, if we hit something that needs to be escaped, or we finally
       * hit a path separator, revert to path mode (the host segment of the url is over).
       */
      use_mask = UNSAFE_PATH;
    }
  }

  result = g_malloc (p - string + unacceptable * 2 + 1);

  use_mask = mask;
  for (q = result, p = string; *p != '\0'; p++) {
    c = *p;

    if (!ACCEPTABLE_CHAR (c)) {
      *q++ = HEX_ESCAPE;        /* means hex coming */
      *q++ = hex[c >> 4];
      *q++ = hex[c & 15];
    } else {
      *q++ = c;
    }
    if ((use_mask == UNSAFE_HOST) && (!ACCEPTABLE_CHAR (c) || (c == '/'))) {
      use_mask = UNSAFE_PATH;
    }
  }

  *q = '\0';

  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);
}

static int
hex_to_int (gchar c)
{
  return c >= '0' && c <= '9' ? c - '0'
      : c >= 'A' && c <= 'F' ? c - 'A' + 10
      : c >= 'a' && c <= 'f' ? c - 'a' + 10 : -1;
}

static int
unescape_character (const char *scanner)
{
  int first_digit;
  int second_digit;

  first_digit = hex_to_int (*scanner++);
  if (first_digit < 0) {
    return -1;
  }

  second_digit = hex_to_int (*scanner);
  if (second_digit < 0) {
    return -1;
  }

  return (first_digit << 4) | second_digit;
}

/* unescape_string:
 * @escaped_string: an escaped URI, path, or other string
 * @illegal_characters: a string containing a sequence of characters
 * considered "illegal", '\0' is automatically in this list.
 *
 * Decodes escaped characters (i.e. PERCENTxx sequences) in @escaped_string.
 * Characters are encoded in PERCENTxy form, where xy is the ASCII hex code
 * for character 16x+y.
 *
 * Return value: (nullable): a newly allocated string with the
 * unescaped equivalents, or %NULL if @escaped_string contained one of
 * the characters in @illegal_characters.
 **/
static char *
unescape_string (const gchar * escaped_string, const gchar * illegal_characters)
{
  const gchar *in;
  gchar *out, *result;
  gint character;

  if (escaped_string == NULL) {
    return NULL;
  }

  result = g_malloc (strlen (escaped_string) + 1);

  out = result;
  for (in = escaped_string; *in != '\0'; in++) {
    character = *in;
    if (*in == HEX_ESCAPE) {
      character = unescape_character (in + 1);

      /* Check for an illegal character. We consider '\0' illegal here. */
      if (character <= 0
          || (illegal_characters != NULL
              && strchr (illegal_characters, (char) character) != NULL)) {
        g_free (result);
        return NULL;
      }
      in += 2;
    }
    *out++ = (char) character;
  }

  *out = '\0';
  g_assert ((gsize) (out - result) <= strlen (escaped_string));
  return result;

}


static void
gst_uri_protocol_check_internal (const gchar * uri, gchar ** endptr)
{
  gchar *check = (gchar *) uri;

  g_assert (uri != NULL);
  g_assert (endptr != NULL);

  if (g_ascii_isalpha (*check)) {
    check++;
    while (g_ascii_isalnum (*check) || *check == '+'
        || *check == '-' || *check == '.')
      check++;
  }

  *endptr = check;
}

/**
 * gst_uri_protocol_is_valid:
 * @protocol: A string
 *
 * Tests if the given string is a valid protocol identifier. Protocols
 * must consist of alphanumeric characters, '+', '-' and '.' and must
 * start with a alphabetic character. See RFC 3986 Section 3.1.
 *
 * Returns: %TRUE if the string is a valid protocol identifier, %FALSE otherwise.
 */
gboolean
gst_uri_protocol_is_valid (const gchar * protocol)
{
  gchar *endptr;

  g_return_val_if_fail (protocol != NULL, FALSE);

  gst_uri_protocol_check_internal (protocol, &endptr);

  return *endptr == '\0' && ((gsize) (endptr - protocol)) >= 2;
}

/**
 * gst_uri_is_valid:
 * @uri: A URI string
 *
 * Tests if the given string is a valid URI identifier. URIs start with a valid
 * scheme followed by ":" and maybe a string identifying the location.
 *
 * Returns: %TRUE if the string is a valid URI
 */
gboolean
gst_uri_is_valid (const gchar * uri)
{
  gchar *endptr;

  g_return_val_if_fail (uri != NULL, FALSE);

  gst_uri_protocol_check_internal (uri, &endptr);

  return *endptr == ':' && ((gsize) (endptr - uri)) >= 2;
}

/**
 * gst_uri_get_protocol:
 * @uri: A URI string
 *
 * Extracts the protocol out of a given valid URI. The returned string must be
 * freed using g_free().
 *
 * Returns: The protocol for this URI.
 */
gchar *
gst_uri_get_protocol (const gchar * uri)
{
  gchar *colon;

  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);

  colon = strstr (uri, ":");

  return g_ascii_strdown (uri, colon - uri);
}

/**
 * gst_uri_has_protocol:
 * @uri: a URI string
 * @protocol: a protocol string (e.g. "http")
 *
 * Checks if the protocol of a given valid URI matches @protocol.
 *
 * Returns: %TRUE if the protocol matches.
 */
gboolean
gst_uri_has_protocol (const gchar * uri, const gchar * protocol)
{
  gchar *colon;

  g_return_val_if_fail (uri != NULL, FALSE);
  g_return_val_if_fail (protocol != NULL, FALSE);
  g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);

  colon = strstr (uri, ":");

  if (colon == NULL)
    return FALSE;

  return (g_ascii_strncasecmp (uri, protocol, (gsize) (colon - uri)) == 0);
}

/**
 * gst_uri_get_location:
 * @uri: A URI string
 *
 * Extracts the location out of a given valid URI, ie. the protocol and "://"
 * are stripped from the URI, which means that the location returned includes
 * the hostname if one is specified. The returned string must be freed using
 * g_free().
 *
 * 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.
 */
gchar *
gst_uri_get_location (const gchar * uri)
{
  const gchar *colon;
  gchar *unescaped = NULL;

  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);

  colon = strstr (uri, "://");
  if (!colon)
    return NULL;

  unescaped = unescape_string (colon + 3, "/");

  /* On Windows an URI might look like file:///c:/foo/bar.txt or
   * file:///c|/foo/bar.txt (some Netscape versions) and we want to
   * return c:/foo/bar.txt as location rather than /c:/foo/bar.txt.
   * Can't use g_filename_from_uri() here because it will only handle the
   * file:// protocol */
#ifdef G_OS_WIN32
  if (unescaped != NULL && unescaped[0] == '/' &&
      g_ascii_isalpha (unescaped[1]) &&
      (unescaped[2] == ':' || unescaped[2] == '|')) {
    unescaped[2] = ':';
    memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
  }
#endif

  GST_LOG ("extracted location '%s' from URI '%s'", GST_STR_NULL (unescaped),
      uri);
  return unescaped;
}

/**
 * gst_uri_construct:
 * @protocol: Protocol for URI
 * @location: (transfer none): Location for URI
 *
 * Constructs a URI for a given valid protocol and location.
 *
 * Free-function: g_free
 *
 * 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.
 */
gchar *
gst_uri_construct (const gchar * protocol, const gchar * location)
{
  char *escaped, *proto_lowercase;
  char *retval;

  g_return_val_if_fail (gst_uri_protocol_is_valid (protocol), NULL);
  g_return_val_if_fail (location != NULL, NULL);

  proto_lowercase = g_ascii_strdown (protocol, -1);
  escaped = escape_string (location);
  retval = g_strdup_printf ("%s://%s", proto_lowercase, escaped);
  g_free (escaped);
  g_free (proto_lowercase);

  return retval;
}

typedef struct
{
  GstURIType type;
  const gchar *protocol;
}
SearchEntry;

static gboolean
search_by_entry (GstPluginFeature * feature, gpointer search_entry)
{
  const gchar *const *protocols;
  GstElementFactory *factory;
  SearchEntry *entry = (SearchEntry *) search_entry;

  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;
  factory = GST_ELEMENT_FACTORY_CAST (feature);

  if (factory->uri_type != entry->type)
    return FALSE;

  protocols = gst_element_factory_get_uri_protocols (factory);

  if (protocols == NULL) {
    g_warning ("Factory '%s' implements GstUriHandler interface but returned "
        "no supported protocols!", gst_plugin_feature_get_name (feature));
    return FALSE;
  }

  while (*protocols != NULL) {
    if (g_ascii_strcasecmp (*protocols, entry->protocol) == 0)
      return TRUE;
    protocols++;
  }
  return FALSE;
}

static gint
sort_by_rank (GstPluginFeature * first, GstPluginFeature * second)
{
  return gst_plugin_feature_get_rank (second) -
      gst_plugin_feature_get_rank (first);
}

static GList *
get_element_factories_from_uri_protocol (const GstURIType type,
    const gchar * protocol)
{
  GList *possibilities;
  SearchEntry entry;

  g_return_val_if_fail (protocol, NULL);

  entry.type = type;
  entry.protocol = protocol;
  possibilities = gst_registry_feature_filter (gst_registry_get (),
      search_by_entry, FALSE, &entry);

  return possibilities;
}

/**
 * gst_uri_protocol_is_supported:
 * @type: Whether to check for a source or a sink
 * @protocol: Protocol that should be checked for (e.g. "http" or "smb")
 *
 * Checks if an element exists that supports the given URI protocol. Note
 * that a positive return value does not imply that a subsequent call to
 * gst_element_make_from_uri() is guaranteed to work.
 *
 * Returns: %TRUE
*/
gboolean
gst_uri_protocol_is_supported (const GstURIType type, const gchar * protocol)
{
  GList *possibilities;

  g_return_val_if_fail (protocol, FALSE);

  possibilities = get_element_factories_from_uri_protocol (type, protocol);

  if (possibilities) {
    g_list_free (possibilities);
    return TRUE;
  } else
    return FALSE;
}

/**
 * gst_element_make_from_uri:
 * @type: Whether to create a source or a sink
 * @uri: URI to create an element for
 * @elementname: (allow-none): Name of created element, can be %NULL.
 * @error: (allow-none): address where to store error information, or %NULL.
 *
 * Creates an element for handling the given URI.
 *
 * Returns: (transfer floating): a new element or %NULL if none could be created
 */
GstElement *
gst_element_make_from_uri (const GstURIType type, const gchar * uri,
    const gchar * elementname, GError ** error)
{
  GList *possibilities, *walk;
  gchar *protocol;
  GstElement *ret = NULL;

  g_return_val_if_fail (gst_is_initialized (), NULL);
  g_return_val_if_fail (GST_URI_TYPE_IS_VALID (type), NULL);
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  GST_DEBUG ("type:%d, uri:%s, elementname:%s", type, uri, elementname);

  protocol = gst_uri_get_protocol (uri);
  possibilities = get_element_factories_from_uri_protocol (type, protocol);

  if (!possibilities) {
    GST_DEBUG ("No %s for URI '%s'", type == GST_URI_SINK ? "sink" : "source",
        uri);
    /* The error message isn't great, but we don't expect applications to
     * show that error to users, but call the missing plugins functions */
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_UNSUPPORTED_PROTOCOL,
        _("No URI handler for the %s protocol found"), protocol);
    g_free (protocol);
    return NULL;
  }
  g_free (protocol);

  possibilities = g_list_sort (possibilities, (GCompareFunc) sort_by_rank);
  walk = possibilities;
  while (walk) {
    GstElementFactory *factory = walk->data;
    GError *uri_err = NULL;

    ret = gst_element_factory_create (factory, elementname);
    if (ret != NULL) {
      GstURIHandler *handler = GST_URI_HANDLER (ret);

      if (gst_uri_handler_set_uri (handler, uri, &uri_err))
        break;

      GST_WARNING ("%s didn't accept URI '%s': %s", GST_OBJECT_NAME (ret), uri,
          uri_err->message);

      if (error != NULL && *error == NULL)
        g_propagate_error (error, uri_err);
      else
        g_error_free (uri_err);

      gst_object_unref (ret);
      ret = NULL;
    }
    walk = walk->next;
  }
  gst_plugin_feature_list_free (possibilities);

  GST_LOG_OBJECT (ret, "created %s for URL '%s'",
      type == GST_URI_SINK ? "sink" : "source", uri);

  /* if the first handler didn't work, but we found another one that works */
  if (ret != NULL)
    g_clear_error (error);

  return ret;
}

/**
 * gst_uri_handler_get_uri_type:
 * @handler: A #GstURIHandler.
 *
 * Gets the type of the given URI handler
 *
 * Returns: the #GstURIType of the URI handler.
 * Returns #GST_URI_UNKNOWN if the @handler isn't implemented correctly.
 */
GstURIType
gst_uri_handler_get_uri_type (GstURIHandler * handler)
{
  GstURIHandlerInterface *iface;
  GstURIType ret;

  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), GST_URI_UNKNOWN);

  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
  g_return_val_if_fail (iface != NULL, GST_URI_UNKNOWN);
  g_return_val_if_fail (iface->get_type != NULL, GST_URI_UNKNOWN);

  ret = iface->get_type (G_OBJECT_TYPE (handler));
  g_return_val_if_fail (GST_URI_TYPE_IS_VALID (ret), GST_URI_UNKNOWN);

  return ret;
}

/**
 * gst_uri_handler_get_protocols:
 * @handler: A #GstURIHandler.
 *
 * Gets the list of protocols supported by @handler. This list may not be
 * modified.
 *
 * Returns: (transfer none) (element-type utf8) (nullable): the
 *     supported protocols.  Returns %NULL if the @handler isn't
 *     implemented properly, or the @handler doesn't support any
 *     protocols.
 */
const gchar *const *
gst_uri_handler_get_protocols (GstURIHandler * handler)
{
  GstURIHandlerInterface *iface;
  const gchar *const *ret;

  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);

  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
  g_return_val_if_fail (iface != NULL, NULL);
  g_return_val_if_fail (iface->get_protocols != NULL, NULL);

  ret = iface->get_protocols (G_OBJECT_TYPE (handler));
  g_return_val_if_fail (ret != NULL, NULL);

  return ret;
}

/**
 * gst_uri_handler_get_uri:
 * @handler: A #GstURIHandler
 *
 * Gets the currently handled URI.
 *
 * Returns: (transfer full) (nullable): the URI currently handled by
 *   the @handler.  Returns %NULL if there are no URI currently
 *   handled. The returned string must be freed with g_free() when no
 *   longer needed.
 */
gchar *
gst_uri_handler_get_uri (GstURIHandler * handler)
{
  GstURIHandlerInterface *iface;
  gchar *ret;

  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);

  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
  g_return_val_if_fail (iface != NULL, NULL);
  g_return_val_if_fail (iface->get_uri != NULL, NULL);
  ret = iface->get_uri (handler);
  if (ret != NULL)
    g_return_val_if_fail (gst_uri_is_valid (ret), NULL);

  return ret;
}

/**
 * gst_uri_handler_set_uri:
 * @handler: A #GstURIHandler
 * @uri: URI to set
 * @error: (allow-none): address where to store a #GError in case of
 *    an error, or %NULL
 *
 * Tries to set the URI of the given handler.
 *
 * Returns: %TRUE if the URI was set successfully, else %FALSE.
 */
gboolean
gst_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  GstURIHandlerInterface *iface;
  gboolean ret;
  gchar *protocol;

  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), FALSE);
  g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
  g_return_val_if_fail (iface != NULL, FALSE);
  g_return_val_if_fail (iface->set_uri != NULL, FALSE);

  protocol = gst_uri_get_protocol (uri);

  if (iface->get_protocols) {
    const gchar *const *protocols;
    const gchar *const *p;
    gboolean found_protocol = FALSE;

    protocols = iface->get_protocols (G_OBJECT_TYPE (handler));
    if (protocols != NULL) {
      for (p = protocols; *p != NULL; ++p) {
        if (g_ascii_strcasecmp (protocol, *p) == 0) {
          found_protocol = TRUE;
          break;
        }
      }

      if (!found_protocol) {
        g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_UNSUPPORTED_PROTOCOL,
            _("URI scheme '%s' not supported"), protocol);
        g_free (protocol);
        return FALSE;
      }
    }
  }

  ret = iface->set_uri (handler, uri, error);

  g_free (protocol);

  return ret;
}

static gchar *
gst_file_utils_canonicalise_path (const gchar * path)
{
  gchar **parts, **p, *clean_path;

#ifdef G_OS_WIN32
  {
    GST_WARNING ("FIXME: canonicalise win32 path");
    return g_strdup (path);
  }
#endif

  parts = g_strsplit (path, "/", -1);

  p = parts;
  while (*p != NULL) {
    if (strcmp (*p, ".") == 0) {
      /* just move all following parts on top of this, incl. NUL terminator */
      g_free (*p);
      memmove (p, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
      /* re-check the new current part again in the next iteration */
      continue;
    } else if (strcmp (*p, "..") == 0 && p > parts) {
      /* just move all following parts on top of the previous part, incl.
       * NUL terminator */
      g_free (*(p - 1));
      g_free (*p);
      memmove (p - 1, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
      /* re-check the new current part again in the next iteration */
      --p;
      continue;
    }
    ++p;
  }
  if (*path == '/') {
    guint num_parts;

    num_parts = g_strv_length (parts) + 1;      /* incl. terminator */
    parts = g_renew (gchar *, parts, num_parts + 1);
    memmove (parts + 1, parts, num_parts * sizeof (gchar *));
    parts[0] = g_strdup ("/");
  }

  clean_path = g_build_filenamev (parts);
  g_strfreev (parts);
  return clean_path;
}

static gboolean
file_path_contains_relatives (const gchar * path)
{
  return (strstr (path, "/./") != NULL || strstr (path, "/../") != NULL ||
      strstr (path, G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S) != NULL ||
      strstr (path, G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S) != NULL);
}

/**
 * gst_filename_to_uri:
 * @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
 * as well. Before converting @filename into an URI, it will be prefixed by
 * the current working directory if it is a relative path, and then the path
 * will be canonicalised so that it doesn't contain any './' or '../' segments.
 *
 * On Windows #filename should be in UTF-8 encoding.
 *
 * Returns: newly-allocated URI string, or NULL on error. The caller must
 *   free the URI string with g_free() when no longer needed.
 */
gchar *
gst_filename_to_uri (const gchar * filename, GError ** error)
{
  gchar *abs_location = NULL;
  gchar *uri, *abs_clean;

  g_return_val_if_fail (filename != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (g_path_is_absolute (filename)) {
    if (!file_path_contains_relatives (filename)) {
      uri = g_filename_to_uri (filename, NULL, error);
      goto beach;
    }

    abs_location = g_strdup (filename);
  } else {
    gchar *cwd;

    cwd = g_get_current_dir ();
    abs_location = g_build_filename (cwd, filename, NULL);
    g_free (cwd);

    if (!file_path_contains_relatives (abs_location)) {
      uri = g_filename_to_uri (abs_location, NULL, error);
      goto beach;
    }
  }

  /* path is now absolute, but contains '.' or '..' */
  abs_clean = gst_file_utils_canonicalise_path (abs_location);
  GST_LOG ("'%s' -> '%s' -> '%s'", filename, abs_location, abs_clean);
  uri = g_filename_to_uri (abs_clean, NULL, error);
  g_free (abs_clean);

beach:

  g_free (abs_location);
  GST_DEBUG ("'%s' -> '%s'", filename, uri);
  return uri;
}

/****************************************************************************
 * GstUri - GstMiniObject to parse and merge URIs according to IETF RFC 3986
 ****************************************************************************/

/**
 * SECTION: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
 * using the algorithm described in RFC3986.
 */

/* Definition for GstUri object */
struct _GstUri
{
  /*< private > */
  GstMiniObject mini_object;
  gchar *scheme;
  gchar *userinfo;
  gchar *host;
  guint port;
  GList *path;
  GHashTable *query;
  gchar *fragment;
};

GST_DEFINE_MINI_OBJECT_TYPE (GstUri, gst_uri);

static GstUri *_gst_uri_copy (const GstUri * uri);
static void _gst_uri_free (GstUri * uri);
static GstUri *_gst_uri_new (void);
static GList *_remove_dot_segments (GList * path);

/* private GstUri functions */

static GstUri *
_gst_uri_new (void)
{
  GstUri *uri;
  uri = GST_URI_CAST (g_slice_new0 (GstUri));

  if (uri)
    gst_mini_object_init (GST_MINI_OBJECT_CAST (uri), 0, gst_uri_get_type (),
        (GstMiniObjectCopyFunction) _gst_uri_copy, NULL,
        (GstMiniObjectFreeFunction) _gst_uri_free);

  return uri;
}

static void
_gst_uri_free (GstUri * uri)
{
  g_return_if_fail (GST_IS_URI (uri));

  g_free (uri->scheme);
  g_free (uri->userinfo);
  g_free (uri->host);
  g_list_free_full (uri->path, g_free);
  if (uri->query)
    g_hash_table_unref (uri->query);
  g_free (uri->fragment);

  g_slice_free1 (sizeof (*uri), uri);
}

static GHashTable *
_gst_uri_copy_query_table (GHashTable * orig)
{
  GHashTable *new = NULL;

  if (orig != NULL) {
    GHashTableIter iter;
    gpointer key, value;
    new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
    g_hash_table_iter_init (&iter, orig);
    while (g_hash_table_iter_next (&iter, &key, &value)) {
      g_hash_table_insert (new, g_strdup (key), g_strdup (value));
    }
  }

  return new;
}

static GstUri *
_gst_uri_copy (const GstUri * orig_uri)
{
  GstUri *new_uri;

  g_return_val_if_fail (GST_IS_URI (orig_uri), NULL);

  new_uri = _gst_uri_new ();

  if (new_uri) {
    new_uri->scheme = g_strdup (orig_uri->scheme);
    new_uri->userinfo = g_strdup (orig_uri->userinfo);
    new_uri->host = g_strdup (orig_uri->host);
    new_uri->port = orig_uri->port;
    new_uri->path = g_list_copy_deep (orig_uri->path, (GCopyFunc) g_strdup,
        NULL);
    new_uri->query = _gst_uri_copy_query_table (orig_uri->query);
    new_uri->fragment = g_strdup (orig_uri->fragment);
  }

  return new_uri;
}

/*
 * _gst_uri_compare_lists:
 *
 * Compare two lists for equality. This compares the two lists, item for item,
 * comparing items in the same position in the two lists. If @first is
 * considered less than @second the result will be negative. If @first is
 * considered to be more than @second then the result will be positive. If the
 * lists are considered to be equal then the result will be 0. If two lists
 * have the same items, but one list is shorter than the other, then the
 * shorter list is considered to be less than the longer list.
 */
static gint
_gst_uri_compare_lists (GList * first, GList * second, GCompareFunc cmp_fn)
{
  GList *itr1, *itr2;
  gint result;

  for (itr1 = first, itr2 = second;
      itr1 != NULL || itr2 != NULL; itr1 = itr1->next, itr2 = itr2->next) {
    if (itr1 == NULL)
      return -1;
    if (itr2 == NULL)
      return 1;
    result = cmp_fn (itr1->data, itr2->data);
    if (result != 0)
      return result;
  }
  return 0;
}

typedef enum
{
  _GST_URI_NORMALIZE_LOWERCASE = 1,
  _GST_URI_NORMALIZE_UPPERCASE = 2
} _GstUriNormalizations;

/*
 * Find the first character that hasn't been normalized according to the @flags.
 */
static gchar *
_gst_uri_first_non_normalized_char (gchar * str, guint flags)
{
  gchar *pos;

  if (str == NULL)
    return NULL;

  for (pos = str; *pos; pos++) {
    if ((flags & _GST_URI_NORMALIZE_UPPERCASE) && g_ascii_islower (*pos))
      return pos;
    if ((flags & _GST_URI_NORMALIZE_LOWERCASE) && g_ascii_isupper (*pos))
      return pos;
  }
  return NULL;
}

static gboolean
_gst_uri_normalize_lowercase (gchar * str)
{
  gchar *pos;
  gboolean ret = FALSE;

  for (pos = _gst_uri_first_non_normalized_char (str,
          _GST_URI_NORMALIZE_LOWERCASE);
      pos != NULL;
      pos = _gst_uri_first_non_normalized_char (pos + 1,
          _GST_URI_NORMALIZE_LOWERCASE)) {
    *pos = g_ascii_tolower (*pos);
    ret = TRUE;
  }

  return ret;
}

#define _gst_uri_normalize_scheme _gst_uri_normalize_lowercase
#define _gst_uri_normalize_hostname _gst_uri_normalize_lowercase

static gboolean
_gst_uri_normalize_path (GList ** path)
{
  GList *new_path;

  new_path = _remove_dot_segments (*path);
  if (_gst_uri_compare_lists (new_path, *path, (GCompareFunc) g_strcmp0) != 0) {
    g_list_free_full (*path, g_free);
    *path = new_path;
    return TRUE;
  }
  g_list_free_full (new_path, g_free);

  return FALSE;
}

static gboolean
_gst_uri_normalize_str_noop (gchar * str)
{
  return FALSE;
}

static gboolean
_gst_uri_normalize_table_noop (GHashTable * table)
{
  return FALSE;
}

#define _gst_uri_normalize_userinfo _gst_uri_normalize_str_noop
#define _gst_uri_normalize_query _gst_uri_normalize_table_noop
#define _gst_uri_normalize_fragment _gst_uri_normalize_str_noop

/* RFC 3986 functions */

static GList *
_merge (GList * base, GList * path)
{
  GList *ret, *path_copy, *last;

  path_copy = g_list_copy_deep (path, (GCopyFunc) g_strdup, NULL);
  /* if base is NULL make path absolute */
  if (base == NULL) {
    if (path_copy != NULL && path_copy->data != NULL) {
      path_copy = g_list_prepend (path_copy, NULL);
    }
    return path_copy;
  }

  ret = g_list_copy_deep (base, (GCopyFunc) g_strdup, NULL);
  last = g_list_last (ret);
  ret = g_list_remove_link (ret, last);
  g_list_free_full (last, g_free);
  ret = g_list_concat (ret, path_copy);

  return ret;
}

static GList *
_remove_dot_segments (GList * path)
{
  GList *out, *elem, *next;

  if (path == NULL)
    return NULL;

  out = g_list_copy_deep (path, (GCopyFunc) g_strdup, NULL);

  for (elem = out; elem; elem = next) {
    next = elem->next;
    if (elem->data == NULL && elem != out && next != NULL) {
      out = g_list_delete_link (out, elem);
    } else if (g_strcmp0 (elem->data, ".") == 0) {
      g_free (elem->data);
      out = g_list_delete_link (out, elem);
    } else if (g_strcmp0 (elem->data, "..") == 0) {
      GList *prev = g_list_previous (elem);
      if (prev && (prev != out || prev->data != NULL)) {
        g_free (prev->data);
        out = g_list_delete_link (out, prev);
      }
      g_free (elem->data);
      out = g_list_delete_link (out, elem);
    }
  }

  return out;
}

static gchar *
_gst_uri_escape_userinfo (const gchar * userinfo)
{
  return g_uri_escape_string (userinfo,
      G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE);
}

static gchar *
_gst_uri_escape_host (const gchar * host)
{
  return g_uri_escape_string (host,
      G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, FALSE);
}

static gchar *
_gst_uri_escape_host_colon (const gchar * host)
{
  return g_uri_escape_string (host,
      G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":", FALSE);
}

static gchar *
_gst_uri_escape_path_segment (const gchar * segment)
{
  return g_uri_escape_string (segment,
      G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE);
}

static gchar *
_gst_uri_escape_http_query_element (const gchar * element)
{
  gchar *ret, *c;

  ret = g_uri_escape_string (element, "!$'()*,;:@/? ", FALSE);
  for (c = ret; *c; c++)
    if (*c == ' ')
      *c = '+';
  return ret;
}

static gchar *
_gst_uri_escape_fragment (const gchar * fragment)
{
  return g_uri_escape_string (fragment,
      G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?", FALSE);
}

static GList *
_gst_uri_string_to_list (const gchar * str, const gchar * sep, gboolean convert,
    gboolean unescape)
{
  GList *new_list = NULL;

  if (str) {
    guint pct_sep_len = 0;
    gchar *pct_sep = NULL;
    gchar **split_str;

    if (convert && !unescape) {
      pct_sep = g_strdup_printf ("%%%2.2X", (guint) (*sep));
      pct_sep_len = 3;
    }

    split_str = g_strsplit (str, sep, -1);
    if (split_str) {
      gchar **next_elem;
      for (next_elem = split_str; *next_elem; next_elem += 1) {
        gchar *elem = *next_elem;
        if (*elem == '\0') {
          new_list = g_list_append (new_list, NULL);
        } else {
          if (convert && !unescape) {
            gchar *next_sep;
            for (next_sep = strcasestr (elem, pct_sep); next_sep;
                next_sep = strcasestr (next_sep + 1, pct_sep)) {
              *next_sep = *sep;
              memmove (next_sep + 1, next_sep + pct_sep_len,
                  strlen (next_sep + pct_sep_len) + 1);
            }
          }
          if (unescape) {
            *next_elem = g_uri_unescape_string (elem, NULL);
            g_free (elem);
            elem = *next_elem;
          }
          new_list = g_list_append (new_list, g_strdup (elem));
        }
      }
    }
    g_strfreev (split_str);
    if (convert && !unescape)
      g_free (pct_sep);
  }

  return new_list;
}

static GHashTable *
_gst_uri_string_to_table (const gchar * str, const gchar * part_sep,
    const gchar * kv_sep, gboolean convert, gboolean unescape)
{
  GHashTable *new_table = NULL;

  if (str) {
    gchar *pct_part_sep = NULL, *pct_kv_sep = NULL;
    gchar **split_parts;

    new_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

    if (convert && !unescape) {
      pct_part_sep = g_strdup_printf ("%%%2.2X", (guint) (*part_sep));
      pct_kv_sep = g_strdup_printf ("%%%2.2X", (guint) (*kv_sep));
    }

    split_parts = g_strsplit (str, part_sep, -1);
    if (split_parts) {
      gchar **next_part;
      for (next_part = split_parts; *next_part; next_part += 1) {
        gchar *part = *next_part;
        gchar *kv_sep_pos;
        gchar *key, *value;
        /* if we are converting percent encoded versions of separators then
         *  substitute the part separator now. */
        if (convert && !unescape) {
          gchar *next_sep;
          for (next_sep = strcasestr (part, pct_part_sep); next_sep;
              next_sep = strcasestr (next_sep + 1, pct_part_sep)) {
            *next_sep = *part_sep;
            memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
          }
        }
        /* find the key/value separator within the part */
        kv_sep_pos = g_strstr_len (part, -1, kv_sep);
        if (kv_sep_pos == NULL) {
          if (unescape) {
            key = g_uri_unescape_string (part, NULL);
          } else {
            key = g_strdup (part);
          }
          value = NULL;
        } else {
          if (unescape) {
            key = g_uri_unescape_segment (part, kv_sep_pos, NULL);
            value = g_uri_unescape_string (kv_sep_pos + 1, NULL);
          } else {
            key = g_strndup (part, kv_sep_pos - part);
            value = g_strdup (kv_sep_pos + 1);
          }
        }
        /* if we are converting percent encoded versions of separators then
         *  substitute the key/value separator in both key and value now. */
        if (convert && !unescape) {
          gchar *next_sep;
          for (next_sep = strcasestr (key, pct_kv_sep); next_sep;
              next_sep = strcasestr (next_sep + 1, pct_kv_sep)) {
            *next_sep = *kv_sep;
            memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
          }
          if (value) {
            for (next_sep = strcasestr (value, pct_kv_sep); next_sep;
                next_sep = strcasestr (next_sep + 1, pct_kv_sep)) {
              *next_sep = *kv_sep;
              memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
            }
          }
        }
        /* add value to the table */
        g_hash_table_insert (new_table, key, value);
      }
    }
    /* tidy up */
    g_strfreev (split_parts);
    if (convert && !unescape) {
      g_free (pct_part_sep);
      g_free (pct_kv_sep);
    }
  }

  return new_table;
}


/*
 * Method definitions.
 */

/**
 * gst_uri_new:
 * @scheme: (nullable): The scheme for the new URI.
 * @userinfo: (nullable): The user-info for the new URI.
 * @host: (nullable): The host name for the new URI.
 * @port: The port number for the new URI or %GST_URI_NO_PORT.
 * @path: (nullable): The path for the new URI with '/' separating path
 *                      elements.
 * @query: (nullable): The query string for the new URI with '&' separating
 *                       query elements. Elements containing '&' characters
 *                       should encode them as "%26".
 * @fragment: (nullable): The fragment name for the new URI.
 *
 * Creates a new #GstUri object with the given URI parts. The path and query
 * strings will be broken down into their elements. All strings should not be
 * escaped except where indicated.
 *
 * Returns: (transfer full): A new #GstUri object.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_new (const gchar * scheme, const gchar * userinfo, const gchar * host,
    guint port, const gchar * path, const gchar * query, const gchar * fragment)
{
  GstUri *new_uri;

  new_uri = _gst_uri_new ();
  if (new_uri) {
    new_uri->scheme = g_strdup (scheme);
    new_uri->userinfo = g_strdup (userinfo);
    new_uri->host = g_strdup (host);
    new_uri->port = port;
    new_uri->path = _gst_uri_string_to_list (path, "/", FALSE, FALSE);
    new_uri->query = _gst_uri_string_to_table (query, "&", "=", TRUE, FALSE);
    new_uri->fragment = g_strdup (fragment);
  }

  return new_uri;
}

/**
 * gst_uri_new_with_base:
 * @base: (transfer none)(nullable): The base URI to join the new URI to.
 * @scheme: (nullable): The scheme for the new URI.
 * @userinfo: (nullable): The user-info for the new URI.
 * @host: (nullable): The host name for the new URI.
 * @port: The port number for the new URI or %GST_URI_NO_PORT.
 * @path: (nullable): The path for the new URI with '/' separating path
 *                      elements.
 * @query: (nullable): The query string for the new URI with '&' separating
 *                       query elements. Elements containing '&' characters
 *                       should encode them as "%26".
 * @fragment: (nullable): The fragment name for the new URI.
 *
 * Like gst_uri_new(), but joins the new URI onto a base URI.
 *
 * Returns: (transfer full): The new URI joined onto @base.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_new_with_base (GstUri * base, const gchar * scheme,
    const gchar * userinfo, const gchar * host, guint port, const gchar * path,
    const gchar * query, const gchar * fragment)
{
  GstUri *new_rel_uri;
  GstUri *new_uri;

  g_return_val_if_fail (base == NULL || GST_IS_URI (base), NULL);

  new_rel_uri = gst_uri_new (scheme, userinfo, host, port, path, query,
      fragment);
  new_uri = gst_uri_join (base, new_rel_uri);
  gst_uri_unref (new_rel_uri);

  return new_uri;
}

/**
 * gst_uri_from_string:
 * @uri: The URI string to parse.
 *
 * 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.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_from_string (const gchar * uri)
{
  const gchar *orig_uri = uri;
  GstUri *uri_obj;

  uri_obj = _gst_uri_new ();

  if (uri_obj && uri != NULL) {
    int i = 0;

    /* be helpful and skip initial white space */
    while (*uri == '\v' || g_ascii_isspace (*uri))
      uri++;

    if (g_ascii_isalpha (uri[i])) {
      /* find end of scheme name */
      i++;
      while (g_ascii_isalnum (uri[i]) || uri[i] == '+' || uri[i] == '-' ||
          uri[i] == '.')
        i++;
    }
    if (i > 0 && uri[i] == ':') {
      /* get scheme */
      uri_obj->scheme = g_strndup (uri, i);
      uri += i + 1;
    }
    if (uri[0] == '/' && uri[1] == '/') {
      const gchar *eoa, *eoui, *eoh, *reoh;
      /* get authority [userinfo@]host[:port] */
      uri += 2;
      /* find end of authority */
      eoa = uri + strcspn (uri, "/?#");

      /* find end of userinfo */
      eoui = strchr (uri, '@');
      if (eoui != NULL && eoui < eoa) {
        uri_obj->userinfo = g_uri_unescape_segment (uri, eoui, NULL);
        uri = eoui + 1;
      }
      /* find end of host */
      if (uri[0] == '[') {
        eoh = strchr (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);
          return NULL;
        }
        reoh = eoh + 1;
        uri++;
      } else {
        reoh = eoh = strchr (uri, ':');
        if (eoh == NULL || eoh > eoa)
          reoh = eoh = eoa;
      }
      /* don't capture empty host strings */
      if (eoh != uri)
        uri_obj->host = g_uri_unescape_segment (uri, eoh, NULL);

      uri = reoh;
      if (uri < eoa) {
        /* if port number is malformed then we can't parse this */
        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);
          return NULL;
        }
        /* otherwise treat port as unsigned decimal number */
        uri++;
        while (uri < eoa) {
          uri_obj->port = uri_obj->port * 10 + g_ascii_digit_value (*uri);
          uri++;
        }
      }
      uri = eoa;
    }
    if (uri != NULL && uri[0] != '\0') {
      /* get path */
      size_t len;
      len = strcspn (uri, "?#");
      if (uri[len] == '\0') {
        uri_obj->path = _gst_uri_string_to_list (uri, "/", FALSE, TRUE);
        uri = NULL;
      } else {
        if (len > 0) {
          gchar *path_str = g_strndup (uri, len);
          uri_obj->path = _gst_uri_string_to_list (path_str, "/", FALSE, TRUE);
          g_free (path_str);
        }
        uri += len;
      }
    }
    if (uri != NULL && uri[0] == '?') {
      /* get query */
      gchar *eoq;
      eoq = strchr (++uri, '#');
      if (eoq == NULL) {
        uri_obj->query = _gst_uri_string_to_table (uri, "&", "=", TRUE, TRUE);
        uri = NULL;
      } else {
        if (eoq != uri) {
          gchar *query_str = g_strndup (uri, eoq - uri);
          uri_obj->query = _gst_uri_string_to_table (query_str, "&", "=", TRUE,
              TRUE);
          g_free (query_str);
        }
        uri = eoq;
      }
    }
    if (uri != NULL && uri[0] == '#') {
      uri_obj->fragment = g_uri_unescape_string (uri + 1, NULL);
    }
  }

  return uri_obj;
}

/**
 * gst_uri_from_string_with_base:
 * @base: (transfer none)(nullable): The base URI to join the new URI with.
 * @uri: The URI string to parse.
 *
 * Like gst_uri_from_string() but also joins with a base URI.
 *
 * Returns: (transfer full): A new #GstUri object.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_from_string_with_base (GstUri * base, const gchar * uri)
{
  GstUri *new_rel_uri;
  GstUri *new_uri;

  g_return_val_if_fail (base == NULL || GST_IS_URI (base), NULL);

  new_rel_uri = gst_uri_from_string (uri);
  new_uri = gst_uri_join (base, new_rel_uri);
  gst_uri_unref (new_rel_uri);

  return new_uri;
}

/**
 * gst_uri_equal:
 * @first: First #GstUri to compare.
 * @second: Second #GstUri to compare.
 *
 * Compares two #GstUri objects to see if they represent the same normalized
 * URI.
 *
 * Returns: %TRUE if the normalized versions of the two URI's would be equal.
 *
 * Since: 1.6
 */
gboolean
gst_uri_equal (const GstUri * first, const GstUri * second)
{
  gchar *first_norm = NULL, *second_norm = NULL;
  GList *first_norm_list = NULL, *second_norm_list = NULL;
  const gchar *first_cmp, *second_cmp;
  GHashTableIter table_iter;
  gpointer key, value;
  int result;

  g_return_val_if_fail ((first == NULL || GST_IS_URI (first)) &&
      (second == NULL || GST_IS_URI (second)), FALSE);

  if (first == second)
    return TRUE;

  if (first == NULL || second == NULL)
    return FALSE;

  if (first->port != second->port)
    return FALSE;

/* work out a version of field value (normalized or not) to compare.
 * first_cmp, second_cmp will be the values to compare later.
 * first_norm, second_norm will be non-NULL if normalized versions are used,
 *  and need to be freed later.
 */
#define GST_URI_NORMALIZED_FIELD(pos, field, norm_fn, flags) \
  pos##_cmp = pos->field; \
  if (_gst_uri_first_non_normalized_char ((gchar*)pos##_cmp, flags) != NULL) { \
    pos##_norm = g_strdup (pos##_cmp); \
    norm_fn (pos##_norm); \
    pos##_cmp = pos##_norm; \
  }

/* compare two string values, normalizing if needed */
#define GST_URI_NORMALIZED_CMP_STR(field, norm_fn, flags) \
  GST_URI_NORMALIZED_FIELD (first, field, norm_fn, flags) \
  GST_URI_NORMALIZED_FIELD (second, field, norm_fn, flags) \
  result = g_strcmp0 (first_cmp, second_cmp); \
  g_free (first_norm); \
  first_norm = NULL; \
  g_free (second_norm); \
  second_norm = NULL; \
  if (result != 0) return FALSE

/* compare two string values */
#define GST_URI_CMP_STR(field) \
  if (g_strcmp0 (first->field, second->field) != 0) return FALSE

/* compare two GLists, normalize lists if needed before comparison */
#define GST_URI_NORMALIZED_CMP_LIST(field, norm_fn, copy_fn, cmp_fn, free_fn) \
  first_norm_list = g_list_copy_deep (first->field, (GCopyFunc) copy_fn, NULL); \
  norm_fn (&first_norm_list); \
  second_norm_list = g_list_copy_deep (second->field, (GCopyFunc) copy_fn, NULL); \
  norm_fn (&second_norm_list); \
  result = _gst_uri_compare_lists (first_norm_list, second_norm_list, (GCompareFunc) cmp_fn); \
  g_list_free_full (first_norm_list, free_fn); \
  g_list_free_full (second_norm_list, free_fn); \
  if (result != 0) return FALSE

  GST_URI_CMP_STR (userinfo);

  GST_URI_CMP_STR (fragment);

  GST_URI_NORMALIZED_CMP_STR (scheme, _gst_uri_normalize_scheme,
      _GST_URI_NORMALIZE_LOWERCASE);

  GST_URI_NORMALIZED_CMP_STR (host, _gst_uri_normalize_hostname,
      _GST_URI_NORMALIZE_LOWERCASE);

  GST_URI_NORMALIZED_CMP_LIST (path, _gst_uri_normalize_path, g_strdup,
      g_strcmp0, g_free);

  if (first->query == NULL && second->query != NULL)
    return FALSE;
  if (first->query != NULL && second->query == NULL)
    return FALSE;
  if (first->query != NULL) {
    if (g_hash_table_size (first->query) != g_hash_table_size (second->query))
      return FALSE;

    g_hash_table_iter_init (&table_iter, first->query);
    while (g_hash_table_iter_next (&table_iter, &key, &value)) {
      if (!g_hash_table_contains (second->query, key))
        return FALSE;
      result = g_strcmp0 (g_hash_table_lookup (second->query, key), value);
      if (result != 0)
        return FALSE;
    }
  }
#undef GST_URI_NORMALIZED_CMP_STR
#undef GST_URI_CMP_STR
#undef GST_URI_NORMALIZED_CMP_LIST
#undef GST_URI_NORMALIZED_FIELD

  return TRUE;
}

/**
 * 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.
 *
 * 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.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_join (GstUri * base_uri, GstUri * ref_uri)
{
  const gchar *r_scheme;
  GstUri *t;

  g_return_val_if_fail ((base_uri == NULL || GST_IS_URI (base_uri)) &&
      (ref_uri == NULL || GST_IS_URI (ref_uri)), NULL);

  if (base_uri == NULL && ref_uri == NULL)
    return NULL;
  if (base_uri == NULL) {
    g_return_val_if_fail (GST_IS_URI (ref_uri), NULL);
    return gst_uri_ref (ref_uri);
  }
  if (ref_uri == NULL) {
    g_return_val_if_fail (GST_IS_URI (base_uri), NULL);
    return gst_uri_ref (base_uri);
  }

  g_return_val_if_fail (GST_IS_URI (base_uri) && GST_IS_URI (ref_uri), NULL);

  t = _gst_uri_new ();

  if (t == NULL)
    return t;

  /* process according to RFC3986 */
  r_scheme = ref_uri->scheme;
  if (r_scheme != NULL && g_strcmp0 (base_uri->scheme, r_scheme) == 0) {
    r_scheme = NULL;
  }
  if (r_scheme != NULL) {
    t->scheme = g_strdup (r_scheme);
    t->userinfo = g_strdup (ref_uri->userinfo);
    t->host = g_strdup (ref_uri->host);
    t->port = ref_uri->port;
    t->path = _remove_dot_segments (ref_uri->path);
    t->query = _gst_uri_copy_query_table (ref_uri->query);
  } else {
    if (ref_uri->host != NULL) {
      t->userinfo = g_strdup (ref_uri->userinfo);
      t->host = g_strdup (ref_uri->host);
      t->port = ref_uri->port;
      t->path = _remove_dot_segments (ref_uri->path);
      t->query = _gst_uri_copy_query_table (ref_uri->query);
    } else {
      if (ref_uri->path == NULL) {
        t->path = g_list_copy_deep (base_uri->path, (GCopyFunc) g_strdup, NULL);
        if (ref_uri->query != NULL)
          t->query = _gst_uri_copy_query_table (ref_uri->query);
        else
          t->query = _gst_uri_copy_query_table (base_uri->query);
      } else {
        if (ref_uri->path->data == NULL)
          t->path = _remove_dot_segments (ref_uri->path);
        else {
          GList *mrgd = _merge (base_uri->path, ref_uri->path);
          t->path = _remove_dot_segments (mrgd);
          g_list_free_full (mrgd, g_free);
        }
        t->query = _gst_uri_copy_query_table (ref_uri->query);
      }
      t->userinfo = g_strdup (base_uri->userinfo);
      t->host = g_strdup (base_uri->host);
      t->port = base_uri->port;
    }
    t->scheme = g_strdup (base_uri->scheme);
  }
  t->fragment = g_strdup (ref_uri->fragment);

  return t;
}

/**
 * gst_uri_join_strings:
 * @base_uri: The percent-encoded base URI.
 * @ref_uri: The percent-encoded reference URI to join to the @base_uri.
 *
 * This is a convenience function to join two URI strings and return the result.
 * The returned string should be g_free()'d after use.
 *
 * Returns: (transfer full): A string representing the percent-encoded join of
 *          the two URIs.
 *
 * Since: 1.6
 */
gchar *
gst_uri_join_strings (const gchar * base_uri, const gchar * ref_uri)
{
  GstUri *base, *result;
  gchar *result_uri;

  base = gst_uri_from_string (base_uri);
  result = gst_uri_from_string_with_base (base, ref_uri);
  result_uri = gst_uri_to_string (result);
  gst_uri_unref (base);
  gst_uri_unref (result);

  return result_uri;
}

/**
 * gst_uri_is_writable:
 * @uri: The #GstUri object to test.
 *
 * Check if it is safe to write to this #GstUri.
 *
 * Check if the refcount of @uri is exactly 1, meaning that no other
 * reference exists to the #GstUri and that the #GstUri is therefore writable.
 *
 * Modification of a #GstUri should only be done after verifying that it is
 * writable.
 *
 * Returns: %TRUE if it is safe to write to the object.
 *
 * Since: 1.6
 */
gboolean
gst_uri_is_writable (const GstUri * uri)
{
  g_return_val_if_fail (GST_IS_URI (uri), FALSE);
  return gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (uri));
}

/**
 * gst_uri_make_writable:
 * @uri: (transfer full): The #GstUri object to make writable.
 *
 * Make the #GstUri writable.
 *
 * Checks if @uri is writable, and if so the original object is returned. If
 * not, then a writable copy is made and returned. This gives away the
 * reference to @uri and returns a reference to the new #GstUri.
 * If @uri is %NULL then %NULL is returned.
 *
 * Returns: (transfer full): A writable version of @uri.
 *
 * Since: 1.6
 */
GstUri *
gst_uri_make_writable (GstUri * uri)
{
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  return
      GST_URI_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (uri)));
}

/**
 * gst_uri_to_string:
 * @uri: This #GstUri to convert to a string.
 *
 * Convert the URI to a 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.
 *
 * Returns: (transfer full): The string version of the URI.
 *
 * Since: 1.6
 */
gchar *
gst_uri_to_string (const GstUri * uri)
{
  GString *uri_str;
  gchar *escaped;

  g_return_val_if_fail (GST_IS_URI (uri), NULL);

  uri_str = g_string_new (NULL);

  if (uri->scheme != NULL)
    g_string_append_printf (uri_str, "%s:", uri->scheme);

  if (uri->userinfo != NULL || uri->host != NULL ||
      uri->port != GST_URI_NO_PORT)
    g_string_append (uri_str, "//");

  if (uri->userinfo != NULL) {
    escaped = _gst_uri_escape_userinfo (uri->userinfo);
    g_string_append_printf (uri_str, "%s@", escaped);
    g_free (escaped);
  }

  if (uri->host != NULL) {
    if (strchr (uri->host, ':') != NULL) {
      escaped = _gst_uri_escape_host_colon (uri->host);
      g_string_append_printf (uri_str, "[%s]", escaped);
      g_free (escaped);
    } else {
      escaped = _gst_uri_escape_host (uri->host);
      g_string_append (uri_str, escaped);
      g_free (escaped);
    }
  }

  if (uri->port != GST_URI_NO_PORT)
    g_string_append_printf (uri_str, ":%u", uri->port);

  if (uri->path != NULL) {
    escaped = gst_uri_get_path_string (uri);
    g_string_append (uri_str, escaped);
    g_free (escaped);
  }

  if (uri->query) {
    g_string_append (uri_str, "?");
    escaped = gst_uri_get_query_string (uri);
    g_string_append (uri_str, escaped);
    g_free (escaped);
  }

  if (uri->fragment != NULL) {
    escaped = _gst_uri_escape_fragment (uri->fragment);
    g_string_append_printf (uri_str, "#%s", escaped);
    g_free (escaped);
  }

  return g_string_free (uri_str, FALSE);
}

/**
 * gst_uri_is_normalized:
 * @uri: The #GstUri to test to see if it is normalized.
 *
 * Tests the @uri to see if it is normalized. A %NULL @uri is considered to be
 * normalized.
 *
 * Returns: TRUE if the URI is normalized or is %NULL.
 *
 * Since: 1.6
 */
gboolean
gst_uri_is_normalized (const GstUri * uri)
{
  GList *new_path;
  gboolean ret;

  if (uri == NULL)
    return TRUE;

  g_return_val_if_fail (GST_IS_URI (uri), FALSE);

  /* check for non-normalized characters in uri parts */
  if (_gst_uri_first_non_normalized_char (uri->scheme,
          _GST_URI_NORMALIZE_LOWERCASE) != NULL ||
      /*_gst_uri_first_non_normalized_char (uri->userinfo,
          _GST_URI_NORMALIZE_PERCENTAGES) != NULL || */
      _gst_uri_first_non_normalized_char (uri->host,
          _GST_URI_NORMALIZE_LOWERCASE /*| _GST_URI_NORMALIZE_PERCENTAGES */ )
      != NULL
      /*|| _gst_uri_first_non_normalized_char (uri->path,
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL
         || _gst_uri_first_non_normalized_char (uri->query,
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL
         || _gst_uri_first_non_normalized_char (uri->fragment,
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL */ )
    return FALSE;

  /* also check path has had dot segments removed */
  new_path = _remove_dot_segments (uri->path);
  ret =
      (_gst_uri_compare_lists (new_path, uri->path,
          (GCompareFunc) g_strcmp0) == 0);
  g_list_free_full (new_path, g_free);
  return ret;
}

/**
 * gst_uri_normalize:
 * @uri: (transfer none): The #GstUri to normalize.
 *
 * Normalization will remove extra path segments ("." and "..") from the URI. It
 * will also convert the scheme and host name to lower case and any
 * percent-encoded values to uppercase.
 *
 * The #GstUri object must be writable. Check with gst_uri_is_writable() or use
 * gst_uri_make_writable() first.
 *
 * Returns: TRUE if the URI was modified.
 *
 * Since: 1.6
 */
gboolean
gst_uri_normalize (GstUri * uri)
{
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  return _gst_uri_normalize_scheme (uri->scheme) |
      _gst_uri_normalize_userinfo (uri->userinfo) |
      _gst_uri_normalize_hostname (uri->host) |
      _gst_uri_normalize_path (&uri->path) |
      _gst_uri_normalize_query (uri->query) |
      _gst_uri_normalize_fragment (uri->fragment);
}

/**
 * gst_uri_get_scheme:
 * @uri: (nullable): This #GstUri object.
 *
 * 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.
 */
const gchar *
gst_uri_get_scheme (const GstUri * uri)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
  return (uri ? uri->scheme : NULL);
}

/**
 * gst_uri_set_scheme:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @scheme: The new scheme to set or %NULL to unset the scheme.
 *
 * Set or unset the scheme for the URI.
 *
 * Returns: %TRUE if the scheme was set/unset successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_scheme (GstUri * uri, const gchar * scheme)
{
  if (!uri)
    return scheme == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_free (uri->scheme);
  uri->scheme = g_strdup (scheme);

  return TRUE;
}

/**
 * gst_uri_get_userinfo:
 * @uri: (nullable): This #GstUri object.
 *
 * 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.
 *
 * Since: 1.6
 */
const gchar *
gst_uri_get_userinfo (const GstUri * uri)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
  return (uri ? uri->userinfo : NULL);
}

/**
 * gst_uri_set_userinfo:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @userinfo: The new user-information string to set or %NULL to unset.
 *
 * Set or unset the user information for the URI.
 *
 * Returns: %TRUE if the user information was set/unset successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_userinfo (GstUri * uri, const gchar * userinfo)
{
  if (!uri)
    return userinfo == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_free (uri->userinfo);
  uri->userinfo = g_strdup (userinfo);

  return TRUE;
}

/**
 * gst_uri_get_host:
 * @uri: (nullable): This #GstUri object.
 *
 * 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.
 *
 * Since: 1.6
 */
const gchar *
gst_uri_get_host (const GstUri * uri)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
  return (uri ? uri->host : NULL);
}

/**
 * gst_uri_set_host:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @host: The new host string to set or %NULL to unset.
 *
 * Set or unset the host for the URI.
 *
 * Returns: %TRUE if the host was set/unset successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_host (GstUri * uri, const gchar * host)
{
  if (!uri)
    return host == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_free (uri->host);
  uri->host = g_strdup (host);

  return TRUE;
}

/**
 * gst_uri_get_port:
 * @uri: (nullable): This #GstUri object.
 *
 * Get the port number from the URI or %GST_URI_NO_PORT if it doesn't exist.
 * If @uri is %NULL then returns %GST_URI_NO_PORT.
 *
 * Returns: The port number from the #GstUri object or %GST_URI_NO_PORT.
 *
 * Since: 1.6
 */
guint
gst_uri_get_port (const GstUri * uri)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), GST_URI_NO_PORT);
  return (uri ? uri->port : GST_URI_NO_PORT);
}

/**
 * gst_uri_set_port:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @port: The new port number to set or %GST_URI_NO_PORT to unset.
 *
 * Set or unset the port number for the URI.
 *
 * Returns: %TRUE if the port number was set/unset successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_port (GstUri * uri, guint port)
{
  if (!uri)
    return port == GST_URI_NO_PORT;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  uri->port = port;

  return TRUE;
}

/**
 * gst_uri_get_path:
 * @uri: The #GstUri to get the path from.
 *
 * 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.
 *
 * Since: 1.6
 */
gchar *
gst_uri_get_path (const GstUri * uri)
{
  GList *path_segment;
  const gchar *sep = "";
  GString *ret;

  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->path)
    return NULL;

  ret = g_string_new (NULL);

  for (path_segment = uri->path; path_segment;
      path_segment = path_segment->next) {
    g_string_append (ret, sep);
    if (path_segment->data) {
      g_string_append (ret, path_segment->data);
    }
    sep = "/";
  }

  return g_string_free (ret, FALSE);
}

/**
 * gst_uri_set_path:
 * @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.
 *
 * Sets or unsets the path in the URI.
 *
 * Returns: %TRUE if the path was set successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_path (GstUri * uri, const gchar * path)
{
  if (!uri)
    return path == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_list_free_full (uri->path, g_free);
  uri->path = _gst_uri_string_to_list (path, "/", FALSE, FALSE);

  return TRUE;
}

/**
 * gst_uri_get_path_string:
 * @uri: The #GstUri to get the path from.
 *
 * 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.
 *
 * Since: 1.6
 */
gchar *
gst_uri_get_path_string (const GstUri * uri)
{
  GList *path_segment;
  const gchar *sep = "";
  GString *ret;
  gchar *escaped;

  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->path)
    return NULL;

  ret = g_string_new (NULL);

  for (path_segment = uri->path; path_segment;
      path_segment = path_segment->next) {
    g_string_append (ret, sep);
    if (path_segment->data) {
      escaped = _gst_uri_escape_path_segment (path_segment->data);
      g_string_append (ret, escaped);
      g_free (escaped);
    }
    sep = "/";
  }

  return g_string_free (ret, FALSE);
}

/**
 * gst_uri_set_path_string:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @path: The new percent encoded path to set with path segments separated by
 * '/', or use %NULL to unset the path.
 *
 * Sets or unsets the path in the URI.
 *
 * Returns: %TRUE if the path was set successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_path_string (GstUri * uri, const gchar * path)
{
  if (!uri)
    return path == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_list_free_full (uri->path, g_free);
  uri->path = _gst_uri_string_to_list (path, "/", FALSE, TRUE);
  return TRUE;
}

/**
 * gst_uri_get_path_segments:
 * @uri: (nullable): The #GstUri to get the path from.
 *
 * Get a list of path segments from the URI.
 *
 * 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).
 *
 * Since: 1.6
 */
GList *
gst_uri_get_path_segments (const GstUri * uri)
{
  GList *ret = NULL;

  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);

  if (uri) {
    ret = g_list_copy_deep (uri->path, (GCopyFunc) g_strdup, NULL);
  }

  return ret;
}

/**
 * gst_uri_set_path_segments:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @path_segments: (transfer full)(nullable)(element-type gchar*): The new
 *                 path list to set.
 *
 * Replace the path segments list in the URI.
 *
 * Returns: %TRUE if the path segments were set successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_path_segments (GstUri * uri, GList * path_segments)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), FALSE);

  if (!uri) {
    if (path_segments)
      g_list_free_full (path_segments, g_free);
    return path_segments == NULL;
  }

  g_return_val_if_fail (gst_uri_is_writable (uri), FALSE);

  g_list_free_full (uri->path, g_free);
  uri->path = path_segments;
  return TRUE;
}

/**
 * gst_uri_append_path:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @relative_path: Relative path to append to the end of the current path.
 *
 * Append a path onto the end of the path in the URI. The path is not
 * normalized, call #gst_uri_normalize() to normalize the path.
 *
 * Returns: %TRUE if the path was appended successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_append_path (GstUri * uri, const gchar * relative_path)
{
  GList *rel_path_list;

  if (!uri)
    return relative_path == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
  if (!relative_path)
    return TRUE;

  if (uri->path) {
    GList *last_elem = g_list_last (uri->path);
    if (last_elem->data == NULL) {
      uri->path = g_list_delete_link (uri->path, last_elem);
    }
  }
  rel_path_list = _gst_uri_string_to_list (relative_path, "/", FALSE, FALSE);
  /* if path was absolute, make it relative by removing initial NULL element */
  if (rel_path_list && rel_path_list->data == NULL) {
    rel_path_list = g_list_delete_link (rel_path_list, rel_path_list);
  }
  uri->path = g_list_concat (uri->path, rel_path_list);
  return TRUE;
}

/**
 * gst_uri_append_path_segment:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @path_segment: The path segment string to append to the URI path.
 *
 * Append a single path segment onto the end of the URI path.
 *
 * Returns: %TRUE if the path was appended successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_append_path_segment (GstUri * uri, const gchar * path_segment)
{
  if (!uri)
    return path_segment == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
  if (!path_segment)
    return TRUE;

  /* if base path ends in a directory (i.e. last element is NULL), remove it */
  if (uri->path && g_list_last (uri->path)->data == NULL) {
    uri->path = g_list_delete_link (uri->path, g_list_last (uri->path));
  }
  uri->path = g_list_append (uri->path, g_strdup (path_segment));
  return TRUE;
}

/**
 * gst_uri_get_query_string:
 * @uri: (nullable): The #GstUri to get the query string from.
 *
 * 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.
 *
 * Since: 1.6
 */
gchar *
gst_uri_get_query_string (const GstUri * uri)
{
  GHashTableIter iter;
  gpointer key, value;
  const gchar *sep = "";
  gchar *escaped;
  GString *ret;

  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->query)
    return NULL;

  ret = g_string_new (NULL);
  g_hash_table_iter_init (&iter, uri->query);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    g_string_append (ret, sep);
    escaped = _gst_uri_escape_http_query_element (key);
    g_string_append (ret, escaped);
    g_free (escaped);
    if (value) {
      escaped = _gst_uri_escape_http_query_element (value);
      g_string_append_printf (ret, "=%s", escaped);
      g_free (escaped);
    }
    sep = "&";
  }

  return g_string_free (ret, FALSE);
}

/**
 * gst_uri_set_query_string:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @query: The new percent encoded query string to use to populate the query
 *        table, or use %NULL to unset the query table.
 *
 * Sets or unsets the query table in the URI.
 *
 * Returns: %TRUE if the query table was set successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_query_string (GstUri * uri, const gchar * query)
{
  if (!uri)
    return query == NULL;

  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  if (uri->query)
    g_hash_table_unref (uri->query);
  uri->query = _gst_uri_string_to_table (query, "&", "=", TRUE, TRUE);

  return TRUE;
}

/**
 * gst_uri_get_query_table:
 * @uri: (nullable): The #GstUri to get the query table from.
 *
 * Get the query table from the URI. Keys and values in the table are freed
 * with g_free when they are deleted. A value may be %NULL to indicate that
 * the key should appear in the query 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 will modify the query in the
 * URI.
 *
 * Returns: (transfer full)(element-type gchar* gchar*): The query hash table
 *          from the URI.
 *
 * Since: 1.6
 */
GHashTable *
gst_uri_get_query_table (const GstUri * uri)
{
  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->query)
    return NULL;

  return g_hash_table_ref (uri->query);
}

/**
 * gst_uri_set_query_table:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @query_table: (transfer none)(nullable)(element-type gchar* gchar*): The new
 *               query table to use.
 *
 * Set the query table to use in the URI. The old table is unreferenced and a
 * 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.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_query_table (GstUri * uri, GHashTable * query_table)
{
  GHashTable *old_table = NULL;

  if (!uri)
    return query_table == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  old_table = uri->query;
  if (query_table)
    uri->query = g_hash_table_ref (query_table);
  else
    uri->query = NULL;
  if (old_table)
    g_hash_table_unref (old_table);

  return TRUE;
}

/**
 * gst_uri_set_query_value:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @query_key: (transfer none): The key for the query entry.
 * @query_value: (transfer none)(nullable): The value for the key.
 *
 * This inserts or replaces a key in the query table. A @query_value of %NULL
 * 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.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_query_value (GstUri * uri, const gchar * query_key,
    const gchar * query_value)
{
  if (!uri)
    return FALSE;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  if (!uri->query) {
    uri->query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
        g_free);
  }
  g_hash_table_insert (uri->query, g_strdup (query_key),
      g_strdup (query_value));

  return TRUE;
}

/**
 * gst_uri_remove_query_key:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @query_key: The key to remove.
 *
 * Remove an entry from the query table by key.
 *
 * Returns: %TRUE if the key existed in the table and was removed.
 *
 * Since: 1.6
 */
gboolean
gst_uri_remove_query_key (GstUri * uri, const gchar * query_key)
{
  gboolean result;

  if (!uri)
    return FALSE;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
  if (!uri->query)
    return FALSE;

  result = g_hash_table_remove (uri->query, query_key);
  /* if this was the last query entry, remove the query string completely */
  if (result && g_hash_table_size (uri->query) == 0) {
    g_hash_table_unref (uri->query);
    uri->query = NULL;
  }
  return result;
}

/**
 * gst_uri_query_has_key:
 * @uri: (nullable): The #GstUri to examine.
 * @query_key: The key to lookup.
 *
 * Check if there is a query table entry for the @query_key key.
 *
 * Returns: %TRUE if @query_key exists in the URI query table.
 *
 * Since: 1.6
 */
gboolean
gst_uri_query_has_key (const GstUri * uri, const gchar * query_key)
{
  if (!uri)
    return FALSE;
  g_return_val_if_fail (GST_IS_URI (uri), FALSE);
  if (!uri->query)
    return FALSE;

  return g_hash_table_contains (uri->query, query_key);
}

/**
 * gst_uri_get_query_value:
 * @uri: (nullable): The #GstUri to examine.
 * @query_key: The key to lookup.
 *
 * Get the value associated with the @query_key key. Will return %NULL if the
 * key has no value or if the key does not exist in the URI query table. Because
 * %NULL is returned for both missing keys and keys with no value, you should
 * 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.
 *
 * Since: 1.6
 */
const gchar *
gst_uri_get_query_value (const GstUri * uri, const gchar * query_key)
{
  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->query)
    return NULL;

  return g_hash_table_lookup (uri->query, query_key);
}

/**
 * gst_uri_get_query_keys:
 * @uri: (nullable): The #GstUri to examine.
 *
 * Get a list of the query keys from the URI.
 *
 * Returns: (transfer container)(element-type gchar*): A list of keys from
 *          the URI query. Free the list with g_list_free().
 *
 * Since: 1.6
 */
GList *
gst_uri_get_query_keys (const GstUri * uri)
{
  if (!uri)
    return NULL;
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
  if (!uri->query)
    return NULL;

  return g_hash_table_get_keys (uri->query);
}

/**
 * gst_uri_get_fragment:
 * @uri: (nullable): This #GstUri object.
 *
 * 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.
 *
 * Since: 1.6
 */
const gchar *
gst_uri_get_fragment (const GstUri * uri)
{
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
  return (uri ? uri->fragment : NULL);
}

/**
 * gst_uri_set_fragment:
 * @uri: (transfer none)(nullable): The #GstUri to modify.
 * @fragment: (nullable): The fragment string to set.
 *
 * Sets the fragment string in the URI. Use a value of %NULL in @fragment to
 * unset the fragment string.
 *
 * Returns: %TRUE if the fragment was set/unset successfully.
 *
 * Since: 1.6
 */
gboolean
gst_uri_set_fragment (GstUri * uri, const gchar * fragment)
{
  if (!uri)
    return fragment == NULL;
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);

  g_free (uri->fragment);
  uri->fragment = g_strdup (fragment);
  return TRUE;
}
