mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-03 09:46:17 +01:00
Added: Added: Renamed to tools/Makefile.am: Renamed to tools/compiler.c:
2008-02-08 Rob Taylor <rob.taylor@codethink.co.uk> * Makefile.am: * configure.ac: * gidl/Makefile.am: Added: * girepository/Makefile.am: Added: * src/Makefile.am: Renamed to tools/Makefile.am: * src/compiler.c: Renamed to tools/compiler.c: * src/g-idl-offsets.pl: Renamed to tools/g-idl-offsets.pl: * src/generate.c: Renamed to tools/generate.c: * src/gidlmodule.c: Renamed to tools/gidlmodule.c: * src/gidlmodule.h: Renamed to tools/gidlmodule.h: * src/gidlnode.c: Renamed to tools/gidlnode.c: * src/gidlnode.h: Renamed to tools/gidlnode.h: * src/gidlparser.c: Renamed to tools/gidlparser.c: * src/gidlparser.h: Renamed to tools/gidlparser.h: * src/gidlwriter.c: Renamed to tools/gidlwriter.c: * src/gidlwriter.h: Renamed to tools/gidlwriter.h: * src/ginfo.c: Renamed to girepository/ginfo.c: * src/ginvoke.c: Renamed to girepository/ginvoke.c: * src/girepository.c: Renamed to girepository/girepository.c: * src/girepository.h: Renamed to girepository/girepository.h: * src/gmetadata.c: Renamed to girepository/gmetadata.c: * src/gmetadata.h: Renamed to girepository/gmetadata.h: * src/scanner.c: Renamed to tools/scanner.c: * src/scanner.h: Renamed to tools/scanner.h: * src/scannerlexer.l: Renamed to tools/scannerlexer.l: * src/scannerparser.y: Renamed to tools/scannerparser.y: * tests/invoke/Makefile.am: Split src/ into girepository/ and tools/ * Makefile.am: * configure.ac: * girepository/Makefile.am: * tests/Makefile.am: * tests/invoke/Makefile.am: * tests/parser/Makefile.am: * tests/roundtrips.sh: * tools/Makefile.am: Make distcheck work. svn path=/trunk/; revision=104
This commit is contained in:
commit
ac69c8f5a4
16
Makefile.am
Normal file
16
Makefile.am
Normal file
@ -0,0 +1,16 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\""
|
||||
|
||||
lib_LTLIBRARIES = libgirepository.la
|
||||
|
||||
libgirepository_la_SOURCES = \
|
||||
girepository.c \
|
||||
gmetadata.h \
|
||||
gmetadata.c \
|
||||
ginfo.c \
|
||||
ginvoke.c
|
||||
libgirepository_la_CFLAGS = $(GIREPO_CFLAGS)
|
||||
|
||||
girepodir = $(includedir)/glib-2.0/gobject-introspection
|
||||
girepo_HEADERS = girepository.h
|
284
ginvoke.c
Normal file
284
ginvoke.c
Normal file
@ -0,0 +1,284 @@
|
||||
/* GObject introspection: Invoke functionality
|
||||
*
|
||||
* 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 <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "girepository.h"
|
||||
#include "gmetadata.h"
|
||||
#include "config.h"
|
||||
|
||||
GQuark
|
||||
g_invoke_error_quark (void)
|
||||
{
|
||||
static GQuark quark = 0;
|
||||
if (quark == 0)
|
||||
quark = g_quark_from_static_string ("g-invoke-error-quark");
|
||||
return quark;
|
||||
}
|
||||
|
||||
#include "ffi.h"
|
||||
|
||||
static ffi_type *
|
||||
get_ffi_type (GITypeInfo *info)
|
||||
{
|
||||
ffi_type *rettype;
|
||||
|
||||
if (g_type_info_is_pointer (info))
|
||||
rettype = &ffi_type_pointer;
|
||||
else
|
||||
switch (g_type_info_get_tag (info))
|
||||
{
|
||||
case GI_TYPE_TAG_VOID:
|
||||
rettype = &ffi_type_void;
|
||||
break;
|
||||
case GI_TYPE_TAG_BOOLEAN:
|
||||
rettype = &ffi_type_uint;
|
||||
break;
|
||||
case GI_TYPE_TAG_INT8:
|
||||
rettype = &ffi_type_sint8;
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT8:
|
||||
rettype = &ffi_type_uint8;
|
||||
break;
|
||||
case GI_TYPE_TAG_INT16:
|
||||
rettype = &ffi_type_sint16;
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT16:
|
||||
rettype = &ffi_type_uint16;
|
||||
break;
|
||||
case GI_TYPE_TAG_INT32:
|
||||
rettype = &ffi_type_sint32;
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT32:
|
||||
rettype = &ffi_type_uint32;
|
||||
break;
|
||||
case GI_TYPE_TAG_INT64:
|
||||
rettype = &ffi_type_sint64;
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT64:
|
||||
rettype = &ffi_type_uint64;
|
||||
break;
|
||||
case GI_TYPE_TAG_INT:
|
||||
rettype = &ffi_type_sint;
|
||||
break;
|
||||
case GI_TYPE_TAG_UINT:
|
||||
rettype = &ffi_type_uint;
|
||||
break;
|
||||
case GI_TYPE_TAG_SSIZE: /* FIXME */
|
||||
case GI_TYPE_TAG_LONG:
|
||||
rettype = &ffi_type_slong;
|
||||
break;
|
||||
case GI_TYPE_TAG_SIZE: /* FIXME */
|
||||
case GI_TYPE_TAG_ULONG:
|
||||
rettype = &ffi_type_ulong;
|
||||
break;
|
||||
case GI_TYPE_TAG_FLOAT:
|
||||
rettype = &ffi_type_float;
|
||||
break;
|
||||
case GI_TYPE_TAG_DOUBLE:
|
||||
rettype = &ffi_type_double;
|
||||
break;
|
||||
case GI_TYPE_TAG_UTF8:
|
||||
case GI_TYPE_TAG_FILENAME:
|
||||
case GI_TYPE_TAG_ARRAY:
|
||||
case GI_TYPE_TAG_INTERFACE:
|
||||
case GI_TYPE_TAG_GLIST:
|
||||
case GI_TYPE_TAG_GSLIST:
|
||||
case GI_TYPE_TAG_GHASH:
|
||||
case GI_TYPE_TAG_ERROR:
|
||||
rettype = &ffi_type_pointer;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return rettype;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_function_info_invoke:
|
||||
* @info: a #GIFunctionInfo describing the function to invoke
|
||||
* @in_args: an array of #GArgument<!-- -->s, one for each in
|
||||
* parameter of @info. If there are no in parameter, @in_args
|
||||
* can be %NULL
|
||||
* @n_in_args: the length of the @in_args array
|
||||
* @out_args: an array of #GArgument<!-- -->s, one for each out
|
||||
* parameter of @info. If there are no out parameters, @out_args
|
||||
* may be %NULL
|
||||
* @n_out_args: the length of the @out_args array
|
||||
* @return_value: return location for the return value of the
|
||||
* function. If the function returns void, @return_value may be
|
||||
* %NULL
|
||||
* @error: return location for detailed error information, or %NULL
|
||||
*
|
||||
* Invokes the function described in @info with the given
|
||||
* arguments. Note that inout parameters must appear in both
|
||||
* argument lists. This function uses dlsym() to obtain a pointer
|
||||
* to the function, so the library or shared object containing the
|
||||
* described function must either be linked to the caller, or must
|
||||
* have been dlopen()<!-- -->ed before calling this function.
|
||||
*
|
||||
* Returns: %TRUE if the function has been invoked, %FALSE if an
|
||||
* error occurred.
|
||||
*/
|
||||
gboolean
|
||||
g_function_info_invoke (GIFunctionInfo *info,
|
||||
const GArgument *in_args,
|
||||
int n_in_args,
|
||||
const GArgument *out_args,
|
||||
int n_out_args,
|
||||
GArgument *return_value,
|
||||
GError **error)
|
||||
{
|
||||
ffi_cif cif;
|
||||
ffi_type *rtype;
|
||||
ffi_type **atypes;
|
||||
const gchar *symbol;
|
||||
gpointer func;
|
||||
GITypeInfo *tinfo;
|
||||
GIArgInfo *ainfo;
|
||||
gint n_args, in_pos, out_pos, i;
|
||||
gpointer *args;
|
||||
gboolean success = FALSE;
|
||||
|
||||
symbol = g_function_info_get_symbol (info);
|
||||
|
||||
if (!g_module_symbol (g_base_info_get_metadata((GIBaseInfo *) info)->module,
|
||||
symbol, &func))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
|
||||
"Could not locate %s: %s", symbol, g_module_error ());
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
tinfo = g_callable_info_get_return_type ((GICallableInfo *)info);
|
||||
rtype = get_ffi_type (tinfo);
|
||||
g_base_info_unref ((GIBaseInfo *)tinfo);
|
||||
|
||||
n_args = g_callable_info_get_n_args ((GICallableInfo *)info);
|
||||
atypes = g_new (ffi_type*, n_args);
|
||||
args = g_new (gpointer, n_args);
|
||||
|
||||
in_pos = 0;
|
||||
out_pos = 0;
|
||||
for (i = 0; i < n_args; i++)
|
||||
{
|
||||
ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i);
|
||||
switch (g_arg_info_get_direction (ainfo))
|
||||
{
|
||||
case GI_DIRECTION_IN:
|
||||
tinfo = g_arg_info_get_type (ainfo);
|
||||
atypes[i] = get_ffi_type (tinfo);
|
||||
g_base_info_unref ((GIBaseInfo *)tinfo);
|
||||
|
||||
if (in_pos >= n_in_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too few \"in\" arguments");
|
||||
goto out;
|
||||
}
|
||||
|
||||
args[i] = (gpointer)&in_args[in_pos];
|
||||
in_pos++;
|
||||
|
||||
break;
|
||||
case GI_DIRECTION_OUT:
|
||||
atypes[i] = &ffi_type_pointer;
|
||||
|
||||
if (out_pos >= n_out_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too few \"out\" arguments");
|
||||
goto out;
|
||||
}
|
||||
|
||||
args[i] = (gpointer)&out_args[out_pos];
|
||||
out_pos++;
|
||||
break;
|
||||
case GI_DIRECTION_INOUT:
|
||||
atypes[i] = &ffi_type_pointer;
|
||||
|
||||
if (in_pos >= n_in_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too few \"in\" arguments");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (out_pos >= n_out_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too few \"in\" arguments");
|
||||
goto out;
|
||||
}
|
||||
|
||||
args[i] = (gpointer)&in_args[in_pos];
|
||||
in_pos++;
|
||||
out_pos++;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
g_base_info_unref ((GIBaseInfo *)ainfo);
|
||||
}
|
||||
if (in_pos < n_in_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too many \"in\" arguments");
|
||||
goto out;
|
||||
}
|
||||
if (out_pos < n_out_args)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_INVOKE_ERROR,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH,
|
||||
"Too many \"out\" arguments");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK)
|
||||
goto out;
|
||||
|
||||
ffi_call (&cif, func, return_value, args);
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
g_free (atypes);
|
||||
g_free (args);
|
||||
|
||||
return success;
|
||||
}
|
499
girepository.c
Normal file
499
girepository.c
Normal file
@ -0,0 +1,499 @@
|
||||
/* -*- Mode: C; c-file-style: "gnu"; -*- */
|
||||
/* GObject introspection: Repository implementation
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <gmodule.h>
|
||||
#include "girepository.h"
|
||||
#include "gmetadata.h"
|
||||
|
||||
static GIRepository *default_repository = NULL;
|
||||
static GHashTable *default_metadata = NULL;
|
||||
static GSList *search_path = NULL;
|
||||
|
||||
struct _GIRepositoryPrivate
|
||||
{
|
||||
GHashTable *metadata; /* (string) namespace -> GMetadata */
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
g_irepository_init (GIRepository *repository)
|
||||
{
|
||||
repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY,
|
||||
GIRepositoryPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
g_irepository_finalize (GObject *object)
|
||||
{
|
||||
GIRepository *repository = G_IREPOSITORY (object);
|
||||
|
||||
g_hash_table_destroy (repository->priv->metadata);
|
||||
|
||||
(* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository));
|
||||
}
|
||||
|
||||
static void
|
||||
g_irepository_class_init (GIRepositoryClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class;
|
||||
|
||||
gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->finalize = g_irepository_finalize;
|
||||
|
||||
g_type_class_add_private (class, sizeof (GIRepositoryPrivate));
|
||||
}
|
||||
|
||||
const gchar *
|
||||
g_irepository_register (GIRepository *repository,
|
||||
GMetadata *metadata)
|
||||
{
|
||||
Header *header;
|
||||
const gchar *name;
|
||||
GHashTable *table;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (metadata != NULL, NULL);
|
||||
|
||||
header = (Header *)metadata->data;
|
||||
|
||||
g_return_val_if_fail (header != NULL, NULL);
|
||||
|
||||
if (repository != NULL)
|
||||
{
|
||||
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);
|
||||
table = repository->priv->metadata;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (default_metadata == NULL)
|
||||
default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) NULL,
|
||||
(GDestroyNotify) g_metadata_free);
|
||||
table = default_metadata;
|
||||
}
|
||||
|
||||
name = g_metadata_get_string (metadata, header->namespace);
|
||||
|
||||
if (g_hash_table_lookup (table, name))
|
||||
{
|
||||
g_printerr ("metadata (%p) for '%s' already registered\n",
|
||||
metadata, name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
g_hash_table_insert (table, g_strdup(name), (void *)metadata);
|
||||
|
||||
if (metadata->module == NULL)
|
||||
metadata->module = g_module_open (NULL, 0);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
g_irepository_unregister (GIRepository *repository,
|
||||
const gchar *namespace)
|
||||
{
|
||||
GHashTable *table;
|
||||
|
||||
if (repository != NULL)
|
||||
table = repository->priv->metadata;
|
||||
else
|
||||
table = default_metadata;
|
||||
|
||||
if (!g_hash_table_remove (table, namespace))
|
||||
{
|
||||
g_printerr ("namespace '%s' not registered\n", namespace);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_irepository_is_registered (GIRepository *repository,
|
||||
const gchar *namespace)
|
||||
{
|
||||
GHashTable *table;
|
||||
|
||||
if (repository != NULL)
|
||||
table = repository->priv->metadata;
|
||||
else
|
||||
table = default_metadata;
|
||||
|
||||
return g_hash_table_lookup (table, namespace) != NULL;
|
||||
}
|
||||
|
||||
GIRepository *
|
||||
g_irepository_get_default (void)
|
||||
{
|
||||
if (default_repository == NULL)
|
||||
{
|
||||
default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
|
||||
if (default_metadata == NULL)
|
||||
default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) NULL,
|
||||
(GDestroyNotify) g_metadata_free);
|
||||
default_repository->priv->metadata = default_metadata;
|
||||
}
|
||||
|
||||
return default_repository;
|
||||
}
|
||||
|
||||
static void
|
||||
count_interfaces (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
guchar *metadata = ((GMetadata *) value)->data;
|
||||
gint *n_interfaces = (gint *)data;
|
||||
|
||||
*n_interfaces += ((Header *)metadata)->n_local_entries;
|
||||
}
|
||||
|
||||
gint
|
||||
g_irepository_get_n_infos (GIRepository *repository,
|
||||
const gchar *namespace)
|
||||
{
|
||||
gint n_interfaces = 0;
|
||||
|
||||
if (namespace)
|
||||
{
|
||||
GMetadata *metadata;
|
||||
|
||||
metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
|
||||
|
||||
if (metadata)
|
||||
n_interfaces = ((Header *)metadata->data)->n_local_entries;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_foreach (repository->priv->metadata,
|
||||
count_interfaces, &n_interfaces);
|
||||
}
|
||||
|
||||
return n_interfaces;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gint index;
|
||||
const gchar *name;
|
||||
const gchar *type;
|
||||
GIBaseInfo *iface;
|
||||
} IfaceData;
|
||||
|
||||
static void
|
||||
find_interface (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
gint i;
|
||||
GMetadata *metadata = (GMetadata *)value;
|
||||
IfaceData *iface_data = (IfaceData *)data;
|
||||
gint index;
|
||||
gint n_entries;
|
||||
guint32 offset;
|
||||
const gchar *name;
|
||||
const gchar *type;
|
||||
DirEntry *entry;
|
||||
|
||||
index = 0;
|
||||
n_entries = ((Header *)metadata->data)->n_local_entries;
|
||||
|
||||
if (iface_data->name)
|
||||
{
|
||||
for (i = 1; i <= n_entries; i++)
|
||||
{
|
||||
entry = g_metadata_get_dir_entry (metadata, i);
|
||||
name = g_metadata_get_string (metadata, entry->name);
|
||||
if (strcmp (name, iface_data->name) == 0)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (iface_data->type)
|
||||
{
|
||||
for (i = 1; i <= n_entries; i++)
|
||||
{
|
||||
entry = g_metadata_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);
|
||||
if (strcmp (type, iface_data->type) == 0)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (iface_data->index > n_entries)
|
||||
iface_data->index -= n_entries;
|
||||
else if (iface_data->index > 0)
|
||||
{
|
||||
index = iface_data->index;
|
||||
iface_data->index = 0;
|
||||
}
|
||||
|
||||
if (index != 0)
|
||||
{
|
||||
entry = g_metadata_get_dir_entry (metadata, index);
|
||||
iface_data->iface = g_info_new (entry->blob_type, NULL,
|
||||
metadata, entry->offset);
|
||||
}
|
||||
}
|
||||
|
||||
GIBaseInfo *
|
||||
g_irepository_get_info (GIRepository *repository,
|
||||
const gchar *namespace,
|
||||
gint index)
|
||||
{
|
||||
IfaceData data;
|
||||
|
||||
data.name = NULL;
|
||||
data.type = NULL;
|
||||
data.index = index + 1;
|
||||
data.iface = NULL;
|
||||
|
||||
if (namespace)
|
||||
{
|
||||
GMetadata *metadata;
|
||||
|
||||
metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
|
||||
|
||||
if (metadata)
|
||||
find_interface ((void *)namespace, metadata, &data);
|
||||
}
|
||||
else
|
||||
g_hash_table_foreach (repository->priv->metadata, find_interface, &data);
|
||||
|
||||
return data.iface;
|
||||
}
|
||||
|
||||
GIBaseInfo *
|
||||
g_irepository_find_by_gtype (GIRepository *repository,
|
||||
GType type)
|
||||
{
|
||||
IfaceData data;
|
||||
|
||||
data.name = NULL;
|
||||
data.type = g_type_name (type);
|
||||
data.index = -1;
|
||||
data.iface = NULL;
|
||||
|
||||
g_hash_table_foreach (repository->priv->metadata, find_interface, &data);
|
||||
|
||||
return data.iface;
|
||||
}
|
||||
|
||||
GIBaseInfo *
|
||||
g_irepository_find_by_name (GIRepository *repository,
|
||||
const gchar *namespace,
|
||||
const gchar *name)
|
||||
{
|
||||
IfaceData data;
|
||||
|
||||
data.name = name;
|
||||
data.type = NULL;
|
||||
data.index = -1;
|
||||
data.iface = NULL;
|
||||
|
||||
if (namespace)
|
||||
{
|
||||
GMetadata *metadata;
|
||||
|
||||
metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
|
||||
|
||||
if (metadata)
|
||||
find_interface ((void *)namespace, metadata, &data);
|
||||
}
|
||||
else
|
||||
g_hash_table_foreach (repository->priv->metadata, find_interface, &data);
|
||||
|
||||
return data.iface;
|
||||
}
|
||||
|
||||
static void
|
||||
collect_namespaces (gpointer key,
|
||||
gpointer value,
|
||||
gpointer data)
|
||||
{
|
||||
GList **list = data;
|
||||
|
||||
*list = g_list_append (*list, key);
|
||||
}
|
||||
|
||||
gchar **
|
||||
g_irepository_get_namespaces (GIRepository *repository)
|
||||
{
|
||||
GList *l, *list = NULL;
|
||||
gchar **names;
|
||||
gint i;
|
||||
|
||||
g_hash_table_foreach (repository->priv->metadata, collect_namespaces, &list);
|
||||
|
||||
names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1));
|
||||
i = 0;
|
||||
for (l = list; l; l = l->next)
|
||||
names[i++] = g_strdup (l->data);
|
||||
g_list_free (list);
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
g_irepository_get_shared_library (GIRepository *repository,
|
||||
const gchar *namespace)
|
||||
{
|
||||
GMetadata *metadata;
|
||||
Header *header;
|
||||
|
||||
metadata = g_hash_table_lookup (repository->priv->metadata, namespace);
|
||||
if (!metadata)
|
||||
return NULL;
|
||||
header = (Header *) metadata->data;
|
||||
if (header->shared_library)
|
||||
return g_metadata_get_string (metadata, header->shared_library);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
g_irepository_build_search_path (void)
|
||||
{
|
||||
gchar **dir;
|
||||
gchar **tokens;
|
||||
|
||||
if (g_getenv ("GIREPOPATH")) {
|
||||
gchar *path;
|
||||
path = g_strconcat (g_getenv ("GIREPOPATH"), ":", GIREPO_DEFAULT_SEARCH_PATH, NULL);
|
||||
tokens = g_strsplit (path, ":", 0);
|
||||
g_free (path);
|
||||
} else
|
||||
tokens = g_strsplit (GIREPO_DEFAULT_SEARCH_PATH, ":", 0);
|
||||
|
||||
search_path = g_slist_prepend (search_path, ".");
|
||||
for (dir = tokens; *dir; ++dir)
|
||||
search_path = g_slist_prepend (search_path, *dir);
|
||||
search_path = g_slist_reverse (search_path);
|
||||
g_free (tokens);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
g_irepository_register_file (GIRepository *repository,
|
||||
const gchar *namespace,
|
||||
GError **error)
|
||||
{
|
||||
GSList *ldir;
|
||||
const char *dir;
|
||||
gchar *fname, *full_path;
|
||||
GMappedFile *mfile;
|
||||
GError *error1 = NULL;
|
||||
GMetadata *metadata = NULL;
|
||||
const gchar *metadata_namespace, *shlib_fname;
|
||||
GModule *module;
|
||||
guint32 shlib;
|
||||
GHashTable *table;
|
||||
|
||||
if (repository != NULL)
|
||||
table = repository->priv->metadata;
|
||||
else
|
||||
table = default_metadata;
|
||||
|
||||
/* don't bother loading a namespace if already registered */
|
||||
if (g_hash_table_lookup (table, namespace))
|
||||
return NULL;
|
||||
|
||||
if (search_path == NULL)
|
||||
g_irepository_build_search_path ();
|
||||
|
||||
fname = g_strconcat (namespace, ".repo", NULL);
|
||||
|
||||
for (ldir = search_path; ldir; ldir = ldir->next) {
|
||||
dir = ldir->data;
|
||||
full_path = g_build_filename (dir, fname, NULL);
|
||||
mfile = g_mapped_file_new (full_path, FALSE, &error1);
|
||||
if (error1) {
|
||||
g_debug ("Failed to mmap \"%s\"", full_path);
|
||||
g_clear_error (&error1);
|
||||
g_free (full_path);
|
||||
continue;
|
||||
}
|
||||
g_free (full_path);
|
||||
metadata = g_metadata_new_from_mapped_file (mfile);
|
||||
metadata_namespace = g_metadata_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,
|
||||
"Metadata file %s for namespace '%s' contains namespace '%s'"
|
||||
" which doesn't match the file name",
|
||||
full_path, namespace, metadata_namespace);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
g_free (fname);
|
||||
if (metadata == NULL) {
|
||||
g_set_error (error, G_IREPOSITORY_ERROR,
|
||||
G_IREPOSITORY_ERROR_METADATA_NOT_FOUND,
|
||||
"Metadata file for namespace '%s' was not found in search"
|
||||
" path or could not be openened", namespace);
|
||||
return NULL;
|
||||
}
|
||||
/* 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);
|
||||
module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL);
|
||||
if (module == NULL) {
|
||||
g_set_error (error, G_IREPOSITORY_ERROR,
|
||||
G_IREPOSITORY_ERROR_METADATA_NOT_FOUND,
|
||||
"Metadata for namespace '%s' references shared library %s,"
|
||||
" but it could not be openened (%s)",
|
||||
namespace, shlib_fname, g_module_error ());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_remove (table, namespace);
|
||||
return g_irepository_register (repository, metadata);
|
||||
}
|
||||
|
||||
|
||||
GQuark
|
||||
g_irepository_error_quark (void)
|
||||
{
|
||||
static GQuark quark = 0;
|
||||
if (quark == 0)
|
||||
quark = g_quark_from_static_string ("g-irepository-error-quark");
|
||||
return quark;
|
||||
}
|
452
girepository.h
Normal file
452
girepository.h
Normal file
@ -0,0 +1,452 @@
|
||||
/* GObject introspection: Repository
|
||||
*
|
||||
* 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_IREPOSITORY_H__
|
||||
#define __G_IREPOSITORY_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define G_TYPE_IREPOSITORY (g_irepository_get_type ())
|
||||
#define G_IREPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_IREPOSITORY, GIRepository))
|
||||
|
||||
typedef struct _GIRepository GIRepository;
|
||||
typedef struct _GIRepositoryClass GIRepositoryClass;
|
||||
typedef struct _GIRepositoryPrivate GIRepositoryPrivate;
|
||||
typedef struct _GIBaseInfo GIBaseInfo;
|
||||
typedef struct _GICallableInfo GICallableInfo;
|
||||
typedef struct _GIFunctionInfo GIFunctionInfo;
|
||||
typedef struct _GICallbackInfo GICallbackInfo;
|
||||
typedef struct _GIRegisteredTypeInfo GIRegisteredTypeInfo;
|
||||
typedef struct _GIStructInfo GIStructInfo;
|
||||
typedef struct _GIUnionInfo GIUnionInfo;
|
||||
typedef struct _GIEnumInfo GIEnumInfo;
|
||||
typedef struct _GIObjectInfo GIObjectInfo;
|
||||
typedef struct _GIInterfaceInfo GIInterfaceInfo;
|
||||
typedef struct _GIConstantInfo GIConstantInfo;
|
||||
typedef struct _GIValueInfo GIValueInfo;
|
||||
typedef struct _GISignalInfo GISignalInfo;
|
||||
typedef struct _GIVFuncInfo GIVFuncInfo;
|
||||
typedef struct _GIPropertyInfo GIPropertyInfo;
|
||||
typedef struct _GIFieldInfo GIFieldInfo;
|
||||
typedef struct _GIArgInfo GIArgInfo;
|
||||
typedef struct _GITypeInfo GITypeInfo;
|
||||
typedef struct _GIErrorDomainInfo GIErrorDomainInfo;
|
||||
typedef struct _GIUnresolvedInfo GIUnresolvedInfo;
|
||||
typedef struct _GMetadata GMetadata;
|
||||
|
||||
struct _GIRepository
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
/*< private >*/
|
||||
GIRepositoryPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GIRepositoryClass
|
||||
{
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
|
||||
/* Repository */
|
||||
|
||||
GType g_irepository_get_type (void) G_GNUC_CONST;
|
||||
GIRepository *g_irepository_get_default (void);
|
||||
const gchar * g_irepository_register (GIRepository *repository,
|
||||
GMetadata *metadata);
|
||||
void g_irepository_unregister (GIRepository *repository,
|
||||
const gchar *namespace);
|
||||
const gchar * g_irepository_register_file (GIRepository *repository,
|
||||
const gchar *filename,
|
||||
GError **error);
|
||||
gboolean g_irepository_is_registered (GIRepository *repository,
|
||||
const gchar *namespace);
|
||||
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
|
||||
const gchar *namespace,
|
||||
const gchar *name);
|
||||
gchar ** g_irepository_get_namespaces (GIRepository *repository);
|
||||
GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository,
|
||||
GType gtype);
|
||||
gint g_irepository_get_n_infos (GIRepository *repository,
|
||||
const gchar *namespace);
|
||||
GIBaseInfo * g_irepository_get_info (GIRepository *repository,
|
||||
const gchar *namespace,
|
||||
gint index);
|
||||
const gchar * g_irepository_get_shared_library (GIRepository *repository,
|
||||
const gchar *namespace);
|
||||
/* Metadata */
|
||||
|
||||
GMetadata * g_metadata_new_from_memory (guchar *memory,
|
||||
gsize len);
|
||||
GMetadata * g_metadata_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,
|
||||
GModule *module);
|
||||
const gchar * g_metadata_get_namespace (GMetadata *metadata);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
G_IREPOSITORY_ERROR_METADATA_NOT_FOUND,
|
||||
G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH,
|
||||
G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND
|
||||
} GIRepositoryError;
|
||||
|
||||
#define G_IREPOSITORY_ERROR (g_irepository_error_quark ())
|
||||
|
||||
GQuark g_irepository_error_quark (void);
|
||||
|
||||
|
||||
/* Types of objects registered in the repository */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GI_INFO_TYPE_INVALID,
|
||||
GI_INFO_TYPE_FUNCTION,
|
||||
GI_INFO_TYPE_CALLBACK,
|
||||
GI_INFO_TYPE_STRUCT,
|
||||
GI_INFO_TYPE_BOXED,
|
||||
GI_INFO_TYPE_ENUM,
|
||||
GI_INFO_TYPE_FLAGS,
|
||||
GI_INFO_TYPE_OBJECT,
|
||||
GI_INFO_TYPE_INTERFACE,
|
||||
GI_INFO_TYPE_CONSTANT,
|
||||
GI_INFO_TYPE_ERROR_DOMAIN,
|
||||
GI_INFO_TYPE_UNION,
|
||||
GI_INFO_TYPE_VALUE,
|
||||
GI_INFO_TYPE_SIGNAL,
|
||||
GI_INFO_TYPE_VFUNC,
|
||||
GI_INFO_TYPE_PROPERTY,
|
||||
GI_INFO_TYPE_FIELD,
|
||||
GI_INFO_TYPE_ARG,
|
||||
GI_INFO_TYPE_TYPE,
|
||||
GI_INFO_TYPE_UNRESOLVED
|
||||
} GIInfoType;
|
||||
|
||||
|
||||
/* GIBaseInfo */
|
||||
|
||||
GIBaseInfo * g_base_info_ref (GIBaseInfo *info);
|
||||
void g_base_info_unref (GIBaseInfo *info);
|
||||
GIInfoType g_base_info_get_type (GIBaseInfo *info);
|
||||
const gchar * g_base_info_get_name (GIBaseInfo *info);
|
||||
const gchar * g_base_info_get_namespace (GIBaseInfo *info);
|
||||
gboolean g_base_info_is_deprecated (GIBaseInfo *info);
|
||||
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);
|
||||
|
||||
GIBaseInfo * g_info_new (GIInfoType type,
|
||||
GIBaseInfo *container,
|
||||
GMetadata *metadata,
|
||||
guint32 offset);
|
||||
|
||||
|
||||
/* GIFunctionInfo */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GI_FUNCTION_IS_METHOD = 1 << 0,
|
||||
GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1,
|
||||
GI_FUNCTION_IS_GETTER = 1 << 2,
|
||||
GI_FUNCTION_IS_SETTER = 1 << 3,
|
||||
GI_FUNCTION_WRAPS_VFUNC = 1 << 4
|
||||
} GIFunctionInfoFlags;
|
||||
|
||||
const gchar * g_function_info_get_symbol (GIFunctionInfo *info);
|
||||
GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info);
|
||||
GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info);
|
||||
GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info);
|
||||
|
||||
typedef union
|
||||
{
|
||||
gboolean v_boolean;
|
||||
gint8 v_int8;
|
||||
guint8 v_uint8;
|
||||
gint16 v_int16;
|
||||
guint16 v_uint16;
|
||||
gint32 v_int32;
|
||||
guint32 v_uint32;
|
||||
gint64 v_int64;
|
||||
guint64 v_uint64;
|
||||
gfloat v_float;
|
||||
gdouble v_double;
|
||||
gint v_int;
|
||||
guint v_uint;
|
||||
glong v_long;
|
||||
gulong v_ulong;
|
||||
gssize v_ssize;
|
||||
gsize v_size;
|
||||
gchar * v_string;
|
||||
gpointer v_pointer;
|
||||
} GArgument;
|
||||
|
||||
#define G_INVOKE_ERROR (g_invoke_error_quark ())
|
||||
GQuark g_invoke_error_quark (void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
G_INVOKE_ERROR_FAILED,
|
||||
G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
|
||||
G_INVOKE_ERROR_ARGUMENT_MISMATCH
|
||||
} GInvokeError;
|
||||
|
||||
gboolean g_function_info_invoke (GIFunctionInfo *info,
|
||||
const GArgument *in_args,
|
||||
int n_in_args,
|
||||
const GArgument *out_args,
|
||||
int n_out_args,
|
||||
GArgument *return_value,
|
||||
GError **error);
|
||||
|
||||
|
||||
/* GICallableInfo */
|
||||
|
||||
typedef enum {
|
||||
GI_TRANSFER_NOTHING,
|
||||
GI_TRANSFER_CONTAINER,
|
||||
GI_TRANSFER_EVERYTHING
|
||||
} GITransfer;
|
||||
|
||||
GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info);
|
||||
GITransfer g_callable_info_get_caller_owns (GICallableInfo *info);
|
||||
gboolean g_callable_info_may_return_null (GICallableInfo *info);
|
||||
gint g_callable_info_get_n_args (GICallableInfo *info);
|
||||
GIArgInfo * g_callable_info_get_arg (GICallableInfo *info,
|
||||
gint n);
|
||||
|
||||
/* GIArgInfo */
|
||||
|
||||
typedef enum {
|
||||
GI_DIRECTION_IN,
|
||||
GI_DIRECTION_OUT,
|
||||
GI_DIRECTION_INOUT
|
||||
} GIDirection;
|
||||
|
||||
GIDirection g_arg_info_get_direction (GIArgInfo *info);
|
||||
gboolean g_arg_info_is_dipper (GIArgInfo *info);
|
||||
gboolean g_arg_info_is_return_value (GIArgInfo *info);
|
||||
gboolean g_arg_info_is_optional (GIArgInfo *info);
|
||||
gboolean g_arg_info_may_be_null (GIArgInfo *info);
|
||||
GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info);
|
||||
GITypeInfo * g_arg_info_get_type (GIArgInfo *info);
|
||||
|
||||
|
||||
/* GITypeInfo */
|
||||
|
||||
typedef enum {
|
||||
GI_TYPE_TAG_VOID = 0,
|
||||
GI_TYPE_TAG_BOOLEAN = 1,
|
||||
GI_TYPE_TAG_INT8 = 2,
|
||||
GI_TYPE_TAG_UINT8 = 3,
|
||||
GI_TYPE_TAG_INT16 = 4,
|
||||
GI_TYPE_TAG_UINT16 = 5,
|
||||
GI_TYPE_TAG_INT32 = 6,
|
||||
GI_TYPE_TAG_UINT32 = 7,
|
||||
GI_TYPE_TAG_INT64 = 8,
|
||||
GI_TYPE_TAG_UINT64 = 9,
|
||||
GI_TYPE_TAG_INT = 10,
|
||||
GI_TYPE_TAG_UINT = 11,
|
||||
GI_TYPE_TAG_LONG = 12,
|
||||
GI_TYPE_TAG_ULONG = 13,
|
||||
GI_TYPE_TAG_SSIZE = 14,
|
||||
GI_TYPE_TAG_SIZE = 15,
|
||||
GI_TYPE_TAG_FLOAT = 16,
|
||||
GI_TYPE_TAG_DOUBLE = 17,
|
||||
GI_TYPE_TAG_UTF8 = 18,
|
||||
GI_TYPE_TAG_FILENAME = 19,
|
||||
GI_TYPE_TAG_ARRAY = 20,
|
||||
GI_TYPE_TAG_INTERFACE = 21,
|
||||
GI_TYPE_TAG_GLIST = 22,
|
||||
GI_TYPE_TAG_GSLIST = 23,
|
||||
GI_TYPE_TAG_GHASH = 24,
|
||||
GI_TYPE_TAG_ERROR = 25
|
||||
} GITypeTag;
|
||||
|
||||
gboolean g_type_info_is_pointer (GITypeInfo *info);
|
||||
GITypeTag g_type_info_get_tag (GITypeInfo *info);
|
||||
GITypeInfo * g_type_info_get_param_type (GITypeInfo *info,
|
||||
gint n);
|
||||
GIBaseInfo * g_type_info_get_interface (GITypeInfo *info);
|
||||
gint g_type_info_get_array_length (GITypeInfo *info);
|
||||
gboolean g_type_info_is_zero_terminated (GITypeInfo *info);
|
||||
|
||||
gint g_type_info_get_n_error_domains (GITypeInfo *info);
|
||||
GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info,
|
||||
gint n);
|
||||
|
||||
/* GIErrorDomainInfo */
|
||||
|
||||
const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info);
|
||||
GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info);
|
||||
|
||||
|
||||
/* GIValueInfo */
|
||||
|
||||
glong g_value_info_get_value (GIValueInfo *info);
|
||||
|
||||
|
||||
/* GIFieldInfo */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GI_FIELD_IS_READABLE = 1 << 0,
|
||||
GI_FIELD_IS_WRITABLE = 1 << 1
|
||||
} GIFieldInfoFlags;
|
||||
|
||||
GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info);
|
||||
gint g_field_info_get_size (GIFieldInfo *info);
|
||||
gint g_field_info_get_offset (GIFieldInfo *info);
|
||||
GITypeInfo * g_field_info_get_type (GIFieldInfo *info);
|
||||
|
||||
|
||||
/* GIUnionInfo */
|
||||
gint g_union_info_get_n_fields (GIUnionInfo *info);
|
||||
GIFieldInfo * g_union_info_get_field (GIUnionInfo *info,
|
||||
gint n);
|
||||
gint g_union_info_get_n_methods (GIUnionInfo *info);
|
||||
GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info,
|
||||
gint n);
|
||||
gboolean g_union_info_is_discriminated (GIUnionInfo *info);
|
||||
gint g_union_info_get_discriminator_offset (GIUnionInfo *info);
|
||||
GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info);
|
||||
GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info,
|
||||
gint n);
|
||||
|
||||
|
||||
/* GIStructInfo */
|
||||
gint g_struct_info_get_n_fields (GIStructInfo *info);
|
||||
GIFieldInfo * g_struct_info_get_field (GIStructInfo *info,
|
||||
gint n);
|
||||
gint g_struct_info_get_n_methods (GIStructInfo *info);
|
||||
GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info,
|
||||
gint n);
|
||||
GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info,
|
||||
const gchar *name);
|
||||
|
||||
/* GIRegisteredTypeInfo */
|
||||
|
||||
const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info);
|
||||
const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info);
|
||||
|
||||
|
||||
/* GIEnumInfo */
|
||||
|
||||
gint g_enum_info_get_n_values (GIEnumInfo *info);
|
||||
GIValueInfo * g_enum_info_get_value (GIEnumInfo *info,
|
||||
gint n);
|
||||
|
||||
/* GIObjectInfo */
|
||||
|
||||
const gchar * g_object_info_get_type_name (GIObjectInfo *info);
|
||||
const gchar * g_object_info_get_type_init (GIObjectInfo *info);
|
||||
GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info);
|
||||
gint g_object_info_get_n_interfaces (GIObjectInfo *info);
|
||||
GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info,
|
||||
gint n);
|
||||
gint g_object_info_get_n_fields (GIObjectInfo *info);
|
||||
GIFieldInfo * g_object_info_get_field (GIObjectInfo *info,
|
||||
gint n);
|
||||
gint g_object_info_get_n_properties (GIObjectInfo *info);
|
||||
GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info,
|
||||
gint n);
|
||||
gint g_object_info_get_n_methods (GIObjectInfo *info);
|
||||
GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info,
|
||||
gint n);
|
||||
GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info,
|
||||
const gchar *name);
|
||||
gint g_object_info_get_n_signals (GIObjectInfo *info);
|
||||
GISignalInfo * g_object_info_get_signal (GIObjectInfo *info,
|
||||
gint n);
|
||||
gint g_object_info_get_n_vfuncs (GIObjectInfo *info);
|
||||
GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info,
|
||||
gint n);
|
||||
gint g_object_info_get_n_constants (GIObjectInfo *info);
|
||||
GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info,
|
||||
gint n);
|
||||
|
||||
|
||||
/* GIInterfaceInfo */
|
||||
|
||||
gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info);
|
||||
GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
gint g_interface_info_get_n_properties (GIInterfaceInfo *info);
|
||||
GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
gint g_interface_info_get_n_methods (GIInterfaceInfo *info);
|
||||
GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info,
|
||||
const gchar *name);
|
||||
gint g_interface_info_get_n_signals (GIInterfaceInfo *info);
|
||||
GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info);
|
||||
GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
gint g_interface_info_get_n_constants (GIInterfaceInfo *info);
|
||||
GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info,
|
||||
gint n);
|
||||
|
||||
|
||||
/* GIPropertyInfo */
|
||||
|
||||
GParamFlags g_property_info_get_flags (GIPropertyInfo *info);
|
||||
GITypeInfo * g_property_info_get_type (GIPropertyInfo *info);
|
||||
|
||||
|
||||
/* GISignalInfo */
|
||||
|
||||
GSignalFlags g_signal_info_get_flags (GISignalInfo *info);
|
||||
GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info);
|
||||
gboolean g_signal_info_true_stops_emit (GISignalInfo *info);
|
||||
|
||||
|
||||
/* GIVFuncInfo */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GI_VFUNC_MUST_CHAIN_UP = 1 << 0,
|
||||
GI_VFUNC_MUST_OVERRIDE = 1 << 1,
|
||||
GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2
|
||||
} GIVFuncInfoFlags;
|
||||
|
||||
GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info);
|
||||
gint g_vfunc_info_get_offset (GIVFuncInfo *info);
|
||||
GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info);
|
||||
|
||||
|
||||
/* GIConstantInfo */
|
||||
|
||||
GITypeInfo * g_constant_info_get_type (GIConstantInfo *info);
|
||||
gint g_constant_info_get_value (GIConstantInfo *info,
|
||||
GArgument *value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_IREPOSITORY_H__ */
|
||||
|
1876
gmetadata.c
Normal file
1876
gmetadata.c
Normal file
File diff suppressed because it is too large
Load Diff
549
gmetadata.h
Normal file
549
gmetadata.h
Normal file
@ -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_METADATA_H__
|
||||
#define __G_METADATA_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 _GMetadata {
|
||||
guchar *data;
|
||||
gsize len;
|
||||
gboolean owns_memory;
|
||||
GMappedFile *mfile;
|
||||
GModule *module;
|
||||
};
|
||||
|
||||
DirEntry *g_metadata_get_dir_entry (GMetadata *metadata,
|
||||
guint16 index);
|
||||
|
||||
void g_metadata_check_sanity (void);
|
||||
|
||||
#define g_metadata_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)])
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
G_METADATA_ERROR_INVALID,
|
||||
G_METADATA_ERROR_INVALID_HEADER,
|
||||
G_METADATA_ERROR_INVALID_DIRECTORY,
|
||||
G_METADATA_ERROR_INVALID_ENTRY,
|
||||
G_METADATA_ERROR_INVALID_BLOB
|
||||
} GMetadataError;
|
||||
|
||||
#define G_METADATA_ERROR (g_metadata_error_quark ())
|
||||
|
||||
GQuark g_metadata_error_quark (void);
|
||||
|
||||
gboolean g_metadata_validate (GMetadata *metadata,
|
||||
GError **error);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_METADATA_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user