mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 13:06:23 +00:00
Add lots of code related to gst_structure_{to,from}_string
Original commit message from CVS: Add lots of code related to gst_structure_{to,from}_string
This commit is contained in:
parent
74a1002b9f
commit
408ca875b9
4 changed files with 350 additions and 22 deletions
|
@ -601,7 +601,7 @@ gst_structure_remove_all_fields(GstStructure *structure)
|
|||
* @fieldname: the name of the field
|
||||
*
|
||||
* Finds the field with the given name, and returns the type of the
|
||||
* value it contains. If the field is not found, G_TYPE_NONE is
|
||||
* value it contains. If the field is not found, G_TYPE_INVALID is
|
||||
* returned.
|
||||
*
|
||||
* Returns: the #GValue of the field
|
||||
|
@ -611,11 +611,11 @@ gst_structure_get_field_type(const GstStructure *structure, const gchar *fieldna
|
|||
{
|
||||
GstStructureField *field;
|
||||
|
||||
g_return_val_if_fail(structure != NULL, G_TYPE_NONE);
|
||||
g_return_val_if_fail(fieldname != NULL, G_TYPE_NONE);
|
||||
g_return_val_if_fail(structure != NULL, G_TYPE_INVALID);
|
||||
g_return_val_if_fail(fieldname != NULL, G_TYPE_INVALID);
|
||||
|
||||
field = gst_structure_get_field(structure, fieldname);
|
||||
if(field == NULL) return G_TYPE_NONE;
|
||||
if(field == NULL) return G_TYPE_INVALID;
|
||||
|
||||
return G_VALUE_TYPE(&field->value);
|
||||
}
|
||||
|
@ -865,6 +865,67 @@ gst_structure_get_string(const GstStructure *structure, const gchar *fieldname)
|
|||
return g_value_get_string(&field->value);
|
||||
}
|
||||
|
||||
typedef struct _GstStructureAbbreviation {
|
||||
char *type_name;
|
||||
GType type;
|
||||
} GstStructureAbbreviation;
|
||||
|
||||
static GstStructureAbbreviation _gst_structure_abbrs[] = {
|
||||
{ "int", G_TYPE_INT },
|
||||
{ "i", G_TYPE_INT },
|
||||
{ "float", G_TYPE_FLOAT },
|
||||
{ "f", G_TYPE_FLOAT },
|
||||
{ "double", G_TYPE_DOUBLE },
|
||||
{ "d", G_TYPE_DOUBLE },
|
||||
//{ "fourcc", GST_TYPE_FOURCC },
|
||||
{ "boolean", G_TYPE_BOOLEAN },
|
||||
{ "bool", G_TYPE_BOOLEAN },
|
||||
{ "b", G_TYPE_BOOLEAN },
|
||||
{ "string", G_TYPE_STRING },
|
||||
{ "str", G_TYPE_STRING },
|
||||
{ "s", G_TYPE_STRING }
|
||||
};
|
||||
|
||||
static GType _gst_structure_from_abbr(const char *type_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail(type_name != NULL, G_TYPE_INVALID);
|
||||
|
||||
for(i=0;i<G_N_ELEMENTS(_gst_structure_abbrs);i++){
|
||||
if(strcmp(type_name,_gst_structure_abbrs[i].type_name)==0){
|
||||
return _gst_structure_abbrs[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME shouldn't be a special case */
|
||||
if (strcmp (type_name,"fourcc") == 0 || strcmp (type_name, "4") == 0) {
|
||||
return GST_TYPE_FOURCC;
|
||||
}
|
||||
|
||||
return g_type_from_name (type_name);
|
||||
}
|
||||
|
||||
static const char *_gst_structure_to_abbr(GType type)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail(type != G_TYPE_INVALID, NULL);
|
||||
|
||||
for(i=0;i<G_N_ELEMENTS(_gst_structure_abbrs);i++){
|
||||
if(type == _gst_structure_abbrs[i].type){
|
||||
return _gst_structure_abbrs[i].type_name;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME shouldn't be a special case */
|
||||
if (type == GST_TYPE_FOURCC) {
|
||||
return "fourcc";
|
||||
}
|
||||
|
||||
return g_type_name(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_structure_to_string:
|
||||
* @structure: a #GstStructure
|
||||
|
@ -892,13 +953,234 @@ gst_structure_to_string(const GstStructure *structure)
|
|||
g_value_init(&s_val, G_TYPE_STRING);
|
||||
|
||||
g_value_transform(&field->value, &s_val);
|
||||
g_string_append_printf(s, ", %s:%s", g_quark_to_string(field->name),
|
||||
g_string_append_printf(s, ", %s:%s=%s", g_quark_to_string(field->name),
|
||||
_gst_structure_to_abbr(G_VALUE_TYPE(&field->value)),
|
||||
g_value_get_string(&s_val));
|
||||
g_value_unset(&s_val);
|
||||
}
|
||||
return g_string_free(s, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* r will still point to the string. if end == next, the string will not be
|
||||
* null-terminated. In all other cases it will be.
|
||||
* end = pointer to char behind end of string, next = pointer to start of
|
||||
* unread data.
|
||||
* THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
|
||||
*/
|
||||
static gboolean
|
||||
_gst_structure_parse_string (gchar *r, gchar **end, gchar **next)
|
||||
{
|
||||
gchar *w;
|
||||
gchar c = '\0';
|
||||
|
||||
w = r;
|
||||
if (*r == '\'' || *r == '\"') {
|
||||
c = *r;
|
||||
r++;
|
||||
}
|
||||
|
||||
for (;;r++) {
|
||||
if (*r == '\0') {
|
||||
if (c) {
|
||||
goto error;
|
||||
} else {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (*r == '\\') {
|
||||
r++;
|
||||
if (*r == '\0')
|
||||
goto error;
|
||||
*w++ = *r;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*r == c) {
|
||||
r++;
|
||||
if (*r == '\0')
|
||||
goto found;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!c) {
|
||||
if (g_ascii_isspace (*r))
|
||||
break;
|
||||
/* this needs to be escaped */
|
||||
if (*r == ',' || *r == ')' || *r == ']' || *r == ':' ||
|
||||
*r == ';' || *r == '(' || *r == '[')
|
||||
break;
|
||||
}
|
||||
*w++ = *r;
|
||||
}
|
||||
|
||||
found:
|
||||
while (g_ascii_isspace (*r)) r++;
|
||||
if (w != r)
|
||||
*w++ = '\0';
|
||||
*end = w;
|
||||
*next = r;
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_gst_structure_parse_field (gchar *str, gchar **after, GstStructureField *field)
|
||||
{
|
||||
/* NAME[:TYPE]=VALUE */
|
||||
gchar *name;
|
||||
gchar *type_name;
|
||||
gchar *s, *del;
|
||||
gchar *val;
|
||||
gchar *end;
|
||||
gboolean have_type = FALSE;
|
||||
GType type = G_TYPE_INVALID;
|
||||
int ret;
|
||||
|
||||
g_print("parsing: \"%s\"\n", str);
|
||||
name = s = str;
|
||||
while (g_ascii_isalnum (*s) || *s == '_' || *s == '-') s++;
|
||||
del = s;
|
||||
while (g_ascii_isspace (*s)) s++;
|
||||
if (!(*s == '=' || *s == ':')) return FALSE;
|
||||
if (*s == ':') have_type = TRUE;
|
||||
s++;
|
||||
while (g_ascii_isspace (*s)) s++;
|
||||
*del = '\0';
|
||||
|
||||
field->name = g_quark_from_string (name);
|
||||
|
||||
if (have_type) {
|
||||
while (g_ascii_isspace (*s)) s++;
|
||||
type_name = s;
|
||||
while (g_ascii_isalnum (*s) || *s == '_' || *s == '-') s++;
|
||||
del = s;
|
||||
while (g_ascii_isspace (*s)) s++;
|
||||
if (*s != '=') return FALSE;
|
||||
s++;
|
||||
while (g_ascii_isspace (*s)) s++;
|
||||
*del = '\0';
|
||||
|
||||
g_print("type name is \"%s\"\n",type_name);
|
||||
type = _gst_structure_from_abbr(type_name);
|
||||
g_print("type n is \"%s\"\n",g_type_name(type));
|
||||
|
||||
if (type == G_TYPE_INVALID) return FALSE;
|
||||
|
||||
} else {
|
||||
if (g_ascii_isdigit (*s)) {
|
||||
char *t = s;
|
||||
while (g_ascii_isdigit (*t)) t++;
|
||||
if (*t == '.'){
|
||||
type = G_TYPE_DOUBLE;
|
||||
} else {
|
||||
type = G_TYPE_INT;
|
||||
}
|
||||
} else if (g_ascii_isalpha (*s) || *s == '"' || *s == '\'') {
|
||||
type = G_TYPE_STRING;
|
||||
} else {
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_value_init(&field->value, type);
|
||||
|
||||
ret = FALSE;
|
||||
val = s;
|
||||
switch (type) {
|
||||
case G_TYPE_INT:
|
||||
{
|
||||
int x;
|
||||
x = strtol (val, &s, 0);
|
||||
if (val != s) {
|
||||
g_value_set_int (&field->value, x);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
{
|
||||
double x;
|
||||
x = g_ascii_strtod (val, &s);
|
||||
if (val != s) {
|
||||
g_value_set_float (&field->value, x);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
{
|
||||
double x;
|
||||
x = g_ascii_strtod (val, &s);
|
||||
if (val != s) {
|
||||
g_value_set_double (&field->value, x);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case G_TYPE_BOOLEAN:
|
||||
{
|
||||
int len;
|
||||
ret = _gst_structure_parse_string (val, &end, &s);
|
||||
len = end - val;
|
||||
if (ret) {
|
||||
if (strncmp (val, "true", len) == 0 ||
|
||||
strncmp (val, "yes", len) == 0 ||
|
||||
(len == 1 && (*val == 't' || *val == '1'))) {
|
||||
g_value_set_boolean (&field->value, TRUE);
|
||||
} else if (strncmp (val, "false", len) == 0 ||
|
||||
strncmp (val, "no", len) == 0 ||
|
||||
(len == 1 && (*val == 'f' || *val == '0'))) {
|
||||
g_value_set_boolean (&field->value, FALSE);
|
||||
} else {
|
||||
ret = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case G_TYPE_STRING:
|
||||
{
|
||||
ret = _gst_structure_parse_string (val, &end, &s);
|
||||
if (ret) {
|
||||
g_value_set_string_take_ownership (&field->value,
|
||||
g_strndup(val, end - val));
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* FIXME: make more general */
|
||||
if (type == GST_TYPE_FOURCC) {
|
||||
guint32 fourcc = 0;
|
||||
if (g_ascii_isdigit (*s)) {
|
||||
fourcc = strtoul (val, &s, 0);
|
||||
if (val != s) {
|
||||
ret = TRUE;
|
||||
}
|
||||
} else {
|
||||
ret = _gst_structure_parse_string (val, &end, &s);
|
||||
g_print("end - val = %d\n", end - val);
|
||||
if (end - val >= 4) {
|
||||
fourcc = GST_MAKE_FOURCC(val[0], val[1], val[2], val[3]);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
gst_value_set_fourcc (&field->value, fourcc);
|
||||
} else {
|
||||
g_critical("not handled");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*after = s;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_structure_from_string:
|
||||
* @structure: a #GstStructure
|
||||
|
@ -908,15 +1190,49 @@ gst_structure_to_string(const GstStructure *structure)
|
|||
* Returns: a new #GstStructure
|
||||
*/
|
||||
GstStructure *
|
||||
gst_structure_from_string (const gchar *string)
|
||||
gst_structure_from_string (const gchar *string, gchar **end)
|
||||
{
|
||||
/* FIXME */
|
||||
char *name;
|
||||
char *copy;
|
||||
char *w;
|
||||
char *r;
|
||||
char save;
|
||||
GstStructure *structure;
|
||||
GstStructureField field = { 0 };
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail(string != NULL, NULL);
|
||||
|
||||
g_assert_not_reached();
|
||||
copy = g_strdup(string);
|
||||
r = copy;
|
||||
|
||||
return NULL;
|
||||
name = r;
|
||||
res = _gst_structure_parse_string (r, &w, &r);
|
||||
if (!res) return NULL;
|
||||
|
||||
while (*r && g_ascii_isspace(*r)) r++;
|
||||
if(!*r) return NULL;
|
||||
if(*r != ';' && *r != ',') return NULL;
|
||||
if(*r == ',') r++;
|
||||
|
||||
save = *w;
|
||||
*w = 0;
|
||||
structure = gst_structure_empty_new(name);
|
||||
*w = save;
|
||||
|
||||
while (*r && g_ascii_isspace(*r)) r++;
|
||||
while (*r && (*r != ';')){
|
||||
res = _gst_structure_parse_field (r, &r, &field);
|
||||
g_print("returned %d \"%s\"\n", res, r);
|
||||
if (!res) {
|
||||
gst_structure_free (structure);
|
||||
return NULL;
|
||||
}
|
||||
gst_structure_set_field(structure, &field);
|
||||
}
|
||||
|
||||
if (end) *end = (char *)string + (r - copy);
|
||||
return structure;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -59,7 +59,7 @@ GstStructure *gst_structure_new_valist(const gchar *name,
|
|||
GstStructure *gst_structure_copy(GstStructure *structure);
|
||||
void gst_structure_free(GstStructure *structure);
|
||||
|
||||
const gchar *gst_structure_get_name(GstStructure *structure);
|
||||
G_CONST_RETURN gchar *gst_structure_get_name(GstStructure *structure);
|
||||
void gst_structure_set_name(GstStructure *structure, const gchar *name);
|
||||
void gst_structure_set_field_copy (GstStructure *structure,
|
||||
const GstStructureField *field);
|
||||
|
@ -73,7 +73,7 @@ void gst_structure_set_value(GstStructure *structure, const gchar *field,
|
|||
void gst_structure_set(GstStructure *structure, const gchar *field, ...);
|
||||
void gst_structure_set_valist(GstStructure *structure, const gchar *field,
|
||||
va_list varargs);
|
||||
const GValue *gst_structure_get_value(const GstStructure *structure, const gchar *field);
|
||||
G_CONST_RETURN GValue *gst_structure_get_value(const GstStructure *structure, const gchar *field);
|
||||
GstStructureField *gst_structure_get_field(const GstStructure *structure,
|
||||
const gchar *fieldname);
|
||||
GstStructureField *gst_structure_id_get_field(const GstStructure *structure,
|
||||
|
@ -100,11 +100,11 @@ gboolean gst_structure_get_fourcc(const GstStructure *structure, const gchar *fi
|
|||
guint32 *value);
|
||||
gboolean gst_structure_get_double(const GstStructure *structure, const gchar *field,
|
||||
gdouble *value);
|
||||
const gchar *gst_structure_get_string(const GstStructure *structure,
|
||||
G_CONST_RETURN gchar *gst_structure_get_string(const GstStructure *structure,
|
||||
const gchar *field);
|
||||
|
||||
gchar * gst_structure_to_string(const GstStructure *structure);
|
||||
GstStructure * gst_structure_from_string (const gchar *string);
|
||||
GstStructure * gst_structure_from_string (const gchar *string, gchar **end);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -48,7 +48,7 @@ struct _GstValueIntersectInfo {
|
|||
GType gst_type_fourcc;
|
||||
GType gst_type_int_range;
|
||||
GType gst_type_double_range;
|
||||
GType gst_type_value_list;
|
||||
GType gst_type_list;
|
||||
|
||||
GArray *gst_value_compare_funcs;
|
||||
GArray *gst_value_union_funcs;
|
||||
|
@ -178,7 +178,7 @@ gst_value_union_lists (GValue *dest, const GValue *value1, const GValue *value2)
|
|||
|
||||
value1_length = (GST_VALUE_HOLDS_LIST (value1) ? gst_value_list_get_size (value1) : 1);
|
||||
value2_length = (GST_VALUE_HOLDS_LIST (value2) ? gst_value_list_get_size (value2) : 1);
|
||||
g_value_init (dest, GST_TYPE_VALUE_LIST);
|
||||
g_value_init (dest, GST_TYPE_LIST);
|
||||
array = (GArray *) dest->data[0].v_pointer;
|
||||
g_array_set_size (array, value1_length + value2_length);
|
||||
|
||||
|
@ -415,8 +415,17 @@ static void
|
|||
gst_value_transform_fourcc_string (const GValue *src_value,
|
||||
GValue *dest_value)
|
||||
{
|
||||
dest_value->data[0].v_pointer = g_strdup_printf(GST_FOURCC_FORMAT,
|
||||
GST_FOURCC_ARGS(src_value->data[0].v_long));
|
||||
guint32 fourcc = src_value->data[0].v_long;
|
||||
|
||||
if (g_ascii_isprint ((fourcc>>0) & 0xff) &&
|
||||
g_ascii_isprint ((fourcc>>8) & 0xff) &&
|
||||
g_ascii_isprint ((fourcc>>16) & 0xff) &&
|
||||
g_ascii_isprint ((fourcc>>24) & 0xff)){
|
||||
dest_value->data[0].v_pointer = g_strdup_printf(
|
||||
"\"" GST_FOURCC_FORMAT "\"", GST_FOURCC_ARGS(fourcc));
|
||||
} else {
|
||||
dest_value->data[0].v_pointer = g_strdup_printf("0x%08x", fourcc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -730,7 +739,7 @@ _gst_value_initialize (void)
|
|||
gst_value_lcopy_list
|
||||
};
|
||||
info.value_table = &value_table;
|
||||
gst_type_value_list = g_type_register_static (G_TYPE_BOXED, "GstValueList", &info, 0);
|
||||
gst_type_list = g_type_register_static (G_TYPE_BOXED, "GstValueList", &info, 0);
|
||||
}
|
||||
|
||||
g_value_register_transform_func (GST_TYPE_FOURCC, G_TYPE_STRING,
|
||||
|
|
|
@ -41,14 +41,16 @@ typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1,
|
|||
((gchar) (((fourcc)>>16)&0xff)), \
|
||||
((gchar) (((fourcc)>>24)&0xff))
|
||||
|
||||
#define GST_VALUE_HOLDS_FOURCC(x) (G_VALUE_TYPE(x) == gst_type_fourcc)
|
||||
#define GST_VALUE_HOLDS_INT_RANGE(x) (G_VALUE_TYPE(x) == gst_type_int_range)
|
||||
#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_TYPE(x) == gst_type_double_range)
|
||||
#define GST_VALUE_HOLDS_CAPS(x) TRUE /* FIXME */
|
||||
#define GST_VALUE_HOLDS_FOURCC(x) (G_VALUE_HOLDS(x, gst_type_fourcc))
|
||||
#define GST_VALUE_HOLDS_INT_RANGE(x) (G_VALUE_HOLDS(x, gst_type_int_range))
|
||||
#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_HOLDS(x, gst_type_double_range))
|
||||
#define GST_VALUE_HOLDS_LIST(x) (G_VALUE_HOLDS(x, gst_type_list))
|
||||
#define GST_VALUE_HOLDS_CAPS(x) TRUE /* FIXME */
|
||||
|
||||
#define GST_TYPE_FOURCC gst_type_fourcc
|
||||
#define GST_TYPE_INT_RANGE gst_type_int_range
|
||||
#define GST_TYPE_DOUBLE_RANGE gst_type_double_range
|
||||
#define GST_TYPE_LIST gst_type_list
|
||||
|
||||
#define GST_VALUE_LESS_THAN (-1)
|
||||
#define GST_VALUE_EQUAL 0
|
||||
|
@ -58,6 +60,7 @@ typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1,
|
|||
extern GType gst_type_fourcc;
|
||||
extern GType gst_type_int_range;
|
||||
extern GType gst_type_double_range;
|
||||
extern GType gst_type_list;
|
||||
|
||||
void gst_value_set_fourcc (GValue *value, guint32 fourcc);
|
||||
guint32 gst_value_get_fourcc (const GValue *value);
|
||||
|
|
Loading…
Reference in a new issue