+2004-11-28 Benjamin Otte <otte@gnome.org>
+
+ * gst/gstelement.c: (gst_element_negotiate_pads):
+ simplify
+ * gst/gstvalue.c: (gst_string_wrap), (gst_string_unwrap),
+ (gst_value_serialize_string), (gst_value_deserialize_string):
+ add unwrapping of previously wrapped strings. Fix bug in wrapping
+ while at it.
+ * testsuite/caps/value_serialize.c: (test1),
+ (test_string_serialization), (test_string_deserialization), (main):
+ add tests for string (de)serialization
+
2004-11-26 Wim Taymans <wim@fluendo.com>
* testsuite/threads/159566.c: (object_deep_notify), (main):
static gboolean
gst_element_negotiate_pads (GstElement * element)
{
- GList *pads = GST_ELEMENT_PADS (element);
+ GList *pads;
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating pads");
- while (pads) {
+ for (pads = GST_ELEMENT_PADS (element); pads; pads = g_list_next (pads)) {
GstPad *pad = GST_PAD (pads->data);
- GstRealPad *srcpad;
-
- pads = g_list_next (pads);
if (!GST_IS_REAL_PAD (pad))
continue;
- srcpad = GST_PAD_REALIZE (pad);
-
/* if we have a link on this pad and it doesn't have caps
* allready, try to negotiate */
- if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) {
- GstRealPad *sinkpad;
- GstElementState otherstate;
- GstElement *parent;
-
- sinkpad = GST_RPAD_PEER (GST_PAD_REALIZE (srcpad));
-
- /* check the parent of the peer pad, if there is no parent do nothing */
- parent = GST_PAD_PARENT (sinkpad);
- if (!parent)
- continue;
-
- /* skips pads that were already negotiating */
- if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
- GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
- continue;
-
- otherstate = GST_STATE (parent);
-
- /* swap pads if needed */
- if (!GST_PAD_IS_SRC (srcpad)) {
- GstRealPad *temp;
-
- temp = srcpad;
- srcpad = sinkpad;
- sinkpad = temp;
- }
-
- /* only try to negotiate if the peer element is in PAUSED or higher too */
- if (otherstate >= GST_STATE_READY) {
- GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
- "perform negotiate for %s:%s and %s:%s",
- GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
- if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
- return FALSE;
- } else {
- GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
- "not negotiating %s:%s and %s:%s, not in READY yet",
- GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
- }
+ if (!gst_pad_is_negotiated (pad)) {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
+ "perform negotiate for %s:%s", GST_DEBUG_PAD_NAME (pad));
+ if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
+ return FALSE;
}
}
*e++ = *t++;
} else if (*t < 0x20 || *t >= 0x7f) {
*e++ = '\\';
- *e++ = '0' + ((*t) >> 6);
+ *e++ = '0' + ((*(guchar *) t) >> 6);
*e++ = '0' + (((*t) >> 3) & 0x7);
*e++ = '0' + ((*t++) & 0x7);
} else {
}
static char *
+gst_string_unwrap (const gchar * s)
+{
+ /* FIXME: do better memory management? */
+ gchar *ret = g_strdup (s);
+ gchar *read = ret, *write = ret;
+
+ if (*read++ != '"') {
+ g_free (ret);
+ return NULL;
+ }
+ while (*read) {
+ if (GST_ASCII_IS_STRING (*read)) {
+ *write++ = *read++;
+ } else if (*read == '"') {
+ break;
+ } else if (*read == '\\') {
+ read++;
+ if (*read >= '0' && *read <= '7') {
+ if (read[1] < '0' || read[1] > '7' || read[2] < '0' || read[2] > '7') {
+ g_free (ret);
+ return NULL;
+ }
+ *write++ = ((read[0] - '0') << 6) +
+ ((read[1] - '0') << 3) + (read[2] - '0');
+ read += 3;
+ } else {
+ *write++ = *read++;
+ }
+ } else {
+ g_free (ret);
+ return NULL;
+ }
+ }
+ if (*read != '"' || read[1] != '\0') {
+ g_free (ret);
+ return NULL;
+ }
+ *write++ = '\0';
+ return ret;
+}
+
+static char *
gst_value_serialize_string (const GValue * value)
{
return gst_string_wrap (value->data[0].v_pointer);
static gboolean
gst_value_deserialize_string (GValue * dest, const char *s)
{
- g_value_set_string (dest, s);
+ if (*s != '"') {
+ g_value_set_string (dest, s);
+ return TRUE;
+ } else {
+ gchar *str = gst_string_unwrap (s);
+
+ if (!str)
+ return FALSE;
+ g_value_take_string (dest, str);
+ }
return TRUE;
}
-
#include <gst/gst.h>
-#include <glib.h>
-void
+static void
test1 (void)
{
GValue value = { 0 };
g_value_init (&value, GST_TYPE_BUFFER);
ret = gst_value_deserialize (&value, "1234567890abcdef");
g_assert (ret);
+}
+
+static gboolean
+test_string_serialization (void)
+{
+ gchar *try[] = {
+ "Dude",
+ "Hi, I'm a string",
+ "tüüüt!"
+ };
+ gchar *tmp;
+ GValue v = { 0, };
+ guint i;
+ gboolean ret = TRUE;
+
+ g_value_init (&v, G_TYPE_STRING);
+ for (i = 0; i < G_N_ELEMENTS (try); i++) {
+ g_value_set_string (&v, try[i]);
+ tmp = gst_value_serialize (&v);
+ if (!tmp) {
+ g_print ("couldn't serialize: %s\n", try[i]);
+ ret = FALSE;
+ continue;
+ }
+ if (!gst_value_deserialize (&v, tmp)) {
+ g_print ("couldn't deserialize: %s\n", tmp);
+ g_free (tmp);
+ ret = FALSE;
+ continue;
+ }
+ g_free (tmp);
+ if (!g_str_equal (g_value_get_string (&v), try[i])) {
+ g_print ("serialized : %s\n", try[i]);
+ g_print ("deserialized: %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ continue;
+ }
+ }
+ g_value_unset (&v);
+ return ret;
}
+static gboolean
+test_string_deserialization (void)
+{
+ struct
+ {
+ gchar *from;
+ gchar *to;
+ } tests[] = {
+ {
+ "", ""}, {
+ "\\", "\\"}, {
+ "\"\"", ""},
+ /* FAILURES */
+ {
+ "\"", NULL}, /* missing second quote */
+ {
+ "\"Hello\\ World", NULL}, /* missing second quote */
+ {
+ "\"\\", NULL}, /* quote at end, missing second quote */
+ {
+ "\"\\0", NULL}, /* missing second quote */
+ {
+ "\"\\0\"", NULL}, /* unfinished escaped character */
+ {
+ "\" \"", NULL}, /* spaces must be escaped */
+ {
+ "tüüt", NULL} /* string with special chars must be escaped */
+ };
+ guint i;
+ GValue v = { 0, };
+ gboolean ret = TRUE;
+
+ g_value_init (&v, G_TYPE_STRING);
+ for (i = 0; i < G_N_ELEMENTS (tests); i++) {
+ if (gst_value_deserialize (&v, tests[i].from)) {
+ if (tests[i].to == NULL) {
+ g_print ("should fail\n");
+ g_print ("but got: %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ } else if (!g_str_equal (g_value_get_string (&v), tests[i].to)) {
+ g_print ("wanted: %s\n", tests[i].to);
+ g_print ("got : %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ }
+ } else {
+ if (tests[i].to != NULL) {
+ g_print ("failed\n");
+ g_print ("but wanted: %s\n", tests[i].to);
+ ret = FALSE;
+ }
+ }
+ }
+ g_value_unset (&v);
+ return ret;
+}
+
int
main (int argc, char *argv[])
{
+ gboolean ret = TRUE;
+
gst_init (&argc, &argv);
test1 ();
+ ret &= test_string_serialization ();
+ ret &= test_string_deserialization ();
- return 0;
-
+ return ret ? 0 : 1;
}
-
#include <gst/gst.h>
-#include <glib.h>
-void
+static void
test1 (void)
{
GValue value = { 0 };
g_value_init (&value, GST_TYPE_BUFFER);
ret = gst_value_deserialize (&value, "1234567890abcdef");
g_assert (ret);
+}
+
+static gboolean
+test_string_serialization (void)
+{
+ gchar *try[] = {
+ "Dude",
+ "Hi, I'm a string",
+ "tüüüt!"
+ };
+ gchar *tmp;
+ GValue v = { 0, };
+ guint i;
+ gboolean ret = TRUE;
+
+ g_value_init (&v, G_TYPE_STRING);
+ for (i = 0; i < G_N_ELEMENTS (try); i++) {
+ g_value_set_string (&v, try[i]);
+ tmp = gst_value_serialize (&v);
+ if (!tmp) {
+ g_print ("couldn't serialize: %s\n", try[i]);
+ ret = FALSE;
+ continue;
+ }
+ if (!gst_value_deserialize (&v, tmp)) {
+ g_print ("couldn't deserialize: %s\n", tmp);
+ g_free (tmp);
+ ret = FALSE;
+ continue;
+ }
+ g_free (tmp);
+ if (!g_str_equal (g_value_get_string (&v), try[i])) {
+ g_print ("serialized : %s\n", try[i]);
+ g_print ("deserialized: %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ continue;
+ }
+ }
+ g_value_unset (&v);
+ return ret;
}
+static gboolean
+test_string_deserialization (void)
+{
+ struct
+ {
+ gchar *from;
+ gchar *to;
+ } tests[] = {
+ {
+ "", ""}, {
+ "\\", "\\"}, {
+ "\"\"", ""},
+ /* FAILURES */
+ {
+ "\"", NULL}, /* missing second quote */
+ {
+ "\"Hello\\ World", NULL}, /* missing second quote */
+ {
+ "\"\\", NULL}, /* quote at end, missing second quote */
+ {
+ "\"\\0", NULL}, /* missing second quote */
+ {
+ "\"\\0\"", NULL}, /* unfinished escaped character */
+ {
+ "\" \"", NULL}, /* spaces must be escaped */
+ {
+ "tüüt", NULL} /* string with special chars must be escaped */
+ };
+ guint i;
+ GValue v = { 0, };
+ gboolean ret = TRUE;
+
+ g_value_init (&v, G_TYPE_STRING);
+ for (i = 0; i < G_N_ELEMENTS (tests); i++) {
+ if (gst_value_deserialize (&v, tests[i].from)) {
+ if (tests[i].to == NULL) {
+ g_print ("should fail\n");
+ g_print ("but got: %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ } else if (!g_str_equal (g_value_get_string (&v), tests[i].to)) {
+ g_print ("wanted: %s\n", tests[i].to);
+ g_print ("got : %s\n", g_value_get_string (&v));
+ ret = FALSE;
+ }
+ } else {
+ if (tests[i].to != NULL) {
+ g_print ("failed\n");
+ g_print ("but wanted: %s\n", tests[i].to);
+ ret = FALSE;
+ }
+ }
+ }
+ g_value_unset (&v);
+ return ret;
+}
+
int
main (int argc, char *argv[])
{
+ gboolean ret = TRUE;
+
gst_init (&argc, &argv);
test1 ();
+ ret &= test_string_serialization ();
+ ret &= test_string_deserialization ();
- return 0;
-
+ return ret ? 0 : 1;
}