mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-12 15:36:17 +01:00
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org> * girepository/ginfo.c (g_info_from_entry), (g_type_info_new), (g_type_info_is_pointer), (g_type_info_get_tag), (g_type_info_get_param_type), (g_type_info_get_interface), (g_type_info_get_array_length), (g_type_info_is_zero_terminated), (g_type_info_get_n_error_domains), (g_type_info_get_error_domain), (g_error_domain_info_get_codes), (g_enum_info_get_value), (g_object_info_get_interface), (g_object_info_get_field), (g_interface_info_get_prerequisite), (g_signal_info_get_class_closure), (g_constant_info_get_value): * girepository/ginvoke.c (get_ffi_type): * girepository/girepository.h: * girepository/gmetadata.c (g_metadata_get_dir_entry), (g_metadata_check_sanity), (validate_header), (validate_array_type_blob), (validate_iface_type_blob), (validate_param_type_blob), (validate_error_type_blob), (validate_type_blob), (validate_constant_blob), (validate_struct_blob), (validate_enum_blob): * girepository/gmetadata.h: * tests/Makefile.am: * tests/invoke/Makefile.am: * tests/invoke/invoke.c (main): * tests/roundtrips.sh: * tools/Makefile.am: * tools/compiler.c (format_output), (write_out_metadata), (main): * tools/generate.c (write_type_name), (write_type_info), (write_constant_value), (write_enum_info), (load_metadata), (main): * tools/gidlcompilercontext.c: * tools/gidlcompilercontext.h: * tools/gidlcompilerentrynode.c: * tools/gidlcompilerentrynode.h: * tools/gidlcompilertypenode.c: * tools/gidlcompilertypenode.h: * tools/gidlmodule.c (g_idl_module_build_metadata): * tools/gidlmodule.h: * tools/gidlnode.c (init_stats), (dump_stats), (g_idl_node_get_size), (g_idl_node_get_full_size), (g_idl_node_cmp), (g_idl_node_can_have_member), (g_idl_node_add_member), (g_idl_node_param_direction_string), (parse_int_value), (parse_uint_value), (parse_float_value), (parse_boolean_value), (find_entry_node), (find_entry), (serialize_type), (g_idl_node_build_metadata), (write_string): * tools/gidlnode.h: * tools/gidlparser.c (parse_type_internal): * tools/quote-file.sh: Revert revisions 157,149-148,136-129 and 120. Move back to using g-idl-generate to generate the metadata and avoids dependency on a c compiler. svn path=/trunk/; revision=214
This commit is contained in:
parent
e8fa684588
commit
4ff71171a9
335
ginfo.c
335
ginfo.c
@ -161,35 +161,29 @@ g_info_from_entry (GMetadata *metadata,
|
||||
{
|
||||
GIBaseInfo *result;
|
||||
DirEntry *entry = g_metadata_get_dir_entry (metadata, index);
|
||||
|
||||
|
||||
if (entry->local)
|
||||
result = g_info_new (entry->blob_type, NULL, metadata, entry->offset);
|
||||
else
|
||||
else
|
||||
{
|
||||
const gchar *namespace = NULL;
|
||||
const gchar *name = NULL;
|
||||
const gchar *namespace = g_metadata_get_string (metadata, entry->offset);
|
||||
const gchar *name = g_metadata_get_string (metadata, entry->name);
|
||||
|
||||
GIRepository *repository = g_irepository_get_default ();
|
||||
|
||||
namespace = g_metadata_get_string (metadata, entry->offset);
|
||||
name = g_metadata_get_string (metadata, entry->name);
|
||||
|
||||
|
||||
result = g_irepository_find_by_name (repository, namespace, name);
|
||||
if (result == NULL)
|
||||
{
|
||||
GIUnresolvedInfo *unresolved;
|
||||
|
||||
unresolved = g_new0 (GIUnresolvedInfo, 1);
|
||||
|
||||
unresolved->type = GI_INFO_TYPE_UNRESOLVED;
|
||||
unresolved->ref_count = 1;
|
||||
unresolved->container = NULL;
|
||||
unresolved->name = name;
|
||||
if (entry->offset)
|
||||
{
|
||||
unresolved->namespace = namespace;
|
||||
}
|
||||
else
|
||||
{
|
||||
unresolved->namespace = NULL;
|
||||
}
|
||||
unresolved->namespace = namespace;
|
||||
|
||||
result = (GIBaseInfo*)unresolved;
|
||||
}
|
||||
}
|
||||
@ -534,27 +528,15 @@ signature_offset (GICallableInfo *info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Type blobs when created always point to a SimpleTypeBlob,
|
||||
* If the type tag means that the type needs to be complex then
|
||||
* the SimpleTypeBlob has an offset which points to the real type.
|
||||
*/
|
||||
GITypeInfo *
|
||||
g_type_info_new (GIBaseInfo *container,
|
||||
GMetadata *metadata,
|
||||
guint32 offset)
|
||||
{
|
||||
TypeHeader *header;
|
||||
SimpleTypeBlob *simple;
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset];
|
||||
|
||||
header = (TypeHeader *)&metadata->data[offset];
|
||||
if (TYPE_IS_COMPLEX (header->tag))
|
||||
{
|
||||
simple = (SimpleTypeBlob *)&metadata->data[offset];
|
||||
offset = simple->offset;
|
||||
}
|
||||
|
||||
return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container,
|
||||
metadata, offset);
|
||||
return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata,
|
||||
type->reserved == 0 ? offset : type->offset);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -739,18 +721,32 @@ gboolean
|
||||
g_type_info_is_pointer (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
|
||||
return header->pointer != 0;
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved == 0)
|
||||
return type->pointer;
|
||||
else
|
||||
{
|
||||
InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return iface->pointer;
|
||||
}
|
||||
}
|
||||
|
||||
GITypeTag
|
||||
g_type_info_get_tag (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return header->tag;
|
||||
if (type->reserved == 0)
|
||||
return type->tag;
|
||||
else
|
||||
{
|
||||
InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return iface->tag;
|
||||
}
|
||||
}
|
||||
|
||||
GITypeInfo *
|
||||
@ -758,39 +754,42 @@ g_type_info_get_param_type (GITypeInfo *info,
|
||||
gint n)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
switch (header->tag)
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
case TYPE_TAG_ARRAY:
|
||||
case TYPE_TAG_LIST:
|
||||
case TYPE_TAG_SLIST:
|
||||
case TYPE_TAG_HASH:
|
||||
{
|
||||
guint32 offset = base->offset + sizeof(ParamTypeBlob) +
|
||||
(sizeof(SimpleTypeBlob)* n);
|
||||
return g_type_info_new (base, base->metadata, offset);
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
g_assert_not_reached ();
|
||||
switch (param->tag)
|
||||
{
|
||||
case GI_TYPE_TAG_ARRAY:
|
||||
case GI_TYPE_TAG_GLIST:
|
||||
case GI_TYPE_TAG_GSLIST:
|
||||
case GI_TYPE_TAG_GHASH:
|
||||
return g_type_info_new (base, base->metadata, base->offset + 4 + 4 * n);
|
||||
break;
|
||||
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GIBaseInfo *
|
||||
g_type_info_get_interface (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (header->tag == TYPE_TAG_SYMBOL)
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset];
|
||||
return g_info_from_entry (base->metadata, simple->offset);
|
||||
InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (blob->tag == GI_TYPE_TAG_INTERFACE)
|
||||
return g_info_from_entry (base->metadata, blob->interface);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -798,13 +797,19 @@ gint
|
||||
g_type_info_get_array_length (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (header->tag == TYPE_TAG_ARRAY && array->has_length)
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
return array->length;
|
||||
ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (blob->tag == GI_TYPE_TAG_ARRAY)
|
||||
{
|
||||
if (blob->has_length)
|
||||
return blob->length;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -812,24 +817,33 @@ gboolean
|
||||
g_type_info_is_zero_terminated (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset];
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return (header->tag == TYPE_TAG_ARRAY &&
|
||||
array->zero_terminated);
|
||||
if (blob->tag == GI_TYPE_TAG_ARRAY)
|
||||
return blob->zero_terminated;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
g_type_info_get_n_error_domains (GITypeInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (header->tag == TYPE_TAG_ERROR)
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
return error->n_domains;
|
||||
ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (blob->tag == GI_TYPE_TAG_ERROR)
|
||||
return blob->n_domains;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -838,16 +852,17 @@ g_type_info_get_error_domain (GITypeInfo *info,
|
||||
gint n)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
|
||||
ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
|
||||
guint16 *domain;
|
||||
|
||||
if (header->tag == TYPE_TAG_ERROR)
|
||||
SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (type->reserved != 0)
|
||||
{
|
||||
domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]);
|
||||
return (GIErrorDomainInfo *) g_info_from_entry (base->metadata,
|
||||
domain[n]);
|
||||
ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (blob->tag == GI_TYPE_TAG_ERROR)
|
||||
return (GIErrorDomainInfo *) g_info_from_entry (base->metadata,
|
||||
blob->domains[n]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -866,13 +881,9 @@ GIInterfaceInfo *
|
||||
g_error_domain_info_get_codes (GIErrorDomainInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
/* FIXME need to check if blob really is an enum */
|
||||
return (GIInterfaceInfo *) g_info_new (BLOB_TYPE_ENUM,
|
||||
NULL,
|
||||
base->metadata,
|
||||
blob->error_codes);
|
||||
ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes);
|
||||
}
|
||||
|
||||
|
||||
@ -999,8 +1010,8 @@ g_struct_info_get_method (GIStructInfo *info,
|
||||
gint offset;
|
||||
|
||||
offset = base->offset + header->struct_blob_size
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
+ n * header->function_blob_size;
|
||||
+ blob->n_fields * header->field_blob_size
|
||||
+ n * header->function_blob_size;
|
||||
return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base,
|
||||
base->metadata, offset);
|
||||
}
|
||||
@ -1054,15 +1065,6 @@ g_enum_info_get_n_values (GIEnumInfo *info)
|
||||
return blob->n_values;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_enum_info_is_registered (GIEnumInfo *info)
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
return !blob->unregistered;
|
||||
}
|
||||
|
||||
GIValueInfo *
|
||||
g_enum_info_get_value (GIEnumInfo *info,
|
||||
gint n)
|
||||
@ -1073,8 +1075,7 @@ g_enum_info_get_value (GIEnumInfo *info,
|
||||
|
||||
offset = base->offset + header->enum_blob_size
|
||||
+ n * header->value_blob_size;
|
||||
return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base,
|
||||
base->metadata, offset);
|
||||
return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->metadata, offset);
|
||||
}
|
||||
|
||||
/* GIObjectInfo functions */
|
||||
@ -1123,11 +1124,8 @@ g_object_info_get_interface (GIObjectInfo *info,
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset];
|
||||
guint16 *interface;
|
||||
|
||||
interface = (guint16 *)&base->metadata->data[base->offset + sizeof(ObjectBlob)];
|
||||
|
||||
return (GIInterfaceInfo *) g_info_from_entry (base->metadata, interface[n]);
|
||||
return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]);
|
||||
}
|
||||
|
||||
gint
|
||||
@ -1152,8 +1150,7 @@ g_object_info_get_field (GIObjectInfo *info,
|
||||
+ (blob->n_interfaces + blob->n_interfaces % 2) * 2
|
||||
+ n * header->field_blob_size;
|
||||
|
||||
return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base,
|
||||
base->metadata, offset);
|
||||
return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, offset);
|
||||
}
|
||||
|
||||
gint
|
||||
@ -1335,11 +1332,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info,
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset];
|
||||
guint16 *prerequisite;
|
||||
|
||||
prerequisite = (guint16 *)&base->metadata->data[base->offset + sizeof(InterfaceBlob)];
|
||||
|
||||
return g_info_from_entry (base->metadata, prerequisite[n]);
|
||||
return g_info_from_entry (base->metadata, blob->prerequisites[n]);
|
||||
}
|
||||
|
||||
|
||||
@ -1578,8 +1572,7 @@ g_signal_info_get_class_closure (GISignalInfo *info)
|
||||
SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset];
|
||||
|
||||
if (blob->has_class_closure)
|
||||
return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container,
|
||||
blob->class_closure);
|
||||
return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1653,67 +1646,63 @@ g_constant_info_get_value (GIConstantInfo *info,
|
||||
{
|
||||
GIBaseInfo *base = (GIBaseInfo *)info;
|
||||
ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset];
|
||||
TypeHeader *header = (TypeHeader*) &blob->type;
|
||||
|
||||
if (TYPE_IS_SIMPLE (header->tag))
|
||||
/* FIXME non-basic types ? */
|
||||
if (blob->type.reserved == 0)
|
||||
{
|
||||
switch (header->tag)
|
||||
{
|
||||
case GI_TYPE_TAG_BOOLEAN:
|
||||
value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT8:
|
||||
value->v_int8 = *(gint8*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT8:
|
||||
value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT16:
|
||||
value->v_int16 = *(gint16*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT16:
|
||||
value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT32:
|
||||
value->v_int32 = *(gint32*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT32:
|
||||
value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT64:
|
||||
value->v_int64 = *(gint64*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT64:
|
||||
value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_FLOAT:
|
||||
value->v_float = *(gfloat*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_DOUBLE:
|
||||
value->v_double = *(gdouble*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT:
|
||||
value->v_int = *(gint*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT:
|
||||
value->v_uint = *(guint*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_LONG:
|
||||
value->v_long = *(glong*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_ULONG:
|
||||
value->v_ulong = *(gulong*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (header->tag)
|
||||
{
|
||||
case GI_TYPE_TAG_SYMBOL:
|
||||
value->v_string = *(gchar**)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
}
|
||||
if (blob->type.pointer)
|
||||
value->v_pointer = g_memdup (&base->metadata->data[blob->offset], blob->size);
|
||||
else
|
||||
{
|
||||
switch (blob->type.tag)
|
||||
{
|
||||
case GI_TYPE_TAG_BOOLEAN:
|
||||
value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT8:
|
||||
value->v_int8 = *(gint8*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT8:
|
||||
value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT16:
|
||||
value->v_int16 = *(gint16*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT16:
|
||||
value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT32:
|
||||
value->v_int32 = *(gint32*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT32:
|
||||
value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT64:
|
||||
value->v_int64 = *(gint64*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT64:
|
||||
value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_FLOAT:
|
||||
value->v_float = *(gfloat*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_DOUBLE:
|
||||
value->v_double = *(gdouble*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_INT:
|
||||
value->v_int = *(gint*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT:
|
||||
value->v_uint = *(guint*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_LONG:
|
||||
value->v_long = *(glong*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
case GI_TYPE_TAG_ULONG:
|
||||
value->v_ulong = *(gulong*)&base->metadata->data[blob->offset];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blob->size;
|
||||
@ -1814,4 +1803,4 @@ g_union_info_get_discriminator (GIUnionInfo *info,
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -100,8 +100,8 @@ get_ffi_type (GITypeInfo *info)
|
||||
break;
|
||||
case GI_TYPE_TAG_UTF8:
|
||||
case GI_TYPE_TAG_FILENAME:
|
||||
case GI_TYPE_TAG_SYMBOL:
|
||||
case GI_TYPE_TAG_ARRAY:
|
||||
case GI_TYPE_TAG_INTERFACE:
|
||||
case GI_TYPE_TAG_GLIST:
|
||||
case GI_TYPE_TAG_GSLIST:
|
||||
case GI_TYPE_TAG_GHASH:
|
||||
|
@ -277,8 +277,8 @@ typedef enum {
|
||||
GI_TYPE_TAG_DOUBLE = 17,
|
||||
GI_TYPE_TAG_UTF8 = 18,
|
||||
GI_TYPE_TAG_FILENAME = 19,
|
||||
GI_TYPE_TAG_SYMBOL = 20,
|
||||
GI_TYPE_TAG_ARRAY = 21,
|
||||
GI_TYPE_TAG_ARRAY = 20,
|
||||
GI_TYPE_TAG_INTERFACE = 21,
|
||||
GI_TYPE_TAG_GLIST = 22,
|
||||
GI_TYPE_TAG_GSLIST = 23,
|
||||
GI_TYPE_TAG_GHASH = 24,
|
||||
@ -355,7 +355,6 @@ const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInf
|
||||
/* GIEnumInfo */
|
||||
|
||||
gint g_enum_info_get_n_values (GIEnumInfo *info);
|
||||
gboolean g_enum_info_get_is_registered (GIEnumInfo *info);
|
||||
GIValueInfo * g_enum_info_get_value (GIEnumInfo *info,
|
||||
gint n);
|
||||
|
||||
|
190
gmetadata.c
190
gmetadata.c
@ -30,11 +30,6 @@
|
||||
#define ALIGN_VALUE(this, boundary) \
|
||||
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
|
||||
|
||||
static gboolean
|
||||
validate_blob (GMetadata *metadata,
|
||||
guint32 offset,
|
||||
GError **error);
|
||||
|
||||
|
||||
DirEntry *
|
||||
g_metadata_get_dir_entry (GMetadata *metadata,
|
||||
@ -42,9 +37,41 @@ g_metadata_get_dir_entry (GMetadata *metadata,
|
||||
{
|
||||
Header *header = (Header *)metadata->data;
|
||||
|
||||
return (DirEntry *)&metadata->data[header->directory + ((index - 1) * header->entry_blob_size)];
|
||||
return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size];
|
||||
}
|
||||
|
||||
void
|
||||
g_metadata_check_sanity (void)
|
||||
{
|
||||
/* Check that struct layout is as we expect */
|
||||
g_assert (sizeof (Header) == 100);
|
||||
g_assert (sizeof (DirEntry) == 12);
|
||||
g_assert (sizeof (SimpleTypeBlob) == 4);
|
||||
g_assert (sizeof (ArgBlob) == 12);
|
||||
g_assert (sizeof (SignatureBlob) == 8);
|
||||
g_assert (sizeof (CommonBlob) == 8);
|
||||
g_assert (sizeof (FunctionBlob) == 16);
|
||||
g_assert (sizeof (InterfaceTypeBlob) == 4);
|
||||
g_assert (sizeof (ArrayTypeBlob) == 8);
|
||||
g_assert (sizeof (ParamTypeBlob) == 4);
|
||||
g_assert (sizeof (ErrorTypeBlob) == 4);
|
||||
g_assert (sizeof (ErrorDomainBlob) == 16);
|
||||
g_assert (sizeof (ValueBlob) == 12);
|
||||
g_assert (sizeof (FieldBlob) == 12);
|
||||
g_assert (sizeof (RegisteredTypeBlob) == 16);
|
||||
g_assert (sizeof (StructBlob) == 20);
|
||||
g_assert (sizeof (EnumBlob) == 20);
|
||||
g_assert (sizeof (PropertyBlob) == 12);
|
||||
g_assert (sizeof (SignalBlob) == 12);
|
||||
g_assert (sizeof (VFuncBlob) == 16);
|
||||
g_assert (sizeof (ObjectBlob) == 32);
|
||||
g_assert (sizeof (InterfaceBlob) == 28);
|
||||
g_assert (sizeof (ConstantBlob) == 20);
|
||||
g_assert (sizeof (AnnotationBlob) == 12);
|
||||
g_assert (sizeof (UnionBlob) == 28);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
is_aligned (guint32 offset)
|
||||
{
|
||||
@ -124,6 +151,32 @@ validate_header (GMetadata *metadata,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (header->entry_blob_size != 12 ||
|
||||
header->function_blob_size != 16 ||
|
||||
header->callback_blob_size != 12 ||
|
||||
header->signal_blob_size != 12 ||
|
||||
header->vfunc_blob_size != 16 ||
|
||||
header->arg_blob_size != 12 ||
|
||||
header->property_blob_size != 12 ||
|
||||
header->field_blob_size != 12 ||
|
||||
header->value_blob_size != 12 ||
|
||||
header->constant_blob_size != 20 ||
|
||||
header->error_domain_blob_size != 16 ||
|
||||
header->annotation_blob_size != 12 ||
|
||||
header->signature_blob_size != 8 ||
|
||||
header->enum_blob_size != 20 ||
|
||||
header->struct_blob_size != 20 ||
|
||||
header->object_blob_size != 32 ||
|
||||
header->interface_blob_size != 28 ||
|
||||
header->union_blob_size != 28)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_HEADER,
|
||||
"Blob size mismatch");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!is_aligned (header->directory))
|
||||
{
|
||||
g_set_error (error,
|
||||
@ -176,16 +229,17 @@ validate_array_type_blob (GMetadata *metadata,
|
||||
gboolean return_type,
|
||||
GError **error)
|
||||
{
|
||||
ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset];
|
||||
TypeHeader *header = (TypeHeader *)&metadata->data[offset];
|
||||
ArrayTypeBlob *blob;
|
||||
|
||||
if (!header->pointer)
|
||||
blob = (ArrayTypeBlob*)&metadata->data[offset];
|
||||
|
||||
if (!blob->pointer)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Pointer type exected for tag %d", header->tag);
|
||||
return FALSE;
|
||||
"Pointer type exected for tag %d", blob->tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME validate length */
|
||||
@ -198,6 +252,32 @@ validate_array_type_blob (GMetadata *metadata,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_iface_type_blob (GMetadata *metadata,
|
||||
guint32 offset,
|
||||
guint32 signature_offset,
|
||||
gboolean return_type,
|
||||
GError **error)
|
||||
{
|
||||
InterfaceTypeBlob *blob;
|
||||
Header *header;
|
||||
|
||||
header = (Header *)metadata->data;
|
||||
|
||||
blob = (InterfaceTypeBlob*)&metadata->data[offset];
|
||||
|
||||
if (blob->interface == 0 || blob->interface > header->n_entries)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Invalid directory index %d", blob->interface);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_param_type_blob (GMetadata *metadata,
|
||||
guint32 offset,
|
||||
@ -206,17 +286,17 @@ validate_param_type_blob (GMetadata *metadata,
|
||||
gint n_params,
|
||||
GError **error)
|
||||
{
|
||||
ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset];
|
||||
TypeHeader *header = (TypeHeader *)&metadata->data[offset];
|
||||
ParamTypeBlob *blob;
|
||||
gint i;
|
||||
|
||||
blob = (ParamTypeBlob*)&metadata->data[offset];
|
||||
|
||||
if (!header->pointer)
|
||||
if (!blob->pointer)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Pointer type exected for tag %d", header->tag);
|
||||
"Pointer type exected for tag %d", blob->tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -249,39 +329,35 @@ validate_error_type_blob (GMetadata *metadata,
|
||||
GError **error)
|
||||
{
|
||||
ErrorTypeBlob *blob;
|
||||
TypeHeader *type_header;
|
||||
Header *header;
|
||||
gint i;
|
||||
DirEntry *entry;
|
||||
guint16 *domain;
|
||||
|
||||
blob = (ErrorTypeBlob*)&metadata->data[offset];
|
||||
type_header = (TypeHeader*)&metadata->data[offset];
|
||||
|
||||
header = (Header *)metadata->data;
|
||||
|
||||
if (!type_header->pointer)
|
||||
if (!blob->pointer)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Pointer type exected for tag %d", type_header->tag);
|
||||
return FALSE;
|
||||
"Pointer type exected for tag %d", blob->tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)];
|
||||
for (i = 0; i < blob->n_domains; i++, domain++)
|
||||
for (i = 0; i < blob->n_domains; i++)
|
||||
{
|
||||
if (*domain == 0 || *domain > header->n_entries)
|
||||
if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Invalid directory index %d", *domain);
|
||||
"Invalid directory index %d", blob->domains[i]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
entry = g_metadata_get_dir_entry (metadata, *domain);
|
||||
entry = g_metadata_get_dir_entry (metadata, blob->domains[i]);
|
||||
|
||||
if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN &&
|
||||
(entry->local || entry->blob_type != BLOB_TYPE_INVALID))
|
||||
@ -305,14 +381,14 @@ validate_type_blob (GMetadata *metadata,
|
||||
GError **error)
|
||||
{
|
||||
SimpleTypeBlob *simple;
|
||||
TypeHeader *header;
|
||||
|
||||
InterfaceTypeBlob *iface;
|
||||
|
||||
simple = (SimpleTypeBlob *)&metadata->data[offset];
|
||||
header = (TypeHeader *)&metadata->data[offset];
|
||||
|
||||
if (TYPE_IS_SIMPLE(header->tag))
|
||||
if (simple->reserved == 0 &&
|
||||
simple->reserved2 == 0)
|
||||
{
|
||||
if (header->tag >= TYPE_TAG_ARRAY)
|
||||
if (simple->tag >= TYPE_TAG_ARRAY)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
@ -321,29 +397,31 @@ validate_type_blob (GMetadata *metadata,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (header->tag >= TYPE_TAG_UTF8 &&
|
||||
!header->pointer)
|
||||
if (simple->tag >= TYPE_TAG_UTF8 &&
|
||||
!simple->pointer)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Pointer type exected for tag %d", header->tag);
|
||||
return FALSE;
|
||||
"Pointer type exected for tag %d", simple->tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (header->tag)
|
||||
iface = (InterfaceTypeBlob*)&metadata->data[simple->offset];
|
||||
|
||||
switch (iface->tag)
|
||||
{
|
||||
case TYPE_TAG_ARRAY:
|
||||
if (!validate_array_type_blob (metadata, simple->offset,
|
||||
signature_offset, return_type, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case TYPE_TAG_SYMBOL:
|
||||
if (!validate_blob (metadata, simple->offset,
|
||||
error))
|
||||
case TYPE_TAG_INTERFACE:
|
||||
if (!validate_iface_type_blob (metadata, simple->offset,
|
||||
signature_offset, return_type, error))
|
||||
return FALSE;
|
||||
break;
|
||||
case TYPE_TAG_LIST:
|
||||
@ -608,7 +686,6 @@ validate_constant_blob (GMetadata *metadata,
|
||||
0, 0
|
||||
};
|
||||
ConstantBlob *blob;
|
||||
TypeHeader *header;
|
||||
SimpleTypeBlob *type;
|
||||
|
||||
if (metadata->len < offset + sizeof (ConstantBlob))
|
||||
@ -652,12 +729,11 @@ validate_constant_blob (GMetadata *metadata,
|
||||
"Misaligned constant value");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
|
||||
header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
|
||||
if (TYPE_IS_SIMPLE(header->tag))
|
||||
if (type->reserved == 0)
|
||||
{
|
||||
if (header->tag == 0)
|
||||
if (type->tag == 0)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
@ -666,8 +742,8 @@ validate_constant_blob (GMetadata *metadata,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (value_size[header->tag] != 0 &&
|
||||
blob->size != value_size[header->tag])
|
||||
if (value_size[type->tag] != 0 &&
|
||||
blob->size != value_size[type->tag])
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
@ -988,6 +1064,17 @@ validate_struct_blob (GMetadata *metadata,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blob->gtype_name || blob->gtype_init)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Gtype data in struct");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata->len < offset + sizeof (StructBlob) +
|
||||
blob->n_fields * sizeof (FieldBlob) +
|
||||
@ -1073,6 +1160,17 @@ validate_enum_blob (GMetadata *metadata,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blob->gtype_name || blob->gtype_init)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_METADATA_ERROR,
|
||||
G_METADATA_ERROR_INVALID_BLOB,
|
||||
"Gtype data in unregistered enum");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_name (metadata->data, blob->name))
|
||||
{
|
||||
|
79
gmetadata.h
79
gmetadata.h
@ -28,7 +28,6 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032"
|
||||
#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032"
|
||||
|
||||
enum
|
||||
{
|
||||
@ -96,6 +95,10 @@ typedef struct
|
||||
guint32 offset;
|
||||
} DirEntry;
|
||||
|
||||
|
||||
#define TYPE_POINTER_MASK 1 << 7
|
||||
#define TYPE_TAG_MASK 63
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TYPE_TAG_VOID = 0,
|
||||
@ -118,34 +121,28 @@ typedef enum
|
||||
TYPE_TAG_DOUBLE = 17,
|
||||
TYPE_TAG_UTF8 = 18,
|
||||
TYPE_TAG_FILENAME = 19,
|
||||
TYPE_TAG_SYMBOL = 20,
|
||||
TYPE_TAG_ARRAY = 21,
|
||||
TYPE_TAG_ARRAY = 20,
|
||||
TYPE_TAG_INTERFACE = 21,
|
||||
TYPE_TAG_LIST = 22,
|
||||
TYPE_TAG_SLIST = 23,
|
||||
TYPE_TAG_HASH = 24,
|
||||
TYPE_TAG_ERROR = 25
|
||||
} TypeTag;
|
||||
|
||||
typedef struct
|
||||
typedef union
|
||||
{
|
||||
guint pointer :1;
|
||||
guint reserved :2;
|
||||
guint tag :5;
|
||||
} TypeHeader;
|
||||
|
||||
#define TYPE_IS_SIMPLE(tAG) (tAG < TYPE_TAG_SYMBOL ? TRUE : FALSE)
|
||||
|
||||
#define TYPE_IS_SYMBOL(tAG) (tAG == TYPE_TAG_SYMBOL ? TRUE : FALSE)
|
||||
|
||||
#define TYPE_IS_COMPLEX(tAG) (tAG > TYPE_TAG_SYMBOL ? TRUE : FALSE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TypeHeader header;
|
||||
|
||||
struct
|
||||
{
|
||||
guint reserved : 8;
|
||||
guint reserved2 :16;
|
||||
guint pointer : 1;
|
||||
guint reserved3 : 2;
|
||||
guint tag : 5;
|
||||
};
|
||||
guint32 offset;
|
||||
} SimpleTypeBlob;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint32 name;
|
||||
@ -174,9 +171,7 @@ typedef struct
|
||||
|
||||
guint16 n_arguments;
|
||||
|
||||
#if 0
|
||||
ArgBlob arguments[];
|
||||
#endif
|
||||
} SignatureBlob;
|
||||
|
||||
typedef struct
|
||||
@ -217,13 +212,25 @@ typedef struct
|
||||
guint32 signature;
|
||||
} CallbackBlob;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint pointer :1;
|
||||
guint reserved :2;
|
||||
guint tag :5;
|
||||
guint8 reserved2;
|
||||
guint16 interface;
|
||||
} InterfaceTypeBlob;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TypeHeader header;
|
||||
guint pointer :1;
|
||||
guint reserved :2;
|
||||
guint tag :5;
|
||||
|
||||
guint zero_terminated :1;
|
||||
guint has_length :1;
|
||||
guint reserved2 :6;
|
||||
|
||||
guint16 length;
|
||||
|
||||
SimpleTypeBlob type;
|
||||
@ -231,24 +238,26 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TypeHeader header;
|
||||
guint pointer :1;
|
||||
guint reserved :2;
|
||||
guint tag :5;
|
||||
|
||||
guint8 reserved2;
|
||||
guint16 n_types;
|
||||
#if 0
|
||||
|
||||
SimpleTypeBlob type[];
|
||||
#endif
|
||||
} ParamTypeBlob;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TypeHeader header;
|
||||
guint pointer :1;
|
||||
guint reserved :2;
|
||||
guint tag :5;
|
||||
|
||||
guint8 reserved2;
|
||||
guint16 n_domains;
|
||||
|
||||
#if 0
|
||||
guint16 domains[];
|
||||
#endif
|
||||
} ErrorTypeBlob;
|
||||
|
||||
typedef struct
|
||||
@ -362,9 +371,7 @@ typedef struct
|
||||
guint16 n_values;
|
||||
guint16 reserved2;
|
||||
|
||||
#if 0
|
||||
ValueBlob values[];
|
||||
#endif
|
||||
ValueBlob values[];
|
||||
} EnumBlob;
|
||||
|
||||
typedef struct
|
||||
@ -439,9 +446,10 @@ typedef struct
|
||||
guint16 n_vfuncs;
|
||||
guint16 n_constants;
|
||||
|
||||
guint16 interfaces[];
|
||||
|
||||
#if 0
|
||||
/* variable-length parts of the blob */
|
||||
guint16 interfaces[];
|
||||
FieldBlob fields[];
|
||||
PropertyBlob properties[];
|
||||
FunctionBlob methods[];
|
||||
@ -468,10 +476,10 @@ typedef struct
|
||||
guint16 n_vfuncs;
|
||||
guint16 n_constants;
|
||||
|
||||
guint16 prerequisites[];
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
/* variable-length parts of the blob */
|
||||
guint16 prerequisites[];
|
||||
PropertyBlob properties[];
|
||||
FunctionBlob methods[];
|
||||
SignalBlob signals[];
|
||||
@ -513,8 +521,11 @@ struct _GMetadata {
|
||||
DirEntry *g_metadata_get_dir_entry (GMetadata *metadata,
|
||||
guint16 index);
|
||||
|
||||
void g_metadata_check_sanity (void);
|
||||
|
||||
#define g_metadata_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)])
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
G_METADATA_ERROR_INVALID,
|
||||
|
Loading…
Reference in New Issue
Block a user