From 7f130d85fc31402eb15e45c4b360e7e05243fc94 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:46:58 +0000 Subject: [PATCH] girepository/ginfo.c girepository/gmetadata.c girepository/gmetadata.h 2008-02-21 Mark Doffman * girepository/ginfo.c * girepository/gmetadata.c * girepository/gmetadata.h Change the metadata format to have a standard header for all the type blobs. Merge the SimpleTypeBlob and InterfaceTypeBlob into a union. A union of these two blobs existed previously but was not explicit in the metadata format. WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=131 --- girepository/ginfo.c | 174 ++++++++++++++++++--------------------- girepository/gmetadata.c | 97 +++++++++------------- girepository/gmetadata.h | 49 +++++------ 3 files changed, 135 insertions(+), 185 deletions(-) diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 6d66de21..0537654c 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -1,4 +1,4 @@ -/* GObject introspection: Repository implementation +data[offset]; + TypeHeader *header; + SimpleTypeBlob *simple; + + 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, - type->reserved == 0 ? offset : type->offset); + return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container, + metadata, offset); } /** @@ -721,32 +733,18 @@ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - 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; - } + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + + return header->pointer != 0; } GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved == 0) - return type->tag; - else - { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - return iface->tag; - } + return header->tag; } GITypeInfo * @@ -754,42 +752,39 @@ g_type_info_get_param_type (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - 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: ; - } + switch (header->tag) + { + 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; } - - return NULL; + + g_assert_not_reached (); } GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (header->tag == TYPE_TAG_SYMBOL) { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; - - if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->metadata, blob->interface); + CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset]; + return g_info_from_entry (base->metadata, simple->offset); } - return NULL; } @@ -797,19 +792,13 @@ gint g_type_info_get_array_length (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - if (blob->tag == GI_TYPE_TAG_ARRAY) - { - if (blob->has_length) - return blob->length; - } + if (header->tag == TYPE_TAG_ARRAY && array->has_length) + { + return array->length; } - return -1; } @@ -817,33 +806,24 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - - if (blob->tag == GI_TYPE_TAG_ARRAY) - return blob->zero_terminated; - } + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - return FALSE; + return (header->tag == TYPE_TAG_ARRAY && + array->zero_terminated); } gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - if (blob->tag == GI_TYPE_TAG_ERROR) - return blob->n_domains; + if (header->tag == TYPE_TAG_ERROR) + { + return error->n_domains; } - return 0; } @@ -852,17 +832,16 @@ g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + guint16 *domain; - if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, - blob->domains[n]); + if (header->tag == TYPE_TAG_ERROR) + { + domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]); + return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, + domain[n]); } - return NULL; } @@ -883,7 +862,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, + blob->error_codes); } @@ -1010,8 +990,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); } @@ -1075,7 +1055,8 @@ 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 */ @@ -1125,7 +1106,8 @@ g_object_info_get_interface (GIObjectInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, + blob->interfaces[n]); } gint @@ -1150,7 +1132,8 @@ 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 @@ -1572,7 +1555,8 @@ 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; } @@ -1803,4 +1787,4 @@ g_union_info_get_discriminator (GIUnionInfo *info, } return NULL; -} +} diff --git a/girepository/gmetadata.c b/girepository/gmetadata.c index d4934706..436969d0 100644 --- a/girepository/gmetadata.c +++ b/girepository/gmetadata.c @@ -234,17 +234,16 @@ validate_array_type_blob (GMetadata *metadata, gboolean return_type, GError **error) { - ArrayTypeBlob *blob; + ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset]; + TypeHeader *header = (TypeHeader *)&metadata->data[offset]; - blob = (ArrayTypeBlob*)&metadata->data[offset]; - - if (!blob->pointer) + if (!header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; + "Pointer type exected for tag %d", header->tag); + return FALSE; } /* FIXME validate length */ @@ -257,32 +256,6 @@ 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, @@ -291,17 +264,17 @@ validate_param_type_blob (GMetadata *metadata, gint n_params, GError **error) { - ParamTypeBlob *blob; + ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset]; + TypeHeader *header = (TypeHeader *)&metadata->data[offset]; gint i; - blob = (ParamTypeBlob*)&metadata->data[offset]; - if (!blob->pointer) + if (!header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); + "Pointer type exected for tag %d", header->tag); return FALSE; } @@ -334,35 +307,39 @@ 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 (!blob->pointer) + if (!type_header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; + "Pointer type exected for tag %d", type_header->tag); + return FALSE; } - for (i = 0; i < blob->n_domains; i++) + domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)]; + for (i = 0; i < blob->n_domains; i++, domain++) { - if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) + if (*domain == 0 || *domain > header->n_entries) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Invalid directory index %d", blob->domains[i]); + "Invalid directory index %d", *domain); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, blob->domains[i]); + entry = g_metadata_get_dir_entry (metadata, *domain); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) @@ -386,14 +363,14 @@ validate_type_blob (GMetadata *metadata, GError **error) { SimpleTypeBlob *simple; - InterfaceTypeBlob *iface; - + TypeHeader *header; + simple = (SimpleTypeBlob *)&metadata->data[offset]; + header = (TypeHeader *)&metadata->data[offset]; - if (simple->reserved == 0 && - simple->reserved2 == 0) + if (TYPE_IS_SIMPLE(header->tag)) { - if (simple->tag >= TYPE_TAG_ARRAY) + if (header->tag >= TYPE_TAG_ARRAY) { g_set_error (error, G_METADATA_ERROR, @@ -402,22 +379,20 @@ validate_type_blob (GMetadata *metadata, return FALSE; } - if (simple->tag >= TYPE_TAG_UTF8 && - !simple->pointer) + if (header->tag >= TYPE_TAG_UTF8 && + !header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", simple->tag); - return FALSE; + "Pointer type exected for tag %d", header->tag); + return FALSE; } return TRUE; } - iface = (InterfaceTypeBlob*)&metadata->data[simple->offset]; - - switch (iface->tag) + switch (header->tag) { case TYPE_TAG_ARRAY: if (!validate_array_type_blob (metadata, simple->offset, @@ -691,6 +666,7 @@ validate_constant_blob (GMetadata *metadata, 0, 0 }; ConstantBlob *blob; + TypeHeader *header; SimpleTypeBlob *type; if (metadata->len < offset + sizeof (ConstantBlob)) @@ -734,11 +710,12 @@ validate_constant_blob (GMetadata *metadata, "Misaligned constant value"); return FALSE; } - + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (type->reserved == 0) + header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; + if (TYPE_IS_SIMPLE(header->tag)) { - if (type->tag == 0) + if (header->tag == 0) { g_set_error (error, G_METADATA_ERROR, @@ -747,8 +724,8 @@ validate_constant_blob (GMetadata *metadata, return FALSE; } - if (value_size[type->tag] != 0 && - blob->size != value_size[type->tag]) + if (value_size[header->tag] != 0 && + blob->size != value_size[header->tag]) { g_set_error (error, G_METADATA_ERROR, diff --git a/girepository/gmetadata.h b/girepository/gmetadata.h index 144c6a45..8c0f2b04 100644 --- a/girepository/gmetadata.h +++ b/girepository/gmetadata.h @@ -126,20 +126,26 @@ typedef enum TYPE_TAG_ERROR = 25 } TypeTag; -typedef union +typedef struct +{ + 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 { - struct - { - guint reserved : 8; - guint reserved2 :16; - guint pointer : 1; - guint reserved3 : 2; - guint tag : 5; - }; + TypeHeader header; + guint32 offset; } SimpleTypeBlob; - typedef struct { guint32 name; @@ -209,25 +215,13 @@ typedef struct guint32 signature; } CallbackBlob; -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - guint8 reserved2; - guint16 interface; -} InterfaceTypeBlob; - typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; guint zero_terminated :1; guint has_length :1; guint reserved2 :6; - guint16 length; SimpleTypeBlob type; @@ -235,9 +229,7 @@ typedef struct typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; guint8 reserved2; guint16 n_types; @@ -247,11 +239,8 @@ typedef struct typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; - guint8 reserved2; guint16 n_domains; guint16 domains[]; -- 2.34.1