girepository/ginfo.c girepository/gmetadata.c girepository/gmetadata.h
authorMark Doffman <mark.doffman@codethink.co.uk>
Mon, 10 Mar 2008 17:46:58 +0000 (17:46 +0000)
committerJohan Dahlin <johan@src.gnome.org>
Mon, 10 Mar 2008 17:46:58 +0000 (17:46 +0000)
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

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

index 6d66de21b4b28f70de1cd28d74e5dcbd487de974..0537654c1c87960ba15ca410835df972b95f6cc2 100644 (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;
+
+  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;
-}
+}   
index d49347066de7bcee9c449c4686fd445720be8507..436969d006fdbe81c412d67fb22634a32f2fcc19 100644 (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;
-  
+  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,
index 144c6a454374f903a59f9db3d3429473cf55203f..8c0f2b04ddc119dd86b422e8335725d22f9e46b0 100644 (file)
@@ -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[];