/* GStreamer
 * Copyright (C) <2005,2006> Wim Taymans <wim@fluendo.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/*
 * Unless otherwise indicated, Source Code is licensed under MIT license.
 * See further explanation attached in License Statement (distributed in the file
 * LICENSE).
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * SECTION:gstsdpmessage
 * @title: GstSDPMessage
 * @short_description: Helper methods for dealing with SDP messages
 *
 * The GstSDPMessage helper functions makes it easy to parse and create SDP
 * messages.
 *
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gio/gio.h>

#include <gst/rtp/gstrtppayloads.h>
#include "gstsdpmessage.h"

#define FREE_STRING(field)              g_free (field); (field) = NULL
#define REPLACE_STRING(field, val)      FREE_STRING(field); (field) = g_strdup (val)

static void
free_string (gchar ** str)
{
  FREE_STRING (*str);
}

#define INIT_ARRAY(field, type, init_func)              \
G_STMT_START {                                          \
  if (field) {                                          \
    guint i;                                            \
    for(i = 0; i < (field)->len; i++)                   \
      init_func (&g_array_index ((field), type, i));    \
    g_array_set_size ((field), 0);                      \
  }                                                     \
  else                                                  \
    (field) = g_array_new (FALSE, TRUE, sizeof (type)); \
} G_STMT_END

#define FREE_ARRAY(field)         \
G_STMT_START {                    \
  if (field)                      \
    g_array_free ((field), TRUE); \
  (field) = NULL;                 \
} G_STMT_END

#define DEFINE_STRING_SETTER(field)                                     \
GstSDPResult gst_sdp_message_set_##field (GstSDPMessage *msg, const gchar *val) { \
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);                   \
  g_free (msg->field);                                                  \
  msg->field = g_strdup (val);                                          \
  return GST_SDP_OK;                                                    \
}
#define DEFINE_STRING_GETTER(field)                                     \
const gchar* gst_sdp_message_get_##field (const GstSDPMessage *msg) {   \
  g_return_val_if_fail (msg != NULL, NULL);                             \
  return msg->field;                                                    \
}

#define DEFINE_ARRAY_LEN(field)                                         \
guint gst_sdp_message_##field##_len (const GstSDPMessage *msg) {        \
  g_return_val_if_fail (msg != NULL, 0);                                \
  return msg->field->len;                                               \
}
#define DEFINE_ARRAY_GETTER(method, field, type)                        \
const type * gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) {  \
  g_return_val_if_fail (msg != NULL, NULL);                             \
  return &g_array_index (msg->field, type, idx);                        \
}
#define DEFINE_PTR_ARRAY_GETTER(method, field, type)                    \
const type gst_sdp_message_get_##method (const GstSDPMessage *msg, guint idx) {    \
  g_return_val_if_fail (msg != NULL, (type) 0);                         \
  return g_array_index (msg->field, type, idx);                         \
}
#define DEFINE_ARRAY_INSERT(method, field, intype, dup_method, type)         \
GstSDPResult gst_sdp_message_insert_##method (GstSDPMessage *msg, gint idx, intype val) {   \
  type vt;                                                              \
  type* v = &vt;                                                         \
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);                   \
  dup_method (v, val);                                                  \
  if (idx == -1)                                                        \
    g_array_append_val (msg->field, vt);                                \
  else                                                                  \
    g_array_insert_val (msg->field, idx, vt);                           \
  return GST_SDP_OK;                                                    \
}

#define DEFINE_ARRAY_REPLACE(method, field, intype, free_method, dup_method, type)         \
GstSDPResult gst_sdp_message_replace_##method (GstSDPMessage *msg, guint idx, intype val) {   \
  type *v;                                                              \
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);                   \
  v = &g_array_index (msg->field, type, idx);                           \
  free_method (v);                                                      \
  dup_method (v, val);                                                  \
  return GST_SDP_OK;                                                    \
}
#define DEFINE_ARRAY_REMOVE(method, field, type, free_method)                        \
GstSDPResult gst_sdp_message_remove_##method (GstSDPMessage *msg, guint idx) {  \
  type *v;                                                              \
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);                   \
  v = &g_array_index (msg->field, type, idx);                           \
  free_method (v);                                                      \
  g_array_remove_index (msg->field, idx);                               \
  return GST_SDP_OK;                                                    \
}
#define DEFINE_ARRAY_ADDER(method, type)                                \
GstSDPResult gst_sdp_message_add_##method (GstSDPMessage *msg, const type val) {   \
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);                   \
  return gst_sdp_message_insert_##method (msg, -1, val);                \
}

#define dup_string(v,val) ((*v) = g_strdup (val))
#define INIT_STR_ARRAY(field) \
    INIT_ARRAY (field, gchar *, free_string)
#define DEFINE_STR_ARRAY_GETTER(method, field) \
    DEFINE_PTR_ARRAY_GETTER(method, field, gchar *)
#define DEFINE_STR_ARRAY_INSERT(method, field) \
    DEFINE_ARRAY_INSERT (method, field, const gchar *, dup_string, gchar *)
#define DEFINE_STR_ARRAY_ADDER(method, field) \
    DEFINE_ARRAY_ADDER (method, gchar *)
#define DEFINE_STR_ARRAY_REPLACE(method, field) \
    DEFINE_ARRAY_REPLACE (method, field, const gchar *, free_string, dup_string, gchar *)
#define DEFINE_STR_ARRAY_REMOVE(method, field) \
    DEFINE_ARRAY_REMOVE (method, field, gchar *, free_string)

static GstSDPMessage *gst_sdp_message_boxed_copy (GstSDPMessage * orig);
static void gst_sdp_message_boxed_free (GstSDPMessage * msg);

G_DEFINE_BOXED_TYPE (GstSDPMessage, gst_sdp_message, gst_sdp_message_boxed_copy,
    gst_sdp_message_boxed_free);

static GstSDPMessage *
gst_sdp_message_boxed_copy (GstSDPMessage * orig)
{
  GstSDPMessage *copy;

  if (!orig)
    return NULL;

  if (gst_sdp_message_copy (orig, &copy) == GST_SDP_OK)
    return copy;

  return NULL;
}

static void
gst_sdp_message_boxed_free (GstSDPMessage * msg)
{
  gst_sdp_message_free (msg);
}

static void
gst_sdp_origin_init (GstSDPOrigin * origin)
{
  FREE_STRING (origin->username);
  FREE_STRING (origin->sess_id);
  FREE_STRING (origin->sess_version);
  FREE_STRING (origin->nettype);
  FREE_STRING (origin->addrtype);
  FREE_STRING (origin->addr);
}

static void
gst_sdp_key_init (GstSDPKey * key)
{
  FREE_STRING (key->type);
  FREE_STRING (key->data);
}

/**
 * gst_sdp_message_new:
 * @msg: (out) (transfer full): pointer to new #GstSDPMessage
 *
 * Allocate a new GstSDPMessage and store the result in @msg.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_new (GstSDPMessage ** msg)
{
  GstSDPMessage *newmsg;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  newmsg = g_new0 (GstSDPMessage, 1);

  *msg = newmsg;

  return gst_sdp_message_init (newmsg);
}

/**
 * gst_sdp_message_init:
 * @msg: a #GstSDPMessage
 *
 * Initialize @msg so that its contents are as if it was freshly allocated
 * with gst_sdp_message_new(). This function is mostly used to initialize a message
 * allocated on the stack. gst_sdp_message_uninit() undoes this operation.
 *
 * When this function is invoked on newly allocated data (with malloc or on the
 * stack), its contents should be set to 0 before calling this function.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_init (GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  FREE_STRING (msg->version);
  gst_sdp_origin_init (&msg->origin);
  FREE_STRING (msg->session_name);
  FREE_STRING (msg->information);
  FREE_STRING (msg->uri);
  INIT_STR_ARRAY (msg->emails);
  INIT_STR_ARRAY (msg->phones);
  gst_sdp_connection_clear (&msg->connection);
  INIT_ARRAY (msg->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_clear);
  INIT_ARRAY (msg->times, GstSDPTime, gst_sdp_time_clear);
  INIT_ARRAY (msg->zones, GstSDPZone, gst_sdp_zone_clear);
  gst_sdp_key_init (&msg->key);
  INIT_ARRAY (msg->attributes, GstSDPAttribute, gst_sdp_attribute_clear);
  INIT_ARRAY (msg->medias, GstSDPMedia, gst_sdp_media_uninit);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_uninit:
 * @msg: a #GstSDPMessage
 *
 * Free all resources allocated in @msg. @msg should not be used anymore after
 * this function. This function should be used when @msg was allocated on the
 * stack and initialized with gst_sdp_message_init().
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_uninit (GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  gst_sdp_message_init (msg);

  FREE_ARRAY (msg->emails);
  FREE_ARRAY (msg->phones);
  FREE_ARRAY (msg->bandwidths);
  FREE_ARRAY (msg->times);
  FREE_ARRAY (msg->zones);
  FREE_ARRAY (msg->attributes);
  FREE_ARRAY (msg->medias);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_copy:
 * @msg: a #GstSDPMessage
 * @copy: (out) (transfer full): pointer to new #GstSDPMessage
 *
 * Allocate a new copy of @msg and store the result in @copy. The value in
 * @copy should be release with gst_sdp_message_free function.
 *
 * Returns: a #GstSDPResult
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_message_copy (const GstSDPMessage * msg, GstSDPMessage ** copy)
{
  GstSDPResult ret;
  GstSDPMessage *cp;
  guint i, len;

  if (msg == NULL)
    return GST_SDP_EINVAL;

  ret = gst_sdp_message_new (copy);
  if (ret != GST_SDP_OK)
    return ret;

  cp = *copy;

  REPLACE_STRING (cp->version, msg->version);
  gst_sdp_message_set_origin (cp, msg->origin.username, msg->origin.sess_id,
      msg->origin.sess_version, msg->origin.nettype, msg->origin.addrtype,
      msg->origin.addr);
  REPLACE_STRING (cp->session_name, msg->session_name);
  REPLACE_STRING (cp->information, msg->information);
  REPLACE_STRING (cp->uri, msg->uri);

  len = gst_sdp_message_emails_len (msg);
  for (i = 0; i < len; i++) {
    gst_sdp_message_add_email (cp, gst_sdp_message_get_email (msg, i));
  }

  len = gst_sdp_message_phones_len (msg);
  for (i = 0; i < len; i++) {
    gst_sdp_message_add_phone (cp, gst_sdp_message_get_phone (msg, i));
  }

  gst_sdp_message_set_connection (cp, msg->connection.nettype,
      msg->connection.addrtype, msg->connection.address, msg->connection.ttl,
      msg->connection.addr_number);

  len = gst_sdp_message_bandwidths_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_message_get_bandwidth (msg, i);
    gst_sdp_message_add_bandwidth (cp, bw->bwtype, bw->bandwidth);
  }

  len = gst_sdp_message_times_len (msg);
  for (i = 0; i < len; i++) {
    const gchar **repeat = NULL;
    const GstSDPTime *time = gst_sdp_message_get_time (msg, i);

    if (time->repeat != NULL) {
      guint j;

      repeat = g_malloc0 ((time->repeat->len + 1) * sizeof (gchar *));
      for (j = 0; j < time->repeat->len; j++) {
        repeat[j] = g_array_index (time->repeat, char *, j);
      }
      repeat[j] = NULL;
    }

    gst_sdp_message_add_time (cp, time->start, time->stop, repeat);

    g_free ((gchar **) repeat);
  }

  len = gst_sdp_message_zones_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPZone *zone = gst_sdp_message_get_zone (msg, i);
    gst_sdp_message_add_zone (cp, zone->time, zone->typed_time);
  }

  gst_sdp_message_set_key (cp, msg->key.type, msg->key.data);

  len = gst_sdp_message_attributes_len (msg);
  for (i = 0; i < len; i++) {
    const GstSDPAttribute *attr = gst_sdp_message_get_attribute (msg, i);
    gst_sdp_message_add_attribute (cp, attr->key, attr->value);
  }

  len = gst_sdp_message_medias_len (msg);
  for (i = 0; i < len; i++) {
    GstSDPMedia *media_copy;
    const GstSDPMedia *media = gst_sdp_message_get_media (msg, i);

    if (gst_sdp_media_copy (media, &media_copy) == GST_SDP_OK) {
      gst_sdp_message_add_media (cp, media_copy);
      gst_sdp_media_free (media_copy);
    }
  }

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_free:
 * @msg: a #GstSDPMessage
 *
 * Free all resources allocated by @msg. @msg should not be used anymore after
 * this function. This function should be used when @msg was dynamically
 * allocated with gst_sdp_message_new().
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_free (GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  gst_sdp_message_uninit (msg);
  g_free (msg);

  return GST_SDP_OK;
}

/**
 * gst_sdp_address_is_multicast:
 * @nettype: a network type
 * @addrtype: an address type
 * @addr: an address
 *
 * Check if the given @addr is a multicast address.
 *
 * Returns: TRUE when @addr is multicast.
 */
gboolean
gst_sdp_address_is_multicast (const gchar * nettype, const gchar * addrtype,
    const gchar * addr)
{
  gboolean ret = FALSE;
  GInetAddress *iaddr;

  g_return_val_if_fail (addr, FALSE);

  /* we only support IN */
  if (nettype && strcmp (nettype, "IN") != 0)
    return FALSE;

  /* guard against parse failures */
  if ((iaddr = g_inet_address_new_from_string (addr)) == NULL)
    return FALSE;

  ret = g_inet_address_get_is_multicast (iaddr);
  g_object_unref (iaddr);

  return ret;
}

/**
 * gst_sdp_message_as_text:
 * @msg: a #GstSDPMessage
 *
 * Convert the contents of @msg to a text string.
 *
 * Returns: A dynamically allocated string representing the SDP description.
 */
gchar *
gst_sdp_message_as_text (const GstSDPMessage * msg)
{
  /* change all vars so they match rfc? */
  GString *lines;
  guint i;

  g_return_val_if_fail (msg != NULL, NULL);

  lines = g_string_new ("");

  if (msg->version)
    g_string_append_printf (lines, "v=%s\r\n", msg->version);

  if (msg->origin.sess_id && msg->origin.sess_version && msg->origin.nettype &&
      msg->origin.addrtype && msg->origin.addr)
    g_string_append_printf (lines, "o=%s %s %s %s %s %s\r\n",
        msg->origin.username ? msg->origin.username : "-", msg->origin.sess_id,
        msg->origin.sess_version, msg->origin.nettype, msg->origin.addrtype,
        msg->origin.addr);

  if (msg->session_name)
    g_string_append_printf (lines, "s=%s\r\n", msg->session_name);

  if (msg->information)
    g_string_append_printf (lines, "i=%s\r\n", msg->information);

  if (msg->uri)
    g_string_append_printf (lines, "u=%s\r\n", msg->uri);

  for (i = 0; i < gst_sdp_message_emails_len (msg); i++)
    g_string_append_printf (lines, "e=%s\r\n",
        gst_sdp_message_get_email (msg, i));

  for (i = 0; i < gst_sdp_message_phones_len (msg); i++)
    g_string_append_printf (lines, "p=%s\r\n",
        gst_sdp_message_get_phone (msg, i));

  if (msg->connection.nettype && msg->connection.addrtype &&
      msg->connection.address) {
    g_string_append_printf (lines, "c=%s %s %s", msg->connection.nettype,
        msg->connection.addrtype, msg->connection.address);
    if (gst_sdp_address_is_multicast (msg->connection.nettype,
            msg->connection.addrtype, msg->connection.address)) {
      /* only add ttl for IP4 */
      if (strcmp (msg->connection.addrtype, "IP4") == 0)
        g_string_append_printf (lines, "/%u", msg->connection.ttl);
      if (msg->connection.addr_number > 1)
        g_string_append_printf (lines, "/%u", msg->connection.addr_number);
    }
    g_string_append_printf (lines, "\r\n");
  }

  for (i = 0; i < gst_sdp_message_bandwidths_len (msg); i++) {
    const GstSDPBandwidth *bandwidth = gst_sdp_message_get_bandwidth (msg, i);

    g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype,
        bandwidth->bandwidth);
  }

  if (gst_sdp_message_times_len (msg) == 0) {
    g_string_append_printf (lines, "t=0 0\r\n");
  } else {
    for (i = 0; i < gst_sdp_message_times_len (msg); i++) {
      const GstSDPTime *times = gst_sdp_message_get_time (msg, i);

      g_string_append_printf (lines, "t=%s %s\r\n", times->start, times->stop);

      if (times->repeat != NULL) {
        guint j;

        g_string_append_printf (lines, "r=%s",
            g_array_index (times->repeat, gchar *, 0));
        for (j = 1; j < times->repeat->len; j++)
          g_string_append_printf (lines, " %s",
              g_array_index (times->repeat, gchar *, j));
        g_string_append_printf (lines, "\r\n");
      }
    }
  }

  if (gst_sdp_message_zones_len (msg) > 0) {
    const GstSDPZone *zone = gst_sdp_message_get_zone (msg, 0);

    g_string_append_printf (lines, "z=%s %s", zone->time, zone->typed_time);
    for (i = 1; i < gst_sdp_message_zones_len (msg); i++) {
      zone = gst_sdp_message_get_zone (msg, i);
      g_string_append_printf (lines, " %s %s", zone->time, zone->typed_time);
    }
    g_string_append_printf (lines, "\r\n");
  }

  if (msg->key.type) {
    g_string_append_printf (lines, "k=%s", msg->key.type);
    if (msg->key.data)
      g_string_append_printf (lines, ":%s", msg->key.data);
    g_string_append_printf (lines, "\r\n");
  }

  for (i = 0; i < gst_sdp_message_attributes_len (msg); i++) {
    const GstSDPAttribute *attr = gst_sdp_message_get_attribute (msg, i);

    if (attr->key) {
      g_string_append_printf (lines, "a=%s", attr->key);
      if (attr->value && attr->value[0] != '\0')
        g_string_append_printf (lines, ":%s", attr->value);
      g_string_append_printf (lines, "\r\n");
    }
  }

  for (i = 0; i < gst_sdp_message_medias_len (msg); i++) {
    const GstSDPMedia *media = gst_sdp_message_get_media (msg, i);
    gchar *sdp_media_str;

    sdp_media_str = gst_sdp_media_as_text (media);
    g_string_append_printf (lines, "%s", sdp_media_str);
    g_free (sdp_media_str);
  }

  return g_string_free (lines, FALSE);
}

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

/**
 * gst_sdp_message_parse_uri:
 * @uri: the start of the uri
 * @msg: the result #GstSDPMessage
 *
 * Parse the null-terminated @uri and store the result in @msg.
 *
 * The uri should be of the form:
 *
 *  scheme://[address[:ttl=ttl][:noa=noa]]/[sessionname]
 *               [#type=value *[&type=value]]
 *
 *  where value is url encoded. This looslely resembles
 *  http://tools.ietf.org/html/draft-fujikawa-sdp-url-01
 *
 * Returns: #GST_SDP_OK on success.
 */
GstSDPResult
gst_sdp_message_parse_uri (const gchar * uri, GstSDPMessage * msg)
{
  GstSDPResult res;
  gchar *message;
  const gchar *colon, *slash, *hash, *p;
  GString *lines;

  g_return_val_if_fail (uri != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  colon = strstr (uri, "://");
  if (!colon)
    goto no_colon;

  /* FIXME connection info goes here */

  slash = strstr (colon + 3, "/");
  if (!slash)
    goto no_slash;

  /* FIXME session name goes here */

  hash = strstr (slash + 1, "#");
  if (!hash)
    goto no_hash;

  lines = g_string_new ("");

  /* unescape */
  for (p = hash + 1; *p; p++) {
    if (*p == '&')
      g_string_append_printf (lines, "\r\n");
    else if (*p == '+')
      g_string_append_c (lines, ' ');
    else if (*p == '%') {
      gchar a, b;

      if ((a = p[1])) {
        if ((b = p[2])) {
          g_string_append_c (lines, (hex_to_int (a) << 4) | hex_to_int (b));
          p += 2;
        }
      } else {
        p++;
      }
    } else
      g_string_append_c (lines, *p);
  }

  message = g_string_free (lines, FALSE);
  res =
      gst_sdp_message_parse_buffer ((const guint8 *) message, strlen (message),
      msg);
  g_free (message);

  return res;

  /* ERRORS */
no_colon:
  {
    return GST_SDP_EINVAL;
  }
no_slash:
  {
    return GST_SDP_EINVAL;
  }
no_hash:
  {
    return GST_SDP_EINVAL;
  }
}

static const guchar acceptable[96] = {
  /* X0   X1    X2    X3    X4    X5    X6    X7    X8    X9    XA    XB    XC    XD    XE    XF */
  0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00,       /* 2X  !"#$%&'()*+,-./   */
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       /* 3X 0123456789:;<=>?   */
  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,       /* 4X @ABCDEFGHIJKLMNO   */
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,       /* 5X PQRSTUVWXYZ[\]^_   */
  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,       /* 6X `abcdefghijklmno   */
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00        /* 7X pqrstuvwxyz{|}~DEL */
};

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

#define ACCEPTABLE_CHAR(a) (((guchar)(a))>=32 && ((guchar)(a))<128 && acceptable[(((guchar)a))-32])

/**
 * gst_sdp_message_as_uri:
 * @scheme: the uri scheme
 * @msg: the #GstSDPMessage
 *
 * Creates a uri from @msg with the given @scheme. The uri has the format:
 *
 *  \@scheme:///[#type=value *[&type=value]]
 *
 *  Where each value is url encoded.
 *
 * Returns: a uri for @msg.
 */
gchar *
gst_sdp_message_as_uri (const gchar * scheme, const GstSDPMessage * msg)
{
  gchar *serialized, *p;
  gchar *res;
  GString *lines;
  gboolean first;

  g_return_val_if_fail (scheme != NULL, NULL);
  g_return_val_if_fail (msg != NULL, NULL);

  p = serialized = gst_sdp_message_as_text (msg);

  lines = g_string_new ("");
  g_string_append_printf (lines, "%s:///#", scheme);

  /* now escape */
  first = TRUE;
  for (p = serialized; *p; p++) {
    if (first) {
      g_string_append_printf (lines, "%c=", *p);
      if (*(p + 1))
        p++;
      first = FALSE;
      continue;
    }
    if (*p == '\r')
      continue;
    else if (*p == '\n') {
      if (*(p + 1))
        g_string_append_c (lines, '&');
      first = TRUE;
    } else if (*p == ' ')
      g_string_append_c (lines, '+');
    else if (ACCEPTABLE_CHAR (*p))
      g_string_append_c (lines, *p);
    else {
      /* escape */
      g_string_append_printf (lines, "%%%c%c", hex[*p >> 4], hex[*p & 0xf]);
    }
  }

  res = g_string_free (lines, FALSE);
  g_free (serialized);

  return res;
}

/**
 * gst_sdp_message_set_version:
 * @msg: a #GstSDPMessage
 * @version: the version
 *
 * Set the version in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_SETTER (version);
/**
 * gst_sdp_message_get_version:
 * @msg: a #GstSDPMessage
 *
 * Get the version in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_GETTER (version);

/**
 * gst_sdp_message_set_origin:
 * @msg: a #GstSDPMessage
 * @username: the user name
 * @sess_id: a session id
 * @sess_version: a session version
 * @nettype: a network type
 * @addrtype: an address type
 * @addr: an address
 *
 * Configure the SDP origin in @msg with the given parameters.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_message_set_origin (GstSDPMessage * msg, const gchar * username,
    const gchar * sess_id, const gchar * sess_version, const gchar * nettype,
    const gchar * addrtype, const gchar * addr)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  REPLACE_STRING (msg->origin.username, username);
  REPLACE_STRING (msg->origin.sess_id, sess_id);
  REPLACE_STRING (msg->origin.sess_version, sess_version);
  REPLACE_STRING (msg->origin.nettype, nettype);
  REPLACE_STRING (msg->origin.addrtype, addrtype);
  REPLACE_STRING (msg->origin.addr, addr);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_get_origin:
 * @msg: a #GstSDPMessage
 *
 * Get the origin of @msg.
 *
 * Returns: a #GstSDPOrigin. The result remains valid as long as @msg is valid.
 */
const GstSDPOrigin *
gst_sdp_message_get_origin (const GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, NULL);

  return &msg->origin;
}

/**
 * gst_sdp_message_set_session_name:
 * @msg: a #GstSDPMessage
 * @session_name: the session name
 *
 * Set the session name in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_SETTER (session_name);
/**
 * gst_sdp_message_get_session_name:
 * @msg: a #GstSDPMessage
 *
 * Get the session name in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_GETTER (session_name);
/**
 * gst_sdp_message_set_information:
 * @msg: a #GstSDPMessage
 * @information: the information
 *
 * Set the information in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_SETTER (information);
/**
 * gst_sdp_message_get_information:
 * @msg: a #GstSDPMessage
 *
 * Get the information in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_GETTER (information);
/**
 * gst_sdp_message_set_uri:
 * @msg: a #GstSDPMessage
 * @uri: the URI
 *
 * Set the URI in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_SETTER (uri);
/**
 * gst_sdp_message_get_uri:
 * @msg: a #GstSDPMessage
 *
 * Get the URI in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STRING_GETTER (uri);

/**
 * gst_sdp_message_emails_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of emails in @msg.
 *
 * Returns: the number of emails in @msg.
 */
DEFINE_ARRAY_LEN (emails);
/**
 * gst_sdp_message_get_email:
 * @msg: a #GstSDPMessage
 * @idx: an email index
 *
 * Get the email with number @idx from @msg.
 *
 * Returns: the email at position @idx.
 */
DEFINE_STR_ARRAY_GETTER (email, emails);

/**
 * gst_sdp_message_insert_email:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @email: an email
 *
 * Insert @email into the array of emails in @msg at index @idx.
 * When -1 is given as @idx, the email is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_INSERT (email, emails);

/**
 * gst_sdp_message_replace_email:
 * @msg: a #GstSDPMessage
 * @idx: an email index
 * @email: an email
 *
 * Replace the email in @msg at index @idx with @email.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REPLACE (email, emails);

/**
 * gst_sdp_message_remove_email:
 * @msg: a #GstSDPMessage
 * @idx: an email index
 *
 * Remove the email in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REMOVE (email, emails);

/**
 * gst_sdp_message_add_email:
 * @msg: a #GstSDPMessage
 * @email: an email
 *
 * Add @email to the list of emails in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STR_ARRAY_ADDER (email, emails);

/**
 * gst_sdp_message_phones_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of phones in @msg.
 *
 * Returns: the number of phones in @msg.
 */
DEFINE_ARRAY_LEN (phones);
/**
 * gst_sdp_message_get_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 *
 * Get the phone with number @idx from @msg.
 *
 * Returns: the phone at position @idx.
 */
DEFINE_STR_ARRAY_GETTER (phone, phones);

/**
 * gst_sdp_message_insert_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 * @phone: a phone
 *
 * Insert @phone into the array of phone numbers in @msg at index @idx.
 * When -1 is given as @idx, the phone is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_INSERT (phone, phones);

/**
 * gst_sdp_message_replace_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 * @phone: a phone
 *
 * Replace the phone number in @msg at index @idx with @phone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REPLACE (phone, phones);

/**
 * gst_sdp_message_remove_phone:
 * @msg: a #GstSDPMessage
 * @idx: a phone index
 *
 * Remove the phone number in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_STR_ARRAY_REMOVE (phone, phones);

/**
 * gst_sdp_message_add_phone:
 * @msg: a #GstSDPMessage
 * @phone: a phone
 *
 * Add @phone to the list of phones in @msg.
 *
 * Returns: a #GstSDPResult.
 */
DEFINE_STR_ARRAY_ADDER (phone, phones);


/**
 * gst_sdp_message_set_connection:
 * @msg: a #GstSDPMessage
 * @nettype: the type of network. "IN" is defined to have the meaning
 * "Internet".
 * @addrtype: the type of address.
 * @address: the address
 * @ttl: the time to live of the address
 * @addr_number: the number of layers
 *
 * Configure the SDP connection in @msg with the given parameters.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_set_connection (GstSDPMessage * msg, const gchar * nettype,
    const gchar * addrtype, const gchar * address, guint ttl, guint addr_number)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  REPLACE_STRING (msg->connection.nettype, nettype);
  REPLACE_STRING (msg->connection.addrtype, addrtype);
  REPLACE_STRING (msg->connection.address, address);
  msg->connection.ttl = ttl;
  msg->connection.addr_number = addr_number;

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_get_connection:
 * @msg: a #GstSDPMessage
 *
 * Get the connection of @msg.
 *
 * Returns: a #GstSDPConnection. The result remains valid as long as @msg is valid.
 */
const GstSDPConnection *
gst_sdp_message_get_connection (const GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, NULL);

  return &msg->connection;
}

/**
 * gst_sdp_bandwidth_set:
 * @bw: a #GstSDPBandwidth
 * @bwtype: the bandwidth modifier type
 * @bandwidth: the bandwidth in kilobits per second
 *
 * Set bandwidth information in @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_bandwidth_set (GstSDPBandwidth * bw, const gchar * bwtype,
    guint bandwidth)
{
  g_return_val_if_fail (bw != NULL, GST_SDP_EINVAL);

  bw->bwtype = g_strdup (bwtype);
  bw->bandwidth = bandwidth;
  return GST_SDP_OK;
}

/**
 * gst_sdp_bandwidth_clear:
 * @bw: a #GstSDPBandwidth
 *
 * Reset the bandwidth information in @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_bandwidth_clear (GstSDPBandwidth * bw)
{
  g_return_val_if_fail (bw != NULL, GST_SDP_EINVAL);

  FREE_STRING (bw->bwtype);
  bw->bandwidth = 0;
  return GST_SDP_OK;
}

/**
 * gst_sdp_message_bandwidths_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of bandwidth information in @msg.
 *
 * Returns: the number of bandwidth information in @msg.
 */
DEFINE_ARRAY_LEN (bandwidths);
/**
 * gst_sdp_message_get_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: the bandwidth index
 *
 * Get the bandwidth at index @idx from @msg.
 *
 * Returns: a #GstSDPBandwidth.
 */
DEFINE_ARRAY_GETTER (bandwidth, bandwidths, GstSDPBandwidth);

#define DUP_BANDWIDTH(v, val) memcpy (v, val, sizeof (GstSDPBandwidth))
#define FREE_BANDWIDTH(v) gst_sdp_bandwidth_clear(v)

/**
 * gst_sdp_message_insert_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @bw: the bandwidth
 *
 * Insert bandwidth parameters into the array of bandwidths in @msg
 * at index @idx.
 * When -1 is given as @idx, the bandwidth is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (bandwidth, bandwidths, GstSDPBandwidth *, DUP_BANDWIDTH,
    GstSDPBandwidth);

/**
 * gst_sdp_message_replace_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: the bandwidth index
 * @bw: the bandwidth
 *
 * Replace the bandwidth information in @msg at index @idx with @bw.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (bandwidth, bandwidths, GstSDPBandwidth *, FREE_BANDWIDTH,
    DUP_BANDWIDTH, GstSDPBandwidth);

/**
 * gst_sdp_message_remove_bandwidth:
 * @msg: a #GstSDPMessage
 * @idx: the bandwidth index
 *
 * Remove the bandwidth information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (bandwidth, bandwidths, GstSDPBandwidth, FREE_BANDWIDTH);

/**
 * gst_sdp_message_add_bandwidth:
 * @msg: a #GstSDPMessage
 * @bwtype: the bandwidth modifier type
 * @bandwidth: the bandwidth in kilobits per second
 *
 * Add the specified bandwidth information to @msg.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_add_bandwidth (GstSDPMessage * msg, const gchar * bwtype,
    guint bandwidth)
{
  GstSDPBandwidth bw;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  gst_sdp_bandwidth_set (&bw, bwtype, bandwidth);
  return gst_sdp_message_insert_bandwidth (msg, -1, &bw);
}

/**
 * gst_sdp_time_set:
 * @t: a #GstSDPTime
 * @start: the start time
 * @stop: the stop time
 * @repeat: (array zero-terminated=1): the repeat times
 *
 * Set time information @start, @stop and @repeat in @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_time_set (GstSDPTime * t, const gchar * start,
    const gchar * stop, const gchar ** repeat)
{
  g_return_val_if_fail (t != NULL, GST_SDP_EINVAL);

  t->start = g_strdup (start);
  t->stop = g_strdup (stop);
  if (repeat) {
    t->repeat = g_array_new (FALSE, TRUE, sizeof (gchar *));
    for (; *repeat; repeat++) {
      gchar *r = g_strdup (*repeat);

      g_array_append_val (t->repeat, r);
    }
  } else
    t->repeat = NULL;

  return GST_SDP_OK;
}

/**
 * gst_sdp_time_clear:
 * @t: a #GstSDPTime
 *
 * Reset the time information in @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_time_clear (GstSDPTime * t)
{
  g_return_val_if_fail (t != NULL, GST_SDP_EINVAL);

  FREE_STRING (t->start);
  FREE_STRING (t->stop);
  INIT_STR_ARRAY (t->repeat);
  FREE_ARRAY (t->repeat);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_times_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of time information entries in @msg.
 *
 * Returns: the number of time information entries in @msg.
 */
DEFINE_ARRAY_LEN (times);

/**
 * gst_sdp_message_get_time:
 * @msg: a #GstSDPMessage
 * @idx: the time index
 *
 * Get time information with index @idx from @msg.
 *
 * Returns: a #GstSDPTime.
 */
DEFINE_ARRAY_GETTER (time, times, GstSDPTime);

#define DUP_TIME(v, val) memcpy (v, val, sizeof (GstSDPTime))
#define FREE_TIME(v) gst_sdp_time_clear(v)

/**
 * gst_sdp_message_insert_time:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @t: a #GstSDPTime
 *
 * Insert time parameters into the array of times in @msg
 * at index @idx.
 * When -1 is given as @idx, the times are inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (time, times, GstSDPTime *, DUP_TIME, GstSDPTime);

/**
 * gst_sdp_message_replace_time:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @t: a #GstSDPTime
 *
 * Replace the time information in @msg at index @idx with @t.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (time, times, GstSDPTime *, FREE_TIME,
    DUP_TIME, GstSDPTime);

/**
 * gst_sdp_message_remove_time:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the time information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (time, times, GstSDPTime, FREE_TIME);

/**
 * gst_sdp_message_add_time:
 * @msg: a #GstSDPMessage
 * @start: the start time
 * @stop: the stop time
 * @repeat: (array zero-terminated=1): the repeat times
 *
 * Add time information @start and @stop to @msg.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_add_time (GstSDPMessage * msg, const gchar * start,
    const gchar * stop, const gchar ** repeat)
{
  GstSDPTime times;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  gst_sdp_time_set (&times, start, stop, repeat);
  g_array_append_val (msg->times, times);

  return GST_SDP_OK;
}

/**
 * gst_sdp_zone_set:
 * @zone: a #GstSDPZone
 * @adj_time: the NTP time that a time zone adjustment happens
 * @typed_time: the offset from the time when the session was first scheduled
 *
 * Set zone information in @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_zone_set (GstSDPZone * zone, const gchar * adj_time,
    const gchar * typed_time)
{
  g_return_val_if_fail (zone != NULL, GST_SDP_EINVAL);

  zone->time = g_strdup (adj_time);
  zone->typed_time = g_strdup (typed_time);
  return GST_SDP_OK;
}

/**
 * gst_sdp_zone_clear:
 * @zone: a #GstSDPZone
 *
 * Reset the zone information in @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_zone_clear (GstSDPZone * zone)
{
  g_return_val_if_fail (zone != NULL, GST_SDP_EINVAL);

  FREE_STRING (zone->time);
  FREE_STRING (zone->typed_time);
  return GST_SDP_OK;
}

/**
 * gst_sdp_message_zones_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of time zone information entries in @msg.
 *
 * Returns: the number of time zone information entries in @msg.
 */
DEFINE_ARRAY_LEN (zones);
/**
 * gst_sdp_message_get_zone:
 * @msg: a #GstSDPMessage
 * @idx: the zone index
 *
 * Get time zone information with index @idx from @msg.
 *
 * Returns: a #GstSDPZone.
 */
DEFINE_ARRAY_GETTER (zone, zones, GstSDPZone);

#define DUP_ZONE(v, val) memcpy (v, val, sizeof (GstSDPZone))
#define FREE_ZONE(v) gst_sdp_zone_clear(v)

/**
 * gst_sdp_message_insert_zone:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @zone a #GstSDPZone
 *
 * Insert zone parameters into the array of zones in @msg
 * at index @idx.
 * When -1 is given as @idx, the zone is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (zone, zones, GstSDPZone *, DUP_ZONE, GstSDPZone);

/**
 * gst_sdp_message_replace_zone:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @zone: a #GstSDPZone
 *
 * Replace the zone information in @msg at index @idx with @zone.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (zone, zones, GstSDPZone *, FREE_ZONE,
    DUP_ZONE, GstSDPZone);

/**
 * gst_sdp_message_remove_zone:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the zone information in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (zone, zones, GstSDPZone, FREE_ZONE);

/**
 * gst_sdp_message_add_zone:
 * @msg: a #GstSDPMessage
 * @adj_time: the NTP time that a time zone adjustment happens
 * @typed_time: the offset from the time when the session was first scheduled
 *
 * Add time zone information to @msg.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_add_zone (GstSDPMessage * msg, const gchar * adj_time,
    const gchar * typed_time)
{
  GstSDPZone zone;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  gst_sdp_zone_set (&zone, adj_time, typed_time);
  g_array_append_val (msg->zones, zone);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_set_key:
 * @msg: a #GstSDPMessage
 * @type: the encryption type
 * @data: the encryption data
 *
 * Adds the encryption information to @msg.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_set_key (GstSDPMessage * msg, const gchar * type,
    const gchar * data)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  REPLACE_STRING (msg->key.type, type);
  REPLACE_STRING (msg->key.data, data);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_get_key:
 * @msg: a #GstSDPMessage
 *
 * Get the encryption information from @msg.
 *
 * Returns: a #GstSDPKey.
 */
const GstSDPKey *
gst_sdp_message_get_key (const GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, NULL);

  return &msg->key;
}

/**
 * gst_sdp_attribute_set:
 * @attr: a #GstSDPAttribute
 * @key: the key
 * @value: (nullable): the value
 *
 * Set the attribute with @key and @value.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_attribute_set (GstSDPAttribute * attr, const gchar * key,
    const gchar * value)
{
  g_return_val_if_fail (attr != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (key != NULL, GST_SDP_EINVAL);

  attr->key = g_strdup (key);
  attr->value = g_strdup (value);
  return GST_SDP_OK;
}

/**
 * gst_sdp_attribute_clear:
 * @attr: a #GstSDPAttribute
 *
 * Clear the attribute.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_attribute_clear (GstSDPAttribute * attr)
{
  g_return_val_if_fail (attr != NULL, GST_SDP_EINVAL);

  FREE_STRING (attr->key);
  FREE_STRING (attr->value);
  return GST_SDP_OK;
}

/**
 * gst_sdp_message_attributes_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of attributes in @msg.
 *
 * Returns: the number of attributes in @msg.
 */
DEFINE_ARRAY_LEN (attributes);

/**
 * gst_sdp_message_get_attribute:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Get the attribute at position @idx in @msg.
 *
 * Returns: the #GstSDPAttribute at position @idx.
 */
DEFINE_ARRAY_GETTER (attribute, attributes, GstSDPAttribute);

/**
 * gst_sdp_message_get_attribute_val_n:
 * @msg: a #GstSDPMessage
 * @key: the key
 * @nth: the index
 *
 * Get the @nth attribute with key @key in @msg.
 *
 * Returns: the attribute value of the @nth attribute with @key.
 */
const gchar *
gst_sdp_message_get_attribute_val_n (const GstSDPMessage * msg,
    const gchar * key, guint nth)
{
  guint i;

  g_return_val_if_fail (msg != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  for (i = 0; i < msg->attributes->len; i++) {
    GstSDPAttribute *attr;

    attr = &g_array_index (msg->attributes, GstSDPAttribute, i);
    if (!strcmp (attr->key, key)) {
      if (nth == 0)
        return attr->value;
      else
        nth--;
    }
  }
  return NULL;
}

/**
 * gst_sdp_message_get_attribute_val:
 * @msg: a #GstSDPMessage
 * @key: the key
 *
 * Get the first attribute with key @key in @msg.
 *
 * Returns: the attribute value of the first attribute with @key.
 */
const gchar *
gst_sdp_message_get_attribute_val (const GstSDPMessage * msg, const gchar * key)
{
  return gst_sdp_message_get_attribute_val_n (msg, key, 0);
}

#define DUP_ATTRIBUTE(v, val) memcpy (v, val, sizeof (GstSDPAttribute))
#define FREE_ATTRIBUTE(v) gst_sdp_attribute_clear(v)

/**
 * gst_sdp_message_insert_attribute:
 * @msg: a #GstSDPMessage
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Insert attribute into the array of attributes in @msg
 * at index @idx.
 * When -1 is given as @idx, the attribute is inserted at the end.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_INSERT (attribute, attributes, GstSDPAttribute *, DUP_ATTRIBUTE,
    GstSDPAttribute);

/**
 * gst_sdp_message_replace_attribute:
 * @msg: a #GstSDPMessage
 * @idx: the index
 * @attr: a #GstSDPAttribute
 *
 * Replace the attribute in @msg at index @idx with @attr.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REPLACE (attribute, attributes, GstSDPAttribute *, FREE_ATTRIBUTE,
    DUP_ATTRIBUTE, GstSDPAttribute);

/**
 * gst_sdp_message_remove_attribute:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Remove the attribute in @msg at index @idx.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.2
 */
DEFINE_ARRAY_REMOVE (attribute, attributes, GstSDPAttribute, FREE_ATTRIBUTE);

/**
 * gst_sdp_message_add_attribute:
 * @msg: a #GstSDPMessage
 * @key: the key
 * @value: (nullable): the value
 *
 * Add the attribute with @key and @value to @msg.
 *
 * Returns: @GST_SDP_OK.
 */
GstSDPResult
gst_sdp_message_add_attribute (GstSDPMessage * msg, const gchar * key,
    const gchar * value)
{
  GstSDPAttribute attr;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (key != NULL, GST_SDP_EINVAL);

  gst_sdp_attribute_set (&attr, key, value);
  g_array_append_val (msg->attributes, attr);

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_medias_len:
 * @msg: a #GstSDPMessage
 *
 * Get the number of media descriptions in @msg.
 *
 * Returns: the number of media descriptions in @msg.
 */
DEFINE_ARRAY_LEN (medias);
/**
 * gst_sdp_message_get_media:
 * @msg: a #GstSDPMessage
 * @idx: the index
 *
 * Get the media description at index @idx in @msg.
 *
 * Returns: a #GstSDPMedia.
 */
DEFINE_ARRAY_GETTER (media, medias, GstSDPMedia);

/**
 * gst_sdp_message_add_media:
 * @msg: a #GstSDPMessage
 * @media: a #GstSDPMedia to add
 *
 * Adds @media to the array of medias in @msg. This function takes ownership of
 * the contents of @media so that @media will have to be reinitialized with
 * gst_sdp_media_init() before it can be used again.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_add_media (GstSDPMessage * msg, GstSDPMedia * media)
{
  guint len;
  GstSDPMedia *nmedia;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  len = msg->medias->len;
  g_array_set_size (msg->medias, len + 1);
  nmedia = &g_array_index (msg->medias, GstSDPMedia, len);

  memcpy (nmedia, media, sizeof (GstSDPMedia));
  memset (media, 0, sizeof (GstSDPMedia));

  return GST_SDP_OK;
}

/* media access */

/**
 * gst_sdp_media_new:
 * @media: (out) (transfer full): pointer to new #GstSDPMedia
 *
 * Allocate a new GstSDPMedia and store the result in @media.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_new (GstSDPMedia ** media)
{
  GstSDPMedia *newmedia;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  newmedia = g_new0 (GstSDPMedia, 1);

  *media = newmedia;

  return gst_sdp_media_init (newmedia);
}

/**
 * gst_sdp_media_init:
 * @media: a #GstSDPMedia
 *
 * Initialize @media so that its contents are as if it was freshly allocated
 * with gst_sdp_media_new(). This function is mostly used to initialize a media
 * allocated on the stack. gst_sdp_media_uninit() undoes this operation.
 *
 * When this function is invoked on newly allocated data (with malloc or on the
 * stack), its contents should be set to 0 before calling this function.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_init (GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  FREE_STRING (media->media);
  media->port = 0;
  media->num_ports = 0;
  FREE_STRING (media->proto);
  INIT_STR_ARRAY (media->fmts);
  FREE_STRING (media->information);
  INIT_ARRAY (media->connections, GstSDPConnection, gst_sdp_connection_clear);
  INIT_ARRAY (media->bandwidths, GstSDPBandwidth, gst_sdp_bandwidth_clear);
  gst_sdp_key_init (&media->key);
  INIT_ARRAY (media->attributes, GstSDPAttribute, gst_sdp_attribute_clear);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_uninit:
 * @media: a #GstSDPMedia
 *
 * Free all resources allocated in @media. @media should not be used anymore after
 * this function. This function should be used when @media was allocated on the
 * stack and initialized with gst_sdp_media_init().
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_uninit (GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  gst_sdp_media_init (media);
  FREE_ARRAY (media->fmts);
  FREE_ARRAY (media->connections);
  FREE_ARRAY (media->bandwidths);
  FREE_ARRAY (media->attributes);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_free:
 * @media: a #GstSDPMedia
 *
 * Free all resources allocated by @media. @media should not be used anymore after
 * this function. This function should be used when @media was dynamically
 * allocated with gst_sdp_media_new().
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_free (GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  gst_sdp_media_uninit (media);
  g_free (media);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_copy:
 * @media: a #GstSDPMedia
 * @copy: (out) (transfer full): pointer to new #GstSDPMedia
 *
 * Allocate a new copy of @media and store the result in @copy. The value in
 * @copy should be release with gst_sdp_media_free function.
 *
 * Returns: a #GstSDPResult
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_copy (const GstSDPMedia * media, GstSDPMedia ** copy)
{
  GstSDPResult ret;
  GstSDPMedia *cp;
  guint i, len;

  if (media == NULL)
    return GST_SDP_EINVAL;

  ret = gst_sdp_media_new (copy);
  if (ret != GST_SDP_OK)
    return ret;

  cp = *copy;

  REPLACE_STRING (cp->media, media->media);
  cp->port = media->port;
  cp->num_ports = media->num_ports;
  REPLACE_STRING (cp->proto, media->proto);

  len = gst_sdp_media_formats_len (media);
  for (i = 0; i < len; i++) {
    gst_sdp_media_add_format (cp, gst_sdp_media_get_format (media, i));
  }

  REPLACE_STRING (cp->information, media->information);

  len = gst_sdp_media_connections_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPConnection *connection =
        gst_sdp_media_get_connection (media, i);
    gst_sdp_media_add_connection (cp, connection->nettype, connection->addrtype,
        connection->address, connection->ttl, connection->addr_number);
  }

  len = gst_sdp_media_bandwidths_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPBandwidth *bw = gst_sdp_media_get_bandwidth (media, i);
    gst_sdp_media_add_bandwidth (cp, bw->bwtype, bw->bandwidth);
  }

  gst_sdp_media_set_key (cp, media->key.type, media->key.data);

  len = gst_sdp_media_attributes_len (media);
  for (i = 0; i < len; i++) {
    const GstSDPAttribute *att = gst_sdp_media_get_attribute (media, i);
    gst_sdp_media_add_attribute (cp, att->key, att->value);
  }

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_as_text:
 * @media: a #GstSDPMedia
 *
 * Convert the contents of @media to a text string.
 *
 * Returns: A dynamically allocated string representing the media.
 */
gchar *
gst_sdp_media_as_text (const GstSDPMedia * media)
{
  GString *lines;
  guint i;

  g_return_val_if_fail (media != NULL, NULL);

  lines = g_string_new ("");

  if (media->media)
    g_string_append_printf (lines, "m=%s", media->media);

  g_string_append_printf (lines, " %u", media->port);

  if (media->num_ports > 1)
    g_string_append_printf (lines, "/%u", media->num_ports);

  g_string_append_printf (lines, " %s", media->proto);

  for (i = 0; i < gst_sdp_media_formats_len (media); i++)
    g_string_append_printf (lines, " %s", gst_sdp_media_get_format (media, i));
  g_string_append_printf (lines, "\r\n");

  if (media->information)
    g_string_append_printf (lines, "i=%s", media->information);

  for (i = 0; i < gst_sdp_media_connections_len (media); i++) {
    const GstSDPConnection *conn = gst_sdp_media_get_connection (media, i);

    if (conn->nettype && conn->addrtype && conn->address) {
      g_string_append_printf (lines, "c=%s %s %s", conn->nettype,
          conn->addrtype, conn->address);
      if (gst_sdp_address_is_multicast (conn->nettype, conn->addrtype,
              conn->address)) {
        /* only add TTL for IP4 multicast */
        if (strcmp (conn->addrtype, "IP4") == 0)
          g_string_append_printf (lines, "/%u", conn->ttl);
        if (conn->addr_number > 1)
          g_string_append_printf (lines, "/%u", conn->addr_number);
      }
      g_string_append_printf (lines, "\r\n");
    }
  }

  for (i = 0; i < gst_sdp_media_bandwidths_len (media); i++) {
    const GstSDPBandwidth *bandwidth = gst_sdp_media_get_bandwidth (media, i);

    g_string_append_printf (lines, "b=%s:%u\r\n", bandwidth->bwtype,
        bandwidth->bandwidth);
  }

  if (media->key.type) {
    g_string_append_printf (lines, "k=%s", media->key.type);
    if (media->key.data)
      g_string_append_printf (lines, ":%s", media->key.data);
    g_string_append_printf (lines, "\r\n");
  }

  for (i = 0; i < gst_sdp_media_attributes_len (media); i++) {
    const GstSDPAttribute *attr = gst_sdp_media_get_attribute (media, i);

    if (attr->key) {
      g_string_append_printf (lines, "a=%s", attr->key);
      if (attr->value && attr->value[0] != '\0')
        g_string_append_printf (lines, ":%s", attr->value);
      g_string_append_printf (lines, "\r\n");
    }
  }

  return g_string_free (lines, FALSE);
}

/**
 * gst_sdp_media_get_media:
 * @media: a #GstSDPMedia
 *
 * Get the media description of @media.
 *
 * Returns: the media description.
 */
const gchar *
gst_sdp_media_get_media (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, NULL);

  return media->media;
}

/**
 * gst_sdp_media_set_media:
 * @media: a #GstSDPMedia
 * @med: the media description
 *
 * Set the media description of @media to @med.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_set_media (GstSDPMedia * media, const gchar * med)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (med != NULL, GST_SDP_EINVAL);

  g_free (media->media);
  media->media = g_strdup (med);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_port:
 * @media: a #GstSDPMedia
 *
 * Get the port number for @media.
 *
 * Returns: the port number of @media.
 */
guint
gst_sdp_media_get_port (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->port;
}

/**
 * gst_sdp_media_get_num_ports:
 * @media: a #GstSDPMedia
 *
 * Get the number of ports for @media.
 *
 * Returns: the number of ports for @media.
 */
guint
gst_sdp_media_get_num_ports (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->num_ports;
}

/**
 * gst_sdp_media_set_port_info:
 * @media: a #GstSDPMedia
 * @port: the port number
 * @num_ports: the number of ports
 *
 * Set the port information in @media.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_set_port_info (GstSDPMedia * media, guint port, guint num_ports)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  media->port = port;
  media->num_ports = num_ports;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_proto:
 * @media: a #GstSDPMedia
 *
 * Get the transport protocol of @media
 *
 * Returns: the transport protocol of @media.
 */
const gchar *
gst_sdp_media_get_proto (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, NULL);

  return media->proto;
}

/**
 * gst_sdp_media_set_proto:
 * @media: a #GstSDPMedia
 * @proto: the media transport protocol
 *
 * Set the media transport protocol of @media to @proto.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_set_proto (GstSDPMedia * media, const gchar * proto)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  g_free (media->proto);
  media->proto = g_strdup (proto);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_formats_len:
 * @media: a #GstSDPMedia
 *
 * Get the number of formats in @media.
 *
 * Returns: the number of formats in @media.
 */
guint
gst_sdp_media_formats_len (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->fmts->len;
}

/**
 * gst_sdp_media_get_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Get the format information at position @idx in @media.
 *
 * Returns: the format at position @idx.
 */
const gchar *
gst_sdp_media_get_format (const GstSDPMedia * media, guint idx)
{
  g_return_val_if_fail (media != NULL, NULL);

  if (idx >= media->fmts->len)
    return NULL;
  return g_array_index (media->fmts, gchar *, idx);
}

/**
 * gst_sdp_media_insert_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @format: the format
 *
 * Insert the format information to @media at @idx. When @idx is -1,
 * the format is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_format (GstSDPMedia * media, gint idx,
    const gchar * format)
{
  gchar *fmt;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (format != NULL, GST_SDP_EINVAL);

  fmt = g_strdup (format);

  if (idx == -1)
    g_array_append_val (media->fmts, fmt);
  else
    g_array_insert_val (media->fmts, idx, fmt);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @format: the format
 *
 * Replace the format information in @media at @idx with @format.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_format (GstSDPMedia * media, guint idx,
    const gchar * format)
{
  gchar **old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (format != NULL, GST_SDP_EINVAL);

  old = &g_array_index (media->fmts, gchar *, idx);
  g_free (*old);
  *old = g_strdup (format);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_format:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the format information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_format (GstSDPMedia * media, guint idx)
{
  gchar **old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  old = &g_array_index (media->fmts, gchar *, idx);
  g_free (*old);
  g_array_remove_index (media->fmts, idx);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_add_format:
 * @media: a #GstSDPMedia
 * @format: the format
 *
 * Add the format information to @media.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_add_format (GstSDPMedia * media, const gchar * format)
{
  gchar *fmt;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (format != NULL, GST_SDP_EINVAL);

  fmt = g_strdup (format);

  g_array_append_val (media->fmts, fmt);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_information:
 * @media: a #GstSDPMedia
 *
 * Get the information of @media
 *
 * Returns: the information of @media.
 */
const gchar *
gst_sdp_media_get_information (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, NULL);

  return media->information;
}

/**
 * gst_sdp_media_set_information:
 * @media: a #GstSDPMedia
 * @information: the media information
 *
 * Set the media information of @media to @information.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_set_information (GstSDPMedia * media, const gchar * information)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  g_free (media->information);
  media->information = g_strdup (information);

  return GST_SDP_OK;
}

/**
 * gst_sdp_connection_set:
 * @conn: a #GstSDPConnection
 * @nettype: the type of network. "IN" is defined to have the meaning
 * "Internet".
 * @addrtype: the type of address.
 * @address: the address
 * @ttl: the time to live of the address
 * @addr_number: the number of layers
 *
 * Set the connection with the given parameters.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_connection_set (GstSDPConnection * conn, const gchar * nettype,
    const gchar * addrtype, const gchar * address, guint ttl, guint addr_number)
{
  g_return_val_if_fail (conn != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (nettype != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (addrtype != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (address != NULL, GST_SDP_EINVAL);

  conn->nettype = g_strdup (nettype);
  conn->addrtype = g_strdup (addrtype);
  conn->address = g_strdup (address);
  conn->ttl = ttl;
  conn->addr_number = addr_number;
  return GST_SDP_OK;
}

/**
 * gst_sdp_connection_clear:
 * @conn: a #GstSDPConnection
 *
 * Clear the connection.
 *
 * Returns: @GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_connection_clear (GstSDPConnection * conn)
{
  g_return_val_if_fail (conn != NULL, GST_SDP_EINVAL);

  FREE_STRING (conn->nettype);
  FREE_STRING (conn->addrtype);
  FREE_STRING (conn->address);
  conn->ttl = 0;
  conn->addr_number = 0;
  return GST_SDP_OK;
}


/**
 * gst_sdp_media_connections_len:
 * @media: a #GstSDPMedia
 *
 * Get the number of connection fields in @media.
 *
 * Returns: the number of connections in @media.
 */
guint
gst_sdp_media_connections_len (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->connections->len;
}

/**
 * gst_sdp_media_get_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Get the connection at position @idx in @media.
 *
 * Returns: the #GstSDPConnection at position @idx.
 */
const GstSDPConnection *
gst_sdp_media_get_connection (const GstSDPMedia * media, guint idx)
{
  g_return_val_if_fail (media != NULL, NULL);
  g_return_val_if_fail (idx < media->connections->len, NULL);

  return &g_array_index (media->connections, GstSDPConnection, idx);
}

/**
 * gst_sdp_media_insert_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @conn: a #GstSDPConnection
 *
 * Insert the connection information to @media at @idx. When @idx is -1,
 * the connection is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_connection (GstSDPMedia * media, gint idx,
    GstSDPConnection * conn)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (conn != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx == -1
      || idx < media->connections->len, GST_SDP_EINVAL);

  if (idx == -1)
    g_array_append_val (media->connections, *conn);
  else
    g_array_insert_val (media->connections, idx, *conn);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @conn: a #GstSDPConnection
 *
 * Replace the connection information in @media at @idx with @conn.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_connection (GstSDPMedia * media, guint idx,
    GstSDPConnection * conn)
{
  GstSDPConnection *old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (conn != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->connections->len, GST_SDP_EINVAL);

  old = &g_array_index (media->connections, GstSDPConnection, idx);
  gst_sdp_connection_clear (old);
  *old = *conn;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_connection:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the connection information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_connection (GstSDPMedia * media, guint idx)
{
  GstSDPConnection *old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->connections->len, GST_SDP_EINVAL);

  old = &g_array_index (media->connections, GstSDPConnection, idx);
  gst_sdp_connection_clear (old);
  g_array_remove_index (media->connections, idx);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_add_connection:
 * @media: a #GstSDPMedia
 * @nettype: the type of network. "IN" is defined to have the meaning
 * "Internet".
 * @addrtype: the type of address.
 * @address: the address
 * @ttl: the time to live of the address
 * @addr_number: the number of layers
 *
 * Add the given connection parameters to @media.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_add_connection (GstSDPMedia * media, const gchar * nettype,
    const gchar * addrtype, const gchar * address, guint ttl, guint addr_number)
{
  GstSDPConnection conn;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (nettype != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (addrtype != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (address != NULL, GST_SDP_EINVAL);

  gst_sdp_connection_set (&conn, nettype, addrtype, address, ttl, addr_number);
  g_array_append_val (media->connections, conn);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_bandwidths_len:
 * @media: a #GstSDPMedia
 *
 * Get the number of bandwidth fields in @media.
 *
 * Returns: the number of bandwidths in @media.
 */
guint
gst_sdp_media_bandwidths_len (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->bandwidths->len;
}

/**
 * gst_sdp_media_get_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Get the bandwidth at position @idx in @media.
 *
 * Returns: the #GstSDPBandwidth at position @idx.
 */
const GstSDPBandwidth *
gst_sdp_media_get_bandwidth (const GstSDPMedia * media, guint idx)
{
  g_return_val_if_fail (media != NULL, NULL);

  return &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
}

/**
 * gst_sdp_media_insert_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @bw: a #GstSDPBandwidth
 *
 * Insert the bandwidth information to @media at @idx. When @idx is -1,
 * the bandwidth is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_bandwidth (GstSDPMedia * media, gint idx,
    GstSDPBandwidth * bw)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (bw != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx == -1
      || idx < media->bandwidths->len, GST_SDP_EINVAL);

  if (idx == -1)
    g_array_append_val (media->bandwidths, *bw);
  else
    g_array_insert_val (media->bandwidths, idx, *bw);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @bw: a #GstSDPBandwidth
 *
 * Replace the bandwidth information in @media at @idx with @bw.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_bandwidth (GstSDPMedia * media, guint idx,
    GstSDPBandwidth * bw)
{
  GstSDPBandwidth *old;
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (bw != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->bandwidths->len, GST_SDP_EINVAL);

  old = &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
  gst_sdp_bandwidth_clear (old);
  *old = *bw;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_bandwidth:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the bandwidth information in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_bandwidth (GstSDPMedia * media, guint idx)
{
  GstSDPBandwidth *old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->bandwidths->len, GST_SDP_EINVAL);

  old = &g_array_index (media->bandwidths, GstSDPBandwidth, idx);
  gst_sdp_bandwidth_clear (old);
  g_array_remove_index (media->bandwidths, idx);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_add_bandwidth:
 * @media: a #GstSDPMedia
 * @bwtype: the bandwidth modifier type
 * @bandwidth: the bandwidth in kilobits per second
 *
 * Add the bandwidth information with @bwtype and @bandwidth to @media.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_add_bandwidth (GstSDPMedia * media, const gchar * bwtype,
    guint bandwidth)
{
  GstSDPBandwidth bw;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (bwtype != NULL, GST_SDP_EINVAL);

  gst_sdp_bandwidth_set (&bw, bwtype, bandwidth);
  g_array_append_val (media->bandwidths, bw);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_set_key:
 * @media: a #GstSDPMedia
 * @type: the encryption type
 * @data: the encryption data
 *
 * Adds the encryption information to @media.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_media_set_key (GstSDPMedia * media, const gchar * type,
    const gchar * data)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  g_free (media->key.type);
  media->key.type = g_strdup (type);
  g_free (media->key.data);
  media->key.data = g_strdup (data);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_key:
 * @media: a #GstSDPMedia
 *
 * Get the encryption information from @media.
 *
 * Returns: a #GstSDPKey.
 */
const GstSDPKey *
gst_sdp_media_get_key (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, NULL);

  return &media->key;
}

/**
 * gst_sdp_media_attributes_len:
 * @media: a #GstSDPMedia
 *
 * Get the number of attribute fields in @media.
 *
 * Returns: the number of attributes in @media.
 */
guint
gst_sdp_media_attributes_len (const GstSDPMedia * media)
{
  g_return_val_if_fail (media != NULL, 0);

  return media->attributes->len;
}

/**
 * gst_sdp_media_add_attribute:
 * @media: a #GstSDPMedia
 * @key: a key
 * @value: (nullable): a value
 *
 * Add the attribute with @key and @value to @media.
 *
 * Returns: #GST_SDP_OK.
 */
GstSDPResult
gst_sdp_media_add_attribute (GstSDPMedia * media, const gchar * key,
    const gchar * value)
{
  GstSDPAttribute attr;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (key != NULL, GST_SDP_EINVAL);

  gst_sdp_attribute_set (&attr, key, value);
  g_array_append_val (media->attributes, attr);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Get the attribute at position @idx in @media.
 *
 * Returns: the #GstSDPAttribute at position @idx.
 */
const GstSDPAttribute *
gst_sdp_media_get_attribute (const GstSDPMedia * media, guint idx)
{
  g_return_val_if_fail (media != NULL, NULL);
  g_return_val_if_fail (idx < media->attributes->len, NULL);

  return &g_array_index (media->attributes, GstSDPAttribute, idx);
}

/**
 * gst_sdp_media_get_attribute_val_n:
 * @media: a #GstSDPMedia
 * @key: a key
 * @nth: an index
 *
 * Get the @nth attribute value for @key in @media.
 *
 * Returns: the @nth attribute value.
 */
const gchar *
gst_sdp_media_get_attribute_val_n (const GstSDPMedia * media, const gchar * key,
    guint nth)
{
  guint i;

  g_return_val_if_fail (media != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  for (i = 0; i < media->attributes->len; i++) {
    GstSDPAttribute *attr;

    attr = &g_array_index (media->attributes, GstSDPAttribute, i);
    if (!strcmp (attr->key, key)) {
      if (nth == 0)
        return attr->value;
      else
        nth--;
    }
  }
  return NULL;
}

/**
 * gst_sdp_media_get_attribute_val:
 * @media: a #GstSDPMedia
 * @key: a key
 *
 * Get the first attribute value for @key in @media.
 *
 * Returns: the first attribute value for @key.
 */
const gchar *
gst_sdp_media_get_attribute_val (const GstSDPMedia * media, const gchar * key)
{
  g_return_val_if_fail (media != NULL, NULL);
  g_return_val_if_fail (key != NULL, NULL);

  return gst_sdp_media_get_attribute_val_n (media, key, 0);
}

/**
 * gst_sdp_media_insert_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Insert the attribute to @media at @idx. When @idx is -1,
 * the attribute is appended.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_insert_attribute (GstSDPMedia * media, gint idx,
    GstSDPAttribute * attr)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (attr != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx == -1
      || idx < media->attributes->len, GST_SDP_EINVAL);

  if (idx == -1)
    g_array_append_val (media->attributes, *attr);
  else
    g_array_insert_val (media->attributes, idx, *attr);

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_replace_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 * @attr: a #GstSDPAttribute
 *
 * Replace the attribute in @media at @idx with @attr.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_replace_attribute (GstSDPMedia * media, guint idx,
    GstSDPAttribute * attr)
{
  GstSDPAttribute *old;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (attr != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->attributes->len, GST_SDP_EINVAL);

  old = &g_array_index (media->attributes, GstSDPAttribute, idx);
  gst_sdp_attribute_clear (old);
  *old = *attr;

  return GST_SDP_OK;
}

/**
 * gst_sdp_media_remove_attribute:
 * @media: a #GstSDPMedia
 * @idx: an index
 *
 * Remove the attribute in @media at @idx.
 *
 * Returns: #GST_SDP_OK.
 *
 * Since: 1.2
 */
GstSDPResult
gst_sdp_media_remove_attribute (GstSDPMedia * media, guint idx)
{
  GstSDPAttribute *old;
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (idx < media->attributes->len, GST_SDP_EINVAL);

  old = &g_array_index (media->attributes, GstSDPAttribute, idx);
  gst_sdp_attribute_clear (old);
  g_array_remove_index (media->attributes, idx);

  return GST_SDP_OK;
}

static void
read_string (gchar * dest, guint size, gchar ** src)
{
  guint idx;

  idx = 0;
  /* skip spaces */
  while (g_ascii_isspace (**src))
    (*src)++;

  while (!g_ascii_isspace (**src) && **src != '\0') {
    if (idx < size - 1)
      dest[idx++] = **src;
    (*src)++;
  }
  if (size > 0)
    dest[idx] = '\0';
}

static void
read_string_del (gchar * dest, guint size, gchar del, gchar ** src)
{
  guint idx;

  idx = 0;
  /* skip spaces */
  while (g_ascii_isspace (**src))
    (*src)++;

  while (**src != del && **src != '\0') {
    if (idx < size - 1)
      dest[idx++] = **src;
    (*src)++;
  }
  if (size > 0)
    dest[idx] = '\0';
}

enum
{
  SDP_SESSION,
  SDP_MEDIA,
};

typedef struct
{
  guint state;
  GstSDPMessage *msg;
  GstSDPMedia *media;
} SDPContext;

static gboolean
gst_sdp_parse_line (SDPContext * c, gchar type, gchar * buffer)
{
  gchar str[8192];
  gchar *p = buffer;

#define READ_STRING(field) \
  do { read_string (str, sizeof (str), &p); REPLACE_STRING (field, str); } while (0)
#define READ_UINT(field) \
  do { read_string (str, sizeof (str), &p); field = strtoul (str, NULL, 10); } while (0)

  switch (type) {
    case 'v':
      if (buffer[0] != '0')
        GST_WARNING ("wrong SDP version");
      gst_sdp_message_set_version (c->msg, buffer);
      break;
    case 'o':
      READ_STRING (c->msg->origin.username);
      READ_STRING (c->msg->origin.sess_id);
      READ_STRING (c->msg->origin.sess_version);
      READ_STRING (c->msg->origin.nettype);
      READ_STRING (c->msg->origin.addrtype);
      READ_STRING (c->msg->origin.addr);
      break;
    case 's':
      REPLACE_STRING (c->msg->session_name, buffer);
      break;
    case 'i':
      if (c->state == SDP_SESSION) {
        REPLACE_STRING (c->msg->information, buffer);
      } else {
        REPLACE_STRING (c->media->information, buffer);
      }
      break;
    case 'u':
      REPLACE_STRING (c->msg->uri, buffer);
      break;
    case 'e':
      gst_sdp_message_add_email (c->msg, buffer);
      break;
    case 'p':
      gst_sdp_message_add_phone (c->msg, buffer);
      break;
    case 'c':
    {
      GstSDPConnection conn;
      gchar *str2;

      memset (&conn, 0, sizeof (conn));

      str2 = p;
      while ((str2 = strchr (str2, '/')))
        *str2++ = ' ';
      READ_STRING (conn.nettype);
      READ_STRING (conn.addrtype);
      READ_STRING (conn.address);
      /* only read TTL for IP4 */
      if (strcmp (conn.addrtype, "IP4") == 0)
        READ_UINT (conn.ttl);
      READ_UINT (conn.addr_number);

      if (c->state == SDP_SESSION) {
        gst_sdp_message_set_connection (c->msg, conn.nettype, conn.addrtype,
            conn.address, conn.ttl, conn.addr_number);
      } else {
        gst_sdp_media_add_connection (c->media, conn.nettype, conn.addrtype,
            conn.address, conn.ttl, conn.addr_number);
      }
      gst_sdp_connection_clear (&conn);
      break;
    }
    case 'b':
    {
      gchar str2[32];

      read_string_del (str, sizeof (str), ':', &p);
      if (*p != '\0')
        p++;
      read_string (str2, sizeof (str2), &p);
      if (c->state == SDP_SESSION)
        gst_sdp_message_add_bandwidth (c->msg, str, atoi (str2));
      else
        gst_sdp_media_add_bandwidth (c->media, str, atoi (str2));
      break;
    }
    case 't':
      break;
    case 'k':
      read_string_del (str, sizeof (str), ':', &p);
      if (*p != '\0')
        p++;
      if (c->state == SDP_SESSION)
        gst_sdp_message_set_key (c->msg, str, p);
      else
        gst_sdp_media_set_key (c->media, str, p);
      break;
    case 'a':
      read_string_del (str, sizeof (str), ':', &p);
      if (*p != '\0')
        p++;
      if (c->state == SDP_SESSION)
        gst_sdp_message_add_attribute (c->msg, str, p);
      else
        gst_sdp_media_add_attribute (c->media, str, p);
      break;
    case 'm':
    {
      gchar *slash;
      GstSDPMedia nmedia;

      c->state = SDP_MEDIA;
      memset (&nmedia, 0, sizeof (nmedia));
      gst_sdp_media_init (&nmedia);

      /* m=<media> <port>/<number of ports> <proto> <fmt> ... */
      READ_STRING (nmedia.media);
      read_string (str, sizeof (str), &p);
      slash = g_strrstr (str, "/");
      if (slash) {
        *slash = '\0';
        nmedia.port = atoi (str);
        nmedia.num_ports = atoi (slash + 1);
      } else {
        nmedia.port = atoi (str);
        nmedia.num_ports = 0;
      }
      READ_STRING (nmedia.proto);
      do {
        read_string (str, sizeof (str), &p);
        gst_sdp_media_add_format (&nmedia, str);
      } while (*p != '\0');

      gst_sdp_message_add_media (c->msg, &nmedia);
      c->media =
          &g_array_index (c->msg->medias, GstSDPMedia, c->msg->medias->len - 1);
      break;
    }
    default:
      break;
  }
  return TRUE;
}

/**
 * gst_sdp_message_parse_buffer:
 * @data: (array length=size): the start of the buffer
 * @size: the size of the buffer
 * @msg: the result #GstSDPMessage
 *
 * Parse the contents of @size bytes pointed to by @data and store the result in
 * @msg.
 *
 * Returns: #GST_SDP_OK on success.
 */
GstSDPResult
gst_sdp_message_parse_buffer (const guint8 * data, guint size,
    GstSDPMessage * msg)
{
  gchar *p, *s;
  SDPContext c;
  gchar type;
  gchar *buffer = NULL;
  guint bufsize = 0;
  guint len = 0;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (data != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (size != 0, GST_SDP_EINVAL);

  c.state = SDP_SESSION;
  c.msg = msg;
  c.media = NULL;

#define SIZE_CHECK_GUARD \
  G_STMT_START { \
    if (p - (gchar *) data >= size) \
      goto out; \
  } G_STMT_END

  p = (gchar *) data;
  while (TRUE) {
    while (p - (gchar *) data < size && g_ascii_isspace (*p))
      p++;

    SIZE_CHECK_GUARD;

    type = *p++;
    if (type == '\0')
      break;

    SIZE_CHECK_GUARD;

    if (*p != '=')
      goto line_done;
    p++;

    SIZE_CHECK_GUARD;

    s = p;
    while (p - (gchar *) data < size && *p != '\n' && *p != '\r' && *p != '\0')
      p++;

    len = p - s;
    if (bufsize <= len) {
      buffer = g_realloc (buffer, len + 1);
      bufsize = len + 1;
    }
    memcpy (buffer, s, len);
    buffer[len] = '\0';

    gst_sdp_parse_line (&c, type, buffer);

    SIZE_CHECK_GUARD;

  line_done:
    while (p - (gchar *) data < size && *p != '\n' && *p != '\0')
      p++;

    SIZE_CHECK_GUARD;

    if (*p == '\n')
      p++;
  }

#undef SIZE_CHECK_GUARD

out:
  g_free (buffer);

  return GST_SDP_OK;
}

static void
print_media (GstSDPMedia * media)
{
  g_print ("   media:       '%s'\n", GST_STR_NULL (media->media));
  g_print ("   port:        '%u'\n", media->port);
  g_print ("   num_ports:   '%u'\n", media->num_ports);
  g_print ("   proto:       '%s'\n", GST_STR_NULL (media->proto));
  if (media->fmts->len > 0) {
    guint i;

    g_print ("   formats:\n");
    for (i = 0; i < media->fmts->len; i++) {
      g_print ("    format  '%s'\n", g_array_index (media->fmts, gchar *, i));
    }
  }
  g_print ("   information: '%s'\n", GST_STR_NULL (media->information));
  if (media->connections->len > 0) {
    guint i;

    g_print ("   connections:\n");
    for (i = 0; i < media->connections->len; i++) {
      GstSDPConnection *conn =
          &g_array_index (media->connections, GstSDPConnection, i);

      g_print ("    nettype:      '%s'\n", GST_STR_NULL (conn->nettype));
      g_print ("    addrtype:     '%s'\n", GST_STR_NULL (conn->addrtype));
      g_print ("    address:      '%s'\n", GST_STR_NULL (conn->address));
      g_print ("    ttl:          '%u'\n", conn->ttl);
      g_print ("    addr_number:  '%u'\n", conn->addr_number);
    }
  }
  if (media->bandwidths->len > 0) {
    guint i;

    g_print ("   bandwidths:\n");
    for (i = 0; i < media->bandwidths->len; i++) {
      GstSDPBandwidth *bw =
          &g_array_index (media->bandwidths, GstSDPBandwidth, i);

      g_print ("    type:         '%s'\n", GST_STR_NULL (bw->bwtype));
      g_print ("    bandwidth:    '%u'\n", bw->bandwidth);
    }
  }
  g_print ("   key:\n");
  g_print ("    type:       '%s'\n", GST_STR_NULL (media->key.type));
  g_print ("    data:       '%s'\n", GST_STR_NULL (media->key.data));
  if (media->attributes->len > 0) {
    guint i;

    g_print ("   attributes:\n");
    for (i = 0; i < media->attributes->len; i++) {
      GstSDPAttribute *attr =
          &g_array_index (media->attributes, GstSDPAttribute, i);

      g_print ("    attribute '%s' : '%s'\n", attr->key, attr->value);
    }
  }
}

/**
 * gst_sdp_message_dump:
 * @msg: a #GstSDPMessage
 *
 * Dump the parsed contents of @msg to stdout.
 *
 * Returns: a #GstSDPResult.
 */
GstSDPResult
gst_sdp_message_dump (const GstSDPMessage * msg)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  g_print ("sdp packet %p:\n", msg);
  g_print (" version:       '%s'\n", GST_STR_NULL (msg->version));
  g_print (" origin:\n");
  g_print ("  username:     '%s'\n", GST_STR_NULL (msg->origin.username));
  g_print ("  sess_id:      '%s'\n", GST_STR_NULL (msg->origin.sess_id));
  g_print ("  sess_version: '%s'\n", GST_STR_NULL (msg->origin.sess_version));
  g_print ("  nettype:      '%s'\n", GST_STR_NULL (msg->origin.nettype));
  g_print ("  addrtype:     '%s'\n", GST_STR_NULL (msg->origin.addrtype));
  g_print ("  addr:         '%s'\n", GST_STR_NULL (msg->origin.addr));
  g_print (" session_name:  '%s'\n", GST_STR_NULL (msg->session_name));
  g_print (" information:   '%s'\n", GST_STR_NULL (msg->information));
  g_print (" uri:           '%s'\n", GST_STR_NULL (msg->uri));

  if (msg->emails->len > 0) {
    guint i;

    g_print (" emails:\n");
    for (i = 0; i < msg->emails->len; i++) {
      g_print ("  email '%s'\n", g_array_index (msg->emails, gchar *, i));
    }
  }
  if (msg->phones->len > 0) {
    guint i;

    g_print (" phones:\n");
    for (i = 0; i < msg->phones->len; i++) {
      g_print ("  phone '%s'\n", g_array_index (msg->phones, gchar *, i));
    }
  }
  g_print (" connection:\n");
  g_print ("  nettype:      '%s'\n", GST_STR_NULL (msg->connection.nettype));
  g_print ("  addrtype:     '%s'\n", GST_STR_NULL (msg->connection.addrtype));
  g_print ("  address:      '%s'\n", GST_STR_NULL (msg->connection.address));
  g_print ("  ttl:          '%u'\n", msg->connection.ttl);
  g_print ("  addr_number:  '%u'\n", msg->connection.addr_number);
  if (msg->bandwidths->len > 0) {
    guint i;

    g_print (" bandwidths:\n");
    for (i = 0; i < msg->bandwidths->len; i++) {
      GstSDPBandwidth *bw =
          &g_array_index (msg->bandwidths, GstSDPBandwidth, i);

      g_print ("  type:         '%s'\n", GST_STR_NULL (bw->bwtype));
      g_print ("  bandwidth:    '%u'\n", bw->bandwidth);
    }
  }
  g_print (" key:\n");
  g_print ("  type:         '%s'\n", GST_STR_NULL (msg->key.type));
  g_print ("  data:         '%s'\n", GST_STR_NULL (msg->key.data));
  if (msg->attributes->len > 0) {
    guint i;

    g_print (" attributes:\n");
    for (i = 0; i < msg->attributes->len; i++) {
      GstSDPAttribute *attr =
          &g_array_index (msg->attributes, GstSDPAttribute, i);

      g_print ("  attribute '%s' : '%s'\n", attr->key, attr->value);
    }
  }
  if (msg->medias->len > 0) {
    guint i;

    g_print (" medias:\n");
    for (i = 0; i < msg->medias->len; i++) {
      g_print ("  media %u:\n", i);
      print_media (&g_array_index (msg->medias, GstSDPMedia, i));
    }
  }
  return GST_SDP_OK;
}

static const gchar *
gst_sdp_get_attribute_for_pt (const GstSDPMedia * media, const gchar * name,
    gint pt)
{
  guint i;

  for (i = 0;; i++) {
    const gchar *attr;
    gint val;

    if ((attr = gst_sdp_media_get_attribute_val_n (media, name, i)) == NULL)
      break;

    if (sscanf (attr, "%d ", &val) != 1)
      continue;

    if (val == pt)
      return attr;
  }
  return NULL;
}

/* this may modify the input string (and resets) */
#define PARSE_INT(p, del, res)          \
G_STMT_START {                          \
  gchar *t = p;                         \
  p = strstr (p, del);                  \
  if (p == NULL)                        \
    res = -1;                           \
  else {                                \
    char prev = *p;                     \
    *p = '\0';                          \
    res = atoi (t);                     \
    *p = prev;                          \
    p++;                                \
  }                                     \
} G_STMT_END

/* this may modify the string without reset */
#define PARSE_STRING(p, del, res)       \
G_STMT_START {                          \
  gchar *t = p;                         \
  p = strstr (p, del);                  \
  if (p == NULL) {                      \
    res = NULL;                         \
    p = t;                              \
  }                                     \
  else {                                \
    *p = '\0';                          \
    p++;                                \
    res = t;                            \
  }                                     \
} G_STMT_END

#define SKIP_SPACES(p)                  \
  while (*p && g_ascii_isspace (*p))    \
    p++;

/* rtpmap contains:
 *
 *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 */
static gboolean
gst_sdp_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
    gint * rate, gchar ** params)
{
  gchar *p, *t, *orig_value;

  p = orig_value = g_strdup (rtpmap);

  PARSE_INT (p, " ", *payload);
  if (*payload == -1)
    goto fail;

  SKIP_SPACES (p);
  if (*p == '\0')
    goto fail;

  PARSE_STRING (p, "/", *name);
  if (*name == NULL) {
    GST_DEBUG ("no rate, name %s", p);
    /* no rate, assume -1 then, this is not supposed to happen but RealMedia
     * streams seem to omit the rate. */
    *name = g_strdup (p);
    *rate = -1;
    *params = NULL;
    goto out;
  } else {
    *name = strdup (*name);
  }

  t = p;
  p = strstr (p, "/");
  if (p == NULL) {
    *rate = atoi (t);
    *params = NULL;
    goto out;
  }
  p++;
  *rate = atoi (t);

  if (*p == '\0')
    *params = NULL;
  else
    *params = g_strdup (p);

out:
  g_free (orig_value);
  return TRUE;

fail:
  g_free (orig_value);
  return FALSE;
}

/**
 * gst_sdp_media_add_rtcp_fb_attributes_from_media:
 * @media: a #GstSDPMedia
 * @pt: payload type
 * @caps: a #GstCaps
 *
 * Parse given @media for "rtcp-fb" attributes and add it to the @caps.
 *
 * Mapping of caps from SDP fields:
 *
 * a=rtcp-fb:(payload) (param1) [param2]...
 *
 * Returns: a #GstSDPResult.
 */
static GstSDPResult
gst_sdp_media_add_rtcp_fb_attributes_from_media (const GstSDPMedia * media,
    gint pt, GstCaps * caps)
{
  const gchar *rtcp_fb;
  gchar *p, *to_free;
  gint payload, i;
  GstStructure *s;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  s = gst_caps_get_structure (caps, 0);

  for (i = 0;; i++) {
    gboolean all_formats = FALSE;

    if ((rtcp_fb = gst_sdp_media_get_attribute_val_n (media,
                "rtcp-fb", i)) == NULL)
      break;

    /* p is now of the format <payload> attr... */
    to_free = p = g_strdup (rtcp_fb);

    /* check if it applies to all formats */
    if (*p == '*') {
      p++;
      all_formats = TRUE;
    } else {
      PARSE_INT (p, " ", payload);
    }

    if (all_formats || (payload != -1 && payload == pt)) {
      gchar *tmp, *key;

      SKIP_SPACES (p);

      /* replace space with '-' */
      key = g_strdup_printf ("rtcp-fb-%s", p);

      for (tmp = key; (tmp = strchr (tmp, ' ')); ++tmp) {
        *tmp = '-';
      }

      gst_structure_set (s, key, G_TYPE_BOOLEAN, TRUE, NULL);
      GST_DEBUG ("adding caps: %s=TRUE", key);
      g_free (key);
    }
    g_free (to_free);
  }
  return GST_SDP_OK;
}

/**
 * gst_sdp_media_get_caps_from_media:
 * @media: a #GstSDPMedia
 * @pt: a payload type
 *
 * Mapping of caps from SDP fields:
 *
 * a=rtpmap:(payload) (encoding_name)/(clock_rate)[/(encoding_params)]
 *
 * a=framesize:(payload) (width)-(height)
 *
 * a=fmtp:(payload) (param)[=(value)];...
 *
 * Returns: a #GstCaps, or %NULL if an error happened
 *
 * Since: 1.8
 */
GstCaps *
gst_sdp_media_get_caps_from_media (const GstSDPMedia * media, gint pt)
{
  GstCaps *caps;
  const gchar *rtpmap;
  gchar *fmtp = NULL;
  gchar *framesize = NULL;
  gchar *name = NULL;
  gint rate = -1;
  gchar *params = NULL;
  gchar *tmp;
  GstStructure *s;
  gint payload = 0;
  gboolean ret;

  g_return_val_if_fail (media != NULL, NULL);

  /* get and parse rtpmap */
  rtpmap = gst_sdp_get_attribute_for_pt (media, "rtpmap", pt);

  if (rtpmap) {
    ret = gst_sdp_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
    if (!ret) {
      GST_ERROR ("error parsing rtpmap, ignoring");
      rtpmap = NULL;
    }
  }
  /* dynamic payloads need rtpmap or we fail */
  if (rtpmap == NULL && pt >= 96)
    goto no_rtpmap;

  /* check if we have a rate, if not, we need to look up the rate from the
   * default rates based on the payload types. */
  if (rate == -1) {
    const GstRTPPayloadInfo *info;

    if (GST_RTP_PAYLOAD_IS_DYNAMIC (pt)) {
      /* dynamic types, use media and encoding_name */
      tmp = g_ascii_strdown (media->media, -1);
      info = gst_rtp_payload_info_for_name (tmp, name);
      g_free (tmp);
    } else {
      /* static types, use payload type */
      info = gst_rtp_payload_info_for_pt (pt);
    }

    if (info) {
      if ((rate = info->clock_rate) == 0)
        rate = -1;
    }
    /* we fail if we cannot find one */
    if (rate == -1)
      goto no_rate;
  }

  tmp = g_ascii_strdown (media->media, -1);
  caps = gst_caps_new_simple ("application/x-unknown",
      "media", G_TYPE_STRING, tmp, "payload", G_TYPE_INT, pt, NULL);
  g_free (tmp);
  s = gst_caps_get_structure (caps, 0);

  gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);

  /* encoding name must be upper case */
  if (name != NULL) {
    tmp = g_ascii_strup (name, -1);
    gst_structure_set (s, "encoding-name", G_TYPE_STRING, tmp, NULL);
    g_free (tmp);
  }

  /* params must be lower case */
  if (params != NULL) {
    tmp = g_ascii_strdown (params, -1);
    gst_structure_set (s, "encoding-params", G_TYPE_STRING, tmp, NULL);
    g_free (tmp);
  }

  /* parse optional fmtp: field */
  if ((fmtp = g_strdup (gst_sdp_get_attribute_for_pt (media, "fmtp", pt)))) {
    gchar *p;
    gint payload = 0;

    p = fmtp;

    /* p is now of the format <payload> <param>[=<value>];... */
    PARSE_INT (p, " ", payload);
    if (payload != -1 && payload == pt) {
      gchar **pairs;
      gint i;

      /* <param>[=<value>] are separated with ';' */
      pairs = g_strsplit (p, ";", 0);
      for (i = 0; pairs[i]; i++) {
        gchar *valpos;
        const gchar *val, *key;
        gint j;
        const gchar *reserved_keys[] =
            { "media", "payload", "clock-rate", "encoding-name",
          "encoding-params"
        };

        /* the key may not have a '=', the value can have other '='s */
        valpos = strstr (pairs[i], "=");
        if (valpos) {
          /* we have a '=' and thus a value, remove the '=' with \0 */
          *valpos = '\0';
          /* value is everything between '=' and ';'. We split the pairs at ;
           * boundaries so we can take the remainder of the value. Some servers
           * put spaces around the value which we strip off here. Alternatively
           * we could strip those spaces in the depayloaders should these spaces
           * actually carry any meaning in the future. */
          val = g_strstrip (valpos + 1);
        } else {
          /* simple <param>;.. is translated into <param>=1;... */
          val = "1";
        }
        /* strip the key of spaces, convert key to lowercase but not the value. */
        key = g_strstrip (pairs[i]);

        /* skip keys from the fmtp, which we already use ourselves for the
         * caps. Some software is adding random things like clock-rate into
         * the fmtp, and we would otherwise here set a string-typed clock-rate
         * in the caps... and thus fail to create valid RTP caps
         */
        for (j = 0; j < G_N_ELEMENTS (reserved_keys); j++) {
          if (g_ascii_strcasecmp (reserved_keys[j], key) == 0) {
            key = "";
            break;
          }
        }

        if (strlen (key) > 1) {
          tmp = g_ascii_strdown (key, -1);
          gst_structure_set (s, tmp, G_TYPE_STRING, val, NULL);
          g_free (tmp);
        }
      }
      g_strfreev (pairs);
    }
  }

  /* parse framesize: field */
  if ((framesize =
          g_strdup (gst_sdp_media_get_attribute_val (media, "framesize")))) {
    gchar *p;

    /* p is now of the format <payload> <width>-<height> */
    p = framesize;

    PARSE_INT (p, " ", payload);
    if (payload != -1 && payload == pt) {
      gst_structure_set (s, "a-framesize", G_TYPE_STRING, p, NULL);
    }
  }

  /* parse rtcp-fb: field */
  gst_sdp_media_add_rtcp_fb_attributes_from_media (media, pt, caps);

out:
  g_free (framesize);
  g_free (fmtp);
  g_free (name);
  g_free (params);
  return caps;

  /* ERRORS */
no_rtpmap:
  {
    GST_ERROR ("rtpmap type not given for dynamic payload %d", pt);
    caps = NULL;
    goto out;
  }
no_rate:
  {
    GST_ERROR ("rate unknown for payload type %d", pt);
    caps = NULL;
    goto out;
  }
}

/**
 * gst_sdp_media_set_media_from_caps:
 * @caps: a #GstCaps
 * @media: a #GstSDPMedia
 *
 * Mapping of caps to SDP fields:
 *
 * a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
 *
 * a=framesize:(payload) (width)-(height)
 *
 * a=fmtp:(payload) (param)[=(value)];...
 *
 * a=rtcp-fb:(payload) (param1) [param2]...
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media)
{
  const gchar *caps_str, *caps_enc, *caps_params;
  gchar *tmp;
  gint caps_pt, caps_rate;
  guint n_fields, j;
  gboolean first, nack, nack_pli, ccm_fir;
  GString *fmtp;
  GstStructure *s;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  s = gst_caps_get_structure (caps, 0);
  if (s == NULL) {
    GST_ERROR ("ignoring stream without media type");
    goto error;
  }

  /* get media type and payload for the m= line */
  caps_str = gst_structure_get_string (s, "media");
  gst_sdp_media_set_media (media, caps_str);

  gst_structure_get_int (s, "payload", &caps_pt);
  tmp = g_strdup_printf ("%d", caps_pt);
  gst_sdp_media_add_format (media, tmp);
  g_free (tmp);

  /* get clock-rate, media type and params for the rtpmap attribute */
  gst_structure_get_int (s, "clock-rate", &caps_rate);
  caps_enc = gst_structure_get_string (s, "encoding-name");
  caps_params = gst_structure_get_string (s, "encoding-params");

  if (caps_enc) {
    if (caps_params)
      tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate,
          caps_params);
    else
      tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate);

    gst_sdp_media_add_attribute (media, "rtpmap", tmp);
    g_free (tmp);
  }

  /* get rtcp-fb attributes */
  if (gst_structure_get_boolean (s, "rtcp-fb-nack", &nack)) {
    if (nack) {
      tmp = g_strdup_printf ("%d nack", caps_pt);
      gst_sdp_media_add_attribute (media, "rtcp-fb", tmp);
      g_free (tmp);
      GST_DEBUG ("adding rtcp-fb-nack to pt=%d", caps_pt);
    }
  }

  if (gst_structure_get_boolean (s, "rtcp-fb-nack-pli", &nack_pli)) {
    if (nack_pli) {
      tmp = g_strdup_printf ("%d nack pli", caps_pt);
      gst_sdp_media_add_attribute (media, "rtcp-fb", tmp);
      g_free (tmp);
      GST_DEBUG ("adding rtcp-fb-nack-pli to pt=%d", caps_pt);
    }
  }

  if (gst_structure_get_boolean (s, "rtcp-fb-ccm-fir", &ccm_fir)) {
    if (ccm_fir) {
      tmp = g_strdup_printf ("%d ccm fir", caps_pt);
      gst_sdp_media_add_attribute (media, "rtcp-fb", tmp);
      g_free (tmp);
      GST_DEBUG ("adding rtcp-fb-ccm-fir to pt=%d", caps_pt);
    }
  }

  /* collect all other properties and add them to fmtp or attributes */
  fmtp = g_string_new ("");
  g_string_append_printf (fmtp, "%d ", caps_pt);
  first = TRUE;
  n_fields = gst_structure_n_fields (s);
  for (j = 0; j < n_fields; j++) {
    const gchar *fname, *fval;

    fname = gst_structure_nth_field_name (s, j);

    /* filter out standard properties */
    if (!strcmp (fname, "media"))
      continue;
    if (!strcmp (fname, "payload"))
      continue;
    if (!strcmp (fname, "clock-rate"))
      continue;
    if (!strcmp (fname, "encoding-name"))
      continue;
    if (!strcmp (fname, "encoding-params"))
      continue;
    if (!strcmp (fname, "ssrc"))
      continue;
    if (!strcmp (fname, "timestamp-offset"))
      continue;
    if (!strcmp (fname, "seqnum-offset"))
      continue;
    if (g_str_has_prefix (fname, "srtp-"))
      continue;
    if (g_str_has_prefix (fname, "srtcp-"))
      continue;
    /* handled later */
    if (g_str_has_prefix (fname, "x-gst-rtsp-server-rtx-time"))
      continue;
    if (g_str_has_prefix (fname, "rtcp-fb-"))
      continue;

    if (!strcmp (fname, "a-framesize")) {
      /* a-framesize attribute */
      if ((fval = gst_structure_get_string (s, fname))) {
        tmp = g_strdup_printf ("%d %s", caps_pt, fval);
        gst_sdp_media_add_attribute (media, fname + 2, tmp);
        g_free (tmp);
      }
      continue;
    }

    if (g_str_has_prefix (fname, "a-")) {
      /* attribute */
      if ((fval = gst_structure_get_string (s, fname)))
        gst_sdp_media_add_attribute (media, fname + 2, fval);
      continue;
    }
    if (g_str_has_prefix (fname, "x-")) {
      /* attribute */
      if ((fval = gst_structure_get_string (s, fname)))
        gst_sdp_media_add_attribute (media, fname, fval);
      continue;
    }

    if ((fval = gst_structure_get_string (s, fname))) {
      g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval);
      first = FALSE;
    }
  }

  if (!first) {
    tmp = g_string_free (fmtp, FALSE);
    gst_sdp_media_add_attribute (media, "fmtp", tmp);
    g_free (tmp);
  } else {
    g_string_free (fmtp, TRUE);
  }

  return GST_SDP_OK;

  /* ERRORS */
error:
  {
    GST_DEBUG ("ignoring stream");
    return GST_SDP_EINVAL;
  }
}

/**
 * gst_sdp_make_keymgmt:
 * @uri: a #gchar URI
 * @base64: a #gchar base64-encoded key data
 *
 * Makes key management data
 *
 * Returns: (transfer full): a #gchar key-mgmt data,
 *
 * Since: 1.8
 */
gchar *
gst_sdp_make_keymgmt (const gchar * uri, const gchar * base64)
{
  g_return_val_if_fail (uri != NULL, NULL);
  g_return_val_if_fail (base64 != NULL, NULL);

  return g_strdup_printf ("prot=mikey;uri=\"%s\";data=\"%s\"", uri, base64);
}

static gboolean
gst_sdp_parse_keymgmt (const gchar * keymgmt, GstMIKEYMessage ** mikey)
{
  gsize size;
  guchar *data;
  gchar *orig_value;
  gchar *p, *kmpid;

  p = orig_value = g_strdup (keymgmt);

  SKIP_SPACES (p);
  if (*p == '\0') {
    g_free (orig_value);
    return FALSE;
  }

  PARSE_STRING (p, " ", kmpid);
  if (kmpid == NULL || !g_str_equal (kmpid, "mikey")) {
    g_free (orig_value);
    return FALSE;
  }
  data = g_base64_decode (p, &size);
  g_free (orig_value);          /* Don't need this any more */

  if (data == NULL)
    return FALSE;

  *mikey = gst_mikey_message_new_from_data (data, size, NULL, NULL);
  g_free (data);

  return (*mikey != NULL);
}

static GstSDPResult
sdp_add_attributes_to_keymgmt (GArray * attributes, GstMIKEYMessage ** mikey)
{
  GstSDPResult res = GST_SDP_OK;

  if (attributes->len > 0) {
    guint i;
    for (i = 0; i < attributes->len; i++) {
      GstSDPAttribute *attr = &g_array_index (attributes, GstSDPAttribute, i);

      if (g_str_equal (attr->key, "key-mgmt")) {
        res = gst_sdp_parse_keymgmt (attr->value, mikey);
        break;
      }
    }
  }

  return res;
}

/**
 * gst_sdp_message_parse_keymgmt:
 * @msg: a #GstSDPMessage
 * @mikey: (out) (transfer full): pointer to new #GstMIKEYMessage
 *
 * Creates a new #GstMIKEYMessage after parsing the key-mgmt attribute
 * from a #GstSDPMessage.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8.1
 */
GstSDPResult
gst_sdp_message_parse_keymgmt (const GstSDPMessage * msg,
    GstMIKEYMessage ** mikey)
{
  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);

  return sdp_add_attributes_to_keymgmt (msg->attributes, mikey);
}

/**
 * gst_sdp_media_parse_keymgmt:
 * @media: a #GstSDPMedia
 * @mikey: (out) (transfer full): pointer to new #GstMIKEYMessage
 *
 * Creates a new #GstMIKEYMessage after parsing the key-mgmt attribute
 * from a #GstSDPMedia.
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8.1
 */
GstSDPResult
gst_sdp_media_parse_keymgmt (const GstSDPMedia * media,
    GstMIKEYMessage ** mikey)
{
  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);

  return sdp_add_attributes_to_keymgmt (media->attributes, mikey);
}

static GstSDPResult
sdp_add_attributes_to_caps (GArray * attributes, GstCaps * caps)
{
  if (attributes->len > 0) {
    GstStructure *s;
    guint i;

    s = gst_caps_get_structure (caps, 0);

    for (i = 0; i < attributes->len; i++) {
      GstSDPAttribute *attr = &g_array_index (attributes, GstSDPAttribute, i);
      gchar *tofree, *key;

      key = attr->key;

      /* skip some of the attribute we already handle */
      if (!strcmp (key, "fmtp"))
        continue;
      if (!strcmp (key, "rtpmap"))
        continue;
      if (!strcmp (key, "control"))
        continue;
      if (!strcmp (key, "range"))
        continue;
      if (!strcmp (key, "framesize"))
        continue;
      if (!strcmp (key, "key-mgmt"))
        continue;

      /* string must be valid UTF8 */
      if (!g_utf8_validate (attr->value, -1, NULL))
        continue;

      if (!g_str_has_prefix (key, "x-"))
        tofree = key = g_strdup_printf ("a-%s", key);
      else
        tofree = NULL;

      GST_DEBUG ("adding caps: %s=%s", key, attr->value);
      gst_structure_set (s, key, G_TYPE_STRING, attr->value, NULL);
      g_free (tofree);
    }
  }

  return GST_SDP_OK;
}

/**
 * gst_sdp_message_attributes_to_caps:
 * @msg: a #GstSDPMessage
 * @caps: a #GstCaps
 *
 * Mapping of attributes of #GstSDPMessage to #GstCaps
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_message_attributes_to_caps (const GstSDPMessage * msg, GstCaps * caps)
{
  GstSDPResult res;
  GstMIKEYMessage *mikey = NULL;

  g_return_val_if_fail (msg != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  res = gst_sdp_message_parse_keymgmt (msg, &mikey);
  if (mikey) {
    if (gst_mikey_message_to_caps (mikey, caps)) {
      res = GST_SDP_EINVAL;
      goto done;
    }
  }

  res = sdp_add_attributes_to_caps (msg->attributes, caps);

done:
  if (mikey)
    gst_mikey_message_unref (mikey);
  return res;
}

/**
 * gst_sdp_media_attributes_to_caps:
 * @media: a #GstSDPMedia
 * @caps: a #GstCaps
 *
 * Mapping of attributes of #GstSDPMedia to #GstCaps
 *
 * Returns: a #GstSDPResult.
 *
 * Since: 1.8
 */
GstSDPResult
gst_sdp_media_attributes_to_caps (const GstSDPMedia * media, GstCaps * caps)
{
  GstSDPResult res;
  GstMIKEYMessage *mikey = NULL;

  g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
  g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);

  res = gst_sdp_media_parse_keymgmt (media, &mikey);
  if (mikey) {
    if (!gst_mikey_message_to_caps (mikey, caps)) {
      res = GST_SDP_EINVAL;
      goto done;
    }
  }

  res = sdp_add_attributes_to_caps (media->attributes, caps);

done:
  if (mikey)
    gst_mikey_message_unref (mikey);
  return res;
}
