/* 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 #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
 * (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);
      if (next != NULL) {
        out = g_list_delete_link (out, elem);
      } else {
        /* path ends in '/..' We need to keep the last '/' */
        elem->data = NULL;
      }
    }
  }

  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 "&percnt;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 "&percnt;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;
}
