guint coutl;
} DecodeCtx;
-static GstRTSPResult read_line (GstRTSPConnection * conn, guint8 * buffer,
- guint * idx, guint size);
-static GstRTSPResult parse_key_value (guint8 * buffer, gchar * key,
- guint keysize, gchar ** value);
-static GstRTSPResult parse_string (gchar * dest, gint size, gchar ** src);
-
#ifdef G_OS_WIN32
#define READ_SOCKET(fd, buf, len) recv (fd, (char *)buf, len, 0)
#define WRITE_SOCKET(fd, buf, len) send (fd, (const char *)buf, len, 0)
return res;
}
-static void
-parse_key (gchar * dest, gint size, gchar ** src)
-{
- gint idx;
-
- idx = 0;
- while (**src != ':' && **src != '\0') {
- if (idx < size - 1)
- dest[idx++] = **src;
- (*src)++;
- }
- if (size > 0)
- dest[idx] = '\0';
-}
-
static GstRTSPResult
parse_protocol_version (gchar * protocol, GstRTSPMsgType * type,
GstRTSPVersion * version)
return res;
}
+/* parsing lines means reading a Key: Value pair */
static GstRTSPResult
-parse_key_value (guint8 * buffer, gchar * key, guint keysize, gchar ** value)
+parse_line (guint8 * buffer, GstRTSPMessage * msg)
{
- gchar *bptr;
+ GstRTSPHeaderField field;
+ gchar *line = (gchar *) buffer;
+ gchar *value;
- bptr = (gchar *) buffer;
+ if ((value = strchr (line, ':')) == NULL || value == line)
+ goto parse_error;
- /* read key */
- parse_key (key, keysize, &bptr);
- if (G_UNLIKELY (*bptr != ':'))
- goto no_column;
+ /* trim space before the colon */
+ if (value[-1] == ' ')
+ value[-1] = '\0';
- bptr++;
- while (g_ascii_isspace (*bptr))
- bptr++;
+ /* replace the colon with a NUL */
+ *value++ = '\0';
- *value = bptr;
+ /* find the header */
+ field = gst_rtsp_find_header_field (line);
+ if (field == GST_RTSP_HDR_INVALID)
+ goto done;
- return GST_RTSP_OK;
+ /* split up the value in multiple key:value pairs if it contains comma(s) */
+ while (*value != '\0') {
+ gchar *next_value;
+ gboolean quoted = FALSE;
+ guint comment = 0;
+
+ /* trim leading space */
+ if (*value == ' ')
+ value++;
+
+ /* find the next value, taking special care of quotes and comments */
+ next_value = value;
+ while (*next_value != '\0') {
+ if ((quoted || comment != 0) && *next_value == '\\' &&
+ next_value[1] != '\0')
+ next_value++;
+ else if (comment == 0 && *next_value == '"')
+ quoted = !quoted;
+ else if (!quoted && *next_value == '(')
+ comment++;
+ else if (comment != 0 && *next_value == ')')
+ comment--;
+ else if (!quoted && comment == 0 && *next_value == ',')
+ break;
- /* ERRORS */
-no_column:
- {
- return GST_RTSP_EPARSE;
- }
-}
+ next_value++;
+ }
-/* parsing lines means reading a Key: Value pair */
-static GstRTSPResult
-parse_line (guint8 * buffer, GstRTSPMessage * msg)
-{
- GstRTSPResult res;
- gchar key[32];
- gchar *value;
- GstRTSPHeaderField field;
+ /* trim space */
+ if (value != next_value && next_value[-1] == ' ')
+ next_value[-1] = '\0';
- res = parse_key_value (buffer, key, sizeof (key), &value);
- if (G_UNLIKELY (res != GST_RTSP_OK))
- goto parse_error;
+ if (*next_value != '\0')
+ *next_value++ = '\0';
- field = gst_rtsp_find_header_field (key);
- if (field != GST_RTSP_HDR_INVALID)
- gst_rtsp_message_add_header (msg, field, value);
+ /* add the key:value pair */
+ if (*value != '\0')
+ gst_rtsp_message_add_header (msg, field, value);
+ value = next_value;
+ }
+
+done:
return GST_RTSP_OK;
/* ERRORS */
parse_error:
{
- return res;
+ return GST_RTSP_EPARSE;
}
}