[telepathy-sofiasip/master] Added the generic parser routine, along with initialization
Mikhail Zabaluev
mikhail.zabaluev at nokia.com
Mon Nov 30 05:51:22 PST 2009
---
tpsip/codec-param-formats.c | 108 ++++++++++++++++++++++++++++++++++++++++++-
tpsip/codec-param-formats.h | 11 +----
2 files changed, 109 insertions(+), 10 deletions(-)
diff --git a/tpsip/codec-param-formats.c b/tpsip/codec-param-formats.c
index f29fd64..cca4f98 100644
--- a/tpsip/codec-param-formats.c
+++ b/tpsip/codec-param-formats.c
@@ -24,6 +24,15 @@
#include <tpsip/util.h>
+/* Regexps for the name and the value parts of the parameter syntax */
+#define FMTP_TOKEN_PARAM "[-A-Za-z0-9!#$%&'*+.^_`{|}~]+"
+#define FMTP_TOKEN_VALUE "[^;\"\\s]+|\"([^\"\\\\]|\\\\.)*\""
+/* Indexes of the respective match groups in the whole regexp below */
+#define FMTP_MATCH_NAME_PARAM "p"
+#define FMTP_MATCH_NAME_VALUE "v"
+
+static GRegex *fmtp_attr_regex = NULL;
+
static void
format_param_generic (gpointer key, gpointer val, gpointer user_data)
{
@@ -38,7 +47,7 @@ format_param_generic (gpointer key, gpointer val, gpointer user_data)
if (out->len != 0)
g_string_append_c (out, ';');
- if (strchr (value, ';') == NULL)
+ if (strpbrk (value, "; \t") == NULL)
g_string_append_printf (out, "%s=%s", name, value);
else
{
@@ -62,3 +71,100 @@ tpsip_codec_param_format_generic (GHashTable *params, GString *out)
{
g_hash_table_foreach (params, format_param_generic, out);
}
+
+/**
+ * tpsip_codec_param_parse_generic:
+ * @fmtp: a string value with the parameter description
+ * @out: the parameter map to populate
+ *
+ * Parses parameters formatted as a semicolon separated list of
+ * <replaceable>parameter</replaceable><literal>=</literal><replaceable>value</replaceable>
+ * pairs, as recommended in IETF RFC 4855 Section 3.
+ */
+void
+tpsip_codec_param_parse_generic (const gchar *fmtp, GHashTable *out)
+{
+ GMatchInfo *match = NULL;
+ gint pos;
+ gint value_start;
+ gint value_end;
+
+ if (fmtp == NULL)
+ return;
+
+ pos = 0;
+
+ /* Fast path for trivial cases, not involving the regex engine */
+ while (g_ascii_isspace (fmtp[pos]))
+ ++pos;
+ if (!fmtp[pos])
+ return;
+
+ g_regex_match_full (fmtp_attr_regex,
+ fmtp, -1, pos, G_REGEX_MATCH_ANCHORED, &match, NULL);
+
+ while (g_match_info_matches (match))
+ {
+ gchar *name;
+ gchar *value;
+
+ name = g_match_info_fetch_named (match, FMTP_MATCH_NAME_PARAM);
+
+ g_match_info_fetch_named_pos (match, FMTP_MATCH_NAME_VALUE,
+ &value_start, &value_end);
+
+ if (value_end - 1 > value_start
+ && fmtp[value_start] == '\"' && fmtp[value_end - 1] == '\"')
+ {
+ value = tpsip_unquote_string (fmtp + value_start,
+ value_end - value_start);
+ }
+ else
+ {
+ value = g_strndup (fmtp + value_start,
+ value_end - value_start);
+ }
+
+ g_hash_table_insert (out, name, value);
+
+ g_match_info_fetch_pos (match, 0, NULL, &pos);
+ if (!fmtp[pos])
+ break;
+
+ g_match_info_next (match, NULL);
+ }
+
+ g_match_info_free (match);
+
+ if (fmtp[pos])
+ g_message ("failed to parse part of format parameters"
+ " as an attribute-value list: %s", &fmtp[pos]);
+}
+
+/**
+ * tpsip_codec_param_formats_init:
+ *
+ * Initializes the codec formatting infrastructure.
+ * This function must be called before using any other functions in this module.
+ * Calling the function more than once has no effect.
+ */
+void
+tpsip_codec_param_formats_init ()
+{
+ static volatile gsize been_here = 0;
+
+ if (g_once_init_enter (&been_here))
+ g_once_init_leave (&been_here, 1);
+ else
+ return;
+
+ fmtp_attr_regex = g_regex_new (
+ "(?<" FMTP_MATCH_NAME_PARAM ">" FMTP_TOKEN_PARAM ")"
+ "\\s*=\\s*"
+ "(?<" FMTP_MATCH_NAME_VALUE ">" FMTP_TOKEN_VALUE ")"
+ "\\s*(;\\s*|$)",
+ G_REGEX_RAW | G_REGEX_OPTIMIZE,
+ 0 /* G_REGEX_MATCH_ANCHORED */,
+ NULL);
+ g_assert (fmtp_attr_regex != NULL);
+}
diff --git a/tpsip/codec-param-formats.h b/tpsip/codec-param-formats.h
index 6707ec0..9d07ebd 100644
--- a/tpsip/codec-param-formats.h
+++ b/tpsip/codec-param-formats.h
@@ -57,17 +57,10 @@ typedef void (* TpsipCodecParamFormatFunc) (GHashTable *params, GString *out);
*/
typedef void (* TpsipCodecParamParseFunc) (const gchar *str, GHashTable *out);
+void tpsip_codec_param_formats_init (void);
+
void tpsip_codec_param_format_generic (GHashTable *params, GString *out);
-/**
- * tpsip_codec_param_parse_generic:
- * @str: a string value with the parameter description
- * @out: the parameter map to populate
- *
- * Parses parameters formatted as a semicolon separated list of
- * <replaceable>parameter</replaceable><literal>=</literal><replaceable>value</replaceable>
- * pairs, as recommended in IETF RFC 4855 Section 3.
- */
void tpsip_codec_param_parse_generic (const gchar *str, GHashTable *out);
G_END_DECLS
--
1.5.6.5
More information about the telepathy-commits
mailing list