Bug 561137 - support multiple repositories

This change makes us stop calling g_irepository_get_default inside ginfo.c,
which won't work for non-default repositories.

Change GIBaseInfo to not only keep track of its source repository,
we hold a reference.  This makes memmgt much clearer.

svn path=/trunk/; revision=970
This commit is contained in:
Colin Walters 2008-11-25 21:48:34 +00:00
parent d8cb1e0d2c
commit a573a1c741
4 changed files with 93 additions and 22 deletions

View File

@ -13,6 +13,7 @@ libgirepository_la_SOURCES = \
gtypelib.h \
gtypelib.c \
gfield.c \
ginfo.h \
ginfo.c \
girffi.c \
girffi.h \

61
ginfo.c
View File

@ -24,13 +24,14 @@
#include <glib.h>
#include <glib-object.h>
#include "girepository.h"
#include "gtypelib.h"
#include "ginfo.h"
struct _GIBaseInfo
{
gint type;
gint ref_count;
GIRepository *repository;
GIBaseInfo *container;
GTypelib *typelib;
@ -135,13 +136,16 @@ struct _GIUnionInfo
/* info creation */
GIBaseInfo *
g_info_new (GIInfoType type,
GIBaseInfo *container,
GTypelib *typelib,
guint32 offset)
g_info_new_full (GIInfoType type,
GIRepository *repository,
GIBaseInfo *container,
GTypelib *typelib,
guint32 offset)
{
GIBaseInfo *info;
g_return_val_if_fail (container != NULL || repository != NULL, NULL);
info = g_new0 (GIBaseInfo, 1);
info->ref_count = 1;
@ -153,38 +157,48 @@ g_info_new (GIInfoType type,
if (container)
info->container = g_base_info_ref (container);
info->repository = g_object_ref (repository);
return info;
}
GIBaseInfo *
g_info_new (GIInfoType type,
GIBaseInfo *container,
GTypelib *typelib,
guint32 offset)
{
return g_info_new_full (type, container->repository, container, typelib, offset);
}
static GIBaseInfo *
g_info_from_entry (GTypelib *typelib,
g_info_from_entry (GIRepository *repository,
GTypelib *typelib,
guint16 index)
{
GIBaseInfo *result;
DirEntry *entry = g_typelib_get_dir_entry (typelib, index);
if (entry->local)
result = g_info_new (entry->blob_type, NULL, typelib, entry->offset);
else
result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset);
else
{
const gchar *namespace = g_typelib_get_string (typelib, entry->offset);
const gchar *name = g_typelib_get_string (typelib, entry->name);
GIRepository *repository = g_irepository_get_default ();
result = g_irepository_find_by_name (repository, namespace, name);
if (result == NULL)
{
GIUnresolvedInfo *unresolved;
unresolved = g_new0 (GIUnresolvedInfo, 1);
unresolved->type = GI_INFO_TYPE_UNRESOLVED;
unresolved->ref_count = 1;
unresolved->container = NULL;
unresolved->name = name;
unresolved->namespace = namespace;
return (GIBaseInfo*)unresolved;
}
return result;
@ -213,6 +227,8 @@ g_base_info_unref (GIBaseInfo *info)
if (info->container)
g_base_info_unref (info->container);
g_object_unref (info->repository);
g_free (info);
}
}
@ -804,7 +820,7 @@ g_type_info_get_interface (GITypeInfo *info)
InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
if (blob->tag == GI_TYPE_TAG_INTERFACE)
return g_info_from_entry (base->typelib, blob->interface);
return g_info_from_entry (base->repository, base->typelib, blob->interface);
}
return NULL;
@ -896,7 +912,8 @@ g_type_info_get_error_domain (GITypeInfo *info,
ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset];
if (blob->tag == GI_TYPE_TAG_ERROR)
return (GIErrorDomainInfo *) g_info_from_entry (base->typelib,
return (GIErrorDomainInfo *) g_info_from_entry (base->repository,
base->typelib,
blob->domains[n]);
}
@ -920,7 +937,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info)
GIBaseInfo *base = (GIBaseInfo *)info;
ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset];
return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes);
return (GIInterfaceInfo *) g_info_from_entry (base->repository,
base->typelib, blob->error_codes);
}
@ -1182,7 +1200,8 @@ g_object_info_get_parent (GIObjectInfo *info)
ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
if (blob->parent)
return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent);
return (GIObjectInfo *) g_info_from_entry (base->repository,
base->typelib, blob->parent);
else
return NULL;
}
@ -1229,7 +1248,8 @@ g_object_info_get_interface (GIObjectInfo *info,
GIBaseInfo *base = (GIBaseInfo *)info;
ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]);
return (GIInterfaceInfo *) g_info_from_entry (base->repository,
base->typelib, blob->interfaces[n]);
}
gint
@ -1437,7 +1457,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info,
GIBaseInfo *base = (GIBaseInfo *)info;
InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
return g_info_from_entry (base->typelib, blob->prerequisites[n]);
return g_info_from_entry (base->repository,
base->typelib, blob->prerequisites[n]);
}

42
ginfo.h Normal file
View File

@ -0,0 +1,42 @@
/* GObject introspection: Typelib info functions
*
* Copyright (C) 2008 Red Hat, Inc
*
* 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 __GIRINFO_H__
#define __GIRINFO_H__
#include "girepository.h"
G_BEGIN_DECLS
GITypeInfo *
g_type_info_new (GIBaseInfo *container,
GTypelib *typelib,
guint32 offset);
GIBaseInfo *
g_info_new_full (GIInfoType type,
GIRepository *repository,
GIBaseInfo *container,
GTypelib *typelib,
guint32 offset);
G_END_DECLS
#endif

View File

@ -30,6 +30,7 @@
#include <gmodule.h>
#include "girepository.h"
#include "gtypelib.h"
#include "ginfo.h"
#include "config.h"
@ -333,6 +334,7 @@ register_internal (GIRepository *repository,
else
key = build_typelib_key (namespace, source);
g_printerr ("loaded: %s\n", key);
g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
}
@ -487,6 +489,7 @@ g_irepository_get_n_infos (GIRepository *repository,
typedef struct
{
GIRepository *repo;
gint index;
const gchar *name;
const gchar *type;
@ -556,8 +559,9 @@ find_interface (gpointer key,
if (index != 0)
{
entry = g_typelib_get_dir_entry (typelib, index);
iface_data->iface = g_info_new (entry->blob_type, NULL,
typelib, entry->offset);
iface_data->iface = g_info_new_full (entry->blob_type,
iface_data->repo,
NULL, typelib, entry->offset);
}
}
@ -585,6 +589,7 @@ g_irepository_get_info (GIRepository *repository,
repository = get_repository (repository);
data.repo = repository;
data.name = NULL;
data.type = NULL;
data.index = index + 1;
@ -621,6 +626,7 @@ g_irepository_find_by_gtype (GIRepository *repository,
repository = get_repository (repository);
data.repo = repository;
data.name = NULL;
data.type = g_type_name (type);
data.index = -1;
@ -657,6 +663,7 @@ g_irepository_find_by_name (GIRepository *repository,
repository = get_repository (repository);
data.repo = repository;
data.name = name;
data.type = NULL;
data.index = -1;