gst/gstelement.c: simplify
authorBenjamin Otte <otte@gnome.org>
Sun, 28 Nov 2004 18:02:48 +0000 (18:02 +0000)
committerBenjamin Otte <otte@gnome.org>
Sun, 28 Nov 2004 18:02:48 +0000 (18:02 +0000)
Original commit message from CVS:
* 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

ChangeLog
gst/gstelement.c
gst/gstvalue.c
tests/old/testsuite/caps/value_serialize.c
testsuite/caps/value_serialize.c

index 43bce9b..fc91752 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+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):
index a1b7aaa..0d8c1b7 100644 (file)
@@ -2835,63 +2835,23 @@ exit:
 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;
     }
   }
 
index a1c7525..0cd297f 100644 (file)
@@ -1266,7 +1266,7 @@ gst_string_wrap (const char *s)
       *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 {
@@ -1281,6 +1281,48 @@ gst_string_wrap (const char *s)
 }
 
 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);
@@ -1289,7 +1331,16 @@ gst_value_serialize_string (const GValue * value)
 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;
 }
index a328f11..ec67141 100644 (file)
@@ -1,8 +1,6 @@
-
 #include <gst/gst.h>
-#include <glib.h>
 
-void
+static void
 test1 (void)
 {
   GValue value = { 0 };
@@ -11,16 +9,115 @@ test1 (void)
   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;
 }
index a328f11..ec67141 100644 (file)
@@ -1,8 +1,6 @@
-
 #include <gst/gst.h>
-#include <glib.h>
 
-void
+static void
 test1 (void)
 {
   GValue value = { 0 };
@@ -11,16 +9,115 @@ test1 (void)
   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;
 }