mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
gstvalue: expose gst_value_deserialize_with_pspec()
Typing hints can only be passed to gst_value_deserialize() through the type of the passed-in value. This means deserialization can only target the desired type for the top-level elements, making it for example impossible to deserialize an array of flags to the expected type. This commit exposes a new function, gst_value_deserialize_full(), that takes an optional pspec as the extra parameter, and updates the deserialization code to pass around that pspec, or the element_spec when recursively parsing the elements of a list-type value. This allows for example passing arrays of flags through the command line or gst_util_set_object_arg, eg: foo="<bar,bar+baz>" Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/629>
This commit is contained in:
parent
220ce9c3fd
commit
acdb4ce03d
7 changed files with 224 additions and 33 deletions
|
@ -172,7 +172,7 @@ G_GNUC_INTERNAL const char * _priv_gst_value_gtype_to_abbr (GType type);
|
||||||
|
|
||||||
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_string (gchar * s, gchar ** end, gchar ** next, gboolean unescape);
|
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_string (gchar * s, gchar ** end, gchar ** next, gboolean unescape);
|
||||||
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_simple_string (gchar * str, gchar ** end);
|
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_simple_string (gchar * str, gchar ** end);
|
||||||
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_value (gchar * str, gchar ** after, GValue * value, GType default_type);
|
G_GNUC_INTERNAL gboolean _priv_gst_value_parse_value (gchar * str, gchar ** after, GValue * value, GType default_type, GParamSpec *pspec);
|
||||||
G_GNUC_INTERNAL gchar * _priv_gst_value_serialize_any_list (const GValue * value, const gchar * begin, const gchar * end, gboolean print_type);
|
G_GNUC_INTERNAL gchar * _priv_gst_value_serialize_any_list (const GValue * value, const gchar * begin, const gchar * end, gboolean print_type);
|
||||||
|
|
||||||
/* Used in GstBin for manual state handling */
|
/* Used in GstBin for manual state handling */
|
||||||
|
|
|
@ -2204,7 +2204,7 @@ gst_structure_parse_field (gchar * str,
|
||||||
*name_end = c;
|
*name_end = c;
|
||||||
|
|
||||||
if (G_UNLIKELY (!_priv_gst_value_parse_value (s, &s, &field->value,
|
if (G_UNLIKELY (!_priv_gst_value_parse_value (s, &s, &field->value,
|
||||||
G_TYPE_INVALID))) {
|
G_TYPE_INVALID, NULL))) {
|
||||||
GST_WARNING ("failed to parse value %s", str);
|
GST_WARNING ("failed to parse value %s", str);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,7 @@ gst_util_set_object_arg (GObject * object, const gchar * name,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_value_deserialize (&v, value))
|
if (!gst_value_deserialize_with_pspec (&v, value, pspec))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
138
gst/gstvalue.c
138
gst/gstvalue.c
|
@ -98,9 +98,9 @@ static void gst_value_register_subtract_func (GType minuend_type,
|
||||||
GType subtrahend_type, GstValueSubtractFunc func);
|
GType subtrahend_type, GstValueSubtractFunc func);
|
||||||
|
|
||||||
static gboolean _priv_gst_value_parse_list (gchar * s, gchar ** after,
|
static gboolean _priv_gst_value_parse_list (gchar * s, gchar ** after,
|
||||||
GValue * value, GType type);
|
GValue * value, GType type, GParamSpec * pspec);
|
||||||
static gboolean _priv_gst_value_parse_array (gchar * s, gchar ** after,
|
static gboolean _priv_gst_value_parse_array (gchar * s, gchar ** after,
|
||||||
GValue * value, GType type);
|
GValue * value, GType type, GParamSpec * pspec);
|
||||||
|
|
||||||
typedef struct _GstValueUnionInfo GstValueUnionInfo;
|
typedef struct _GstValueUnionInfo GstValueUnionInfo;
|
||||||
struct _GstValueUnionInfo
|
struct _GstValueUnionInfo
|
||||||
|
@ -1244,10 +1244,11 @@ gst_value_serialize_value_list (const GValue * value)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_value_deserialize_value_list (GValue * dest, const gchar * s)
|
gst_value_deserialize_value_list (GValue * dest, const gchar * s,
|
||||||
|
GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
gchar *s2 = (gchar *) s;
|
gchar *s2 = (gchar *) s;
|
||||||
return _priv_gst_value_parse_list (s2, &s2, dest, G_TYPE_INVALID);
|
return _priv_gst_value_parse_list (s2, &s2, dest, G_TYPE_INVALID, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
|
@ -1257,10 +1258,11 @@ gst_value_serialize_value_array (const GValue * value)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_value_deserialize_value_array (GValue * dest, const gchar * s)
|
gst_value_deserialize_value_array (GValue * dest, const gchar * s,
|
||||||
|
GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
gchar *s2 = (gchar *) s;
|
gchar *s2 = (gchar *) s;
|
||||||
return _priv_gst_value_parse_array (s2, &s2, dest, G_TYPE_INVALID);
|
return _priv_gst_value_parse_array (s2, &s2, dest, G_TYPE_INVALID, pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
|
@ -2469,7 +2471,7 @@ _priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
ret = _priv_gst_value_parse_value (s, &s, &value1, type);
|
ret = _priv_gst_value_parse_value (s, &s, &value1, type, NULL);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -2483,7 +2485,7 @@ _priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value,
|
||||||
while (g_ascii_isspace (*s))
|
while (g_ascii_isspace (*s))
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
ret = _priv_gst_value_parse_value (s, &s, &value2, type);
|
ret = _priv_gst_value_parse_value (s, &s, &value2, type, NULL);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -2499,7 +2501,7 @@ _priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value,
|
||||||
while (g_ascii_isspace (*s))
|
while (g_ascii_isspace (*s))
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
ret = _priv_gst_value_parse_value (s, &s, &value3, type);
|
ret = _priv_gst_value_parse_value (s, &s, &value3, type, NULL);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -2562,11 +2564,15 @@ _priv_gst_value_parse_range (gchar * s, gchar ** after, GValue * value,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
|
_priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
|
||||||
GType type, char begin, char end)
|
GType type, char begin, char end, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
GValue list_value = { 0 };
|
GValue list_value = { 0 };
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
GstValueList *vlist = VALUE_LIST_ARRAY (value);
|
GstValueList *vlist = VALUE_LIST_ARRAY (value);
|
||||||
|
GParamSpec *element_spec = NULL;
|
||||||
|
|
||||||
|
if (pspec)
|
||||||
|
element_spec = GST_PARAM_SPEC_ARRAY_LIST (pspec)->element_spec;
|
||||||
|
|
||||||
if (*s != begin)
|
if (*s != begin)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2588,7 +2594,8 @@ _priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&list_value, 0, sizeof (list_value));
|
memset (&list_value, 0, sizeof (list_value));
|
||||||
ret = _priv_gst_value_parse_value (s, &s, &list_value, type);
|
|
||||||
|
ret = _priv_gst_value_parse_value (s, &s, &list_value, type, element_spec);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -2609,16 +2616,18 @@ _priv_gst_value_parse_any_list (gchar * s, gchar ** after, GValue * value,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_priv_gst_value_parse_list (gchar * s, gchar ** after, GValue * value,
|
_priv_gst_value_parse_list (gchar * s, gchar ** after, GValue * value,
|
||||||
GType type)
|
GType type, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
return _priv_gst_value_parse_any_list (s, after, value, type, '{', '}');
|
return _priv_gst_value_parse_any_list (s, after, value, type, '{', '}',
|
||||||
|
pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_priv_gst_value_parse_array (gchar * s, gchar ** after, GValue * value,
|
_priv_gst_value_parse_array (gchar * s, gchar ** after, GValue * value,
|
||||||
GType type)
|
GType type, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
return _priv_gst_value_parse_any_list (s, after, value, type, '<', '>');
|
return _priv_gst_value_parse_any_list (s, after, value, type, '<', '>',
|
||||||
|
pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -2637,7 +2646,7 @@ _priv_gst_value_parse_simple_string (gchar * str, gchar ** end)
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_priv_gst_value_parse_value (gchar * str,
|
_priv_gst_value_parse_value (gchar * str,
|
||||||
gchar ** after, GValue * value, GType default_type)
|
gchar ** after, GValue * value, GType default_type, GParamSpec * pspec)
|
||||||
{
|
{
|
||||||
gchar *type_name;
|
gchar *type_name;
|
||||||
gchar *type_end;
|
gchar *type_end;
|
||||||
|
@ -2654,7 +2663,10 @@ _priv_gst_value_parse_value (gchar * str,
|
||||||
|
|
||||||
/* check if there's a (type_name) 'cast' */
|
/* check if there's a (type_name) 'cast' */
|
||||||
type_name = NULL;
|
type_name = NULL;
|
||||||
if (*s == '(') {
|
|
||||||
|
if (pspec) {
|
||||||
|
type = G_PARAM_SPEC_VALUE_TYPE (pspec);
|
||||||
|
} else if (*s == '(') {
|
||||||
s++;
|
s++;
|
||||||
while (g_ascii_isspace (*s))
|
while (g_ascii_isspace (*s))
|
||||||
s++;
|
s++;
|
||||||
|
@ -2688,10 +2700,10 @@ _priv_gst_value_parse_value (gchar * str,
|
||||||
ret = _priv_gst_value_parse_range (s, &s, value, type);
|
ret = _priv_gst_value_parse_range (s, &s, value, type);
|
||||||
} else if (*s == '{') {
|
} else if (*s == '{') {
|
||||||
g_value_init (value, GST_TYPE_LIST);
|
g_value_init (value, GST_TYPE_LIST);
|
||||||
ret = _priv_gst_value_parse_list (s, &s, value, type);
|
ret = _priv_gst_value_parse_list (s, &s, value, type, pspec);
|
||||||
} else if (*s == '<') {
|
} else if (*s == '<') {
|
||||||
g_value_init (value, GST_TYPE_ARRAY);
|
g_value_init (value, GST_TYPE_ARRAY);
|
||||||
ret = _priv_gst_value_parse_array (s, &s, value, type);
|
ret = _priv_gst_value_parse_array (s, &s, value, type, pspec);
|
||||||
} else {
|
} else {
|
||||||
value_s = s;
|
value_s = s;
|
||||||
|
|
||||||
|
@ -2725,7 +2737,7 @@ _priv_gst_value_parse_value (gchar * str,
|
||||||
c = *value_end;
|
c = *value_end;
|
||||||
*value_end = '\0';
|
*value_end = '\0';
|
||||||
|
|
||||||
ret = gst_value_deserialize (value, value_s);
|
ret = gst_value_deserialize_with_pspec (value, value_s, pspec);
|
||||||
if (G_UNLIKELY (!ret))
|
if (G_UNLIKELY (!ret))
|
||||||
g_value_unset (value);
|
g_value_unset (value);
|
||||||
}
|
}
|
||||||
|
@ -6439,19 +6451,80 @@ gst_value_deserialize (GValue * dest, const gchar * src)
|
||||||
type = G_VALUE_TYPE (dest);
|
type = G_VALUE_TYPE (dest);
|
||||||
|
|
||||||
best = gst_value_hash_lookup_type (type);
|
best = gst_value_hash_lookup_type (type);
|
||||||
if (G_UNLIKELY (!best || !best->deserialize)) {
|
if (G_UNLIKELY (!best || (!best->deserialize
|
||||||
|
&& !best->deserialize_with_pspec))) {
|
||||||
len = gst_value_table->len;
|
len = gst_value_table->len;
|
||||||
best = NULL;
|
best = NULL;
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
table = &g_array_index (gst_value_table, GstValueTable, i);
|
table = &g_array_index (gst_value_table, GstValueTable, i);
|
||||||
if (table->deserialize && g_type_is_a (type, table->type)) {
|
if ((table->deserialize || table->deserialize_with_pspec) &&
|
||||||
|
g_type_is_a (type, table->type)) {
|
||||||
if (!best || g_type_is_a (table->type, best->type))
|
if (!best || g_type_is_a (table->type, best->type))
|
||||||
best = table;
|
best = table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (G_LIKELY (best))
|
if (G_LIKELY (best)) {
|
||||||
return best->deserialize (dest, src);
|
if (best->deserialize_with_pspec)
|
||||||
|
return best->deserialize_with_pspec (dest, src, NULL);
|
||||||
|
else
|
||||||
|
return best->deserialize (dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_value_deserialize_with_pspec:
|
||||||
|
* @dest: (out caller-allocates): #GValue to fill with contents of
|
||||||
|
* deserialization
|
||||||
|
* @src: string to deserialize
|
||||||
|
* @pspec: (nullable): the #GParamSpec describing the expected value
|
||||||
|
*
|
||||||
|
* Tries to deserialize a string into the type specified by the given GValue.
|
||||||
|
* @pspec may be used to guide the deserializing of nested members.
|
||||||
|
* If the operation succeeds, %TRUE is returned, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE on success
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_value_deserialize_with_pspec (GValue * dest, const gchar * src,
|
||||||
|
GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstValueTable *table, *best;
|
||||||
|
guint i, len;
|
||||||
|
GType type;
|
||||||
|
|
||||||
|
g_return_val_if_fail (src != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (G_IS_VALUE (dest), FALSE);
|
||||||
|
|
||||||
|
if (pspec)
|
||||||
|
g_return_val_if_fail (G_VALUE_TYPE (dest) ==
|
||||||
|
G_PARAM_SPEC_VALUE_TYPE (pspec), FALSE);
|
||||||
|
|
||||||
|
type = G_VALUE_TYPE (dest);
|
||||||
|
|
||||||
|
best = gst_value_hash_lookup_type (type);
|
||||||
|
if (G_UNLIKELY (!best || (!best->deserialize
|
||||||
|
&& !best->deserialize_with_pspec))) {
|
||||||
|
len = gst_value_table->len;
|
||||||
|
best = NULL;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
table = &g_array_index (gst_value_table, GstValueTable, i);
|
||||||
|
if ((table->deserialize || table->deserialize_with_pspec) &&
|
||||||
|
g_type_is_a (type, table->type)) {
|
||||||
|
if (!best || g_type_is_a (table->type, best->type))
|
||||||
|
best = table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (G_LIKELY (best)) {
|
||||||
|
if (best->deserialize_with_pspec)
|
||||||
|
return best->deserialize_with_pspec (dest, src, pspec);
|
||||||
|
else
|
||||||
|
return best->deserialize (dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -7750,7 +7823,8 @@ gst_g_thread_get_type (void)
|
||||||
return G_TYPE_THREAD;
|
return G_TYPE_THREAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SERIAL_VTABLE(t,c,s,d) { t, c, s, d }
|
#define SERIAL_VTABLE(t,c,s,d) { t, c, s, d, NULL }
|
||||||
|
#define SERIAL_VTABLE_PSPEC(t,c,s,d) { t, c, s, NULL, d }
|
||||||
|
|
||||||
#define REGISTER_SERIALIZATION_CONST(_gtype, _type) \
|
#define REGISTER_SERIALIZATION_CONST(_gtype, _type) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
|
@ -7769,6 +7843,15 @@ G_STMT_START { \
|
||||||
gst_value_register (&gst_value); \
|
gst_value_register (&gst_value); \
|
||||||
} G_STMT_END
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define REGISTER_SERIALIZATION_WITH_PSPEC(_gtype, _type) \
|
||||||
|
G_STMT_START { \
|
||||||
|
static GstValueTable gst_value = \
|
||||||
|
SERIAL_VTABLE_PSPEC (0, gst_value_compare_ ## _type, \
|
||||||
|
gst_value_serialize_ ## _type, gst_value_deserialize_ ## _type); \
|
||||||
|
gst_value.type = _gtype; \
|
||||||
|
gst_value_register (&gst_value); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
#define REGISTER_SERIALIZATION_NO_COMPARE(_gtype, _type) \
|
#define REGISTER_SERIALIZATION_NO_COMPARE(_gtype, _type) \
|
||||||
G_STMT_START { \
|
G_STMT_START { \
|
||||||
static GstValueTable gst_value = \
|
static GstValueTable gst_value = \
|
||||||
|
@ -7813,8 +7896,6 @@ _priv_gst_value_initialize (void)
|
||||||
REGISTER_SERIALIZATION (gst_int64_range_get_type (), int64_range);
|
REGISTER_SERIALIZATION (gst_int64_range_get_type (), int64_range);
|
||||||
REGISTER_SERIALIZATION (gst_double_range_get_type (), double_range);
|
REGISTER_SERIALIZATION (gst_double_range_get_type (), double_range);
|
||||||
REGISTER_SERIALIZATION (gst_fraction_range_get_type (), fraction_range);
|
REGISTER_SERIALIZATION (gst_fraction_range_get_type (), fraction_range);
|
||||||
REGISTER_SERIALIZATION (gst_value_list_get_type (), value_list);
|
|
||||||
REGISTER_SERIALIZATION (gst_value_array_get_type (), value_array);
|
|
||||||
REGISTER_SERIALIZATION (g_value_array_get_type (), g_value_array);
|
REGISTER_SERIALIZATION (g_value_array_get_type (), g_value_array);
|
||||||
REGISTER_SERIALIZATION (gst_buffer_get_type (), buffer);
|
REGISTER_SERIALIZATION (gst_buffer_get_type (), buffer);
|
||||||
REGISTER_SERIALIZATION (gst_sample_get_type (), sample);
|
REGISTER_SERIALIZATION (gst_sample_get_type (), sample);
|
||||||
|
@ -7857,6 +7938,9 @@ _priv_gst_value_initialize (void)
|
||||||
|
|
||||||
REGISTER_SERIALIZATION (G_TYPE_GTYPE, gtype);
|
REGISTER_SERIALIZATION (G_TYPE_GTYPE, gtype);
|
||||||
|
|
||||||
|
REGISTER_SERIALIZATION_WITH_PSPEC (gst_value_list_get_type (), value_list);
|
||||||
|
REGISTER_SERIALIZATION_WITH_PSPEC (gst_value_array_get_type (), value_array);
|
||||||
|
|
||||||
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING,
|
||||||
gst_value_transform_int_range_string);
|
gst_value_transform_int_range_string);
|
||||||
g_value_register_transform_func (GST_TYPE_INT64_RANGE, G_TYPE_STRING,
|
g_value_register_transform_func (GST_TYPE_INT64_RANGE, G_TYPE_STRING,
|
||||||
|
|
|
@ -472,6 +472,22 @@ typedef gchar * (* GstValueSerializeFunc) (const GValue *value1);
|
||||||
typedef gboolean (* GstValueDeserializeFunc) (GValue *dest,
|
typedef gboolean (* GstValueDeserializeFunc) (GValue *dest,
|
||||||
const gchar *s);
|
const gchar *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstValueDeserializeWithPSpecFunc:
|
||||||
|
* @dest: a #GValue
|
||||||
|
* @s: a string
|
||||||
|
* @pspec: a #GParamSpec describing the expected value
|
||||||
|
*
|
||||||
|
* Used by gst_value_deserialize_with_pspec() to parse a non-binary form into the #GValue.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE for success
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
typedef gboolean (* GstValueDeserializeWithPSpecFunc) (GValue *dest,
|
||||||
|
const gchar *s,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
|
||||||
typedef struct _GstValueTable GstValueTable;
|
typedef struct _GstValueTable GstValueTable;
|
||||||
/**
|
/**
|
||||||
* GstValueTable:
|
* GstValueTable:
|
||||||
|
@ -479,6 +495,7 @@ typedef struct _GstValueTable GstValueTable;
|
||||||
* @compare: a #GstValueCompareFunc
|
* @compare: a #GstValueCompareFunc
|
||||||
* @serialize: a #GstValueSerializeFunc
|
* @serialize: a #GstValueSerializeFunc
|
||||||
* @deserialize: a #GstValueDeserializeFunc
|
* @deserialize: a #GstValueDeserializeFunc
|
||||||
|
* @deserialize_with_pspec: a #GstValueDeserializeWithPSpecFunc
|
||||||
*
|
*
|
||||||
* VTable for the #GValue @type.
|
* VTable for the #GValue @type.
|
||||||
*/
|
*/
|
||||||
|
@ -488,8 +505,17 @@ struct _GstValueTable {
|
||||||
GstValueSerializeFunc serialize;
|
GstValueSerializeFunc serialize;
|
||||||
GstValueDeserializeFunc deserialize;
|
GstValueDeserializeFunc deserialize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstValueTable.deserialize_with_pspec:
|
||||||
|
*
|
||||||
|
* a #GstValueDeserializeWithPSpecFunc
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
GstValueDeserializeWithPSpecFunc deserialize_with_pspec;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gpointer _gst_reserved [GST_PADDING];
|
gpointer _gst_reserved [GST_PADDING - 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_API
|
GST_API
|
||||||
|
@ -538,6 +564,11 @@ GST_API
|
||||||
gboolean gst_value_deserialize (GValue *dest,
|
gboolean gst_value_deserialize (GValue *dest,
|
||||||
const gchar *src);
|
const gchar *src);
|
||||||
|
|
||||||
|
GST_API
|
||||||
|
gboolean gst_value_deserialize_with_pspec (GValue *dest,
|
||||||
|
const gchar *src,
|
||||||
|
GParamSpec *pspec);
|
||||||
|
|
||||||
/* list */
|
/* list */
|
||||||
|
|
||||||
GST_API
|
GST_API
|
||||||
|
|
|
@ -328,7 +328,7 @@ static void gst_parse_new_child(GstChildProxy *child_proxy, GObject *object,
|
||||||
GST_CAT_LOG_OBJECT (GST_CAT_PIPELINE, child_proxy, "parsing delayed property %s as a %s from %s",
|
GST_CAT_LOG_OBJECT (GST_CAT_PIPELINE, child_proxy, "parsing delayed property %s as a %s from %s",
|
||||||
pspec->name, g_type_name (value_type), set->value_str);
|
pspec->name, g_type_name (value_type), set->value_str);
|
||||||
g_value_init (&v, value_type);
|
g_value_init (&v, value_type);
|
||||||
if (gst_value_deserialize (&v, set->value_str))
|
if (gst_value_deserialize_with_pspec (&v, set->value_str, pspec))
|
||||||
got_value = TRUE;
|
got_value = TRUE;
|
||||||
else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
|
else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
|
||||||
GstElement *bin;
|
GstElement *bin;
|
||||||
|
@ -424,7 +424,7 @@ static void gst_parse_element_set (gchar *value, GstElement *element, graph_t *g
|
||||||
pspec->name, g_type_name (value_type));
|
pspec->name, g_type_name (value_type));
|
||||||
|
|
||||||
g_value_init (&v, value_type);
|
g_value_init (&v, value_type);
|
||||||
if (gst_value_deserialize (&v, pos))
|
if (gst_value_deserialize_with_pspec (&v, pos, pspec))
|
||||||
got_value = TRUE;
|
got_value = TRUE;
|
||||||
else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
|
else if (g_type_is_a (value_type, GST_TYPE_ELEMENT)) {
|
||||||
GstElement *bin;
|
GstElement *bin;
|
||||||
|
|
|
@ -3508,6 +3508,81 @@ GST_START_TEST (test_deserialize_array)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
#define TEST_FLAGS_TYPE (test_flags_get_type())
|
||||||
|
static GType
|
||||||
|
test_flags_get_type (void)
|
||||||
|
{
|
||||||
|
static const GFlagsValue values[] = {
|
||||||
|
{1, "One", "one"},
|
||||||
|
{1 << 1, "Two", "two"},
|
||||||
|
{1 << 3, "Eight", "eight"},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
static volatile GType id = 0;
|
||||||
|
|
||||||
|
if (g_once_init_enter ((gsize *) & id)) {
|
||||||
|
GType _id;
|
||||||
|
|
||||||
|
_id = g_flags_register_static ("TestFlags", values);
|
||||||
|
|
||||||
|
g_once_init_leave ((gsize *) & id, _id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _RESULT(i) result_##i
|
||||||
|
#define RESULT(i) _RESULT(i)
|
||||||
|
|
||||||
|
GST_START_TEST (test_deserialize_with_pspec)
|
||||||
|
{
|
||||||
|
GValue value = { 0 };
|
||||||
|
GParamSpec *pspec;
|
||||||
|
const gchar *strings[] = {
|
||||||
|
"< one, 0>",
|
||||||
|
"< one+eight, two >",
|
||||||
|
"< 9, 0>",
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
gint results[3][2] = {
|
||||||
|
{1, 0},
|
||||||
|
{9, 2},
|
||||||
|
{9, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
pspec = gst_param_spec_array ("flags-array",
|
||||||
|
"Flags Array", "An array of flags",
|
||||||
|
g_param_spec_flags ("flags", "Flags", "Flags", TEST_FLAGS_TYPE, 0,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (strings); ++i) {
|
||||||
|
int j;
|
||||||
|
gchar *str = g_strdup (strings[i]);
|
||||||
|
g_value_init (&value, GST_TYPE_ARRAY);
|
||||||
|
|
||||||
|
fail_unless (gst_value_deserialize_with_pspec (&value, str, pspec),
|
||||||
|
"could not deserialize %s (%d)", str, i);
|
||||||
|
|
||||||
|
fail_unless (gst_value_array_get_size (&value) ==
|
||||||
|
G_N_ELEMENTS (results[i]));
|
||||||
|
|
||||||
|
for (j = 0; j < G_N_ELEMENTS (results[i]); j++) {
|
||||||
|
const GValue *elem_value = gst_value_array_get_value (&value, j);
|
||||||
|
fail_unless (G_VALUE_TYPE (elem_value) == TEST_FLAGS_TYPE);
|
||||||
|
fail_unless_equals_int (g_value_get_flags (elem_value), results[i][j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_value_unset (&value);
|
||||||
|
g_free (str);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_param_spec_unref (pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_value_suite (void)
|
gst_value_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -3562,6 +3637,7 @@ gst_value_suite (void)
|
||||||
tcase_add_test (tc_chain, test_transform_array);
|
tcase_add_test (tc_chain, test_transform_array);
|
||||||
tcase_add_test (tc_chain, test_transform_list);
|
tcase_add_test (tc_chain, test_transform_list);
|
||||||
tcase_add_test (tc_chain, test_serialize_null_aray);
|
tcase_add_test (tc_chain, test_serialize_null_aray);
|
||||||
|
tcase_add_test (tc_chain, test_deserialize_with_pspec);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue