girepository/ginfo.c girepository/gmetadata.c girepository/gmetadata.h

2008-02-21  Mark Doffman  <mark.doffman@codethink.co.uk>

        * 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
This commit is contained in:
Mark Doffman 2008-03-10 17:46:58 +00:00 committed by Johan Dahlin
parent 9713aa96d7
commit 0f2b1089ad
3 changed files with 137 additions and 187 deletions

176
ginfo.c
View File

@ -1,4 +1,4 @@
/* GObject introspection: Repository implementation
</* GObject introspection: Repository implementation
*
* Copyright (C) 2005 Matthias Clasen
*
@ -528,15 +528,27 @@ 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)
{
SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset];
TypeHeader *header;
SimpleTypeBlob *simple;
return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata,
type->reserved == 0 ? offset : type->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);
}
/**
@ -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];
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
if (type->reserved == 0)
return type->tag;
else
{
InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&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)
{
InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset];
if (blob->tag == GI_TYPE_TAG_INTERFACE)
return g_info_from_entry (base->metadata, blob->interface);
}
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset];
if (header->tag == TYPE_TAG_SYMBOL)
{
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)
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)
{
ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset];
if (blob->tag == GI_TYPE_TAG_ARRAY)
{
if (blob->has_length)
return blob->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];
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset];
if (blob->tag == GI_TYPE_TAG_ARRAY)
return blob->zero_terminated;
}
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)
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
if (header->tag == TYPE_TAG_ERROR)
{
ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset];
if (blob->tag == GI_TYPE_TAG_ERROR)
return blob->n_domains;
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)
TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset];
ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset];
guint16 *domain;
if (header->tag == TYPE_TAG_ERROR)
{
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]);
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;
}
}

View File

@ -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;
simple = (SimpleTypeBlob *)&metadata->data[offset];
TypeHeader *header;
if (simple->reserved == 0 &&
simple->reserved2 == 0)
simple = (SimpleTypeBlob *)&metadata->data[offset];
header = (TypeHeader *)&metadata->data[offset];
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,

View File

@ -126,20 +126,26 @@ typedef enum
TYPE_TAG_ERROR = 25
} TypeTag;
typedef union
typedef struct
{
struct
{
guint reserved : 8;
guint reserved2 :16;
guint pointer : 1;
guint reserved3 : 2;
guint tag : 5;
};
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;
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[];