gobject-introspection r288 - in trunk: . girepository tools



Author: pvanhoof
Date: Sun Jun  8 14:37:30 2008
New Revision: 288
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=288&view=rev

Log:
2008-06-08  Philip Van Hoof  <pvanhoof gnome org>

        * girepository/girepository.c:
        * girepository/gtypelib.c:
        * girepository/ginfo.c:
        * girepository/ginvoke.c:
        * girepository/girepository.h:
        * girepository/gtypelib.h:
        * girepository/gmetadata.c:
        * girepository/Makefile.am:
        * girepository/gmetadata.h:
        * tools/compiler.c:
        * tools/gidlmodule.c:
        * tools/gidlnode.c
        * tools/generate.c:
        * tools/gidlmodule.h:
        * tools/gidlparser.c:

        Renamed GMetadata to GTypelib



Added:
   trunk/girepository/gtypelib.c
   trunk/girepository/gtypelib.h
Removed:
   trunk/girepository/gmetadata.c
   trunk/girepository/gmetadata.h
Modified:
   trunk/ChangeLog
   trunk/girepository/Makefile.am
   trunk/girepository/ginfo.c
   trunk/girepository/ginvoke.c
   trunk/girepository/girepository.c
   trunk/girepository/girepository.h
   trunk/tools/compiler.c
   trunk/tools/generate.c
   trunk/tools/gidlmodule.c
   trunk/tools/gidlmodule.h
   trunk/tools/gidlnode.c
   trunk/tools/gidlparser.c

Modified: trunk/girepository/Makefile.am
==============================================================================
--- trunk/girepository/Makefile.am	(original)
+++ trunk/girepository/Makefile.am	Sun Jun  8 14:37:30 2008
@@ -8,8 +8,8 @@
 
 libgirepository_la_SOURCES =			\
 	girepository.c				\
-	gmetadata.h				\
-	gmetadata.c				\
+	gtypelib.h				\
+	gtypelib.c				\
 	ginfo.c					\
 	ginvoke.c
 libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS)

Modified: trunk/girepository/ginfo.c
==============================================================================
--- trunk/girepository/ginfo.c	(original)
+++ trunk/girepository/ginfo.c	Sun Jun  8 14:37:30 2008
@@ -24,7 +24,7 @@
 #include <glib-object.h>
 
 #include "girepository.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 struct _GIBaseInfo 
 {
@@ -32,7 +32,7 @@
   gint ref_count;
   GIBaseInfo *container;
 
-  GMetadata *metadata;
+  GTypelib *metadata;
   guint32 offset;
 };
 
@@ -136,7 +136,7 @@
 GIBaseInfo *
 g_info_new (GIInfoType     type,
 	    GIBaseInfo    *container,
-	    GMetadata     *metadata, 
+	    GTypelib     *metadata, 
 	    guint32        offset)
 {
   GIBaseInfo *info;
@@ -156,18 +156,18 @@
 }
 
 static GIBaseInfo *
-g_info_from_entry (GMetadata *metadata,
+g_info_from_entry (GTypelib *metadata,
 		   guint16    index)
 {
   GIBaseInfo *result;
-  DirEntry *entry = g_metadata_get_dir_entry (metadata, index);
+  DirEntry *entry = g_typelib_get_dir_entry (metadata, index);
   
   if (entry->local)
     result = g_info_new (entry->blob_type, NULL, metadata, entry->offset);
   else 
     {
-      const gchar *namespace = g_metadata_get_string (metadata, entry->offset);
-      const gchar *name = g_metadata_get_string (metadata, entry->name);
+      const gchar *namespace = g_typelib_get_string (metadata, entry->offset);
+      const gchar *name = g_typelib_get_string (metadata, entry->name);
       
       GIRepository *repository = g_irepository_get_default ();
       
@@ -240,7 +240,7 @@
       {
 	CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset];
 
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -248,7 +248,7 @@
       {
 	ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset];
 
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -256,7 +256,7 @@
       {
 	SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset];
 
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -264,7 +264,7 @@
       {
 	PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset];
 
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -272,7 +272,7 @@
       {
 	VFuncBlob *blob = (VFuncBlob *)&info->metadata->data[info->offset];
 
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -280,7 +280,7 @@
       {
 	FieldBlob *blob = (FieldBlob *)&info->metadata->data[info->offset];
 	
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -288,7 +288,7 @@
       {
 	ArgBlob *blob = (ArgBlob *)&info->metadata->data[info->offset];
 	
-	return g_metadata_get_string (info->metadata, blob->name);
+	return g_typelib_get_string (info->metadata, blob->name);
       }
       break;
 
@@ -320,7 +320,7 @@
       return unresolved->namespace;
     }
 
-  return g_metadata_get_string (info->metadata, header->namespace);
+  return g_typelib_get_string (info->metadata, header->namespace);
 }
 
 gboolean 
@@ -430,9 +430,9 @@
     {
       res = next;
       
-      rname = g_metadata_get_string (base->metadata, res->name);
+      rname = g_typelib_get_string (base->metadata, res->name);
       if (strcmp (name, rname) == 0)
-	return g_metadata_get_string (base->metadata, res->value);
+	return g_typelib_get_string (base->metadata, res->value);
 
       next = res += header->annotation_blob_size;
     }
@@ -447,7 +447,7 @@
   return info->container;
 }
 
-GMetadata *
+GTypelib *
 g_base_info_get_metadata (GIBaseInfo *info)
 {
   return info->metadata;
@@ -460,7 +460,7 @@
   GIBaseInfo *base = (GIBaseInfo *)info;
   FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset];
 
-  return g_metadata_get_string (base->metadata, blob->symbol);
+  return g_typelib_get_string (base->metadata, blob->symbol);
 }
 
 GIFunctionInfoFlags
@@ -530,7 +530,7 @@
 
 GITypeInfo *
 g_type_info_new (GIBaseInfo    *container,
-		 GMetadata     *metadata,
+		 GTypelib     *metadata,
 		 guint32        offset)
 {
   SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset];
@@ -874,7 +874,7 @@
   GIBaseInfo *base = (GIBaseInfo *)info;
   ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset];
 
-  return g_metadata_get_string (base->metadata, blob->get_quark);
+  return g_typelib_get_string (base->metadata, blob->get_quark);
 }
 
 GIInterfaceInfo *
@@ -951,7 +951,7 @@
   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset];
 
   if (blob->gtype_name)
-    return g_metadata_get_string (base->metadata, blob->gtype_name);
+    return g_typelib_get_string (base->metadata, blob->gtype_name);
 
   return NULL;
 }
@@ -963,7 +963,7 @@
   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset];
 
   if (blob->gtype_init)
-    return g_metadata_get_string (base->metadata, blob->gtype_init);
+    return g_typelib_get_string (base->metadata, blob->gtype_init);
 
   return NULL;
 }
@@ -1116,7 +1116,7 @@
   GIBaseInfo *base = (GIBaseInfo *)info;
   ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset];
 
-  return g_metadata_get_string (base->metadata, blob->gtype_name);
+  return g_typelib_get_string (base->metadata, blob->gtype_name);
 }
 
 const gchar *
@@ -1125,7 +1125,7 @@
   GIBaseInfo *base = (GIBaseInfo *)info;
   ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset];
 
-  return g_metadata_get_string (base->metadata, blob->gtype_init);
+  return g_typelib_get_string (base->metadata, blob->gtype_init);
 }
 
 gint

Modified: trunk/girepository/ginvoke.c
==============================================================================
--- trunk/girepository/ginvoke.c	(original)
+++ trunk/girepository/ginvoke.c	Sun Jun  8 14:37:30 2008
@@ -24,7 +24,7 @@
 #include <glib-object.h>
 
 #include "girepository.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 #include "config.h"
 
 GQuark

Modified: trunk/girepository/girepository.c
==============================================================================
--- trunk/girepository/girepository.c	(original)
+++ trunk/girepository/girepository.c	Sun Jun  8 14:37:30 2008
@@ -26,7 +26,7 @@
 #include <glib/gprintf.h>
 #include <gmodule.h>
 #include "girepository.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 static GIRepository *default_repository = NULL;
 static GHashTable *default_metadata = NULL;
@@ -34,7 +34,7 @@
 
 struct _GIRepositoryPrivate 
 {
-  GHashTable *metadata; /* (string) namespace -> GMetadata */
+  GHashTable *metadata; /* (string) namespace -> GTypelib */
 };
 
 G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
@@ -70,7 +70,7 @@
 
 const gchar *
 g_irepository_register (GIRepository *repository,
-                        GMetadata    *metadata)
+                        GTypelib    *metadata)
 {
   Header *header;
   const gchar *name;
@@ -88,7 +88,7 @@
       if (repository->priv->metadata == NULL)
 	repository->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                             (GDestroyNotify) NULL,
-                                                            (GDestroyNotify) g_metadata_free);
+                                                            (GDestroyNotify) g_typelib_free);
       table = repository->priv->metadata;
     }
   else 
@@ -96,11 +96,11 @@
       if (default_metadata == NULL)
 	default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   (GDestroyNotify) NULL,
-                                                  (GDestroyNotify) g_metadata_free);
+                                                  (GDestroyNotify) g_typelib_free);
       table = default_metadata;
     }
 
-  name = g_metadata_get_string (metadata, header->namespace);
+  name = g_typelib_get_string (metadata, header->namespace);
 
   if (g_hash_table_lookup (table, name))
     {
@@ -158,7 +158,7 @@
       if (default_metadata == NULL)
 	default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   (GDestroyNotify) NULL,
-                                                  (GDestroyNotify) g_metadata_free);
+                                                  (GDestroyNotify) g_typelib_free);
       default_repository->priv->metadata = default_metadata;
     }
 
@@ -170,7 +170,7 @@
 		  gpointer value,
 		  gpointer data)
 {
-  guchar *metadata = ((GMetadata *) value)->data;
+  guchar *metadata = ((GTypelib *) value)->data;
   gint *n_interfaces = (gint *)data;
   
   *n_interfaces += ((Header *)metadata)->n_local_entries;
@@ -184,7 +184,7 @@
   
   if (namespace)
     {
-      GMetadata *metadata;
+      GTypelib *metadata;
 
       metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
 
@@ -214,7 +214,7 @@
 		gpointer data)
 {
   gint i;
-  GMetadata *metadata = (GMetadata *)value;
+  GTypelib *metadata = (GTypelib *)value;
   IfaceData *iface_data = (IfaceData *)data;
   gint index;
   gint n_entries;
@@ -230,8 +230,8 @@
     {
       for (i = 1; i <= n_entries; i++)
 	{
-	  entry = g_metadata_get_dir_entry (metadata, i);
-	  name = g_metadata_get_string (metadata, entry->name);
+	  entry = g_typelib_get_dir_entry (metadata, i);
+	  name = g_typelib_get_string (metadata, entry->name);
 	  if (strcmp (name, iface_data->name) == 0)
 	    {
 	      index = i;
@@ -243,12 +243,12 @@
     {
       for (i = 1; i <= n_entries; i++)
 	{
-	  entry = g_metadata_get_dir_entry (metadata, i);
+	  entry = g_typelib_get_dir_entry (metadata, i);
 	  if (entry->blob_type < 4)
 	    continue;
 	  
 	  offset = *(guint32*)&metadata->data[entry->offset + 8];
-	  type = g_metadata_get_string (metadata, offset);
+	  type = g_typelib_get_string (metadata, offset);
 	  if (strcmp (type, iface_data->type) == 0)
 	    {
 	      index = i;
@@ -266,7 +266,7 @@
 
   if (index != 0)
     {
-      entry = g_metadata_get_dir_entry (metadata, index);
+      entry = g_typelib_get_dir_entry (metadata, index);
       iface_data->iface = g_info_new (entry->blob_type, NULL,
 				      metadata, entry->offset);
     }
@@ -286,7 +286,7 @@
 
   if (namespace)
     {
-      GMetadata *metadata;
+      GTypelib *metadata;
       
       metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
       
@@ -329,7 +329,7 @@
 
   if (namespace)
     {
-      GMetadata *metadata;
+      GTypelib *metadata;
       
       metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
       
@@ -374,7 +374,7 @@
 g_irepository_get_shared_library (GIRepository *repository,
                                    const gchar  *namespace)
 {
-  GMetadata *metadata;
+  GTypelib *metadata;
   Header *header;
 
   metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
@@ -382,7 +382,7 @@
     return NULL;
   header = (Header *) metadata->data;
   if (header->shared_library)
-    return g_metadata_get_string (metadata, header->shared_library);
+    return g_typelib_get_string (metadata, header->shared_library);
   else
     return NULL;
 }
@@ -418,7 +418,7 @@
   gchar *fname, *full_path;
   GMappedFile *mfile;
   GError *error1 = NULL;
-  GMetadata *metadata = NULL;
+  GTypelib *metadata = NULL;
   const gchar *metadata_namespace, *shlib_fname;
   GModule *module;
   guint32 shlib;
@@ -449,8 +449,8 @@
       continue;
     }
     g_free (full_path);
-    metadata = g_metadata_new_from_mapped_file (mfile);
-    metadata_namespace = g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace);
+    metadata = g_typelib_new_from_mapped_file (mfile);
+    metadata_namespace = g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace);
     if (strcmp (metadata_namespace, namespace) != 0) {
       g_set_error (error, G_IREPOSITORY_ERROR,
                    G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH,
@@ -472,7 +472,7 @@
   /* optionally load shared library and attach it to the metadata */
   shlib = ((Header *) metadata->data)->shared_library;
   if (shlib) {
-    shlib_fname = g_metadata_get_string (metadata, shlib);
+    shlib_fname = g_typelib_get_string (metadata, shlib);
     module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL);
     if (module == NULL) {
       g_set_error (error, G_IREPOSITORY_ERROR,

Modified: trunk/girepository/girepository.h
==============================================================================
--- trunk/girepository/girepository.h	(original)
+++ trunk/girepository/girepository.h	Sun Jun  8 14:37:30 2008
@@ -52,7 +52,7 @@
 typedef struct _GITypeInfo           GITypeInfo;
 typedef struct _GIErrorDomainInfo    GIErrorDomainInfo;
 typedef struct _GIUnresolvedInfo     GIUnresolvedInfo;
-typedef struct _GMetadata            GMetadata;
+typedef struct _GTypelib            GTypelib;
 
 struct _GIRepository 
 { 
@@ -73,7 +73,7 @@
 GType         g_irepository_get_type      (void) G_GNUC_CONST;
 GIRepository *g_irepository_get_default   (void);
 const gchar * g_irepository_register      (GIRepository *repository,
-					   GMetadata    *metadata);
+					   GTypelib    *metadata);
 void          g_irepository_unregister    (GIRepository *repository,
 					   const gchar  *namespace);
 const gchar * g_irepository_register_file (GIRepository *repository,
@@ -96,15 +96,15 @@
 						const gchar  *namespace);
 /* Metadata */
 
-GMetadata *   g_metadata_new_from_memory       (guchar       *memory,
+GTypelib *   g_typelib_new_from_memory       (guchar       *memory,
                                                 gsize         len);
-GMetadata *   g_metadata_new_from_const_memory (const guchar *memory,
+GTypelib *   g_typelib_new_from_const_memory (const guchar *memory,
                                                 gsize         len);
-GMetadata *   g_metadata_new_from_mapped_file  (GMappedFile  *mfile);
-void          g_metadata_free                  (GMetadata    *metadata);
-void          g_metadata_set_module            (GMetadata    *metadata,
+GTypelib *   g_typelib_new_from_mapped_file  (GMappedFile  *mfile);
+void          g_typelib_free                  (GTypelib    *metadata);
+void          g_typelib_set_module            (GTypelib    *metadata,
                                                 GModule      *module);
-const gchar * g_metadata_get_namespace         (GMetadata    *metadata);
+const gchar * g_typelib_get_namespace         (GTypelib    *metadata);
 
 typedef enum
 {
@@ -156,11 +156,11 @@
 const gchar *          g_base_info_get_annotation   (GIBaseInfo   *info,
                                                      const gchar  *name);
 GIBaseInfo *           g_base_info_get_container    (GIBaseInfo   *info);
-GMetadata *            g_base_info_get_metadata     (GIBaseInfo   *info);
+GTypelib *            g_base_info_get_metadata     (GIBaseInfo   *info);
 
 GIBaseInfo *           g_info_new                   (GIInfoType     type,
 						     GIBaseInfo    *container,
-						     GMetadata     *metadata, 
+						     GTypelib     *metadata, 
 						     guint32       offset);
 
 

Added: trunk/girepository/gtypelib.c
==============================================================================
--- (empty file)
+++ trunk/girepository/gtypelib.c	Sun Jun  8 14:37:30 2008
@@ -0,0 +1,1959 @@
+/* GObject introspection: metadata validation, auxiliary functions 
+ * related to the binary metadata format
+ *
+ * Copyright (C) 2005 Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "gtypelib.h"
+
+
+#define ALIGN_VALUE(this, boundary) \
+  (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
+
+
+DirEntry *
+g_typelib_get_dir_entry (GTypelib *metadata,
+			  guint16    index)
+{
+  Header *header = (Header *)metadata->data;
+
+  return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size];
+}
+
+void    
+g_typelib_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)
+{
+  return offset == ALIGN_VALUE (offset, 4);
+}
+
+#define MAX_NAME_LEN 200
+
+static gboolean
+is_name (const guchar *data, guint32 offset)
+{
+  gchar *name;
+
+  name = (gchar*)&data[offset];
+  
+  if (!memchr (name, '\0', MAX_NAME_LEN))
+    return FALSE;
+  
+  if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
+    return FALSE;
+  
+  return TRUE;
+}
+
+static gboolean 
+validate_header (GTypelib  *metadata,
+		 GError    **error)
+{
+  Header *header;
+
+  if (metadata->len < sizeof (Header))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  header = (Header *)metadata->data;
+
+  if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Magic string not found");
+      return FALSE;
+      
+    }
+
+  if (header->major_version != 1 || header->minor_version != 0)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Version mismatch");
+      return FALSE;
+      
+    }
+
+  if (header->n_entries < header->n_local_entries)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Inconsistent entry counts");
+      return FALSE; 
+    }
+
+  if (header->size != metadata->len)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Metadata size mismatch");
+      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_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Blob size mismatch");
+      return FALSE; 
+    }
+
+  if (!is_aligned (header->directory))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Misaligned directory");
+      return FALSE; 
+    }
+
+  if (!is_aligned (header->annotations))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Misaligned annotations");
+      return FALSE; 
+    }
+
+  if (header->annotations == 0 && header->n_annotations > 0)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Wrong number of annotations");
+      return FALSE; 
+    }
+
+  if (!is_name (metadata->data, header->namespace))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_HEADER,
+		   "Invalid namespace name");
+      return FALSE; 
+    }
+
+  return TRUE;
+}
+
+static gboolean validate_type_blob (GTypelib     *metadata,
+				    guint32        offset,
+				    guint32        signature_offset,
+				    gboolean       return_type,
+				    GError       **error);
+
+static gboolean
+validate_array_type_blob (GTypelib     *metadata,
+			  guint32        offset,
+			  guint32        signature_offset,
+			  gboolean       return_type,
+			  GError       **error)
+{
+  ArrayTypeBlob *blob;
+
+  blob = (ArrayTypeBlob*)&metadata->data[offset];
+
+  if (!blob->pointer)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Pointer type exected for tag %d", blob->tag);
+      return FALSE;	  
+    }
+
+  /* FIXME validate length */
+
+  if (!validate_type_blob (metadata,
+			   offset + G_STRUCT_OFFSET (ArrayTypeBlob, type),
+			   0, FALSE, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+validate_iface_type_blob (GTypelib     *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_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid directory index %d", blob->interface);
+      return FALSE;	        
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_param_type_blob (GTypelib     *metadata,
+			  guint32        offset,
+			  guint32        signature_offset,
+			  gboolean       return_type,
+			  gint           n_params,
+			  GError       **error)
+{
+  ParamTypeBlob *blob;
+  gint i;
+
+  blob = (ParamTypeBlob*)&metadata->data[offset];
+
+  if (!blob->pointer)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Pointer type exected for tag %d", blob->tag);
+      return FALSE;	  
+    }
+  
+  if (blob->n_types != n_params)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Parameter type number mismatch");
+      return FALSE;	        
+    }
+  
+  for (i = 0; i < n_params; i++)
+    {
+      if (!validate_type_blob (metadata,
+			       offset + sizeof (ParamTypeBlob) +
+			       i * sizeof (SimpleTypeBlob),
+			       0, FALSE, error))
+	return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_error_type_blob (GTypelib     *metadata,
+			  guint32        offset,
+			  guint32        signature_offset,
+			  gboolean       return_type,
+			  GError       **error)
+{
+  ErrorTypeBlob *blob;
+  Header *header;
+  gint i;
+  DirEntry *entry;
+
+  blob = (ErrorTypeBlob*)&metadata->data[offset];
+
+  header = (Header *)metadata->data;
+
+  if (!blob->pointer)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Pointer type exected for tag %d", blob->tag);
+      return FALSE;	  
+    }
+  
+  for (i = 0; i < blob->n_domains; i++)
+    {
+      if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid directory index %d", blob->domains[i]);
+	  return FALSE;	        
+	}
+
+      entry = g_typelib_get_dir_entry (metadata, blob->domains[i]);
+
+      if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN &&
+	  (entry->local || entry->blob_type != BLOB_TYPE_INVALID))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Wrong blob type");
+	  return FALSE;	        
+	}
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_type_blob (GTypelib     *metadata,
+		    guint32        offset,
+		    guint32        signature_offset,
+		    gboolean       return_type,
+		    GError       **error)
+{
+  SimpleTypeBlob *simple;
+  InterfaceTypeBlob *iface;
+  
+  simple = (SimpleTypeBlob *)&metadata->data[offset];
+
+  if (simple->reserved == 0 && 
+      simple->reserved2 == 0)
+    {
+      if (simple->tag >= TYPE_TAG_ARRAY)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Wrong tag in simple type");
+	  return FALSE;
+	}
+      
+      if (simple->tag >= TYPE_TAG_UTF8 &&
+	  !simple->pointer)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Pointer type exected for tag %d", simple->tag);
+	  return FALSE;	  
+	}
+
+      return TRUE;
+    }
+
+  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_INTERFACE:
+      if (!validate_iface_type_blob (metadata, simple->offset, 
+				     signature_offset, return_type, error))
+	return FALSE;
+      break;
+    case TYPE_TAG_LIST:
+    case TYPE_TAG_SLIST:
+      if (!validate_param_type_blob (metadata, simple->offset, 
+				     signature_offset, return_type, 1, error))
+	return FALSE;
+      break;
+    case TYPE_TAG_HASH:
+      if (!validate_param_type_blob (metadata, simple->offset, 
+				     signature_offset, return_type, 2, error))
+	return FALSE;
+      break;
+    case TYPE_TAG_ERROR:
+      if (!validate_error_type_blob (metadata, simple->offset, 
+				     signature_offset, return_type, error))
+	return FALSE;
+      break;
+    default:
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong tag in complex type");
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_arg_blob (GTypelib     *metadata,
+		   guint32        offset,
+		   guint32        signature_offset,
+		   GError       **error)
+{
+  ArgBlob *blob;
+
+  if (metadata->len < offset + sizeof (ArgBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (ArgBlob*) &metadata->data[offset];
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid argument name");
+      return FALSE; 
+    }
+ 
+  if (!validate_type_blob (metadata, 
+			   offset + G_STRUCT_OFFSET (ArgBlob, arg_type), 
+			   signature_offset, FALSE, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+validate_signature_blob (GTypelib     *metadata,
+			 guint32        offset,
+			 GError       **error)
+{
+  SignatureBlob *blob;
+  gint i;
+
+  if (metadata->len < offset + sizeof (SignatureBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (SignatureBlob*) &metadata->data[offset];
+
+  if (blob->return_type.offset != 0)
+    {
+      if (!validate_type_blob (metadata, 
+			       offset + G_STRUCT_OFFSET (SignatureBlob, return_type), 
+			       offset, TRUE, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_arguments; i++)
+    {
+      if (!validate_arg_blob (metadata, 
+			      offset + sizeof (SignatureBlob) + 
+			      i * sizeof (ArgBlob), 
+			      offset, 
+			      error))
+	return FALSE;
+    }
+
+  /* FIXME check constraints on return_value */
+  /* FIXME check array-length pairs */
+  return TRUE;
+}
+
+static gboolean
+validate_function_blob (GTypelib     *metadata,
+			guint32        offset,
+			guint16        container_type,
+			GError       **error)
+{
+  FunctionBlob *blob;
+
+  if (metadata->len < offset + sizeof (FunctionBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (FunctionBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != BLOB_TYPE_FUNCTION)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid function name");
+      return FALSE; 
+    }
+  
+  if (!is_name (metadata->data, blob->symbol))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid function symbol");
+      return FALSE; 
+    }
+  
+  if (blob->constructor)
+    {
+      switch (container_type)
+	{
+	case BLOB_TYPE_BOXED:
+	case BLOB_TYPE_OBJECT:
+	case BLOB_TYPE_INTERFACE:
+	  break;
+	default:
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Constructor not allowed");
+	  return FALSE;
+	}
+    }
+
+  if (blob->setter || blob->getter || blob->wraps_vfunc)
+    {
+      switch (container_type)
+	{
+	case BLOB_TYPE_OBJECT:
+	case BLOB_TYPE_INTERFACE:
+	  break;
+	default:
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Setter, getter or wrapper not allowed");
+	  return FALSE;
+	}
+    }
+
+  if (blob->index)
+    {
+      if (!(blob->setter || blob->getter || blob->wraps_vfunc))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Must be setter, getter or wrapper");
+	  return FALSE;
+	}
+    }
+
+  /* FIXME: validate index range */
+  /* FIXME: validate "this" argument for methods */
+  /* FIXME: validate return type for constructors */
+
+  if (!validate_signature_blob (metadata, blob->signature, error))
+    return FALSE;
+	
+  return TRUE;
+}
+
+static gboolean
+validate_callback_blob (GTypelib     *metadata,
+			guint32        offset,
+			GError       **error)
+{
+  CallbackBlob *blob;
+
+  if (metadata->len < offset + sizeof (CallbackBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (CallbackBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != BLOB_TYPE_CALLBACK)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid callback name");
+      return FALSE; 
+    }
+  
+  if (!validate_signature_blob (metadata, blob->signature, error))
+    return FALSE;
+	
+  return TRUE;
+}
+
+static gboolean
+validate_constant_blob (GTypelib     *metadata,
+			guint32        offset,
+			GError       **error)
+{
+  gint value_size[] = {
+    0, 4, 1, 1, 2, 2, 4, 4, 8, 8, 
+    sizeof (gint), sizeof (guint), 
+    sizeof (glong), sizeof (gulong),
+    sizeof (gssize), sizeof (gsize),
+    sizeof (gfloat), sizeof (gdouble), 
+    0, 0
+  }; 
+  ConstantBlob *blob;
+  SimpleTypeBlob *type;
+
+  if (metadata->len < offset + sizeof (ConstantBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (ConstantBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != BLOB_TYPE_CONSTANT)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid constant name");
+      return FALSE; 
+    }
+  
+  if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type), 
+			   0, FALSE, error))
+    return FALSE;
+
+  if (!is_aligned (blob->offset))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Misaligned constant value");
+      return FALSE;
+    }
+  
+  type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
+  if (type->reserved == 0)
+    {
+      if (type->tag == 0)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Constant value type void");
+	  return FALSE;
+	}
+
+      if (value_size[type->tag] != 0 &&
+	  blob->size != value_size[type->tag])
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Constant value size mismatch");
+	  return FALSE;
+	}
+      /* FIXME check string values */
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_value_blob (GTypelib     *metadata,
+		     guint32        offset,
+		     GError       **error)
+{
+  ValueBlob *blob;
+
+  if (metadata->len < offset + sizeof (ValueBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (ValueBlob*) &metadata->data[offset];
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid value name");
+      return FALSE; 
+    }
+  
+  return TRUE;
+}
+
+static gboolean
+validate_field_blob (GTypelib     *metadata,
+		     guint32        offset,
+		     GError       **error)
+{
+  FieldBlob *blob;
+
+  if (metadata->len < offset + sizeof (FieldBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (FieldBlob*) &metadata->data[offset];
+  
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid field name");
+      return FALSE; 
+    }
+    
+  if (!validate_type_blob (metadata,
+			   offset + G_STRUCT_OFFSET (FieldBlob, type), 
+			   0, FALSE, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+validate_property_blob (GTypelib     *metadata,
+			guint32        offset,
+			GError       **error)
+{
+  PropertyBlob *blob;
+
+  if (metadata->len < offset + sizeof (PropertyBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (PropertyBlob*) &metadata->data[offset];
+  
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid property name");
+      return FALSE; 
+    }
+    
+  if (!validate_type_blob (metadata,
+			   offset + G_STRUCT_OFFSET (PropertyBlob, type), 
+			   0, FALSE, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+validate_signal_blob (GTypelib     *metadata,
+		      guint32        offset,
+		      guint32        container_offset,
+		      GError       **error)
+{
+  SignalBlob *blob;
+  gint n_signals;
+
+  if (metadata->len < offset + sizeof (SignalBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (SignalBlob*) &metadata->data[offset];
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid signal name");
+      return FALSE; 
+    }
+  
+  if ((blob->run_first != 0) + 
+      (blob->run_last != 0) + 
+      (blob->run_cleanup != 0) != 1)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid signal run flags");
+      return FALSE; 
+    }
+
+  if (blob->has_class_closure)
+    {
+      if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
+	{
+	  ObjectBlob *object;
+
+	  object = (ObjectBlob*)&metadata->data[container_offset];
+	  
+	  n_signals = object->n_signals;
+	}
+      else
+	{
+	  InterfaceBlob *iface;
+	  
+	  iface = (InterfaceBlob*)&metadata->data[container_offset];
+	  
+	  n_signals = iface->n_signals;
+	}
+
+      if (blob->class_closure >= n_signals)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid class closure index");
+	  return FALSE; 
+	}
+    }
+
+  if (!validate_signature_blob (metadata, blob->signature, error))
+    return FALSE;
+  
+  return TRUE;
+}
+
+static gboolean
+validate_vfunc_blob (GTypelib     *metadata,
+		     guint32        offset,
+		     guint32        container_offset,
+		     GError       **error)
+{
+  VFuncBlob *blob;
+  gint n_vfuncs;
+
+  if (metadata->len < offset + sizeof (VFuncBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (VFuncBlob*) &metadata->data[offset];
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid vfunc name");
+      return FALSE; 
+    }
+  
+  if (blob->class_closure)
+    {
+      if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
+	{
+	  ObjectBlob *object;
+
+	  object = (ObjectBlob*)&metadata->data[container_offset];
+	  
+	  n_vfuncs = object->n_vfuncs;
+	}
+      else
+	{
+	  InterfaceBlob *iface;
+	  
+	  iface = (InterfaceBlob*)&metadata->data[container_offset];
+	  
+	  n_vfuncs = iface->n_vfuncs;
+	}
+
+      if (blob->class_closure >= n_vfuncs)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid class closure index");
+	  return FALSE; 
+	}
+    }
+
+  if (!validate_signature_blob (metadata, blob->signature, error))
+    return FALSE;
+  
+  return TRUE;
+}
+
+static gboolean
+validate_struct_blob (GTypelib     *metadata,
+		      guint32        offset,
+		      guint16        blob_type,
+		      GError       **error)
+{
+  StructBlob *blob;
+  gint i;
+
+  if (metadata->len < offset + sizeof (StructBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (StructBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != blob_type)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+  
+  if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) ||
+      (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Registration/blob type mismatch");
+      return FALSE;
+    }
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid struct name");
+      return FALSE; 
+    }
+  
+  if (blob_type == BLOB_TYPE_BOXED)
+    {
+      if (!is_name (metadata->data, blob->gtype_name))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid boxed type name");
+	  return FALSE; 
+	}
+
+      if (!is_name (metadata->data, blob->gtype_init))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid boxed type init");
+	  return FALSE; 
+	}
+    }
+  else
+    {
+      if (blob->gtype_name || blob->gtype_init)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Gtype data in struct");
+	  return FALSE; 
+	}
+    }
+
+  if (metadata->len < offset + sizeof (StructBlob) + 
+            blob->n_fields * sizeof (FieldBlob) +
+            blob->n_methods * sizeof (FunctionBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  for (i = 0; i < blob->n_fields; i++)
+    {
+      if (!validate_field_blob (metadata, 
+				offset + sizeof (StructBlob) + 
+				i * sizeof (FieldBlob), 
+				error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_methods; i++)
+    {
+      if (!validate_function_blob (metadata, 
+				   offset + sizeof (StructBlob) + 
+				   blob->n_fields * sizeof (FieldBlob) + 
+				   i * sizeof (FunctionBlob), 
+				   blob_type,
+				   error))
+	return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_enum_blob (GTypelib     *metadata,
+		    guint32        offset,
+		    guint16        blob_type,
+		    GError       **error)
+{
+  EnumBlob *blob;
+  ValueBlob *v1, *v2;
+  gint i, j; 
+
+  if (metadata->len < offset + sizeof (EnumBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (EnumBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != blob_type)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+  
+  if (!blob->unregistered)
+    {
+      if (!is_name (metadata->data, blob->gtype_name))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid enum type name");
+	  return FALSE; 
+	}
+
+      if (!is_name (metadata->data, blob->gtype_init))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid enum type init");
+	  return FALSE; 
+	}
+    }
+  else
+    {
+      if (blob->gtype_name || blob->gtype_init)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Gtype data in unregistered enum");
+	  return FALSE; 
+	}
+    }
+
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid enum name");
+      return FALSE; 
+    }
+  
+  if (metadata->len < offset + sizeof (EnumBlob) + 
+      blob->n_values * sizeof (ValueBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+  
+  for (i = 0; i < blob->n_values; i++)
+    {
+      if (!validate_value_blob (metadata, 
+				offset + sizeof (EnumBlob) + 
+				i * sizeof (ValueBlob), 
+				error))
+	return FALSE;
+
+      v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + 
+                                        i * sizeof (ValueBlob)];
+      for (j = 0; j < i; j++) 
+	{
+	  v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + 
+                                            j * sizeof (ValueBlob)];
+
+	  if (v1->value == v2->value)
+	    {
+	      /* FIXME should this be an error ? */
+	      g_set_error (error,
+			   G_TYPELIB_ERROR,
+			   G_TYPELIB_ERROR_INVALID_BLOB,
+			   "Duplicate enum value");
+	      return FALSE;
+	    }
+	}
+    }
+  
+  return TRUE;
+}
+
+static gboolean
+validate_object_blob (GTypelib     *metadata,
+		      guint32        offset,
+		      GError       **error)
+{
+  Header *header;
+  ObjectBlob *blob;
+  gint i;
+  guint32 offset2;
+
+  header = (Header *)metadata->data;
+
+  if (metadata->len < offset + sizeof (ObjectBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (ObjectBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != BLOB_TYPE_OBJECT)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+  
+  if (!is_name (metadata->data, blob->gtype_name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid object type name");
+      return FALSE; 
+    }
+  
+  if (!is_name (metadata->data, blob->gtype_init))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid object type init");
+      return FALSE; 
+    }
+  
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid object name");
+      return FALSE; 
+    }
+  
+  if (blob->parent > header->n_entries)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid parent index");
+      return FALSE; 
+    }
+
+  if (blob->parent != 0)
+    {
+      DirEntry *entry;
+
+      entry = g_typelib_get_dir_entry (metadata, blob->parent);
+      if (entry->blob_type != BLOB_TYPE_OBJECT &&
+	  (entry->local || entry->blob_type != 0))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Parent not object");
+	  return FALSE; 
+	}
+    }
+  
+  if (metadata->len < offset + sizeof (ObjectBlob) + 
+            (blob->n_interfaces + blob->n_interfaces % 2) * 2 +
+            blob->n_fields * sizeof (FieldBlob) +
+            blob->n_properties * sizeof (PropertyBlob) +
+            blob->n_methods * sizeof (FunctionBlob) +
+            blob->n_signals * sizeof (SignalBlob) +
+            blob->n_vfuncs * sizeof (VFuncBlob) +
+            blob->n_constants * sizeof (ConstantBlob))
+     
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  offset2 = offset + sizeof (ObjectBlob);
+
+  for (i = 0; i < blob->n_interfaces; i++, offset2 += 2)
+    {
+      guint16 iface;
+      DirEntry *entry;
+
+      iface = *(guint16*)&metadata->data[offset2];
+      if (iface == 0 || iface > header->n_entries)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid interface index");
+	  return FALSE; 
+	}
+      
+      entry = g_typelib_get_dir_entry (metadata, iface);
+
+      if (entry->blob_type != BLOB_TYPE_INTERFACE &&
+	  (entry->local || entry->blob_type != 0))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Not an interface");
+	  return FALSE; 
+	}
+    }
+
+  offset2 += 2 * (blob->n_interfaces %2);
+
+  for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob))
+    {
+      if (!validate_field_blob (metadata, offset2, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
+    {
+      if (!validate_property_blob (metadata, offset2, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
+    {
+      if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
+    {
+      if (!validate_signal_blob (metadata, offset2, offset, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
+    {
+      if (!validate_vfunc_blob (metadata, offset2, offset, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
+    {
+      if (!validate_constant_blob (metadata, offset2, error))
+	return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_interface_blob (GTypelib     *metadata,
+			 guint32        offset,
+			 GError       **error)
+{
+  Header *header;
+  InterfaceBlob *blob;
+  gint i;
+  guint32 offset2;
+  
+  header = (Header *)metadata->data;
+
+  if (metadata->len < offset + sizeof (InterfaceBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  blob = (InterfaceBlob*) &metadata->data[offset];
+
+  if (blob->blob_type != BLOB_TYPE_INTERFACE)
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Wrong blob type");
+      return FALSE;
+    }
+  
+  if (!is_name (metadata->data, blob->gtype_name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid interface type name");
+      return FALSE; 
+    }
+  
+  if (!is_name (metadata->data, blob->gtype_init))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid interface type init");
+      return FALSE; 
+    }
+  
+  if (!is_name (metadata->data, blob->name))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_BLOB,
+		   "Invalid interface name");
+      return FALSE; 
+    }
+  
+  if (metadata->len < offset + sizeof (InterfaceBlob) + 
+            (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
+            blob->n_properties * sizeof (PropertyBlob) +
+            blob->n_methods * sizeof (FunctionBlob) +
+            blob->n_signals * sizeof (SignalBlob) +
+            blob->n_vfuncs * sizeof (VFuncBlob) +
+            blob->n_constants * sizeof (ConstantBlob))
+     
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  offset2 = offset + sizeof (InterfaceBlob);
+
+  for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2)
+    {
+      DirEntry *entry;
+      guint16 req;
+
+      req = *(guint16*)&metadata->data[offset2];
+      if (req == 0 || req > header->n_entries)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Invalid prerequisite index");
+	  return FALSE; 
+	}
+
+      entry = g_typelib_get_dir_entry (metadata, req);
+      if (entry->blob_type != BLOB_TYPE_INTERFACE &&
+	  entry->blob_type != BLOB_TYPE_OBJECT &&
+	  (entry->local || entry->blob_type != 0))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_BLOB,
+		       "Not an interface or object");
+	  return FALSE; 
+	}
+    }
+
+  offset2 += 2 * (blob->n_prerequisites % 2);
+
+  for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
+    {
+      if (!validate_property_blob (metadata, offset2, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
+    {
+      if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error))
+	return FALSE;
+    }
+  
+  for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
+    {
+      if (!validate_signal_blob (metadata, offset2, offset, error))
+	return FALSE;
+    }
+  
+  for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
+    {
+      if (!validate_vfunc_blob (metadata, offset2, offset, error))
+	return FALSE;
+    }
+
+  for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
+    {
+      if (!validate_constant_blob (metadata, offset2, error))
+	return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_errordomain_blob (GTypelib     *metadata,
+			   guint32        offset,
+			   GError       **error)
+{
+  return TRUE;
+}
+
+static gboolean
+validate_union_blob (GTypelib     *metadata,
+		     guint32        offset,
+		     GError       **error)
+{
+  return TRUE;
+}
+
+static gboolean
+validate_blob (GTypelib     *metadata,
+	       guint32        offset,
+	       GError       **error)
+{
+  CommonBlob *common;
+
+  if (metadata->len < offset + sizeof (CommonBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  common = (CommonBlob*)&metadata->data[offset];
+  
+  switch (common->blob_type)
+    {
+    case BLOB_TYPE_FUNCTION:
+      if (!validate_function_blob (metadata, offset, 0, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_CALLBACK:
+      if (!validate_callback_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_STRUCT:
+    case BLOB_TYPE_BOXED:
+      if (!validate_struct_blob (metadata, offset, common->blob_type, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_ENUM:
+    case BLOB_TYPE_FLAGS:
+      if (!validate_enum_blob (metadata, offset, common->blob_type, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_OBJECT:
+      if (!validate_object_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_INTERFACE:
+      if (!validate_interface_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_CONSTANT:
+      if (!validate_constant_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_ERROR_DOMAIN:
+      if (!validate_errordomain_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    case BLOB_TYPE_UNION:
+      if (!validate_union_blob (metadata, offset, error))
+	return FALSE;
+      break;
+    default:
+      g_set_error (error, 
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID_ENTRY,
+		   "Invalid blob type");
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean 
+validate_directory (GTypelib     *metadata,
+		    GError       **error)
+{
+  Header *header = (Header *)metadata->data;
+  DirEntry *entry;
+  gint i;
+  
+  if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;
+    }
+
+  for (i = 0; i < header->n_entries; i++)
+    {
+      entry = g_typelib_get_dir_entry (metadata, i + 1);
+
+      if (!is_name (metadata->data, entry->name))
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_DIRECTORY,
+		       "Invalid entry name");
+	  return FALSE; 
+	}
+      
+      if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
+	  entry->blob_type > BLOB_TYPE_UNION)
+	{
+	  g_set_error (error,
+		       G_TYPELIB_ERROR,
+		       G_TYPELIB_ERROR_INVALID_DIRECTORY,
+		       "Invalid entry type");
+	  return FALSE; 
+	}
+
+      if (i < header->n_local_entries)
+	{
+	  if (!entry->local)
+	    {
+	      g_set_error (error,
+			   G_TYPELIB_ERROR,
+			   G_TYPELIB_ERROR_INVALID_DIRECTORY,
+			   "Too few local directory entries");
+	      return FALSE;
+	    }
+
+	  if (!is_aligned (entry->offset))
+	    {
+	      g_set_error (error,
+			   G_TYPELIB_ERROR,
+			   G_TYPELIB_ERROR_INVALID_DIRECTORY,
+			   "Misaligned entry");
+	      return FALSE;
+	    }
+
+	  if (!validate_blob (metadata, entry->offset, error))
+	    return FALSE;
+	}
+      else
+	{
+	  if (entry->local)
+	    {
+	      g_set_error (error,
+			   G_TYPELIB_ERROR,
+			   G_TYPELIB_ERROR_INVALID_DIRECTORY,
+			   "Too many local directory entries");
+	      return FALSE;
+	    }
+
+	  if (!is_name (metadata->data, entry->offset))
+	    {
+	      g_set_error (error,
+			   G_TYPELIB_ERROR,
+			   G_TYPELIB_ERROR_INVALID_DIRECTORY,
+			   "Invalid namespace name");
+	      return FALSE; 
+	    }
+	}
+    }
+
+  return TRUE;
+}
+
+static gboolean
+validate_annotations (GTypelib     *metadata, 
+		      GError       **error)
+{
+  Header *header = (Header *)metadata->data;
+
+  if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob))
+    {
+      g_set_error (error,
+		   G_TYPELIB_ERROR,
+		   G_TYPELIB_ERROR_INVALID,
+		   "The buffer is too short");
+      return FALSE;      
+    }
+  
+  return TRUE;
+}
+
+gboolean 
+g_typelib_validate (GTypelib     *metadata,
+		     GError       **error)
+{
+  if (!validate_header (metadata, error))
+    return FALSE;
+
+  if (!validate_directory (metadata, error))
+    return FALSE;
+
+  if (!validate_annotations (metadata, error))
+    return FALSE;
+
+  return TRUE;
+}
+
+GQuark
+g_typelib_error_quark (void)
+{
+  static GQuark quark = 0;
+  if (quark == 0)
+    quark = g_quark_from_static_string ("g-metadata-error-quark");
+  return quark;
+}
+
+static const char*
+find_some_symbol (GTypelib *metadata)
+{
+  Header *header = (Header *) metadata->data;
+  gint i;
+
+  for (i = 0; i < header->n_entries; i++)
+    {
+      DirEntry *entry;
+      
+      entry = g_typelib_get_dir_entry (metadata, i + 1);
+
+      switch (entry->blob_type)
+        {
+        case BLOB_TYPE_FUNCTION:
+          {
+            FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset];
+            
+            if (blob->symbol)
+              return g_typelib_get_string (metadata, blob->symbol);
+          }
+          break;
+        case BLOB_TYPE_OBJECT:
+          {
+            RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset];
+            
+            if (blob->gtype_init)
+              return g_typelib_get_string (metadata, blob->gtype_init);
+          }
+          break;
+        default:
+          break;
+        }
+    }
+
+  return NULL;
+}
+
+static inline void
+_g_typelib_init (GTypelib *metadata)
+{
+  Header *header;
+
+  header = (Header *) metadata->data;
+  if (header->shared_library)
+    {
+      const gchar *shlib;
+
+      shlib = g_typelib_get_string (metadata, header->shared_library);
+      /* note that NULL shlib means to open the main app, which is allowed */
+
+      /* If we do have a shared lib, first be sure the main app isn't already linked to it */
+      if (shlib != NULL)
+        {
+          const char *symbol_in_module;
+           
+          symbol_in_module = find_some_symbol (metadata);
+          if (symbol_in_module != NULL)
+            {
+              metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+              if (metadata->module == NULL)
+                {
+                  g_warning ("Could not open main app as GModule: %s",
+                             g_module_error ());
+                }
+              else
+                {
+                  void *sym;
+                  if (!g_module_symbol (metadata->module, symbol_in_module, &sym))
+                    {
+                      /* we will try opening the shlib, symbol is not in app already */
+                      g_module_close (metadata->module);
+                      metadata->module = NULL;
+                    }
+                }
+            }
+          else
+            {
+              g_warning ("Could not find any symbols in metadata");
+            }
+        }
+     
+      if (metadata->module == NULL)
+        {
+          /* Glade's autoconnect feature and OpenGL's extension mechanism
+           * as used by Clutter rely on dlopen(NULL) to work as a means of
+           * accessing the app's symbols. This keeps us from using
+           * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
+           * in general libraries are not expecting multiple copies of
+           * themselves and are not expecting to be unloaded. So we just
+           * load modules globally for now.
+           */
+          
+          metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY);
+          if (metadata->module == NULL)
+            g_warning ("Failed to load shared library referenced by the metadata: %s",
+                       g_module_error ());
+        }
+    }
+}
+
+/**
+ * g_typelib_new_from_memory:
+ * @memory: address of memory chunk containing the metadata
+ * @len: length of memory chunk containing the metadata
+ * 
+ * Creates a new #GTypelib from a memory location.  The memory block
+ * pointed to by @metadata will be automatically g_free()d when the
+ * repository is destroyed.
+ * 
+ * Return value: the new #GTypelib
+ **/
+GTypelib *
+g_typelib_new_from_memory (guchar *memory, gsize len)
+{
+  GTypelib *meta;
+
+  meta = g_new0 (GTypelib, 1);
+  meta->data = memory;
+  meta->len = len;
+  meta->owns_memory = TRUE;
+  _g_typelib_init (meta);
+  return meta;
+}
+
+/**
+ * g_typelib_new_from_const_memory:
+ * @memory: address of memory chunk containing the metadata
+ * @len: length of memory chunk containing the metadata
+ * 
+ * Creates a new #GTypelib from a memory location.
+ * 
+ * Return value: the new #GTypelib
+ **/
+GTypelib *
+g_typelib_new_from_const_memory (const guchar *memory, gsize len)
+{
+  GTypelib *meta;
+
+  meta = g_new0 (GTypelib, 1);
+  meta->data = (guchar *) memory;
+  meta->len = len;
+  meta->owns_memory = FALSE;
+  _g_typelib_init (meta);
+  return meta;
+}
+
+/**
+ * g_typelib_new_from_mapped_file:
+ * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
+ * 
+ * Creates a new #GTypelib from a #GMappedFile.
+ * 
+ * Return value: the new #GTypelib
+ **/
+GTypelib *
+g_typelib_new_from_mapped_file (GMappedFile *mfile)
+{
+  GTypelib *meta;
+
+  meta = g_new0 (GTypelib, 1);
+  meta->mfile = mfile;
+  meta->owns_memory = FALSE;
+  meta->data = (guchar *) g_mapped_file_get_contents (mfile);
+  meta->len = g_mapped_file_get_length (mfile);
+  _g_typelib_init (meta);
+  return meta;
+}
+
+/**
+ * g_typelib_free:
+ * @metadata: a #GTypelib
+ * 
+ * Free a #GTypelib.
+ **/
+void
+g_typelib_free (GTypelib *metadata)
+{
+  if (metadata->mfile)
+    g_mapped_file_free (metadata->mfile);
+  else
+    if (metadata->owns_memory)
+      g_free (metadata->data);
+  if (metadata->module)
+    g_module_close (metadata->module);
+  g_free (metadata);
+}
+
+/**
+ * g_typelib_set_module:
+ * @metadata: a #GTypelib instance
+ * @module: a #GModule; takes ownership of this module
+ * 
+ * Sets the target module for all symbols referenced by the metadata.
+ **/
+void
+g_typelib_set_module (GTypelib *metadata, GModule *module)
+{
+  if (metadata->module)
+    g_module_close (metadata->module);
+  metadata->module = module;
+}
+
+const gchar *
+g_typelib_get_namespace(GTypelib *metadata)
+{
+  return g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace);
+}

Added: trunk/girepository/gtypelib.h
==============================================================================
--- (empty file)
+++ trunk/girepository/gtypelib.h	Sun Jun  8 14:37:30 2008
@@ -0,0 +1,549 @@
+/* GObject introspection: struct definitions for the binary
+ * metadata format, validation
+ *
+ * Copyright (C) 2005 Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_TYPELIB_H__
+#define __G_TYPELIB_H__
+
+#include <gmodule.h>
+#include "girepository.h"
+
+G_BEGIN_DECLS
+
+#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032"
+
+enum 
+{
+  BLOB_TYPE_INVALID,
+  BLOB_TYPE_FUNCTION,
+  BLOB_TYPE_CALLBACK,
+  BLOB_TYPE_STRUCT,
+  BLOB_TYPE_BOXED,
+  BLOB_TYPE_ENUM,
+  BLOB_TYPE_FLAGS,
+  BLOB_TYPE_OBJECT,
+  BLOB_TYPE_INTERFACE,
+  BLOB_TYPE_CONSTANT,
+  BLOB_TYPE_ERROR_DOMAIN,
+  BLOB_TYPE_UNION
+};
+
+typedef struct
+{
+  gchar   magic[16];
+  guint8  major_version;
+  guint8  minor_version;
+  guint16 reserved;
+  guint16 n_entries;
+  guint16 n_local_entries;
+  guint32 directory;
+  guint32 n_annotations;
+  guint32 annotations;
+
+  guint32 size;
+  guint32 namespace;
+  guint32 shared_library;
+
+  guint16 entry_blob_size;
+  guint16 function_blob_size;
+  guint16 callback_blob_size;
+  guint16 signal_blob_size;
+  guint16 vfunc_blob_size;
+  guint16 arg_blob_size;
+  guint16 property_blob_size;
+  guint16 field_blob_size;
+  guint16 value_blob_size;
+  guint16 annotation_blob_size;
+  guint16 constant_blob_size;
+  guint16 error_domain_blob_size;
+
+  guint16 signature_blob_size;
+  guint16 enum_blob_size;
+  guint16 struct_blob_size;
+  guint16 object_blob_size;
+  guint16 interface_blob_size;
+  guint16 union_blob_size;
+  
+  guint16 padding[7];
+} Header;
+
+typedef struct
+{
+  guint16 blob_type;
+
+  guint   local    : 1;
+  guint   reserved :15;
+
+  guint32 name;
+  guint32 offset;
+} DirEntry;
+
+
+#define TYPE_POINTER_MASK 1 << 7
+#define TYPE_TAG_MASK         63
+
+typedef enum 
+{
+  TYPE_TAG_VOID      =  0,
+  TYPE_TAG_BOOLEAN   =  1,
+  TYPE_TAG_INT8      =  2,
+  TYPE_TAG_UINT8     =  3,
+  TYPE_TAG_INT16     =  4,
+  TYPE_TAG_UINT16    =  5,  
+  TYPE_TAG_INT32     =  6,
+  TYPE_TAG_UINT32    =  7,
+  TYPE_TAG_INT64     =  8,
+  TYPE_TAG_UINT64    =  9,
+  TYPE_TAG_INT       = 10,
+  TYPE_TAG_UINT      = 11,
+  TYPE_TAG_LONG      = 12,
+  TYPE_TAG_ULONG     = 13,
+  TYPE_TAG_SSIZE     = 14,
+  TYPE_TAG_SIZE      = 15,
+  TYPE_TAG_FLOAT     = 16,
+  TYPE_TAG_DOUBLE    = 17,
+  TYPE_TAG_UTF8      = 18,
+  TYPE_TAG_FILENAME  = 19,
+  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 union
+{
+  struct 
+  {
+    guint reserved   : 8;
+    guint reserved2  :16;
+    guint pointer    : 1;
+    guint reserved3  : 2;
+    guint tag        : 5;    
+  };
+  guint32    offset;
+} SimpleTypeBlob;
+
+
+typedef struct
+{
+  guint32        name;
+
+  guint          in                           : 1;
+  guint          out                          : 1;
+  guint          dipper                       : 1;
+  guint          null_ok                      : 1;
+  guint          optional                     : 1;
+  guint          transfer_ownership           : 1;
+  guint          transfer_container_ownership : 1;
+  guint          return_value                 : 1;
+  guint          reserved                     :24;
+
+  SimpleTypeBlob arg_type;
+} ArgBlob;
+
+typedef struct 
+{
+  SimpleTypeBlob return_type;
+
+  guint          may_return_null              : 1;
+  guint          caller_owns_return_value     : 1;
+  guint          caller_owns_return_container : 1;
+  guint          reserved                     :13;
+
+  guint16        n_arguments;
+
+  ArgBlob        arguments[];
+} SignatureBlob;
+
+typedef struct
+{
+  guint16 blob_type;  /* 1 */
+
+  guint   deprecated     : 1;
+  guint   reserved       :15;
+
+  guint32 name;
+} CommonBlob;
+
+typedef struct 
+{
+  guint16 blob_type;  /* 1 */
+
+  guint   deprecated     : 1;
+  guint   setter         : 1; 
+  guint   getter         : 1;
+  guint   constructor    : 1;
+  guint   wraps_vfunc    : 1;
+  guint   reserved       : 1;
+  guint   index          :10;
+
+  guint32 name;
+  guint32 symbol;
+  guint32 signature;
+} FunctionBlob;
+
+typedef struct 
+{
+  guint16 blob_type;  /* 2 */
+
+  guint   deprecated     : 1;
+  guint   reserved       :15;
+
+  guint32 name;
+  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;    
+
+  guint          zero_terminated :1;
+  guint          has_length      :1;
+  guint          reserved2       :6;
+
+  guint16        length;
+
+  SimpleTypeBlob type;
+} ArrayTypeBlob;
+
+typedef struct
+{
+  guint pointer    :1;
+  guint reserved   :2;
+  guint tag        :5;    
+
+  guint8         reserved2;
+  guint16        n_types;
+
+  SimpleTypeBlob type[];
+} ParamTypeBlob;
+
+typedef struct
+{
+  guint pointer    :1;
+  guint reserved   :2;
+  guint tag        :5;    
+
+  guint8     reserved2;
+  guint16    n_domains;
+
+  guint16    domains[];
+}  ErrorTypeBlob;
+
+typedef struct
+{
+  guint16 blob_type;  /* 10 */
+
+  guint   deprecated     : 1;
+  guint   reserved       :15;
+  
+  guint32 name;
+
+  guint32 get_quark;
+  guint16 error_codes;
+  guint16 reserved2;
+} ErrorDomainBlob;
+
+typedef struct
+{
+  guint   deprecated : 1;
+  guint   reserved   :31;
+  guint32 name;
+  guint32 value;
+} ValueBlob;
+
+typedef struct 
+{
+  guint32        name;
+
+  guint          readable : 1; 
+  guint          writable : 1;
+  guint          reserved : 6;
+  guint8         bits;
+
+  guint16        struct_offset;      
+
+  SimpleTypeBlob type;
+} FieldBlob;
+
+typedef struct
+{
+  guint16 blob_type;  
+  guint   deprecated   : 1; 
+  guint   unregistered :15;
+  guint32 name; 
+
+  guint32 gtype_name;
+  guint32 gtype_init;
+} RegisteredTypeBlob;
+
+typedef struct
+{
+  guint16   blob_type;
+
+  guint     deprecated   : 1;
+  guint     unregistered : 1;
+  guint     reserved     :14;
+
+  guint32   name;
+
+  guint32   gtype_name;
+  guint32   gtype_init;
+
+  guint16   n_fields;
+  guint16   n_methods;
+
+#if 0
+  /* variable-length parts of the blob */
+  FieldBlob    fields[];   
+  FunctionBlob methods[];
+#endif
+} StructBlob;
+
+typedef struct 
+{  
+  guint16      blob_type; 
+  guint        deprecated    : 1;
+  guint        unregistered  : 1;
+  guint        discriminated : 1;
+  guint        reserved      :13;
+  guint32      name;
+
+  guint32      gtype_name;
+  guint32      gtype_init;
+
+  guint16      n_fields;
+  guint16      n_functions;
+
+  gint32       discriminator_offset; 
+  SimpleTypeBlob discriminator_type;
+
+#if 0
+  FieldBlob    fields[];   
+  FunctionBlob functions[];  
+  ConstantBlob discriminator_values[]
+#endif
+} UnionBlob;
+
+typedef struct
+{
+  guint16   blob_type;
+
+  guint     deprecated   : 1; 
+  guint     unregistered : 1;
+  guint     reserved     :14;
+
+  guint32   name; 
+
+  guint32   gtype_name;
+  guint32   gtype_init;
+
+  guint16   n_values;
+  guint16   reserved2;
+
+  ValueBlob values[];    
+} EnumBlob;
+
+typedef struct
+{
+  guint32        name;
+
+  guint          deprecated     : 1;
+  guint          readable       : 1;
+  guint          writable       : 1;
+  guint          construct      : 1;
+  guint          construct_only : 1;
+  guint          reserved       :27;
+
+  SimpleTypeBlob type;
+
+} PropertyBlob;
+
+typedef struct
+{
+  guint   deprecated        : 1;
+  guint   run_first         : 1;
+  guint   run_last          : 1;
+  guint   run_cleanup       : 1;
+  guint   no_recurse        : 1;
+  guint   detailed          : 1;
+  guint   action            : 1;
+  guint   no_hooks          : 1;
+  guint   has_class_closure : 1;
+  guint   true_stops_emit   : 1;
+  guint   reserved          : 6;
+
+  guint16 class_closure;
+
+  guint32 name;
+
+  guint32 signature;
+} SignalBlob;
+
+typedef struct 
+{
+  guint32 name;
+
+  guint   must_chain_up           : 1;
+  guint   must_be_implemented     : 1;
+  guint   must_not_be_implemented : 1;
+  guint   class_closure           : 1;
+  guint   reserved                :12;
+  guint16 signal;
+
+  guint16 struct_offset;
+  guint16 reserved2;
+  guint32 signature;
+} VFuncBlob;
+
+typedef struct
+{
+  guint16   blob_type;  /* 7 */
+  guint     deprecated   : 1; 
+  guint     reserved     :15;
+  guint32   name; 
+
+  guint32   gtype_name;
+  guint32   gtype_init;
+
+  guint16   parent;
+
+  guint16   n_interfaces;
+  guint16   n_fields;
+  guint16   n_properties;
+  guint16   n_methods;
+  guint16   n_signals;
+  guint16   n_vfuncs;
+  guint16   n_constants;
+
+  guint16   interfaces[];
+ 
+#if 0
+  /* variable-length parts of the blob */
+  FieldBlob           fields[];
+  PropertyBlob        properties[];
+  FunctionBlob        methods[];
+  SignalBlob          signals[];
+  VFuncBlob           vfuncs[];
+  ConstantBlob        constants[];
+#endif
+} ObjectBlob;
+
+typedef struct 
+{
+  guint16 blob_type;  
+  guint   deprecated   : 1; 
+  guint   reserved     :15;
+  guint32 name; 
+
+  guint32 gtype_name;
+  guint32 gtype_init;
+
+  guint16 n_prerequisites;
+  guint16 n_properties;
+  guint16 n_methods;
+  guint16 n_signals;
+  guint16 n_vfuncs;
+  guint16 n_constants;  
+
+  guint16 prerequisites[];
+
+#if 0 
+  /* variable-length parts of the blob */
+  PropertyBlob        properties[];
+  FunctionBlob        methods[];
+  SignalBlob          signals[];
+  VFuncBlob           vfuncs[];
+  ConstantBlob        constants[];
+#endif
+} InterfaceBlob;
+
+
+typedef struct
+{
+  guint16        blob_type;
+  guint          deprecated   : 1; 
+  guint          reserved     :15;
+  guint32        name; 
+
+  SimpleTypeBlob type;
+
+  guint32        size;
+  guint32        offset;
+} ConstantBlob;
+
+typedef struct
+{ 
+  guint32 offset;
+  guint32 name;
+  guint32 value;
+} AnnotationBlob;
+
+
+struct _GTypelib {
+  guchar *data;
+  gsize len;
+  gboolean owns_memory;
+  GMappedFile *mfile;
+  GModule *module;
+};
+
+DirEntry *g_typelib_get_dir_entry (GTypelib *metadata,
+				    guint16            index);
+
+void      g_typelib_check_sanity (void);
+
+#define   g_typelib_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)])
+
+
+typedef enum
+{
+  G_TYPELIB_ERROR_INVALID,
+  G_TYPELIB_ERROR_INVALID_HEADER,
+  G_TYPELIB_ERROR_INVALID_DIRECTORY,
+  G_TYPELIB_ERROR_INVALID_ENTRY,
+  G_TYPELIB_ERROR_INVALID_BLOB
+} GTypelibError;
+
+#define G_TYPELIB_ERROR (g_typelib_error_quark ())
+
+GQuark g_typelib_error_quark (void);
+
+gboolean g_typelib_validate (GTypelib  *metadata,
+			      GError    **error);
+
+
+G_END_DECLS
+
+#endif  /* __G_TYPELIB_H__ */
+

Modified: trunk/tools/compiler.c
==============================================================================
--- trunk/tools/compiler.c	(original)
+++ trunk/tools/compiler.c	Sun Jun  8 14:37:30 2008
@@ -27,7 +27,7 @@
 #include "gidlmodule.h"
 #include "gidlnode.h"
 #include "gidlparser.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 gboolean raw = FALSE;
 gboolean no_init = FALSE;
@@ -39,7 +39,7 @@
 gboolean verbose = FALSE;
 
 static gchar *
-format_output (GMetadata *metadata)
+format_output (GTypelib *metadata)
 {
   GString *result;
   gint i;
@@ -49,7 +49,7 @@
   g_string_append_printf (result, "#include <stdlib.h>\n");
   g_string_append_printf (result, "#include <girepository.h>\n\n");
   
-  g_string_append_printf (result, "const unsigned char _G_METADATA[] = \n{");
+  g_string_append_printf (result, "const unsigned char _G_TYPELIB[] = \n{");
 
   for (i = 0; i < metadata->len; i++)
     {
@@ -63,7 +63,7 @@
     }
 
   g_string_append_printf (result, "\n};\n\n");
-  g_string_append_printf (result, "const gsize _G_METADATA_SIZE = %u;\n\n",
+  g_string_append_printf (result, "const gsize _G_TYPELIB_SIZE = %u;\n\n",
 			  (guint)metadata->len);
 
   if (!no_init)
@@ -72,8 +72,8 @@
 			      "__attribute__((constructor)) void\n"
 			      "register_metadata (void)\n"
 			      "{\n"
-			      "\tGMetadata *metadata;\n"
-			      "\tmetadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n"
+			      "\tGTypelib *metadata;\n"
+			      "\tmetadata = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE);\n"
 			      "\tg_irepository_register (NULL, metadata);\n"
 			      "}\n\n");
 
@@ -83,7 +83,7 @@
 			      "{\n"
 			      "\tg_irepository_unregister (NULL, \"%s\");\n"
 			      "}\n",
-			      g_metadata_get_namespace (metadata));
+			      g_typelib_get_namespace (metadata));
     }
 
   return g_string_free (result, FALSE);
@@ -91,7 +91,7 @@
 
 static void
 write_out_metadata (gchar *prefix,
-		    GMetadata *metadata)
+		    GTypelib *metadata)
 {
   FILE *file;
 
@@ -167,7 +167,7 @@
   GError *error = NULL;
   GList *c, *m, *modules; 
   gint i;
-  g_metadata_check_sanity ();
+  g_typelib_check_sanity ();
 
   context = g_option_context_new ("");
   g_option_context_add_main_entries (context, options, NULL);
@@ -210,7 +210,7 @@
     {
       GIdlModule *module = m->data;
       gchar *prefix;
-      GMetadata *metadata;
+      GTypelib *metadata;
 
       if (mname && strcmp (mname, module->name) != 0)
 	continue;
@@ -227,7 +227,7 @@
 
 	  continue;
 	}
-      if (!g_metadata_validate (metadata, &error))
+      if (!g_typelib_validate (metadata, &error))
 	g_error ("Invalid metadata for module '%s': %s", 
 		 module->name, error->message);
 
@@ -237,7 +237,7 @@
 	prefix = NULL;
 
       write_out_metadata (prefix, metadata);
-      g_metadata_free (metadata);
+      g_typelib_free (metadata);
       metadata = NULL;
 
       /* when writing to stdout, stop after the first module */

Modified: trunk/tools/generate.c
==============================================================================
--- trunk/tools/generate.c	(original)
+++ trunk/tools/generate.c	Sun Jun  8 14:37:30 2008
@@ -28,7 +28,7 @@
 #include <glib/gstdio.h>
 
 #include "girepository.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 /* FIXME: Avoid global */
 static gchar *output = NULL;
@@ -1103,14 +1103,14 @@
   GModule *handle; 
 
   handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
-  if (!g_module_symbol (handle, "_G_METADATA", (gpointer *) &metadata))
+  if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &metadata))
     {
       g_printerr ("Could not load metadata from '%s': %s\n", 
 		  filename, g_module_error ());
       return NULL;
     }
   
-  if (!g_module_symbol (handle, "_G_METADATA_SIZE", (gpointer *) &metadata_size))
+  if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &metadata_size))
     {
       g_printerr ("Could not load metadata from '%s': %s\n", 
 		  filename, g_module_error ());
@@ -1134,7 +1134,7 @@
   GError *error = NULL;
   gboolean needs_prefix;
   gint i;
-  GMetadata *data;
+  GTypelib *data;
   GOptionEntry options[] = 
     {
       { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "handle raw metadata", NULL },
@@ -1145,7 +1145,7 @@
 
   g_type_init ();
 
-  g_metadata_check_sanity ();
+  g_typelib_check_sanity ();
 
   context = g_option_context_new ("");
   g_option_context_add_main_entries (context, options, NULL);
@@ -1190,10 +1190,10 @@
       else
 	needs_prefix = FALSE;
 
-      data = g_metadata_new_from_const_memory (metadata, len);
+      data = g_typelib_new_from_const_memory (metadata, len);
       {
         GError *error = NULL;
-        if (!g_metadata_validate (data, &error)) {
+        if (!g_typelib_validate (data, &error)) {
           g_printerr ("metadata not valid: %s\n", error->message);
           g_clear_error (&error);
         }
@@ -1201,7 +1201,7 @@
       g_irepository_register (g_irepository_get_default (), data);
       write_repository (g_irepository_get_default (), needs_prefix);
       g_irepository_unregister (g_irepository_get_default (),
-                                g_metadata_get_namespace (data));
+                                g_typelib_get_namespace (data));
 
       if (dlhandle)
 	{

Modified: trunk/tools/gidlmodule.c
==============================================================================
--- trunk/tools/gidlmodule.c	(original)
+++ trunk/tools/gidlmodule.c	Sun Jun  8 14:37:30 2008
@@ -60,7 +60,7 @@
   g_free (module);
 }
 
-GMetadata *
+GTypelib *
 g_idl_module_build_metadata (GIdlModule  *module,
 			     GList       *modules)
 {
@@ -210,6 +210,6 @@
 
   metadata = g_realloc (data, offset2);
   length = header->size = offset2;
-  return g_metadata_new_from_memory (metadata, length);
+  return g_typelib_new_from_memory (metadata, length);
 }
 

Modified: trunk/tools/gidlmodule.h
==============================================================================
--- trunk/tools/gidlmodule.h	(original)
+++ trunk/tools/gidlmodule.h	Sun Jun  8 14:37:30 2008
@@ -22,7 +22,7 @@
 #define __G_IDL_MODULE_H__
 
 #include <glib.h>
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 G_BEGIN_DECLS
 
@@ -40,7 +40,7 @@
                                          const gchar *module_filename);
 void        g_idl_module_free           (GIdlModule  *module);
 
-GMetadata * g_idl_module_build_metadata (GIdlModule  *module,
+GTypelib * g_idl_module_build_metadata (GIdlModule  *module,
 					 GList       *modules);
 
 G_END_DECLS

Modified: trunk/tools/gidlnode.c
==============================================================================
--- trunk/tools/gidlnode.c	(original)
+++ trunk/tools/gidlnode.c	Sun Jun  8 14:37:30 2008
@@ -24,7 +24,7 @@
 
 #include "gidlmodule.h"
 #include "gidlnode.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 static gulong string_count = 0;
 static gulong unique_string_count = 0;

Modified: trunk/tools/gidlparser.c
==============================================================================
--- trunk/tools/gidlparser.c	(original)
+++ trunk/tools/gidlparser.c	Sun Jun  8 14:37:30 2008
@@ -25,7 +25,7 @@
 #include <glib.h>
 #include "gidlmodule.h"
 #include "gidlnode.h"
-#include "gmetadata.h"
+#include "gtypelib.h"
 
 typedef enum
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]