Blame gst/gsturi.c

Packit Service 963350
/* GStreamer
Packit Service 963350
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
Packit Service 963350
 *                    2000 Wim Taymans <wtay@chello.be>
Packit Service 963350
 * Copyright (C) 2011 Tim-Philipp Müller <tim centricular net>
Packit Service 963350
 * Copyright (C) 2014 David Waring, British Broadcasting Corporation
Packit Service 963350
 *                        <david.waring@rd.bbc.co.uk>
Packit Service 963350
 *
Packit Service 963350
 * gsturi.c: register URI handlers and IETF RFC 3986 URI manipulations.
Packit Service 963350
 *
Packit Service 963350
 * This library is free software; you can redistribute it and/or
Packit Service 963350
 * modify it under the terms of the GNU Library General Public
Packit Service 963350
 * License as published by the Free Software Foundation; either
Packit Service 963350
 * version 2 of the License, or (at your option) any later version.
Packit Service 963350
 *
Packit Service 963350
 * This library is distributed in the hope that it will be useful,
Packit Service 963350
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 963350
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 963350
 * Library General Public License for more details.
Packit Service 963350
 *
Packit Service 963350
 * You should have received a copy of the GNU Library General Public
Packit Service 963350
 * License along with this library; if not, write to the
Packit Service 963350
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit Service 963350
 * Boston, MA 02110-1301, USA.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * SECTION:gsturihandler
Packit Service 963350
 * @title: GstUriHandler
Packit Service 963350
 * @short_description: Interface to ease URI handling in plugins.
Packit Service 963350
 *
Packit Service 963350
 * The #GstURIHandler is an interface that is implemented by Source and Sink
Packit Service 963350
 * #GstElement to unify handling of URI.
Packit Service 963350
 *
Packit Service 963350
 * An application can use the following functions to quickly get an element
Packit Service 963350
 * that handles the given URI for reading or writing
Packit Service 963350
 * (gst_element_make_from_uri()).
Packit Service 963350
 *
Packit Service 963350
 * Source and Sink plugins should implement this interface when possible.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
#ifdef HAVE_CONFIG_H
Packit Service 963350
#  include "config.h"
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
#include "gst_private.h"
Packit Service 963350
#include "gst.h"
Packit Service 963350
#include "gsturi.h"
Packit Service 963350
#include "gstinfo.h"
Packit Service 963350
#include "gstregistry.h"
Packit Service 963350
Packit Service 963350
#include "gst-i18n-lib.h"
Packit Service 963350
Packit Service 963350
#include <string.h>
Packit Service 963350
#include <glib.h>
Packit Service 963350
#include <glib/gprintf.h>
Packit Service 963350
Packit Service 963350
GST_DEBUG_CATEGORY_STATIC (gst_uri_handler_debug);
Packit Service 963350
#define GST_CAT_DEFAULT gst_uri_handler_debug
Packit Service 963350
Packit Service 963350
#ifndef HAVE_STRCASESTR
Packit Service 963350
#define strcasestr _gst_ascii_strcasestr
Packit Service 963350
Packit Service 963350
/* From https://github.com/freebsd/freebsd/blob/master/contrib/file/src/strcasestr.c
Packit Service 963350
 * Updated to use GLib types and GLib string functions
Packit Service 963350
 *
Packit Service 963350
 * Copyright (c) 1990, 1993
Packit Service 963350
 *	The Regents of the University of California.  All rights reserved.
Packit Service 963350
 *
Packit Service 963350
 * This code is derived from software contributed to Berkeley by
Packit Service 963350
 * Chris Torek.
Packit Service 963350
 *
Packit Service 963350
 * Redistribution and use in source and binary forms, with or without
Packit Service 963350
 * modification, are permitted provided that the following conditions
Packit Service 963350
 * are met:
Packit Service 963350
 * 1. Redistributions of source code must retain the above copyright
Packit Service 963350
 *    notice, this list of conditions and the following disclaimer.
Packit Service 963350
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 963350
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 963350
 *    documentation and/or other materials provided with the distribution.
Packit Service 963350
 * 3. Neither the name of the University nor the names of its contributors
Packit Service 963350
 *    may be used to endorse or promote products derived from this software
Packit Service 963350
 *    without specific prior written permission.
Packit Service 963350
 *
Packit Service 963350
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit Service 963350
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 963350
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit Service 963350
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit Service 963350
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 963350
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service 963350
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service 963350
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit Service 963350
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit Service 963350
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit Service 963350
 * SUCH DAMAGE.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/*
Packit Service 963350
 * Find the first occurrence of find in s, ignore case.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_ascii_strcasestr (const gchar * s, const gchar * find)
Packit Service 963350
{
Packit Service 963350
  gchar c, sc;
Packit Service 963350
  gsize len;
Packit Service 963350
Packit Service 963350
  if ((c = *find++) != 0) {
Packit Service 963350
    c = g_ascii_tolower (c);
Packit Service 963350
    len = strlen (find);
Packit Service 963350
    do {
Packit Service 963350
      do {
Packit Service 963350
        if ((sc = *s++) == 0)
Packit Service 963350
          return (NULL);
Packit Service 963350
      } while (g_ascii_tolower (sc) != c);
Packit Service 963350
    } while (g_ascii_strncasecmp (s, find, len) != 0);
Packit Service 963350
    s--;
Packit Service 963350
  }
Packit Service 963350
  return (gchar *) (gintptr) (s);
Packit Service 963350
}
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
GType
Packit Service 963350
gst_uri_handler_get_type (void)
Packit Service 963350
{
Packit Service 963350
  static volatile gsize urihandler_type = 0;
Packit Service 963350
Packit Service 963350
  if (g_once_init_enter (&urihandler_type)) {
Packit Service 963350
    GType _type;
Packit Service 963350
    static const GTypeInfo urihandler_info = {
Packit Service 963350
      sizeof (GstURIHandlerInterface),
Packit Service 963350
      NULL,
Packit Service 963350
      NULL,
Packit Service 963350
      NULL,
Packit Service 963350
      NULL,
Packit Service 963350
      NULL,
Packit Service 963350
      0,
Packit Service 963350
      0,
Packit Service 963350
      NULL,
Packit Service 963350
      NULL
Packit Service 963350
    };
Packit Service 963350
Packit Service 963350
    _type = g_type_register_static (G_TYPE_INTERFACE,
Packit Service 963350
        "GstURIHandler", &urihandler_info, 0);
Packit Service 963350
Packit Service 963350
    GST_DEBUG_CATEGORY_INIT (gst_uri_handler_debug, "GST_URI", GST_DEBUG_BOLD,
Packit Service 963350
        "handling of URIs");
Packit Service 963350
    g_once_init_leave (&urihandler_type, _type);
Packit Service 963350
  }
Packit Service 963350
  return urihandler_type;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
GQuark
Packit Service 963350
gst_uri_error_quark (void)
Packit Service 963350
{
Packit Service 963350
  return g_quark_from_static_string ("gst-uri-error-quark");
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
#define HEX_ESCAPE '%'
Packit Service 963350
Packit Service 963350
#ifndef GST_REMOVE_DEPRECATED
Packit Service 963350
static const guchar acceptable[96] = {  /* X0   X1   X2   X3   X4   X5   X6   X7   X8   X9   XA   XB   XC   XD   XE   XF */
Packit Service 963350
  0x00, 0x3F, 0x20, 0x20, 0x20, 0x00, 0x2C, 0x3F, 0x3F, 0x3F, 0x3F, 0x22, 0x20, 0x3F, 0x3F, 0x1C,       /* 2X  !"#$%&'()*+,-./   */
Packit Service 963350
  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x20, 0x20, 0x2C, 0x20, 0x2C,       /* 3X 0123456789:;<=>?   */
Packit Service 963350
  0x30, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,       /* 4X @ABCDEFGHIJKLMNO   */
Packit Service 963350
  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x3F,       /* 5X PQRSTUVWXYZ[\]^_   */
Packit Service 963350
  0x20, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,       /* 6X `abcdefghijklmno   */
Packit Service 963350
  0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x3F, 0x20        /* 7X pqrstuvwxyz{|}~DEL */
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
typedef enum
Packit Service 963350
{
Packit Service 963350
  UNSAFE_ALL = 0x1,             /* Escape all unsafe characters   */
Packit Service 963350
  UNSAFE_ALLOW_PLUS = 0x2,      /* Allows '+'  */
Packit Service 963350
  UNSAFE_PATH = 0x4,            /* Allows '/' and '?' and '&' and '='  */
Packit Service 963350
  UNSAFE_DOS_PATH = 0x8,        /* Allows '/' and '?' and '&' and '=' and ':' */
Packit Service 963350
  UNSAFE_HOST = 0x10,           /* Allows '/' and ':' and '@' */
Packit Service 963350
  UNSAFE_SLASHES = 0x20         /* Allows all characters except for '/' and '%' */
Packit Service 963350
} UnsafeCharacterSet;
Packit Service 963350
Packit Service 963350
/*  Escape undesirable characters using %
Packit Service 963350
 *  -------------------------------------
Packit Service 963350
 *
Packit Service 963350
 * This function takes a pointer to a string in which
Packit Service 963350
 * some characters may be unacceptable unescaped.
Packit Service 963350
 * It returns a string which has these characters
Packit Service 963350
 * represented by a '%' character followed by two hex digits.
Packit Service 963350
 *
Packit Service 963350
 * This routine returns a g_malloced string.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
static const gchar hex[16] = "0123456789ABCDEF";
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
escape_string_internal (const gchar * string, UnsafeCharacterSet mask)
Packit Service 963350
{
Packit Service 963350
#define ACCEPTABLE_CHAR(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
Packit Service 963350
Packit Service 963350
  const gchar *p;
Packit Service 963350
  gchar *q;
Packit Service 963350
  gchar *result;
Packit Service 963350
  guchar c;
Packit Service 963350
  gint unacceptable;
Packit Service 963350
  UnsafeCharacterSet use_mask;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (mask == UNSAFE_ALL
Packit Service 963350
      || mask == UNSAFE_ALLOW_PLUS
Packit Service 963350
      || mask == UNSAFE_PATH
Packit Service 963350
      || mask == UNSAFE_DOS_PATH
Packit Service 963350
      || mask == UNSAFE_HOST || mask == UNSAFE_SLASHES, NULL);
Packit Service 963350
Packit Service 963350
  if (string == NULL) {
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  unacceptable = 0;
Packit Service 963350
  use_mask = mask;
Packit Service 963350
  for (p = string; *p != '\0'; p++) {
Packit Service 963350
    c = *p;
Packit Service 963350
    if (!ACCEPTABLE_CHAR (c)) {
Packit Service 963350
      unacceptable++;
Packit Service 963350
    }
Packit Service 963350
    if ((use_mask == UNSAFE_HOST) && (unacceptable || (c == '/'))) {
Packit Service 963350
      /* when escaping a host, if we hit something that needs to be escaped, or we finally
Packit Service 963350
       * hit a path separator, revert to path mode (the host segment of the url is over).
Packit Service 963350
       */
Packit Service 963350
      use_mask = UNSAFE_PATH;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  result = g_malloc (p - string + unacceptable * 2 + 1);
Packit Service 963350
Packit Service 963350
  use_mask = mask;
Packit Service 963350
  for (q = result, p = string; *p != '\0'; p++) {
Packit Service 963350
    c = *p;
Packit Service 963350
Packit Service 963350
    if (!ACCEPTABLE_CHAR (c)) {
Packit Service 963350
      *q++ = HEX_ESCAPE;        /* means hex coming */
Packit Service 963350
      *q++ = hex[c >> 4];
Packit Service 963350
      *q++ = hex[c & 15];
Packit Service 963350
    } else {
Packit Service 963350
      *q++ = c;
Packit Service 963350
    }
Packit Service 963350
    if ((use_mask == UNSAFE_HOST) && (!ACCEPTABLE_CHAR (c) || (c == '/'))) {
Packit Service 963350
      use_mask = UNSAFE_PATH;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  *q = '\0';
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
static int
Packit Service 963350
hex_to_int (gchar c)
Packit Service 963350
{
Packit Service 963350
  return c >= '0' && c <= '9' ? c - '0'
Packit Service 963350
      : c >= 'A' && c <= 'F' ? c - 'A' + 10
Packit Service 963350
      : c >= 'a' && c <= 'f' ? c - 'a' + 10 : -1;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static int
Packit Service 963350
unescape_character (const char *scanner)
Packit Service 963350
{
Packit Service 963350
  int first_digit;
Packit Service 963350
  int second_digit;
Packit Service 963350
Packit Service 963350
  first_digit = hex_to_int (*scanner++);
Packit Service 963350
  if (first_digit < 0) {
Packit Service 963350
    return -1;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  second_digit = hex_to_int (*scanner);
Packit Service 963350
  if (second_digit < 0) {
Packit Service 963350
    return -1;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return (first_digit << 4) | second_digit;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* unescape_string:
Packit Service 963350
 * @escaped_string: an escaped URI, path, or other string
Packit Service 963350
 * @illegal_characters: a string containing a sequence of characters
Packit Service 963350
 * considered "illegal", '\0' is automatically in this list.
Packit Service 963350
 *
Packit Service 963350
 * Decodes escaped characters (i.e. PERCENTxx sequences) in @escaped_string.
Packit Service 963350
 * Characters are encoded in PERCENTxy form, where xy is the ASCII hex code
Packit Service 963350
 * for character 16x+y.
Packit Service 963350
 *
Packit Service 963350
 * Return value: (nullable): a newly allocated string with the
Packit Service 963350
 * unescaped equivalents, or %NULL if @escaped_string contained one of
Packit Service 963350
 * the characters in @illegal_characters.
Packit Service 963350
 **/
Packit Service 963350
static char *
Packit Service 963350
unescape_string (const gchar * escaped_string, const gchar * illegal_characters)
Packit Service 963350
{
Packit Service 963350
  const gchar *in;
Packit Service 963350
  gchar *out, *result;
Packit Service 963350
  gint character;
Packit Service 963350
Packit Service 963350
  if (escaped_string == NULL) {
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  result = g_malloc (strlen (escaped_string) + 1);
Packit Service 963350
Packit Service 963350
  out = result;
Packit Service 963350
  for (in = escaped_string; *in != '\0'; in++) {
Packit Service 963350
    character = *in;
Packit Service 963350
    if (*in == HEX_ESCAPE) {
Packit Service 963350
      character = unescape_character (in + 1);
Packit Service 963350
Packit Service 963350
      /* Check for an illegal character. We consider '\0' illegal here. */
Packit Service 963350
      if (character <= 0
Packit Service 963350
          || (illegal_characters != NULL
Packit Service 963350
              && strchr (illegal_characters, (char) character) != NULL)) {
Packit Service 963350
        g_free (result);
Packit Service 963350
        return NULL;
Packit Service 963350
      }
Packit Service 963350
      in += 2;
Packit Service 963350
    }
Packit Service 963350
    *out++ = (char) character;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  *out = '\0';
Packit Service 963350
  g_assert ((gsize) (out - result) <= strlen (escaped_string));
Packit Service 963350
  return result;
Packit Service 963350
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_uri_protocol_check_internal (const gchar * uri, gchar ** endptr)
Packit Service 963350
{
Packit Service 963350
  gchar *check = (gchar *) uri;
Packit Service 963350
Packit Service 963350
  g_assert (uri != NULL);
Packit Service 963350
  g_assert (endptr != NULL);
Packit Service 963350
Packit Service 963350
  if (g_ascii_isalpha (*check)) {
Packit Service 963350
    check++;
Packit Service 963350
    while (g_ascii_isalnum (*check) || *check == '+'
Packit Service 963350
        || *check == '-' || *check == '.')
Packit Service 963350
      check++;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  *endptr = check;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_protocol_is_valid:
Packit Service 963350
 * @protocol: A string
Packit Service 963350
 *
Packit Service 963350
 * Tests if the given string is a valid protocol identifier. Protocols
Packit Service 963350
 * must consist of alphanumeric characters, '+', '-' and '.' and must
Packit Service 963350
 * start with a alphabetic character. See RFC 3986 Section 3.1.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the string is a valid protocol identifier, %FALSE otherwise.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_protocol_is_valid (const gchar * protocol)
Packit Service 963350
{
Packit Service 963350
  gchar *endptr;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (protocol != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  gst_uri_protocol_check_internal (protocol, &endptr);
Packit Service 963350
Packit Service 963350
  return *endptr == '\0' && ((gsize) (endptr - protocol)) >= 2;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_is_valid:
Packit Service 963350
 * @uri: A URI string
Packit Service 963350
 *
Packit Service 963350
 * Tests if the given string is a valid URI identifier. URIs start with a valid
Packit Service 963350
 * scheme followed by ":" and maybe a string identifying the location.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the string is a valid URI
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_is_valid (const gchar * uri)
Packit Service 963350
{
Packit Service 963350
  gchar *endptr;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (uri != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  gst_uri_protocol_check_internal (uri, &endptr);
Packit Service 963350
Packit Service 963350
  return *endptr == ':' && ((gsize) (endptr - uri)) >= 2;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_protocol:
Packit Service 963350
 * @uri: A URI string
Packit Service 963350
 *
Packit Service 963350
 * Extracts the protocol out of a given valid URI. The returned string must be
Packit Service 963350
 * freed using g_free().
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The protocol for this URI.
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_get_protocol (const gchar * uri)
Packit Service 963350
{
Packit Service 963350
  gchar *colon;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (uri != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
Packit Service 963350
Packit Service 963350
  colon = strstr (uri, ":");
Packit Service 963350
Packit Service 963350
  return g_ascii_strdown (uri, colon - uri);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_has_protocol:
Packit Service 963350
 * @uri: a URI string
Packit Service 963350
 * @protocol: a protocol string (e.g. "http")
Packit Service 963350
 *
Packit Service 963350
 * Checks if the protocol of a given valid URI matches @protocol.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the protocol matches.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_has_protocol (const gchar * uri, const gchar * protocol)
Packit Service 963350
{
Packit Service 963350
  gchar *colon;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (uri != NULL, FALSE);
Packit Service 963350
  g_return_val_if_fail (protocol != NULL, FALSE);
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
Packit Service 963350
Packit Service 963350
  colon = strstr (uri, ":");
Packit Service 963350
Packit Service 963350
  if (colon == NULL)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  return (g_ascii_strncasecmp (uri, protocol, (gsize) (colon - uri)) == 0);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_location:
Packit Service 963350
 * @uri: A URI string
Packit Service 963350
 *
Packit Service 963350
 * Extracts the location out of a given valid URI, ie. the protocol and "://"
Packit Service 963350
 * are stripped from the URI, which means that the location returned includes
Packit Service 963350
 * the hostname if one is specified. The returned string must be freed using
Packit Service 963350
 * g_free().
Packit Service 963350
 *
Packit Service 963350
 * Free-function: g_free
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the location for this URI. Returns
Packit Service 963350
 *     %NULL if the URI isn't valid. If the URI does not contain a location, an
Packit Service 963350
 *     empty string is returned.
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_get_location (const gchar * uri)
Packit Service 963350
{
Packit Service 963350
  const gchar *colon;
Packit Service 963350
  gchar *unescaped = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (uri != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
Packit Service 963350
Packit Service 963350
  colon = strstr (uri, "://");
Packit Service 963350
  if (!colon)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  unescaped = unescape_string (colon + 3, "/");
Packit Service 963350
Packit Service 963350
  /* On Windows an URI might look like file:///c:/foo/bar.txt or
Packit Service 963350
   * file:///c|/foo/bar.txt (some Netscape versions) and we want to
Packit Service 963350
   * return c:/foo/bar.txt as location rather than /c:/foo/bar.txt.
Packit Service 963350
   * Can't use g_filename_from_uri() here because it will only handle the
Packit Service 963350
   * file:// protocol */
Packit Service 963350
#ifdef G_OS_WIN32
Packit Service 963350
  if (unescaped != NULL && unescaped[0] == '/' &&
Packit Service 963350
      g_ascii_isalpha (unescaped[1]) &&
Packit Service 963350
      (unescaped[2] == ':' || unescaped[2] == '|')) {
Packit Service 963350
    unescaped[2] = ':';
Packit Service 963350
    memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
Packit Service 963350
  }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
  GST_LOG ("extracted location '%s' from URI '%s'", GST_STR_NULL (unescaped),
Packit Service 963350
      uri);
Packit Service 963350
  return unescaped;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_construct:
Packit Service 963350
 * @protocol: Protocol for URI
Packit Service 963350
 * @location: (transfer none): Location for URI
Packit Service 963350
 *
Packit Service 963350
 * Constructs a URI for a given valid protocol and location.
Packit Service 963350
 *
Packit Service 963350
 * Free-function: g_free
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): a new string for this URI. Returns %NULL if the
Packit Service 963350
 *     given URI protocol is not valid, or the given location is %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Deprecated: Use GstURI instead.
Packit Service 963350
 */
Packit Service 963350
#ifndef GST_REMOVE_DEPRECATED
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_construct (const gchar * protocol, const gchar * location)
Packit Service 963350
{
Packit Service 963350
  char *escaped, *proto_lowercase;
Packit Service 963350
  char *retval;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (gst_uri_protocol_is_valid (protocol), NULL);
Packit Service 963350
  g_return_val_if_fail (location != NULL, NULL);
Packit Service 963350
Packit Service 963350
  proto_lowercase = g_ascii_strdown (protocol, -1);
Packit Service 963350
  escaped = escape_string_internal (location, UNSAFE_PATH);
Packit Service 963350
  retval = g_strdup_printf ("%s://%s", proto_lowercase, escaped);
Packit Service 963350
  g_free (escaped);
Packit Service 963350
  g_free (proto_lowercase);
Packit Service 963350
Packit Service 963350
  return retval;
Packit Service 963350
}
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
typedef struct
Packit Service 963350
{
Packit Service 963350
  GstURIType type;
Packit Service 963350
  const gchar *protocol;
Packit Service 963350
}
Packit Service 963350
SearchEntry;
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
search_by_entry (GstPluginFeature * feature, gpointer search_entry)
Packit Service 963350
{
Packit Service 963350
  const gchar *const *protocols;
Packit Service 963350
  GstElementFactory *factory;
Packit Service 963350
  SearchEntry *entry = (SearchEntry *) search_entry;
Packit Service 963350
Packit Service 963350
  if (!GST_IS_ELEMENT_FACTORY (feature))
Packit Service 963350
    return FALSE;
Packit Service 963350
  factory = GST_ELEMENT_FACTORY_CAST (feature);
Packit Service 963350
Packit Service 963350
  if (factory->uri_type != entry->type)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  protocols = gst_element_factory_get_uri_protocols (factory);
Packit Service 963350
Packit Service 963350
  if (protocols == NULL) {
Packit Service 963350
    g_warning ("Factory '%s' implements GstUriHandler interface but returned "
Packit Service 963350
        "no supported protocols!", gst_plugin_feature_get_name (feature));
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  while (*protocols != NULL) {
Packit Service 963350
    if (g_ascii_strcasecmp (*protocols, entry->protocol) == 0)
Packit Service 963350
      return TRUE;
Packit Service 963350
    protocols++;
Packit Service 963350
  }
Packit Service 963350
  return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gint
Packit Service 963350
sort_by_rank (GstPluginFeature * first, GstPluginFeature * second)
Packit Service 963350
{
Packit Service 963350
  return gst_plugin_feature_get_rank (second) -
Packit Service 963350
      gst_plugin_feature_get_rank (first);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GList *
Packit Service 963350
get_element_factories_from_uri_protocol (const GstURIType type,
Packit Service 963350
    const gchar * protocol)
Packit Service 963350
{
Packit Service 963350
  GList *possibilities;
Packit Service 963350
  SearchEntry entry;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (protocol, NULL);
Packit Service 963350
Packit Service 963350
  entry.type = type;
Packit Service 963350
  entry.protocol = protocol;
Packit Service 963350
  possibilities = gst_registry_feature_filter (gst_registry_get (),
Packit Service 963350
      search_by_entry, FALSE, &entry);
Packit Service 963350
Packit Service 963350
  return possibilities;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_protocol_is_supported:
Packit Service 963350
 * @type: Whether to check for a source or a sink
Packit Service 963350
 * @protocol: Protocol that should be checked for (e.g. "http" or "smb")
Packit Service 963350
 *
Packit Service 963350
 * Checks if an element exists that supports the given URI protocol. Note
Packit Service 963350
 * that a positive return value does not imply that a subsequent call to
Packit Service 963350
 * gst_element_make_from_uri() is guaranteed to work.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE
Packit Service 963350
*/
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_protocol_is_supported (const GstURIType type, const gchar * protocol)
Packit Service 963350
{
Packit Service 963350
  GList *possibilities;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (protocol, FALSE);
Packit Service 963350
Packit Service 963350
  possibilities = get_element_factories_from_uri_protocol (type, protocol);
Packit Service 963350
Packit Service 963350
  if (possibilities) {
Packit Service 963350
    g_list_free (possibilities);
Packit Service 963350
    return TRUE;
Packit Service 963350
  } else
Packit Service 963350
    return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_make_from_uri:
Packit Service 963350
 * @type: Whether to create a source or a sink
Packit Service 963350
 * @uri: URI to create an element for
Packit Service 963350
 * @elementname: (allow-none): Name of created element, can be %NULL.
Packit Service 963350
 * @error: (allow-none): address where to store error information, or %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Creates an element for handling the given URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer floating) (nullable): a new element or %NULL if none
Packit Service 963350
 * could be created
Packit Service 963350
 */
Packit Service 963350
GstElement *
Packit Service 963350
gst_element_make_from_uri (const GstURIType type, const gchar * uri,
Packit Service 963350
    const gchar * elementname, GError ** error)
Packit Service 963350
{
Packit Service 963350
  GList *possibilities, *walk;
Packit Service 963350
  gchar *protocol;
Packit Service 963350
  GstElement *ret = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (gst_is_initialized (), NULL);
Packit Service 963350
  g_return_val_if_fail (GST_URI_TYPE_IS_VALID (type), NULL);
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
Packit Service 963350
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
Packit Service 963350
Packit Service 963350
  GST_DEBUG ("type:%d, uri:%s, elementname:%s", type, uri, elementname);
Packit Service 963350
Packit Service 963350
  protocol = gst_uri_get_protocol (uri);
Packit Service 963350
  possibilities = get_element_factories_from_uri_protocol (type, protocol);
Packit Service 963350
Packit Service 963350
  if (!possibilities) {
Packit Service 963350
    GST_DEBUG ("No %s for URI '%s'", type == GST_URI_SINK ? "sink" : "source",
Packit Service 963350
        uri);
Packit Service 963350
    /* The error message isn't great, but we don't expect applications to
Packit Service 963350
     * show that error to users, but call the missing plugins functions */
Packit Service 963350
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_UNSUPPORTED_PROTOCOL,
Packit Service 963350
        _("No URI handler for the %s protocol found"), protocol);
Packit Service 963350
    g_free (protocol);
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
  g_free (protocol);
Packit Service 963350
Packit Service 963350
  possibilities = g_list_sort (possibilities, (GCompareFunc) sort_by_rank);
Packit Service 963350
  walk = possibilities;
Packit Service 963350
  while (walk) {
Packit Service 963350
    GstElementFactory *factory = walk->data;
Packit Service 963350
    GError *uri_err = NULL;
Packit Service 963350
Packit Service 963350
    ret = gst_element_factory_create (factory, elementname);
Packit Service 963350
    if (ret != NULL) {
Packit Service 963350
      GstURIHandler *handler = GST_URI_HANDLER (ret);
Packit Service 963350
Packit Service 963350
      if (gst_uri_handler_set_uri (handler, uri, &uri_err))
Packit Service 963350
        break;
Packit Service 963350
Packit Service 963350
      GST_WARNING ("%s didn't accept URI '%s': %s", GST_OBJECT_NAME (ret), uri,
Packit Service 963350
          uri_err->message);
Packit Service 963350
Packit Service 963350
      if (error != NULL && *error == NULL)
Packit Service 963350
        g_propagate_error (error, uri_err);
Packit Service 963350
      else
Packit Service 963350
        g_error_free (uri_err);
Packit Service 963350
Packit Service 963350
      gst_object_unref (ret);
Packit Service 963350
      ret = NULL;
Packit Service 963350
    }
Packit Service 963350
    walk = walk->next;
Packit Service 963350
  }
Packit Service 963350
  gst_plugin_feature_list_free (possibilities);
Packit Service 963350
Packit Service 963350
  GST_LOG_OBJECT (ret, "created %s for URL '%s'",
Packit Service 963350
      type == GST_URI_SINK ? "sink" : "source", uri);
Packit Service 963350
Packit Service 963350
  /* if the first handler didn't work, but we found another one that works */
Packit Service 963350
  if (ret != NULL)
Packit Service 963350
    g_clear_error (error);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_handler_get_uri_type:
Packit Service 963350
 * @handler: A #GstURIHandler.
Packit Service 963350
 *
Packit Service 963350
 * Gets the type of the given URI handler
Packit Service 963350
 *
Packit Service 963350
 * Returns: the #GstURIType of the URI handler.
Packit Service 963350
 * Returns #GST_URI_UNKNOWN if the @handler isn't implemented correctly.
Packit Service 963350
 */
Packit Service 963350
GstURIType
Packit Service 963350
gst_uri_handler_get_uri_type (GstURIHandler * handler)
Packit Service 963350
{
Packit Service 963350
  GstURIHandlerInterface *iface;
Packit Service 963350
  GstURIType ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), GST_URI_UNKNOWN);
Packit Service 963350
Packit Service 963350
  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
Packit Service 963350
  g_return_val_if_fail (iface != NULL, GST_URI_UNKNOWN);
Packit Service 963350
  g_return_val_if_fail (iface->get_type != NULL, GST_URI_UNKNOWN);
Packit Service 963350
Packit Service 963350
  ret = iface->get_type (G_OBJECT_TYPE (handler));
Packit Service 963350
  g_return_val_if_fail (GST_URI_TYPE_IS_VALID (ret), GST_URI_UNKNOWN);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_handler_get_protocols:
Packit Service 963350
 * @handler: A #GstURIHandler.
Packit Service 963350
 *
Packit Service 963350
 * Gets the list of protocols supported by @handler. This list may not be
Packit Service 963350
 * modified.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none) (element-type utf8) (nullable): the
Packit Service 963350
 *     supported protocols.  Returns %NULL if the @handler isn't
Packit Service 963350
 *     implemented properly, or the @handler doesn't support any
Packit Service 963350
 *     protocols.
Packit Service 963350
 */
Packit Service 963350
const gchar *const *
Packit Service 963350
gst_uri_handler_get_protocols (GstURIHandler * handler)
Packit Service 963350
{
Packit Service 963350
  GstURIHandlerInterface *iface;
Packit Service 963350
  const gchar *const *ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);
Packit Service 963350
Packit Service 963350
  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
Packit Service 963350
  g_return_val_if_fail (iface != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (iface->get_protocols != NULL, NULL);
Packit Service 963350
Packit Service 963350
  ret = iface->get_protocols (G_OBJECT_TYPE (handler));
Packit Service 963350
  g_return_val_if_fail (ret != NULL, NULL);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_handler_get_uri:
Packit Service 963350
 * @handler: A #GstURIHandler
Packit Service 963350
 *
Packit Service 963350
 * Gets the currently handled URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the URI currently handled by
Packit Service 963350
 *   the @handler.  Returns %NULL if there are no URI currently
Packit Service 963350
 *   handled. The returned string must be freed with g_free() when no
Packit Service 963350
 *   longer needed.
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_handler_get_uri (GstURIHandler * handler)
Packit Service 963350
{
Packit Service 963350
  GstURIHandlerInterface *iface;
Packit Service 963350
  gchar *ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);
Packit Service 963350
Packit Service 963350
  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
Packit Service 963350
  g_return_val_if_fail (iface != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (iface->get_uri != NULL, NULL);
Packit Service 963350
  ret = iface->get_uri (handler);
Packit Service 963350
  if (ret != NULL)
Packit Service 963350
    g_return_val_if_fail (gst_uri_is_valid (ret), NULL);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_handler_set_uri:
Packit Service 963350
 * @handler: A #GstURIHandler
Packit Service 963350
 * @uri: URI to set
Packit Service 963350
 * @error: (allow-none): address where to store a #GError in case of
Packit Service 963350
 *    an error, or %NULL
Packit Service 963350
 *
Packit Service 963350
 * Tries to set the URI of the given handler.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the URI was set successfully, else %FALSE.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri,
Packit Service 963350
    GError ** error)
Packit Service 963350
{
Packit Service 963350
  GstURIHandlerInterface *iface;
Packit Service 963350
  gboolean ret;
Packit Service 963350
  gchar *protocol;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI_HANDLER (handler), FALSE);
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
Packit Service 963350
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
Packit Service 963350
Packit Service 963350
  iface = GST_URI_HANDLER_GET_INTERFACE (handler);
Packit Service 963350
  g_return_val_if_fail (iface != NULL, FALSE);
Packit Service 963350
  g_return_val_if_fail (iface->set_uri != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  protocol = gst_uri_get_protocol (uri);
Packit Service 963350
Packit Service 963350
  if (iface->get_protocols) {
Packit Service 963350
    const gchar *const *protocols;
Packit Service 963350
    const gchar *const *p;
Packit Service 963350
    gboolean found_protocol = FALSE;
Packit Service 963350
Packit Service 963350
    protocols = iface->get_protocols (G_OBJECT_TYPE (handler));
Packit Service 963350
    if (protocols != NULL) {
Packit Service 963350
      for (p = protocols; *p != NULL; ++p) {
Packit Service 963350
        if (g_ascii_strcasecmp (protocol, *p) == 0) {
Packit Service 963350
          found_protocol = TRUE;
Packit Service 963350
          break;
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
Packit Service 963350
      if (!found_protocol) {
Packit Service 963350
        g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_UNSUPPORTED_PROTOCOL,
Packit Service 963350
            _("URI scheme '%s' not supported"), protocol);
Packit Service 963350
        g_free (protocol);
Packit Service 963350
        return FALSE;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  ret = iface->set_uri (handler, uri, error);
Packit Service 963350
Packit Service 963350
  g_free (protocol);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
gst_file_utils_canonicalise_path (const gchar * path)
Packit Service 963350
{
Packit Service 963350
  gchar **parts, **p, *clean_path;
Packit Service 963350
Packit Service 963350
#ifdef G_OS_WIN32
Packit Service 963350
  {
Packit Service 963350
    GST_WARNING ("FIXME: canonicalise win32 path");
Packit Service 963350
    return g_strdup (path);
Packit Service 963350
  }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
  parts = g_strsplit (path, "/", -1);
Packit Service 963350
Packit Service 963350
  p = parts;
Packit Service 963350
  while (*p != NULL) {
Packit Service 963350
    if (strcmp (*p, ".") == 0) {
Packit Service 963350
      /* just move all following parts on top of this, incl. NUL terminator */
Packit Service 963350
      g_free (*p);
Packit Service 963350
      memmove (p, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
Packit Service 963350
      /* re-check the new current part again in the next iteration */
Packit Service 963350
      continue;
Packit Service 963350
    } else if (strcmp (*p, "..") == 0 && p > parts) {
Packit Service 963350
      /* just move all following parts on top of the previous part, incl.
Packit Service 963350
       * NUL terminator */
Packit Service 963350
      g_free (*(p - 1));
Packit Service 963350
      g_free (*p);
Packit Service 963350
      memmove (p - 1, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
Packit Service 963350
      /* re-check the new current part again in the next iteration */
Packit Service 963350
      --p;
Packit Service 963350
      continue;
Packit Service 963350
    }
Packit Service 963350
    ++p;
Packit Service 963350
  }
Packit Service 963350
  if (*path == '/') {
Packit Service 963350
    guint num_parts;
Packit Service 963350
Packit Service 963350
    num_parts = g_strv_length (parts) + 1;      /* incl. terminator */
Packit Service 963350
    parts = g_renew (gchar *, parts, num_parts + 1);
Packit Service 963350
    memmove (parts + 1, parts, num_parts * sizeof (gchar *));
Packit Service 963350
    parts[0] = g_strdup ("/");
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  clean_path = g_build_filenamev (parts);
Packit Service 963350
  g_strfreev (parts);
Packit Service 963350
  return clean_path;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
file_path_contains_relatives (const gchar * path)
Packit Service 963350
{
Packit Service 963350
  return (strstr (path, "/./") != NULL || strstr (path, "/../") != NULL ||
Packit Service 963350
      strstr (path, G_DIR_SEPARATOR_S "." G_DIR_SEPARATOR_S) != NULL ||
Packit Service 963350
      strstr (path, G_DIR_SEPARATOR_S ".." G_DIR_SEPARATOR_S) != NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_filename_to_uri:
Packit Service 963350
 * @filename: (type filename): absolute or relative file name path
Packit Service 963350
 * @error: pointer to error, or %NULL
Packit Service 963350
 *
Packit Service 963350
 * Similar to g_filename_to_uri(), but attempts to handle relative file paths
Packit Service 963350
 * as well. Before converting @filename into an URI, it will be prefixed by
Packit Service 963350
 * the current working directory if it is a relative path, and then the path
Packit Service 963350
 * will be canonicalised so that it doesn't contain any './' or '../' segments.
Packit Service 963350
 *
Packit Service 963350
 * On Windows #filename should be in UTF-8 encoding.
Packit Service 963350
 *
Packit Service 963350
 * Returns: newly-allocated URI string, or NULL on error. The caller must
Packit Service 963350
 *   free the URI string with g_free() when no longer needed.
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_filename_to_uri (const gchar * filename, GError ** error)
Packit Service 963350
{
Packit Service 963350
  gchar *abs_location = NULL;
Packit Service 963350
  gchar *uri, *abs_clean;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (filename != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
Packit Service 963350
Packit Service 963350
  if (g_path_is_absolute (filename)) {
Packit Service 963350
    if (!file_path_contains_relatives (filename)) {
Packit Service 963350
      uri = g_filename_to_uri (filename, NULL, error);
Packit Service 963350
      goto beach;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    abs_location = g_strdup (filename);
Packit Service 963350
  } else {
Packit Service 963350
    gchar *cwd;
Packit Service 963350
Packit Service 963350
    cwd = g_get_current_dir ();
Packit Service 963350
    abs_location = g_build_filename (cwd, filename, NULL);
Packit Service 963350
    g_free (cwd);
Packit Service 963350
Packit Service 963350
    if (!file_path_contains_relatives (abs_location)) {
Packit Service 963350
      uri = g_filename_to_uri (abs_location, NULL, error);
Packit Service 963350
      goto beach;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* path is now absolute, but contains '.' or '..' */
Packit Service 963350
  abs_clean = gst_file_utils_canonicalise_path (abs_location);
Packit Service 963350
  GST_LOG ("'%s' -> '%s' -> '%s'", filename, abs_location, abs_clean);
Packit Service 963350
  uri = g_filename_to_uri (abs_clean, NULL, error);
Packit Service 963350
  g_free (abs_clean);
Packit Service 963350
Packit Service 963350
beach:
Packit Service 963350
Packit Service 963350
  g_free (abs_location);
Packit Service 963350
  GST_DEBUG ("'%s' -> '%s'", filename, uri);
Packit Service 963350
  return uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/****************************************************************************
Packit Service 963350
 * GstUri - GstMiniObject to parse and merge URIs according to IETF RFC 3986
Packit Service 963350
 ****************************************************************************/
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * SECTION:gsturi
Packit Service 963350
 * @title: GstUri
Packit Service 963350
 * @short_description: URI parsing and manipulation.
Packit Service 963350
 *
Packit Service 963350
 * A #GstUri object can be used to parse and split a URI string into its
Packit Service 963350
 * constituant parts. Two #GstUri objects can be joined to make a new #GstUri
Packit Service 963350
 * using the algorithm described in RFC3986.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/* Definition for GstUri object */
Packit Service 963350
struct _GstUri
Packit Service 963350
{
Packit Service 963350
  /*< private > */
Packit Service 963350
  GstMiniObject mini_object;
Packit Service 963350
  gchar *scheme;
Packit Service 963350
  gchar *userinfo;
Packit Service 963350
  gchar *host;
Packit Service 963350
  guint port;
Packit Service 963350
  GList *path;
Packit Service 963350
  GHashTable *query;
Packit Service 963350
  gchar *fragment;
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
GST_DEFINE_MINI_OBJECT_TYPE (GstUri, gst_uri);
Packit Service 963350
Packit Service 963350
static GstUri *_gst_uri_copy (const GstUri * uri);
Packit Service 963350
static void _gst_uri_free (GstUri * uri);
Packit Service 963350
static GstUri *_gst_uri_new (void);
Packit Service 963350
static GList *_remove_dot_segments (GList * path);
Packit Service 963350
Packit Service 963350
/* private GstUri functions */
Packit Service 963350
Packit Service 963350
static GstUri *
Packit Service 963350
_gst_uri_new (void)
Packit Service 963350
{
Packit Service 963350
  GstUri *uri;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (gst_is_initialized (), NULL);
Packit Service 963350
Packit Service 963350
  uri = GST_URI_CAST (g_slice_new0 (GstUri));
Packit Service 963350
Packit Service 963350
  if (uri)
Packit Service 963350
    gst_mini_object_init (GST_MINI_OBJECT_CAST (uri), 0, gst_uri_get_type (),
Packit Service 963350
        (GstMiniObjectCopyFunction) _gst_uri_copy, NULL,
Packit Service 963350
        (GstMiniObjectFreeFunction) _gst_uri_free);
Packit Service 963350
Packit Service 963350
  return uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
_gst_uri_free (GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_if_fail (GST_IS_URI (uri));
Packit Service 963350
Packit Service 963350
  g_free (uri->scheme);
Packit Service 963350
  g_free (uri->userinfo);
Packit Service 963350
  g_free (uri->host);
Packit Service 963350
  g_list_free_full (uri->path, g_free);
Packit Service 963350
  if (uri->query)
Packit Service 963350
    g_hash_table_unref (uri->query);
Packit Service 963350
  g_free (uri->fragment);
Packit Service 963350
Packit Service 963350
  g_slice_free1 (sizeof (*uri), uri);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GHashTable *
Packit Service 963350
_gst_uri_copy_query_table (GHashTable * orig)
Packit Service 963350
{
Packit Service 963350
  GHashTable *new = NULL;
Packit Service 963350
Packit Service 963350
  if (orig != NULL) {
Packit Service 963350
    GHashTableIter iter;
Packit Service 963350
    gpointer key, value;
Packit Service 963350
    new = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
Packit Service 963350
    g_hash_table_iter_init (&iter, orig);
Packit Service 963350
    while (g_hash_table_iter_next (&iter, &key, &value)) {
Packit Service 963350
      g_hash_table_insert (new, g_strdup (key), g_strdup (value));
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return new;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GstUri *
Packit Service 963350
_gst_uri_copy (const GstUri * orig_uri)
Packit Service 963350
{
Packit Service 963350
  GstUri *new_uri;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (orig_uri), NULL);
Packit Service 963350
Packit Service 963350
  new_uri = _gst_uri_new ();
Packit Service 963350
Packit Service 963350
  if (new_uri) {
Packit Service 963350
    new_uri->scheme = g_strdup (orig_uri->scheme);
Packit Service 963350
    new_uri->userinfo = g_strdup (orig_uri->userinfo);
Packit Service 963350
    new_uri->host = g_strdup (orig_uri->host);
Packit Service 963350
    new_uri->port = orig_uri->port;
Packit Service 963350
    new_uri->path = g_list_copy_deep (orig_uri->path, (GCopyFunc) g_strdup,
Packit Service 963350
        NULL);
Packit Service 963350
    new_uri->query = _gst_uri_copy_query_table (orig_uri->query);
Packit Service 963350
    new_uri->fragment = g_strdup (orig_uri->fragment);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return new_uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/*
Packit Service 963350
 * _gst_uri_compare_lists:
Packit Service 963350
 *
Packit Service 963350
 * Compare two lists for equality. This compares the two lists, item for item,
Packit Service 963350
 * comparing items in the same position in the two lists. If @first is
Packit Service 963350
 * considered less than @second the result will be negative. If @first is
Packit Service 963350
 * considered to be more than @second then the result will be positive. If the
Packit Service 963350
 * lists are considered to be equal then the result will be 0. If two lists
Packit Service 963350
 * have the same items, but one list is shorter than the other, then the
Packit Service 963350
 * shorter list is considered to be less than the longer list.
Packit Service 963350
 */
Packit Service 963350
static gint
Packit Service 963350
_gst_uri_compare_lists (GList * first, GList * second, GCompareFunc cmp_fn)
Packit Service 963350
{
Packit Service 963350
  GList *itr1, *itr2;
Packit Service 963350
  gint result;
Packit Service 963350
Packit Service 963350
  for (itr1 = first, itr2 = second;
Packit Service 963350
      itr1 != NULL || itr2 != NULL; itr1 = itr1->next, itr2 = itr2->next) {
Packit Service 963350
    if (itr1 == NULL)
Packit Service 963350
      return -1;
Packit Service 963350
    if (itr2 == NULL)
Packit Service 963350
      return 1;
Packit Service 963350
    result = cmp_fn (itr1->data, itr2->data);
Packit Service 963350
    if (result != 0)
Packit Service 963350
      return result;
Packit Service 963350
  }
Packit Service 963350
  return 0;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
typedef enum
Packit Service 963350
{
Packit Service 963350
  _GST_URI_NORMALIZE_LOWERCASE = 1,
Packit Service 963350
  _GST_URI_NORMALIZE_UPPERCASE = 2
Packit Service 963350
} _GstUriNormalizations;
Packit Service 963350
Packit Service 963350
/*
Packit Service 963350
 * Find the first character that hasn't been normalized according to the @flags.
Packit Service 963350
 */
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_first_non_normalized_char (gchar * str, guint flags)
Packit Service 963350
{
Packit Service 963350
  gchar *pos;
Packit Service 963350
Packit Service 963350
  if (str == NULL)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  for (pos = str; *pos; pos++) {
Packit Service 963350
    if ((flags & _GST_URI_NORMALIZE_UPPERCASE) && g_ascii_islower (*pos))
Packit Service 963350
      return pos;
Packit Service 963350
    if ((flags & _GST_URI_NORMALIZE_LOWERCASE) && g_ascii_isupper (*pos))
Packit Service 963350
      return pos;
Packit Service 963350
  }
Packit Service 963350
  return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
_gst_uri_normalize_lowercase (gchar * str)
Packit Service 963350
{
Packit Service 963350
  gchar *pos;
Packit Service 963350
  gboolean ret = FALSE;
Packit Service 963350
Packit Service 963350
  for (pos = _gst_uri_first_non_normalized_char (str,
Packit Service 963350
          _GST_URI_NORMALIZE_LOWERCASE);
Packit Service 963350
      pos != NULL;
Packit Service 963350
      pos = _gst_uri_first_non_normalized_char (pos + 1,
Packit Service 963350
          _GST_URI_NORMALIZE_LOWERCASE)) {
Packit Service 963350
    *pos = g_ascii_tolower (*pos);
Packit Service 963350
    ret = TRUE;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
#define _gst_uri_normalize_scheme _gst_uri_normalize_lowercase
Packit Service 963350
#define _gst_uri_normalize_hostname _gst_uri_normalize_lowercase
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
_gst_uri_normalize_path (GList ** path)
Packit Service 963350
{
Packit Service 963350
  GList *new_path;
Packit Service 963350
Packit Service 963350
  new_path = _remove_dot_segments (*path);
Packit Service 963350
  if (_gst_uri_compare_lists (new_path, *path, (GCompareFunc) g_strcmp0) != 0) {
Packit Service 963350
    g_list_free_full (*path, g_free);
Packit Service 963350
    *path = new_path;
Packit Service 963350
    return TRUE;
Packit Service 963350
  }
Packit Service 963350
  g_list_free_full (new_path, g_free);
Packit Service 963350
Packit Service 963350
  return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
_gst_uri_normalize_str_noop (gchar * str)
Packit Service 963350
{
Packit Service 963350
  return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
_gst_uri_normalize_table_noop (GHashTable * table)
Packit Service 963350
{
Packit Service 963350
  return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
#define _gst_uri_normalize_userinfo _gst_uri_normalize_str_noop
Packit Service 963350
#define _gst_uri_normalize_query _gst_uri_normalize_table_noop
Packit Service 963350
#define _gst_uri_normalize_fragment _gst_uri_normalize_str_noop
Packit Service 963350
Packit Service 963350
/* RFC 3986 functions */
Packit Service 963350
Packit Service 963350
static GList *
Packit Service 963350
_merge (GList * base, GList * path)
Packit Service 963350
{
Packit Service 963350
  GList *ret, *path_copy, *last;
Packit Service 963350
Packit Service 963350
  path_copy = g_list_copy_deep (path, (GCopyFunc) g_strdup, NULL);
Packit Service 963350
  /* if base is NULL make path absolute */
Packit Service 963350
  if (base == NULL) {
Packit Service 963350
    if (path_copy != NULL && path_copy->data != NULL) {
Packit Service 963350
      path_copy = g_list_prepend (path_copy, NULL);
Packit Service 963350
    }
Packit Service 963350
    return path_copy;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  ret = g_list_copy_deep (base, (GCopyFunc) g_strdup, NULL);
Packit Service 963350
  last = g_list_last (ret);
Packit Service 963350
  ret = g_list_remove_link (ret, last);
Packit Service 963350
  g_list_free_full (last, g_free);
Packit Service 963350
  ret = g_list_concat (ret, path_copy);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GList *
Packit Service 963350
_remove_dot_segments (GList * path)
Packit Service 963350
{
Packit Service 963350
  GList *out, *elem, *next;
Packit Service 963350
Packit Service 963350
  if (path == NULL)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  out = g_list_copy_deep (path, (GCopyFunc) g_strdup, NULL);
Packit Service 963350
Packit Service 963350
  for (elem = out; elem; elem = next) {
Packit Service 963350
    next = elem->next;
Packit Service 963350
    if (elem->data == NULL && elem != out && next != NULL) {
Packit Service 963350
      out = g_list_delete_link (out, elem);
Packit Service 963350
    } else if (g_strcmp0 (elem->data, ".") == 0) {
Packit Service 963350
      g_free (elem->data);
Packit Service 963350
      out = g_list_delete_link (out, elem);
Packit Service 963350
    } else if (g_strcmp0 (elem->data, "..") == 0) {
Packit Service 963350
      GList *prev = g_list_previous (elem);
Packit Service 963350
      if (prev && (prev != out || prev->data != NULL)) {
Packit Service 963350
        g_free (prev->data);
Packit Service 963350
        out = g_list_delete_link (out, prev);
Packit Service 963350
      }
Packit Service 963350
      g_free (elem->data);
Packit Service 963350
      if (next != NULL) {
Packit Service 963350
        out = g_list_delete_link (out, elem);
Packit Service 963350
      } else {
Packit Service 963350
        /* path ends in '/..' We need to keep the last '/' */
Packit Service 963350
        elem->data = NULL;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return out;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_userinfo (const gchar * userinfo)
Packit Service 963350
{
Packit Service 963350
  return g_uri_escape_string (userinfo,
Packit Service 963350
      G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_host (const gchar * host)
Packit Service 963350
{
Packit Service 963350
  return g_uri_escape_string (host,
Packit Service 963350
      G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_host_colon (const gchar * host)
Packit Service 963350
{
Packit Service 963350
  return g_uri_escape_string (host,
Packit Service 963350
      G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":", FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_path_segment (const gchar * segment)
Packit Service 963350
{
Packit Service 963350
  return g_uri_escape_string (segment,
Packit Service 963350
      G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_http_query_element (const gchar * element)
Packit Service 963350
{
Packit Service 963350
  gchar *ret, *c;
Packit Service 963350
Packit Service 963350
  ret = g_uri_escape_string (element, "!$'()*,;:@/? ", FALSE);
Packit Service 963350
  for (c = ret; *c; c++)
Packit Service 963350
    if (*c == ' ')
Packit Service 963350
      *c = '+';
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gchar *
Packit Service 963350
_gst_uri_escape_fragment (const gchar * fragment)
Packit Service 963350
{
Packit Service 963350
  return g_uri_escape_string (fragment,
Packit Service 963350
      G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?", FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GList *
Packit Service 963350
_gst_uri_string_to_list (const gchar * str, const gchar * sep, gboolean convert,
Packit Service 963350
    gboolean unescape)
Packit Service 963350
{
Packit Service 963350
  GList *new_list = NULL;
Packit Service 963350
Packit Service 963350
  if (str) {
Packit Service 963350
    guint pct_sep_len = 0;
Packit Service 963350
    gchar *pct_sep = NULL;
Packit Service 963350
    gchar **split_str;
Packit Service 963350
Packit Service 963350
    if (convert && !unescape) {
Packit Service 963350
      pct_sep = g_strdup_printf ("%%%2.2X", (guint) (*sep));
Packit Service 963350
      pct_sep_len = 3;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    split_str = g_strsplit (str, sep, -1);
Packit Service 963350
    if (split_str) {
Packit Service 963350
      gchar **next_elem;
Packit Service 963350
      for (next_elem = split_str; *next_elem; next_elem += 1) {
Packit Service 963350
        gchar *elem = *next_elem;
Packit Service 963350
        if (*elem == '\0') {
Packit Service 963350
          new_list = g_list_append (new_list, NULL);
Packit Service 963350
        } else {
Packit Service 963350
          if (convert && !unescape) {
Packit Service 963350
            gchar *next_sep;
Packit Service 963350
            for (next_sep = strcasestr (elem, pct_sep); next_sep;
Packit Service 963350
                next_sep = strcasestr (next_sep + 1, pct_sep)) {
Packit Service 963350
              *next_sep = *sep;
Packit Service 963350
              memmove (next_sep + 1, next_sep + pct_sep_len,
Packit Service 963350
                  strlen (next_sep + pct_sep_len) + 1);
Packit Service 963350
            }
Packit Service 963350
          }
Packit Service 963350
          if (unescape) {
Packit Service 963350
            *next_elem = g_uri_unescape_string (elem, NULL);
Packit Service 963350
            g_free (elem);
Packit Service 963350
            elem = *next_elem;
Packit Service 963350
          }
Packit Service 963350
          new_list = g_list_append (new_list, g_strdup (elem));
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
    g_strfreev (split_str);
Packit Service 963350
    if (convert && !unescape)
Packit Service 963350
      g_free (pct_sep);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return new_list;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GHashTable *
Packit Service 963350
_gst_uri_string_to_table (const gchar * str, const gchar * part_sep,
Packit Service 963350
    const gchar * kv_sep, gboolean convert, gboolean unescape)
Packit Service 963350
{
Packit Service 963350
  GHashTable *new_table = NULL;
Packit Service 963350
Packit Service 963350
  if (str) {
Packit Service 963350
    gchar *pct_part_sep = NULL, *pct_kv_sep = NULL;
Packit Service 963350
    gchar **split_parts;
Packit Service 963350
Packit Service 963350
    new_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
Packit Service 963350
Packit Service 963350
    if (convert && !unescape) {
Packit Service 963350
      pct_part_sep = g_strdup_printf ("%%%2.2X", (guint) (*part_sep));
Packit Service 963350
      pct_kv_sep = g_strdup_printf ("%%%2.2X", (guint) (*kv_sep));
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    split_parts = g_strsplit (str, part_sep, -1);
Packit Service 963350
    if (split_parts) {
Packit Service 963350
      gchar **next_part;
Packit Service 963350
      for (next_part = split_parts; *next_part; next_part += 1) {
Packit Service 963350
        gchar *part = *next_part;
Packit Service 963350
        gchar *kv_sep_pos;
Packit Service 963350
        gchar *key, *value;
Packit Service 963350
        /* if we are converting percent encoded versions of separators then
Packit Service 963350
         *  substitute the part separator now. */
Packit Service 963350
        if (convert && !unescape) {
Packit Service 963350
          gchar *next_sep;
Packit Service 963350
          for (next_sep = strcasestr (part, pct_part_sep); next_sep;
Packit Service 963350
              next_sep = strcasestr (next_sep + 1, pct_part_sep)) {
Packit Service 963350
            *next_sep = *part_sep;
Packit Service 963350
            memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
Packit Service 963350
          }
Packit Service 963350
        }
Packit Service 963350
        /* find the key/value separator within the part */
Packit Service 963350
        kv_sep_pos = g_strstr_len (part, -1, kv_sep);
Packit Service 963350
        if (kv_sep_pos == NULL) {
Packit Service 963350
          if (unescape) {
Packit Service 963350
            key = g_uri_unescape_string (part, NULL);
Packit Service 963350
          } else {
Packit Service 963350
            key = g_strdup (part);
Packit Service 963350
          }
Packit Service 963350
          value = NULL;
Packit Service 963350
        } else {
Packit Service 963350
          if (unescape) {
Packit Service 963350
            key = g_uri_unescape_segment (part, kv_sep_pos, NULL);
Packit Service 963350
            value = g_uri_unescape_string (kv_sep_pos + 1, NULL);
Packit Service 963350
          } else {
Packit Service 963350
            key = g_strndup (part, kv_sep_pos - part);
Packit Service 963350
            value = g_strdup (kv_sep_pos + 1);
Packit Service 963350
          }
Packit Service 963350
        }
Packit Service 963350
        /* if we are converting percent encoded versions of separators then
Packit Service 963350
         *  substitute the key/value separator in both key and value now. */
Packit Service 963350
        if (convert && !unescape) {
Packit Service 963350
          gchar *next_sep;
Packit Service 963350
          for (next_sep = strcasestr (key, pct_kv_sep); next_sep;
Packit Service 963350
              next_sep = strcasestr (next_sep + 1, pct_kv_sep)) {
Packit Service 963350
            *next_sep = *kv_sep;
Packit Service 963350
            memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
Packit Service 963350
          }
Packit Service 963350
          if (value) {
Packit Service 963350
            for (next_sep = strcasestr (value, pct_kv_sep); next_sep;
Packit Service 963350
                next_sep = strcasestr (next_sep + 1, pct_kv_sep)) {
Packit Service 963350
              *next_sep = *kv_sep;
Packit Service 963350
              memmove (next_sep + 1, next_sep + 3, strlen (next_sep + 3) + 1);
Packit Service 963350
            }
Packit Service 963350
          }
Packit Service 963350
        }
Packit Service 963350
        /* add value to the table */
Packit Service 963350
        g_hash_table_insert (new_table, key, value);
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
    /* tidy up */
Packit Service 963350
    g_strfreev (split_parts);
Packit Service 963350
    if (convert && !unescape) {
Packit Service 963350
      g_free (pct_part_sep);
Packit Service 963350
      g_free (pct_kv_sep);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return new_table;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
Packit Service 963350
/*
Packit Service 963350
 * Method definitions.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_new:
Packit Service 963350
 * @scheme: (nullable): The scheme for the new URI.
Packit Service 963350
 * @userinfo: (nullable): The user-info for the new URI.
Packit Service 963350
 * @host: (nullable): The host name for the new URI.
Packit Service 963350
 * @port: The port number for the new URI or %GST_URI_NO_PORT.
Packit Service 963350
 * @path: (nullable): The path for the new URI with '/' separating path
Packit Service 963350
 *                      elements.
Packit Service 963350
 * @query: (nullable): The query string for the new URI with '&' separating
Packit Service 963350
 *                       query elements. Elements containing '&' characters
Packit Service 963350
 *                       should encode them as "%26".
Packit Service 963350
 * @fragment: (nullable): The fragment name for the new URI.
Packit Service 963350
 *
Packit Service 963350
 * Creates a new #GstUri object with the given URI parts. The path and query
Packit Service 963350
 * strings will be broken down into their elements. All strings should not be
Packit Service 963350
 * escaped except where indicated.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): A new #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_new (const gchar * scheme, const gchar * userinfo, const gchar * host,
Packit Service 963350
    guint port, const gchar * path, const gchar * query, const gchar * fragment)
Packit Service 963350
{
Packit Service 963350
  GstUri *new_uri;
Packit Service 963350
Packit Service 963350
  new_uri = _gst_uri_new ();
Packit Service 963350
  if (new_uri) {
Packit Service 963350
    new_uri->scheme = g_strdup (scheme);
Packit Service 963350
    new_uri->userinfo = g_strdup (userinfo);
Packit Service 963350
    new_uri->host = g_strdup (host);
Packit Service 963350
    new_uri->port = port;
Packit Service 963350
    new_uri->path = _gst_uri_string_to_list (path, "/", FALSE, FALSE);
Packit Service 963350
    new_uri->query = _gst_uri_string_to_table (query, "&", "=", TRUE, FALSE);
Packit Service 963350
    new_uri->fragment = g_strdup (fragment);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return new_uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_new_with_base:
Packit Service 963350
 * @base: (transfer none)(nullable): The base URI to join the new URI to.
Packit Service 963350
 * @scheme: (nullable): The scheme for the new URI.
Packit Service 963350
 * @userinfo: (nullable): The user-info for the new URI.
Packit Service 963350
 * @host: (nullable): The host name for the new URI.
Packit Service 963350
 * @port: The port number for the new URI or %GST_URI_NO_PORT.
Packit Service 963350
 * @path: (nullable): The path for the new URI with '/' separating path
Packit Service 963350
 *                      elements.
Packit Service 963350
 * @query: (nullable): The query string for the new URI with '&' separating
Packit Service 963350
 *                       query elements. Elements containing '&' characters
Packit Service 963350
 *                       should encode them as "%26".
Packit Service 963350
 * @fragment: (nullable): The fragment name for the new URI.
Packit Service 963350
 *
Packit Service 963350
 * Like gst_uri_new(), but joins the new URI onto a base URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): The new URI joined onto @base.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_new_with_base (GstUri * base, const gchar * scheme,
Packit Service 963350
    const gchar * userinfo, const gchar * host, guint port, const gchar * path,
Packit Service 963350
    const gchar * query, const gchar * fragment)
Packit Service 963350
{
Packit Service 963350
  GstUri *new_rel_uri;
Packit Service 963350
  GstUri *new_uri;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (base == NULL || GST_IS_URI (base), NULL);
Packit Service 963350
Packit Service 963350
  new_rel_uri = gst_uri_new (scheme, userinfo, host, port, path, query,
Packit Service 963350
      fragment);
Packit Service 963350
  new_uri = gst_uri_join (base, new_rel_uri);
Packit Service 963350
  gst_uri_unref (new_rel_uri);
Packit Service 963350
Packit Service 963350
  return new_uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_from_string:
Packit Service 963350
 * @uri: The URI string to parse.
Packit Service 963350
 *
Packit Service 963350
 * Parses a URI string into a new #GstUri object. Will return NULL if the URI
Packit Service 963350
 * cannot be parsed.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): A new #GstUri object, or NULL.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_from_string (const gchar * uri)
Packit Service 963350
{
Packit Service 963350
  const gchar *orig_uri = uri;
Packit Service 963350
  GstUri *uri_obj;
Packit Service 963350
Packit Service 963350
  uri_obj = _gst_uri_new ();
Packit Service 963350
Packit Service 963350
  if (uri_obj && uri != NULL) {
Packit Service 963350
    int i = 0;
Packit Service 963350
Packit Service 963350
    /* be helpful and skip initial white space */
Packit Service 963350
    while (*uri == '\v' || g_ascii_isspace (*uri))
Packit Service 963350
      uri++;
Packit Service 963350
Packit Service 963350
    if (g_ascii_isalpha (uri[i])) {
Packit Service 963350
      /* find end of scheme name */
Packit Service 963350
      i++;
Packit Service 963350
      while (g_ascii_isalnum (uri[i]) || uri[i] == '+' || uri[i] == '-' ||
Packit Service 963350
          uri[i] == '.')
Packit Service 963350
        i++;
Packit Service 963350
    }
Packit Service 963350
    if (i > 0 && uri[i] == ':') {
Packit Service 963350
      /* get scheme */
Packit Service 963350
      uri_obj->scheme = g_strndup (uri, i);
Packit Service 963350
      uri += i + 1;
Packit Service 963350
    }
Packit Service 963350
    if (uri[0] == '/' && uri[1] == '/') {
Packit Service 963350
      const gchar *eoa, *eoui, *eoh, *reoh;
Packit Service 963350
      /* get authority [userinfo@]host[:port] */
Packit Service 963350
      uri += 2;
Packit Service 963350
      /* find end of authority */
Packit Service 963350
      eoa = uri + strcspn (uri, "/?#");
Packit Service 963350
Packit Service 963350
      /* find end of userinfo */
Packit Service 963350
      eoui = strchr (uri, '@');
Packit Service 963350
      if (eoui != NULL && eoui < eoa) {
Packit Service 963350
        uri_obj->userinfo = g_uri_unescape_segment (uri, eoui, NULL);
Packit Service 963350
        uri = eoui + 1;
Packit Service 963350
      }
Packit Service 963350
      /* find end of host */
Packit Service 963350
      if (uri[0] == '[') {
Packit Service 963350
        eoh = strchr (uri, ']');
Packit Service 963350
        if (eoh == NULL || eoh > eoa) {
Packit Service 963350
          GST_DEBUG ("Unable to parse the host part of the URI '%s'.",
Packit Service 963350
              orig_uri);
Packit Service 963350
          gst_uri_unref (uri_obj);
Packit Service 963350
          return NULL;
Packit Service 963350
        }
Packit Service 963350
        reoh = eoh + 1;
Packit Service 963350
        uri++;
Packit Service 963350
      } else {
Packit Service 963350
        reoh = eoh = strchr (uri, ':');
Packit Service 963350
        if (eoh == NULL || eoh > eoa)
Packit Service 963350
          reoh = eoh = eoa;
Packit Service 963350
      }
Packit Service 963350
      /* don't capture empty host strings */
Packit Service 963350
      if (eoh != uri)
Packit Service 963350
        uri_obj->host = g_uri_unescape_segment (uri, eoh, NULL);
Packit Service 963350
Packit Service 963350
      uri = reoh;
Packit Service 963350
      if (uri < eoa) {
Packit Service 963350
        /* if port number is malformed then we can't parse this */
Packit Service 963350
        if (uri[0] != ':' || strspn (uri + 1, "0123456789") != eoa - uri - 1) {
Packit Service 963350
          GST_DEBUG ("Unable to parse host/port part of the URI '%s'.",
Packit Service 963350
              orig_uri);
Packit Service 963350
          gst_uri_unref (uri_obj);
Packit Service 963350
          return NULL;
Packit Service 963350
        }
Packit Service 963350
        /* otherwise treat port as unsigned decimal number */
Packit Service 963350
        uri++;
Packit Service 963350
        while (uri < eoa) {
Packit Service 963350
          uri_obj->port = uri_obj->port * 10 + g_ascii_digit_value (*uri);
Packit Service 963350
          uri++;
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
      uri = eoa;
Packit Service 963350
    }
Packit Service 963350
    if (uri != NULL && uri[0] != '\0') {
Packit Service 963350
      /* get path */
Packit Service 963350
      size_t len;
Packit Service 963350
      len = strcspn (uri, "?#");
Packit Service 963350
      if (uri[len] == '\0') {
Packit Service 963350
        uri_obj->path = _gst_uri_string_to_list (uri, "/", FALSE, TRUE);
Packit Service 963350
        uri = NULL;
Packit Service 963350
      } else {
Packit Service 963350
        if (len > 0) {
Packit Service 963350
          gchar *path_str = g_strndup (uri, len);
Packit Service 963350
          uri_obj->path = _gst_uri_string_to_list (path_str, "/", FALSE, TRUE);
Packit Service 963350
          g_free (path_str);
Packit Service 963350
        }
Packit Service 963350
        uri += len;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
    if (uri != NULL && uri[0] == '?') {
Packit Service 963350
      /* get query */
Packit Service 963350
      gchar *eoq;
Packit Service 963350
      eoq = strchr (++uri, '#');
Packit Service 963350
      if (eoq == NULL) {
Packit Service 963350
        uri_obj->query = _gst_uri_string_to_table (uri, "&", "=", TRUE, TRUE);
Packit Service 963350
        uri = NULL;
Packit Service 963350
      } else {
Packit Service 963350
        if (eoq != uri) {
Packit Service 963350
          gchar *query_str = g_strndup (uri, eoq - uri);
Packit Service 963350
          uri_obj->query = _gst_uri_string_to_table (query_str, "&", "=", TRUE,
Packit Service 963350
              TRUE);
Packit Service 963350
          g_free (query_str);
Packit Service 963350
        }
Packit Service 963350
        uri = eoq;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
    if (uri != NULL && uri[0] == '#') {
Packit Service 963350
      uri_obj->fragment = g_uri_unescape_string (uri + 1, NULL);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return uri_obj;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_from_string_with_base:
Packit Service 963350
 * @base: (transfer none)(nullable): The base URI to join the new URI with.
Packit Service 963350
 * @uri: The URI string to parse.
Packit Service 963350
 *
Packit Service 963350
 * Like gst_uri_from_string() but also joins with a base URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): A new #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_from_string_with_base (GstUri * base, const gchar * uri)
Packit Service 963350
{
Packit Service 963350
  GstUri *new_rel_uri;
Packit Service 963350
  GstUri *new_uri;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (base == NULL || GST_IS_URI (base), NULL);
Packit Service 963350
Packit Service 963350
  new_rel_uri = gst_uri_from_string (uri);
Packit Service 963350
  new_uri = gst_uri_join (base, new_rel_uri);
Packit Service 963350
  gst_uri_unref (new_rel_uri);
Packit Service 963350
Packit Service 963350
  return new_uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_equal:
Packit Service 963350
 * @first: First #GstUri to compare.
Packit Service 963350
 * @second: Second #GstUri to compare.
Packit Service 963350
 *
Packit Service 963350
 * Compares two #GstUri objects to see if they represent the same normalized
Packit Service 963350
 * URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the normalized versions of the two URI's would be equal.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_equal (const GstUri * first, const GstUri * second)
Packit Service 963350
{
Packit Service 963350
  gchar *first_norm = NULL, *second_norm = NULL;
Packit Service 963350
  GList *first_norm_list = NULL, *second_norm_list = NULL;
Packit Service 963350
  const gchar *first_cmp, *second_cmp;
Packit Service 963350
  GHashTableIter table_iter;
Packit Service 963350
  gpointer key, value;
Packit Service 963350
  int result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail ((first == NULL || GST_IS_URI (first)) &&
Packit Service 963350
      (second == NULL || GST_IS_URI (second)), FALSE);
Packit Service 963350
Packit Service 963350
  if (first == second)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  if (first == NULL || second == NULL)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  if (first->port != second->port)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
/* work out a version of field value (normalized or not) to compare.
Packit Service 963350
 * first_cmp, second_cmp will be the values to compare later.
Packit Service 963350
 * first_norm, second_norm will be non-NULL if normalized versions are used,
Packit Service 963350
 *  and need to be freed later.
Packit Service 963350
 */
Packit Service 963350
#define GST_URI_NORMALIZED_FIELD(pos, field, norm_fn, flags) \
Packit Service 963350
  pos##_cmp = pos->field; \
Packit Service 963350
  if (_gst_uri_first_non_normalized_char ((gchar*)pos##_cmp, flags) != NULL) { \
Packit Service 963350
    pos##_norm = g_strdup (pos##_cmp); \
Packit Service 963350
    norm_fn (pos##_norm); \
Packit Service 963350
    pos##_cmp = pos##_norm; \
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
/* compare two string values, normalizing if needed */
Packit Service 963350
#define GST_URI_NORMALIZED_CMP_STR(field, norm_fn, flags) \
Packit Service 963350
  GST_URI_NORMALIZED_FIELD (first, field, norm_fn, flags) \
Packit Service 963350
  GST_URI_NORMALIZED_FIELD (second, field, norm_fn, flags) \
Packit Service 963350
  result = g_strcmp0 (first_cmp, second_cmp); \
Packit Service 963350
  g_free (first_norm); \
Packit Service 963350
  first_norm = NULL; \
Packit Service 963350
  g_free (second_norm); \
Packit Service 963350
  second_norm = NULL; \
Packit Service 963350
  if (result != 0) return FALSE
Packit Service 963350
Packit Service 963350
/* compare two string values */
Packit Service 963350
#define GST_URI_CMP_STR(field) \
Packit Service 963350
  if (g_strcmp0 (first->field, second->field) != 0) return FALSE
Packit Service 963350
Packit Service 963350
/* compare two GLists, normalize lists if needed before comparison */
Packit Service 963350
#define GST_URI_NORMALIZED_CMP_LIST(field, norm_fn, copy_fn, cmp_fn, free_fn) \
Packit Service 963350
  first_norm_list = g_list_copy_deep (first->field, (GCopyFunc) copy_fn, NULL); \
Packit Service 963350
  norm_fn (&first_norm_list); \
Packit Service 963350
  second_norm_list = g_list_copy_deep (second->field, (GCopyFunc) copy_fn, NULL); \
Packit Service 963350
  norm_fn (&second_norm_list); \
Packit Service 963350
  result = _gst_uri_compare_lists (first_norm_list, second_norm_list, (GCompareFunc) cmp_fn); \
Packit Service 963350
  g_list_free_full (first_norm_list, free_fn); \
Packit Service 963350
  g_list_free_full (second_norm_list, free_fn); \
Packit Service 963350
  if (result != 0) return FALSE
Packit Service 963350
Packit Service 963350
  GST_URI_CMP_STR (userinfo);
Packit Service 963350
Packit Service 963350
  GST_URI_CMP_STR (fragment);
Packit Service 963350
Packit Service 963350
  GST_URI_NORMALIZED_CMP_STR (scheme, _gst_uri_normalize_scheme,
Packit Service 963350
      _GST_URI_NORMALIZE_LOWERCASE);
Packit Service 963350
Packit Service 963350
  GST_URI_NORMALIZED_CMP_STR (host, _gst_uri_normalize_hostname,
Packit Service 963350
      _GST_URI_NORMALIZE_LOWERCASE);
Packit Service 963350
Packit Service 963350
  GST_URI_NORMALIZED_CMP_LIST (path, _gst_uri_normalize_path, g_strdup,
Packit Service 963350
      g_strcmp0, g_free);
Packit Service 963350
Packit Service 963350
  if (first->query == NULL && second->query != NULL)
Packit Service 963350
    return FALSE;
Packit Service 963350
  if (first->query != NULL && second->query == NULL)
Packit Service 963350
    return FALSE;
Packit Service 963350
  if (first->query != NULL) {
Packit Service 963350
    if (g_hash_table_size (first->query) != g_hash_table_size (second->query))
Packit Service 963350
      return FALSE;
Packit Service 963350
Packit Service 963350
    g_hash_table_iter_init (&table_iter, first->query);
Packit Service 963350
    while (g_hash_table_iter_next (&table_iter, &key, &value)) {
Packit Service 963350
      if (!g_hash_table_contains (second->query, key))
Packit Service 963350
        return FALSE;
Packit Service 963350
      result = g_strcmp0 (g_hash_table_lookup (second->query, key), value);
Packit Service 963350
      if (result != 0)
Packit Service 963350
        return FALSE;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
#undef GST_URI_NORMALIZED_CMP_STR
Packit Service 963350
#undef GST_URI_CMP_STR
Packit Service 963350
#undef GST_URI_NORMALIZED_CMP_LIST
Packit Service 963350
#undef GST_URI_NORMALIZED_FIELD
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_join:
Packit Service 963350
 * @base_uri: (transfer none) (nullable): The base URI to join another to.
Packit Service 963350
 * @ref_uri: (transfer none) (nullable): The reference URI to join onto the
Packit Service 963350
 *                                       base URI.
Packit Service 963350
 *
Packit Service 963350
 * Join a reference URI onto a base URI using the method from RFC 3986.
Packit Service 963350
 * If either URI is %NULL then the other URI will be returned with the ref count
Packit Service 963350
 * increased.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): A #GstUri which represents the base
Packit Service 963350
 *                                      with the reference URI joined on.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_join (GstUri * base_uri, GstUri * ref_uri)
Packit Service 963350
{
Packit Service 963350
  const gchar *r_scheme;
Packit Service 963350
  GstUri *t;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail ((base_uri == NULL || GST_IS_URI (base_uri)) &&
Packit Service 963350
      (ref_uri == NULL || GST_IS_URI (ref_uri)), NULL);
Packit Service 963350
Packit Service 963350
  if (base_uri == NULL && ref_uri == NULL)
Packit Service 963350
    return NULL;
Packit Service 963350
  if (base_uri == NULL) {
Packit Service 963350
    g_return_val_if_fail (GST_IS_URI (ref_uri), NULL);
Packit Service 963350
    return gst_uri_ref (ref_uri);
Packit Service 963350
  }
Packit Service 963350
  if (ref_uri == NULL) {
Packit Service 963350
    g_return_val_if_fail (GST_IS_URI (base_uri), NULL);
Packit Service 963350
    return gst_uri_ref (base_uri);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (base_uri) && GST_IS_URI (ref_uri), NULL);
Packit Service 963350
Packit Service 963350
  t = _gst_uri_new ();
Packit Service 963350
Packit Service 963350
  if (t == NULL)
Packit Service 963350
    return t;
Packit Service 963350
Packit Service 963350
  /* process according to RFC3986 */
Packit Service 963350
  r_scheme = ref_uri->scheme;
Packit Service 963350
  if (r_scheme != NULL && g_strcmp0 (base_uri->scheme, r_scheme) == 0) {
Packit Service 963350
    r_scheme = NULL;
Packit Service 963350
  }
Packit Service 963350
  if (r_scheme != NULL) {
Packit Service 963350
    t->scheme = g_strdup (r_scheme);
Packit Service 963350
    t->userinfo = g_strdup (ref_uri->userinfo);
Packit Service 963350
    t->host = g_strdup (ref_uri->host);
Packit Service 963350
    t->port = ref_uri->port;
Packit Service 963350
    t->path = _remove_dot_segments (ref_uri->path);
Packit Service 963350
    t->query = _gst_uri_copy_query_table (ref_uri->query);
Packit Service 963350
  } else {
Packit Service 963350
    if (ref_uri->host != NULL) {
Packit Service 963350
      t->userinfo = g_strdup (ref_uri->userinfo);
Packit Service 963350
      t->host = g_strdup (ref_uri->host);
Packit Service 963350
      t->port = ref_uri->port;
Packit Service 963350
      t->path = _remove_dot_segments (ref_uri->path);
Packit Service 963350
      t->query = _gst_uri_copy_query_table (ref_uri->query);
Packit Service 963350
    } else {
Packit Service 963350
      if (ref_uri->path == NULL) {
Packit Service 963350
        t->path = g_list_copy_deep (base_uri->path, (GCopyFunc) g_strdup, NULL);
Packit Service 963350
        if (ref_uri->query != NULL)
Packit Service 963350
          t->query = _gst_uri_copy_query_table (ref_uri->query);
Packit Service 963350
        else
Packit Service 963350
          t->query = _gst_uri_copy_query_table (base_uri->query);
Packit Service 963350
      } else {
Packit Service 963350
        if (ref_uri->path->data == NULL)
Packit Service 963350
          t->path = _remove_dot_segments (ref_uri->path);
Packit Service 963350
        else {
Packit Service 963350
          GList *mrgd = _merge (base_uri->path, ref_uri->path);
Packit Service 963350
          t->path = _remove_dot_segments (mrgd);
Packit Service 963350
          g_list_free_full (mrgd, g_free);
Packit Service 963350
        }
Packit Service 963350
        t->query = _gst_uri_copy_query_table (ref_uri->query);
Packit Service 963350
      }
Packit Service 963350
      t->userinfo = g_strdup (base_uri->userinfo);
Packit Service 963350
      t->host = g_strdup (base_uri->host);
Packit Service 963350
      t->port = base_uri->port;
Packit Service 963350
    }
Packit Service 963350
    t->scheme = g_strdup (base_uri->scheme);
Packit Service 963350
  }
Packit Service 963350
  t->fragment = g_strdup (ref_uri->fragment);
Packit Service 963350
Packit Service 963350
  return t;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_join_strings:
Packit Service 963350
 * @base_uri: The percent-encoded base URI.
Packit Service 963350
 * @ref_uri: The percent-encoded reference URI to join to the @base_uri.
Packit Service 963350
 *
Packit Service 963350
 * This is a convenience function to join two URI strings and return the result.
Packit Service 963350
 * The returned string should be g_free()'d after use.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): A string representing the percent-encoded join of
Packit Service 963350
 *          the two URIs.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_join_strings (const gchar * base_uri, const gchar * ref_uri)
Packit Service 963350
{
Packit Service 963350
  GstUri *base, *result;
Packit Service 963350
  gchar *result_uri;
Packit Service 963350
Packit Service 963350
  base = gst_uri_from_string (base_uri);
Packit Service 963350
  result = gst_uri_from_string_with_base (base, ref_uri);
Packit Service 963350
  result_uri = gst_uri_to_string (result);
Packit Service 963350
  gst_uri_unref (base);
Packit Service 963350
  gst_uri_unref (result);
Packit Service 963350
Packit Service 963350
  return result_uri;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_is_writable:
Packit Service 963350
 * @uri: The #GstUri object to test.
Packit Service 963350
 *
Packit Service 963350
 * Check if it is safe to write to this #GstUri.
Packit Service 963350
 *
Packit Service 963350
 * Check if the refcount of @uri is exactly 1, meaning that no other
Packit Service 963350
 * reference exists to the #GstUri and that the #GstUri is therefore writable.
Packit Service 963350
 *
Packit Service 963350
 * Modification of a #GstUri should only be done after verifying that it is
Packit Service 963350
 * writable.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if it is safe to write to the object.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_is_writable (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), FALSE);
Packit Service 963350
  return gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (uri));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_make_writable:
Packit Service 963350
 * @uri: (transfer full): The #GstUri object to make writable.
Packit Service 963350
 *
Packit Service 963350
 * Make the #GstUri writable.
Packit Service 963350
 *
Packit Service 963350
 * Checks if @uri is writable, and if so the original object is returned. If
Packit Service 963350
 * not, then a writable copy is made and returned. This gives away the
Packit Service 963350
 * reference to @uri and returns a reference to the new #GstUri.
Packit Service 963350
 * If @uri is %NULL then %NULL is returned.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): A writable version of @uri.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstUri *
Packit Service 963350
gst_uri_make_writable (GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  return
Packit Service 963350
      GST_URI_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (uri)));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_to_string:
Packit Service 963350
 * @uri: This #GstUri to convert to a string.
Packit Service 963350
 *
Packit Service 963350
 * Convert the URI to a string.
Packit Service 963350
 *
Packit Service 963350
 * Returns the URI as held in this object as a #gchar* nul-terminated string.
Packit Service 963350
 * The caller should g_free() the string once they are finished with it.
Packit Service 963350
 * The string is put together as described in RFC 3986.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): The string version of the URI.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_to_string (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GString *uri_str;
Packit Service 963350
  gchar *escaped;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
Packit Service 963350
  uri_str = g_string_new (NULL);
Packit Service 963350
Packit Service 963350
  if (uri->scheme != NULL)
Packit Service 963350
    g_string_append_printf (uri_str, "%s:", uri->scheme);
Packit Service 963350
Packit Service 963350
  if (uri->userinfo != NULL || uri->host != NULL ||
Packit Service 963350
      uri->port != GST_URI_NO_PORT)
Packit Service 963350
    g_string_append (uri_str, "//");
Packit Service 963350
Packit Service 963350
  if (uri->userinfo != NULL) {
Packit Service 963350
    escaped = _gst_uri_escape_userinfo (uri->userinfo);
Packit Service 963350
    g_string_append_printf (uri_str, "%s@", escaped);
Packit Service 963350
    g_free (escaped);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (uri->host != NULL) {
Packit Service 963350
    if (strchr (uri->host, ':') != NULL) {
Packit Service 963350
      escaped = _gst_uri_escape_host_colon (uri->host);
Packit Service 963350
      g_string_append_printf (uri_str, "[%s]", escaped);
Packit Service 963350
      g_free (escaped);
Packit Service 963350
    } else {
Packit Service 963350
      escaped = _gst_uri_escape_host (uri->host);
Packit Service 963350
      g_string_append (uri_str, escaped);
Packit Service 963350
      g_free (escaped);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (uri->port != GST_URI_NO_PORT)
Packit Service 963350
    g_string_append_printf (uri_str, ":%u", uri->port);
Packit Service 963350
Packit Service 963350
  if (uri->path != NULL) {
Packit Service 963350
    escaped = gst_uri_get_path_string (uri);
Packit Service 963350
    g_string_append (uri_str, escaped);
Packit Service 963350
    g_free (escaped);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (uri->query) {
Packit Service 963350
    g_string_append (uri_str, "?");
Packit Service 963350
    escaped = gst_uri_get_query_string (uri);
Packit Service 963350
    g_string_append (uri_str, escaped);
Packit Service 963350
    g_free (escaped);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (uri->fragment != NULL) {
Packit Service 963350
    escaped = _gst_uri_escape_fragment (uri->fragment);
Packit Service 963350
    g_string_append_printf (uri_str, "#%s", escaped);
Packit Service 963350
    g_free (escaped);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return g_string_free (uri_str, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_is_normalized:
Packit Service 963350
 * @uri: The #GstUri to test to see if it is normalized.
Packit Service 963350
 *
Packit Service 963350
 * Tests the @uri to see if it is normalized. A %NULL @uri is considered to be
Packit Service 963350
 * normalized.
Packit Service 963350
 *
Packit Service 963350
 * Returns: TRUE if the URI is normalized or is %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_is_normalized (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GList *new_path;
Packit Service 963350
  gboolean ret;
Packit Service 963350
Packit Service 963350
  if (uri == NULL)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), FALSE);
Packit Service 963350
Packit Service 963350
  /* check for non-normalized characters in uri parts */
Packit Service 963350
  if (_gst_uri_first_non_normalized_char (uri->scheme,
Packit Service 963350
          _GST_URI_NORMALIZE_LOWERCASE) != NULL ||
Packit Service 963350
      /*_gst_uri_first_non_normalized_char (uri->userinfo,
Packit Service 963350
          _GST_URI_NORMALIZE_PERCENTAGES) != NULL || */
Packit Service 963350
      _gst_uri_first_non_normalized_char (uri->host,
Packit Service 963350
          _GST_URI_NORMALIZE_LOWERCASE /*| _GST_URI_NORMALIZE_PERCENTAGES */ )
Packit Service 963350
      != NULL
Packit Service 963350
      /*|| _gst_uri_first_non_normalized_char (uri->path,
Packit Service 963350
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL
Packit Service 963350
         || _gst_uri_first_non_normalized_char (uri->query,
Packit Service 963350
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL
Packit Service 963350
         || _gst_uri_first_non_normalized_char (uri->fragment,
Packit Service 963350
         _GST_URI_NORMALIZE_PERCENTAGES) != NULL */ )
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  /* also check path has had dot segments removed */
Packit Service 963350
  new_path = _remove_dot_segments (uri->path);
Packit Service 963350
  ret =
Packit Service 963350
      (_gst_uri_compare_lists (new_path, uri->path,
Packit Service 963350
          (GCompareFunc) g_strcmp0) == 0);
Packit Service 963350
  g_list_free_full (new_path, g_free);
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_normalize:
Packit Service 963350
 * @uri: (transfer none): The #GstUri to normalize.
Packit Service 963350
 *
Packit Service 963350
 * Normalization will remove extra path segments ("." and "..") from the URI. It
Packit Service 963350
 * will also convert the scheme and host name to lower case and any
Packit Service 963350
 * percent-encoded values to uppercase.
Packit Service 963350
 *
Packit Service 963350
 * The #GstUri object must be writable. Check with gst_uri_is_writable() or use
Packit Service 963350
 * gst_uri_make_writable() first.
Packit Service 963350
 *
Packit Service 963350
 * Returns: TRUE if the URI was modified.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_normalize (GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  return _gst_uri_normalize_scheme (uri->scheme) |
Packit Service 963350
      _gst_uri_normalize_userinfo (uri->userinfo) |
Packit Service 963350
      _gst_uri_normalize_hostname (uri->host) |
Packit Service 963350
      _gst_uri_normalize_path (&uri->path) |
Packit Service 963350
      _gst_uri_normalize_query (uri->query) |
Packit Service 963350
      _gst_uri_normalize_fragment (uri->fragment);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_scheme:
Packit Service 963350
 * @uri: (nullable): This #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Get the scheme name from the URI or %NULL if it doesn't exist.
Packit Service 963350
 * If @uri is %NULL then returns %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The scheme from the #GstUri object or %NULL.
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_uri_get_scheme (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
  return (uri ? uri->scheme : NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_scheme:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @scheme: The new scheme to set or %NULL to unset the scheme.
Packit Service 963350
 *
Packit Service 963350
 * Set or unset the scheme for the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the scheme was set/unset successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_scheme (GstUri * uri, const gchar * scheme)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return scheme == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_free (uri->scheme);
Packit Service 963350
  uri->scheme = g_strdup (scheme);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_userinfo:
Packit Service 963350
 * @uri: (nullable): This #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Get the userinfo (usually in the form "username:password") from the URI
Packit Service 963350
 * or %NULL if it doesn't exist. If @uri is %NULL then returns %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The userinfo from the #GstUri object or %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_uri_get_userinfo (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
  return (uri ? uri->userinfo : NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_userinfo:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @userinfo: The new user-information string to set or %NULL to unset.
Packit Service 963350
 *
Packit Service 963350
 * Set or unset the user information for the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the user information was set/unset successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_userinfo (GstUri * uri, const gchar * userinfo)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return userinfo == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_free (uri->userinfo);
Packit Service 963350
  uri->userinfo = g_strdup (userinfo);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_host:
Packit Service 963350
 * @uri: (nullable): This #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Get the host name from the URI or %NULL if it doesn't exist.
Packit Service 963350
 * If @uri is %NULL then returns %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The host name from the #GstUri object or %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_uri_get_host (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
  return (uri ? uri->host : NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_host:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @host: The new host string to set or %NULL to unset.
Packit Service 963350
 *
Packit Service 963350
 * Set or unset the host for the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the host was set/unset successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_host (GstUri * uri, const gchar * host)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return host == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_free (uri->host);
Packit Service 963350
  uri->host = g_strdup (host);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_port:
Packit Service 963350
 * @uri: (nullable): This #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Get the port number from the URI or %GST_URI_NO_PORT if it doesn't exist.
Packit Service 963350
 * If @uri is %NULL then returns %GST_URI_NO_PORT.
Packit Service 963350
 *
Packit Service 963350
 * Returns: The port number from the #GstUri object or %GST_URI_NO_PORT.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
guint
Packit Service 963350
gst_uri_get_port (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), GST_URI_NO_PORT);
Packit Service 963350
  return (uri ? uri->port : GST_URI_NO_PORT);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_port:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @port: The new port number to set or %GST_URI_NO_PORT to unset.
Packit Service 963350
 *
Packit Service 963350
 * Set or unset the port number for the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the port number was set/unset successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_port (GstUri * uri, guint port)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return port == GST_URI_NO_PORT;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  uri->port = port;
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_path:
Packit Service 963350
 * @uri: The #GstUri to get the path from.
Packit Service 963350
 *
Packit Service 963350
 * Extract the path string from the URI object.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): (nullable): The path from the URI. Once finished
Packit Service 963350
 *                                       with the string should be g_free()'d.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_get_path (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GList *path_segment;
Packit Service 963350
  const gchar *sep = "";
Packit Service 963350
  GString *ret;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->path)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  ret = g_string_new (NULL);
Packit Service 963350
Packit Service 963350
  for (path_segment = uri->path; path_segment;
Packit Service 963350
      path_segment = path_segment->next) {
Packit Service 963350
    g_string_append (ret, sep);
Packit Service 963350
    if (path_segment->data) {
Packit Service 963350
      g_string_append (ret, path_segment->data);
Packit Service 963350
    }
Packit Service 963350
    sep = "/";
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return g_string_free (ret, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_path:
Packit Service 963350
 * @uri: (transfer none) (nullable): The #GstUri to modify.
Packit Service 963350
 * @path: The new path to set with path segments separated by '/', or use %NULL
Packit Service 963350
 *        to unset the path.
Packit Service 963350
 *
Packit Service 963350
 * Sets or unsets the path in the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the path was set successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_path (GstUri * uri, const gchar * path)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return path == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_list_free_full (uri->path, g_free);
Packit Service 963350
  uri->path = _gst_uri_string_to_list (path, "/", FALSE, FALSE);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_path_string:
Packit Service 963350
 * @uri: The #GstUri to get the path from.
Packit Service 963350
 *
Packit Service 963350
 * Extract the path string from the URI object as a percent encoded URI path.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): The path from the URI. Once finished
Packit Service 963350
 *                                      with the string should be g_free()'d.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_get_path_string (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GList *path_segment;
Packit Service 963350
  const gchar *sep = "";
Packit Service 963350
  GString *ret;
Packit Service 963350
  gchar *escaped;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->path)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  ret = g_string_new (NULL);
Packit Service 963350
Packit Service 963350
  for (path_segment = uri->path; path_segment;
Packit Service 963350
      path_segment = path_segment->next) {
Packit Service 963350
    g_string_append (ret, sep);
Packit Service 963350
    if (path_segment->data) {
Packit Service 963350
      escaped = _gst_uri_escape_path_segment (path_segment->data);
Packit Service 963350
      g_string_append (ret, escaped);
Packit Service 963350
      g_free (escaped);
Packit Service 963350
    }
Packit Service 963350
    sep = "/";
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return g_string_free (ret, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_path_string:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @path: The new percent encoded path to set with path segments separated by
Packit Service 963350
 * '/', or use %NULL to unset the path.
Packit Service 963350
 *
Packit Service 963350
 * Sets or unsets the path in the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the path was set successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_path_string (GstUri * uri, const gchar * path)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return path == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_list_free_full (uri->path, g_free);
Packit Service 963350
  uri->path = _gst_uri_string_to_list (path, "/", FALSE, TRUE);
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_path_segments:
Packit Service 963350
 * @uri: (nullable): The #GstUri to get the path from.
Packit Service 963350
 *
Packit Service 963350
 * Get a list of path segments from the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (element-type gchar*): A #GList of path segment
Packit Service 963350
 *          strings or %NULL if no path segments are available. Free the list
Packit Service 963350
 *          when no longer needed with g_list_free_full(list, g_free).
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GList *
Packit Service 963350
gst_uri_get_path_segments (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GList *ret = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
Packit Service 963350
  if (uri) {
Packit Service 963350
    ret = g_list_copy_deep (uri->path, (GCopyFunc) g_strdup, NULL);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_path_segments:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @path_segments: (transfer full)(nullable)(element-type gchar*): The new
Packit Service 963350
 *                 path list to set.
Packit Service 963350
 *
Packit Service 963350
 * Replace the path segments list in the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the path segments were set successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_path_segments (GstUri * uri, GList * path_segments)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), FALSE);
Packit Service 963350
Packit Service 963350
  if (!uri) {
Packit Service 963350
    if (path_segments)
Packit Service 963350
      g_list_free_full (path_segments, g_free);
Packit Service 963350
    return path_segments == NULL;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_list_free_full (uri->path, g_free);
Packit Service 963350
  uri->path = path_segments;
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_append_path:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @relative_path: Relative path to append to the end of the current path.
Packit Service 963350
 *
Packit Service 963350
 * Append a path onto the end of the path in the URI. The path is not
Packit Service 963350
 * normalized, call #gst_uri_normalize() to normalize the path.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the path was appended successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_append_path (GstUri * uri, const gchar * relative_path)
Packit Service 963350
{
Packit Service 963350
  GList *rel_path_list;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return relative_path == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
  if (!relative_path)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  if (uri->path) {
Packit Service 963350
    GList *last_elem = g_list_last (uri->path);
Packit Service 963350
    if (last_elem->data == NULL) {
Packit Service 963350
      uri->path = g_list_delete_link (uri->path, last_elem);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  rel_path_list = _gst_uri_string_to_list (relative_path, "/", FALSE, FALSE);
Packit Service 963350
  /* if path was absolute, make it relative by removing initial NULL element */
Packit Service 963350
  if (rel_path_list && rel_path_list->data == NULL) {
Packit Service 963350
    rel_path_list = g_list_delete_link (rel_path_list, rel_path_list);
Packit Service 963350
  }
Packit Service 963350
  uri->path = g_list_concat (uri->path, rel_path_list);
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_append_path_segment:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @path_segment: The path segment string to append to the URI path.
Packit Service 963350
 *
Packit Service 963350
 * Append a single path segment onto the end of the URI path.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the path was appended successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_append_path_segment (GstUri * uri, const gchar * path_segment)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return path_segment == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
  if (!path_segment)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  /* if base path ends in a directory (i.e. last element is NULL), remove it */
Packit Service 963350
  if (uri->path && g_list_last (uri->path)->data == NULL) {
Packit Service 963350
    uri->path = g_list_delete_link (uri->path, g_list_last (uri->path));
Packit Service 963350
  }
Packit Service 963350
  uri->path = g_list_append (uri->path, g_strdup (path_segment));
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_query_string:
Packit Service 963350
 * @uri: (nullable): The #GstUri to get the query string from.
Packit Service 963350
 *
Packit Service 963350
 * Get a percent encoded URI query string from the @uri.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): A percent encoded query string. Use
Packit Service 963350
 *                                      g_free() when no longer needed.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_uri_get_query_string (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  GHashTableIter iter;
Packit Service 963350
  gpointer key, value;
Packit Service 963350
  const gchar *sep = "";
Packit Service 963350
  gchar *escaped;
Packit Service 963350
  GString *ret;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  ret = g_string_new (NULL);
Packit Service 963350
  g_hash_table_iter_init (&iter, uri->query);
Packit Service 963350
  while (g_hash_table_iter_next (&iter, &key, &value)) {
Packit Service 963350
    g_string_append (ret, sep);
Packit Service 963350
    escaped = _gst_uri_escape_http_query_element (key);
Packit Service 963350
    g_string_append (ret, escaped);
Packit Service 963350
    g_free (escaped);
Packit Service 963350
    if (value) {
Packit Service 963350
      escaped = _gst_uri_escape_http_query_element (value);
Packit Service 963350
      g_string_append_printf (ret, "=%s", escaped);
Packit Service 963350
      g_free (escaped);
Packit Service 963350
    }
Packit Service 963350
    sep = "&";
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return g_string_free (ret, FALSE);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_query_string:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @query: The new percent encoded query string to use to populate the query
Packit Service 963350
 *        table, or use %NULL to unset the query table.
Packit Service 963350
 *
Packit Service 963350
 * Sets or unsets the query table in the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the query table was set successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_query_string (GstUri * uri, const gchar * query)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return query == NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  if (uri->query)
Packit Service 963350
    g_hash_table_unref (uri->query);
Packit Service 963350
  uri->query = _gst_uri_string_to_table (query, "&", "=", TRUE, TRUE);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_query_table:
Packit Service 963350
 * @uri: (nullable): The #GstUri to get the query table from.
Packit Service 963350
 *
Packit Service 963350
 * Get the query table from the URI. Keys and values in the table are freed
Packit Service 963350
 * with g_free when they are deleted. A value may be %NULL to indicate that
Packit Service 963350
 * the key should appear in the query string in the URI, but does not have a
Packit Service 963350
 * value. Free the returned #GHashTable with #g_hash_table_unref() when it is
Packit Service 963350
 * no longer required. Modifying this hash table will modify the query in the
Packit Service 963350
 * URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (element-type gchar* gchar*) (nullable): The query
Packit Service 963350
 *          hash table from the URI.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GHashTable *
Packit Service 963350
gst_uri_get_query_table (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  return g_hash_table_ref (uri->query);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_query_table:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @query_table: (transfer none)(nullable)(element-type gchar* gchar*): The new
Packit Service 963350
 *               query table to use.
Packit Service 963350
 *
Packit Service 963350
 * Set the query table to use in the URI. The old table is unreferenced and a
Packit Service 963350
 * reference to the new one is used instead. A value if %NULL for @query_table
Packit Service 963350
 * will remove the query string from the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the new table was sucessfully used for the query table.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_query_table (GstUri * uri, GHashTable * query_table)
Packit Service 963350
{
Packit Service 963350
  GHashTable *old_table = NULL;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return query_table == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  old_table = uri->query;
Packit Service 963350
  if (query_table)
Packit Service 963350
    uri->query = g_hash_table_ref (query_table);
Packit Service 963350
  else
Packit Service 963350
    uri->query = NULL;
Packit Service 963350
  if (old_table)
Packit Service 963350
    g_hash_table_unref (old_table);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_query_value:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @query_key: (transfer none): The key for the query entry.
Packit Service 963350
 * @query_value: (transfer none)(nullable): The value for the key.
Packit Service 963350
 *
Packit Service 963350
 * This inserts or replaces a key in the query table. A @query_value of %NULL
Packit Service 963350
 * indicates that the key has no associated value, but will still be present in
Packit Service 963350
 * the query string.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the query table was sucessfully updated.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_query_value (GstUri * uri, const gchar * query_key,
Packit Service 963350
    const gchar * query_value)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return FALSE;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  if (!uri->query) {
Packit Service 963350
    uri->query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
Packit Service 963350
        g_free);
Packit Service 963350
  }
Packit Service 963350
  g_hash_table_insert (uri->query, g_strdup (query_key),
Packit Service 963350
      g_strdup (query_value));
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_remove_query_key:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @query_key: The key to remove.
Packit Service 963350
 *
Packit Service 963350
 * Remove an entry from the query table by key.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the key existed in the table and was removed.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_remove_query_key (GstUri * uri, const gchar * query_key)
Packit Service 963350
{
Packit Service 963350
  gboolean result;
Packit Service 963350
Packit Service 963350
  if (!uri)
Packit Service 963350
    return FALSE;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  result = g_hash_table_remove (uri->query, query_key);
Packit Service 963350
  /* if this was the last query entry, remove the query string completely */
Packit Service 963350
  if (result && g_hash_table_size (uri->query) == 0) {
Packit Service 963350
    g_hash_table_unref (uri->query);
Packit Service 963350
    uri->query = NULL;
Packit Service 963350
  }
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_query_has_key:
Packit Service 963350
 * @uri: (nullable): The #GstUri to examine.
Packit Service 963350
 * @query_key: The key to lookup.
Packit Service 963350
 *
Packit Service 963350
 * Check if there is a query table entry for the @query_key key.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if @query_key exists in the URI query table.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_query_has_key (const GstUri * uri, const gchar * query_key)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return FALSE;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), FALSE);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  return g_hash_table_contains (uri->query, query_key);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_query_value:
Packit Service 963350
 * @uri: (nullable): The #GstUri to examine.
Packit Service 963350
 * @query_key: The key to lookup.
Packit Service 963350
 *
Packit Service 963350
 * Get the value associated with the @query_key key. Will return %NULL if the
Packit Service 963350
 * key has no value or if the key does not exist in the URI query table. Because
Packit Service 963350
 * %NULL is returned for both missing keys and keys with no value, you should
Packit Service 963350
 * use gst_uri_query_has_key() to determine if a key is present in the URI
Packit Service 963350
 * query.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The value for the given key, or %NULL if not found.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_uri_get_query_value (const GstUri * uri, const gchar * query_key)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  return g_hash_table_lookup (uri->query, query_key);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_query_keys:
Packit Service 963350
 * @uri: (nullable): The #GstUri to examine.
Packit Service 963350
 *
Packit Service 963350
 * Get a list of the query keys from the URI.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer container) (element-type gchar*): A list of keys from
Packit Service 963350
 *          the URI query. Free the list with g_list_free().
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GList *
Packit Service 963350
gst_uri_get_query_keys (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri), NULL);
Packit Service 963350
  if (!uri->query)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  return g_hash_table_get_keys (uri->query);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_fragment:
Packit Service 963350
 * @uri: (nullable): This #GstUri object.
Packit Service 963350
 *
Packit Service 963350
 * Get the fragment name from the URI or %NULL if it doesn't exist.
Packit Service 963350
 * If @uri is %NULL then returns %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The host name from the #GstUri object or %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_uri_get_fragment (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
  return (uri ? uri->fragment : NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_set_fragment:
Packit Service 963350
 * @uri: (transfer none)(nullable): The #GstUri to modify.
Packit Service 963350
 * @fragment: (nullable): The fragment string to set.
Packit Service 963350
 *
Packit Service 963350
 * Sets the fragment string in the URI. Use a value of %NULL in @fragment to
Packit Service 963350
 * unset the fragment string.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the fragment was set/unset successfully.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_uri_set_fragment (GstUri * uri, const gchar * fragment)
Packit Service 963350
{
Packit Service 963350
  if (!uri)
Packit Service 963350
    return fragment == NULL;
Packit Service 963350
  g_return_val_if_fail (GST_IS_URI (uri) && gst_uri_is_writable (uri), FALSE);
Packit Service 963350
Packit Service 963350
  g_free (uri->fragment);
Packit Service 963350
  uri->fragment = g_strdup (fragment);
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_uri_get_media_fragment_table:
Packit Service 963350
 * @uri: (nullable): The #GstUri to get the fragment table from.
Packit Service 963350
 *
Packit Service 963350
 * Get the media fragment table from the URI, as defined by "Media Fragments URI 1.0".
Packit Service 963350
 * Hash table returned by this API is a list of "key-value" pairs, and the each
Packit Service 963350
 * pair is generated by splitting "URI fragment" per "&" sub-delims, then "key"
Packit Service 963350
 * and "value" are splitted by "=" sub-delims. The "key" returned by this API may
Packit Service 963350
 * be undefined keyword by standard.
Packit Service 963350
 * A value may be %NULL to indicate that the key should appear in the fragment
Packit Service 963350
 * string in the URI, but does not have a value. Free the returned #GHashTable
Packit Service 963350
 * with #g_hash_table_unref() when it is no longer required.
Packit Service 963350
 * Modifying this hash table does not affect the fragment in the URI.
Packit Service 963350
 *
Packit Service 963350
 * See more about Media Fragments URI 1.0 (W3C) at https://www.w3.org/TR/media-frags/
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (element-type gchar* gchar*) (nullable): The
Packit Service 963350
 *          fragment hash table from the URI.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.12
Packit Service 963350
 */
Packit Service 963350
GHashTable *
Packit Service 963350
gst_uri_get_media_fragment_table (const GstUri * uri)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (uri == NULL || GST_IS_URI (uri), NULL);
Packit Service 963350
Packit Service 963350
  if (!uri->fragment)
Packit Service 963350
    return NULL;
Packit Service 963350
  return _gst_uri_string_to_table (uri->fragment, "&", "=", TRUE, TRUE);
Packit Service 963350
}