gst/gstelement.c: simplify

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
This commit is contained in:
Benjamin Otte 2004-11-28 18:02:48 +00:00
parent 7d5e71663c
commit a9bad8aa6e
5 changed files with 276 additions and 59 deletions

View file

@ -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> 2004-11-26 Wim Taymans <wim@fluendo.com>
* testsuite/threads/159566.c: (object_deep_notify), (main): * testsuite/threads/159566.c: (object_deep_notify), (main):

View file

@ -2835,63 +2835,23 @@ exit:
static gboolean static gboolean
gst_element_negotiate_pads (GstElement * element) gst_element_negotiate_pads (GstElement * element)
{ {
GList *pads = GST_ELEMENT_PADS (element); GList *pads;
GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element, "negotiating 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); GstPad *pad = GST_PAD (pads->data);
GstRealPad *srcpad;
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD (pad)) if (!GST_IS_REAL_PAD (pad))
continue; continue;
srcpad = GST_PAD_REALIZE (pad);
/* if we have a link on this pad and it doesn't have caps /* if we have a link on this pad and it doesn't have caps
* allready, try to negotiate */ * allready, try to negotiate */
if (GST_PAD_IS_LINKED (srcpad) && !GST_PAD_CAPS (srcpad)) { if (!gst_pad_is_negotiated (pad)) {
GstRealPad *sinkpad; GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, element,
GstElementState otherstate; "perform negotiate for %s:%s", GST_DEBUG_PAD_NAME (pad));
GstElement *parent; if (gst_pad_renegotiate (pad) == GST_PAD_LINK_REFUSED)
return FALSE;
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));
}
} }
} }

View file

@ -1266,7 +1266,7 @@ gst_string_wrap (const char *s)
*e++ = *t++; *e++ = *t++;
} else if (*t < 0x20 || *t >= 0x7f) { } else if (*t < 0x20 || *t >= 0x7f) {
*e++ = '\\'; *e++ = '\\';
*e++ = '0' + ((*t) >> 6); *e++ = '0' + ((*(guchar *) t) >> 6);
*e++ = '0' + (((*t) >> 3) & 0x7); *e++ = '0' + (((*t) >> 3) & 0x7);
*e++ = '0' + ((*t++) & 0x7); *e++ = '0' + ((*t++) & 0x7);
} else { } else {
@ -1280,6 +1280,48 @@ gst_string_wrap (const char *s)
return d; return d;
} }
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 * static char *
gst_value_serialize_string (const GValue * value) gst_value_serialize_string (const GValue * value)
{ {
@ -1289,7 +1331,16 @@ gst_value_serialize_string (const GValue * value)
static gboolean static gboolean
gst_value_deserialize_string (GValue * dest, const char *s) 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; return TRUE;
} }

View file

@ -1,8 +1,6 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h>
void static void
test1 (void) test1 (void)
{ {
GValue value = { 0 }; GValue value = { 0 };
@ -11,16 +9,115 @@ test1 (void)
g_value_init (&value, GST_TYPE_BUFFER); g_value_init (&value, GST_TYPE_BUFFER);
ret = gst_value_deserialize (&value, "1234567890abcdef"); ret = gst_value_deserialize (&value, "1234567890abcdef");
g_assert (ret); 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 int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
gboolean ret = TRUE;
gst_init (&argc, &argv); gst_init (&argc, &argv);
test1 (); test1 ();
ret &= test_string_serialization ();
ret &= test_string_deserialization ();
return 0; return ret ? 0 : 1;
} }

View file

@ -1,8 +1,6 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h>
void static void
test1 (void) test1 (void)
{ {
GValue value = { 0 }; GValue value = { 0 };
@ -11,16 +9,115 @@ test1 (void)
g_value_init (&value, GST_TYPE_BUFFER); g_value_init (&value, GST_TYPE_BUFFER);
ret = gst_value_deserialize (&value, "1234567890abcdef"); ret = gst_value_deserialize (&value, "1234567890abcdef");
g_assert (ret); 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 int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
gboolean ret = TRUE;
gst_init (&argc, &argv); gst_init (&argc, &argv);
test1 (); test1 ();
ret &= test_string_serialization ();
ret &= test_string_deserialization ();
return 0; return ret ? 0 : 1;
} }