mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
sdp: add methods to convert between uri and message
Add methods to convert between uri and sdpmessages, loosly based on http://tools.ietf.org/html/draft-fujikawa-sdp-url-01 API: GstSDPMessage::gst_sdp_message_parse_uri API: GstSDPMessage::gst_sdp_message_as_uri
This commit is contained in:
parent
78055cc852
commit
f5cbb6047f
3 changed files with 193 additions and 6 deletions
|
@ -1543,7 +1543,13 @@ gst_sdp_message_new
|
|||
gst_sdp_message_init
|
||||
gst_sdp_message_uninit
|
||||
gst_sdp_message_free
|
||||
|
||||
gst_sdp_message_parse_buffer
|
||||
gst_sdp_message_as_text
|
||||
|
||||
gst_sdp_message_parse_uri
|
||||
gst_sdp_message_as_uri
|
||||
|
||||
gst_sdp_message_get_version
|
||||
gst_sdp_message_set_version
|
||||
gst_sdp_message_get_origin
|
||||
|
@ -1582,7 +1588,6 @@ gst_sdp_message_medias_len
|
|||
gst_sdp_message_get_media
|
||||
gst_sdp_message_add_media
|
||||
gst_sdp_message_dump
|
||||
gst_sdp_message_as_text
|
||||
|
||||
gst_sdp_media_new
|
||||
gst_sdp_media_init
|
||||
|
|
|
@ -341,12 +341,12 @@ is_multicast_address (const gchar * host_name, guint * family)
|
|||
for (ai = res; !ret && ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family == AF_INET)
|
||||
ret =
|
||||
IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->
|
||||
sin_addr.s_addr));
|
||||
IN_MULTICAST (ntohl (((struct sockaddr_in *) ai->ai_addr)->sin_addr.
|
||||
s_addr));
|
||||
else
|
||||
ret =
|
||||
IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->
|
||||
ai_addr)->sin6_addr);
|
||||
IN6_IS_ADDR_MULTICAST (&((struct sockaddr_in6 *) ai->ai_addr)->
|
||||
sin6_addr);
|
||||
if (ret && family)
|
||||
*family = ai->ai_family;
|
||||
}
|
||||
|
@ -486,6 +486,185 @@ gst_sdp_message_as_text (const GstSDPMessage * msg)
|
|||
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.
|
||||
*
|
||||
* Since: 0.10.31
|
||||
*/
|
||||
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);
|
||||
|
||||
g_print ("uri %s\n", uri);
|
||||
|
||||
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) ((a)>=32 && (a)<128 && acceptable[(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.
|
||||
*
|
||||
* Since: 0.10.31
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -280,9 +280,12 @@ GstSDPResult gst_sdp_message_uninit (GstSDPMessage *msg)
|
|||
GstSDPResult gst_sdp_message_free (GstSDPMessage *msg);
|
||||
|
||||
GstSDPResult gst_sdp_message_parse_buffer (const guint8 *data, guint size, GstSDPMessage *msg);
|
||||
|
||||
gchar* gst_sdp_message_as_text (const GstSDPMessage *msg);
|
||||
|
||||
/* convert from/to uri */
|
||||
GstSDPResult gst_sdp_message_parse_uri (const gchar *uri, GstSDPMessage *msg);
|
||||
gchar* gst_sdp_message_as_uri (const gchar *scheme, const GstSDPMessage *msg);
|
||||
|
||||
/* v=.. */
|
||||
const gchar* gst_sdp_message_get_version (const GstSDPMessage *msg);
|
||||
GstSDPResult gst_sdp_message_set_version (GstSDPMessage *msg, const gchar *version);
|
||||
|
|
Loading…
Reference in a new issue