summaryrefslogtreecommitdiff
path: root/girepository
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-06-08 16:40:35 +0200
committerTomeu Vizoso <tomeu.vizoso@collabora.co.uk>2010-06-08 17:35:12 +0200
commit22ae017ffd3052c0b81822b2ca6e41626b76b9c4 (patch)
treeb280bde67eaa4096bd8a83ad539a8fe9c7c14f5c /girepository
parent862cdbe9ed2464c722e566238980895d08a48106 (diff)
downloadgobject-introspection-22ae017ffd3052c0b81822b2ca6e41626b76b9c4.tar.gz
Support the (transfer) annotation for properties.
* girepository/*: Add g_property_info_get_ownership_transfer() and write the transfer attribute of properties into the typelib. * giscanner/*: Parse the (transfer) annotation and write it into the .gir. * tools/generate.c: Read the transfer annotation for properties and write to the .tgir. https://bugzilla.gnome.org/show_bug.cgi?id=620484
Diffstat (limited to 'girepository')
-rw-r--r--girepository/gipropertyinfo.c27
-rw-r--r--girepository/gipropertyinfo.h1
-rw-r--r--girepository/girnode.c2
-rw-r--r--girepository/girnode.h2
-rw-r--r--girepository/girparser.c42
-rw-r--r--girepository/girwriter.c52
-rw-r--r--girepository/gitypelib-internal.h20
-rw-r--r--girepository/gitypes.h30
8 files changed, 135 insertions, 41 deletions
diff --git a/girepository/gipropertyinfo.c b/girepository/gipropertyinfo.c
index 705a80bf..224709d2 100644
--- a/girepository/gipropertyinfo.c
+++ b/girepository/gipropertyinfo.c
@@ -57,3 +57,30 @@ g_property_info_get_type (GIPropertyInfo *info)
return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type));
}
+/**
+ * g_property_info_get_ownership_transfer:
+ * @info: a #GIPropertyInfo
+ *
+ * Obtain the ownership transfer for this property. See #GITransfer for more
+ * information about transfer values.
+ *
+ * Returns: the transfer
+ */
+GITransfer
+g_property_info_get_ownership_transfer (GIPropertyInfo *info)
+{
+ GIRealInfo *rinfo = (GIRealInfo *)info;
+ PropertyBlob *blob;
+
+ g_return_val_if_fail (info != NULL, -1);
+ g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), -1);
+
+ blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
+
+ if (blob->transfer_ownership)
+ return GI_TRANSFER_EVERYTHING;
+ else if (blob->transfer_container_ownership)
+ return GI_TRANSFER_CONTAINER;
+ else
+ return GI_TRANSFER_NOTHING;
+}
diff --git a/girepository/gipropertyinfo.h b/girepository/gipropertyinfo.h
index 168b88cc..487389cb 100644
--- a/girepository/gipropertyinfo.h
+++ b/girepository/gipropertyinfo.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
GParamFlags g_property_info_get_flags (GIPropertyInfo *info);
GITypeInfo * g_property_info_get_type (GIPropertyInfo *info);
+GITransfer g_property_info_get_ownership_transfer (GIPropertyInfo *info);
G_END_DECLS
diff --git a/girepository/girnode.c b/girepository/girnode.c
index db029989..0f5223fa 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -1648,6 +1648,8 @@ g_ir_node_build_typelib (GIrNode *node,
blob->writable = prop->writable;
blob->construct = prop->construct;
blob->construct_only = prop->construct_only;
+ blob->transfer_ownership = prop->transfer;
+ blob->transfer_container_ownership = prop->shallow_transfer;
blob->reserved = 0;
g_ir_node_build_typelib ((GIrNode *)prop->type,
diff --git a/girepository/girnode.h b/girepository/girnode.h
index 8c7b14eb..038a53d7 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -178,6 +178,8 @@ struct _GIrNodeProperty
gboolean writable;
gboolean construct;
gboolean construct_only;
+ gboolean transfer;
+ gboolean shallow_transfer;
GIrNodeType *type;
};
diff --git a/girepository/girparser.c b/girepository/girparser.c
index bda72e12..65f038ce 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -841,6 +841,44 @@ start_function (GMarkupParseContext *context,
}
static void
+parse_property_transfer (GIrNodeProperty *property,
+ const gchar *transfer,
+ ParseContext *ctx)
+{
+ if (transfer == NULL)
+ {
+ GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
+
+ g_warning ("required attribute 'transfer-ownership' for property '%s' in "
+ "type '%s.%s'", property->node.name, ctx->namespace,
+ iface->node.name);
+ }
+ else if (strcmp (transfer, "none") == 0)
+ {
+ property->transfer = FALSE;
+ property->shallow_transfer = FALSE;
+ }
+ else if (strcmp (transfer, "container") == 0)
+ {
+ property->transfer = FALSE;
+ property->shallow_transfer = TRUE;
+ }
+ else if (strcmp (transfer, "full") == 0)
+ {
+ property->transfer = TRUE;
+ property->shallow_transfer = FALSE;
+ }
+ else
+ {
+ GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
+
+ g_warning ("Unknown transfer-ownership value: '%s' for property '%s' in "
+ "type '%s.%s'", transfer, property->node.name, ctx->namespace,
+ iface->node.name);
+ }
+}
+
+static void
parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name)
{
if (transfer == NULL)
@@ -1237,12 +1275,14 @@ start_property (GMarkupParseContext *context,
const gchar *writable;
const gchar *construct;
const gchar *construct_only;
+ const gchar *transfer;
name = find_attribute ("name", attribute_names, attribute_values);
readable = find_attribute ("readable", attribute_names, attribute_values);
writable = find_attribute ("writable", attribute_names, attribute_values);
construct = find_attribute ("construct", attribute_names, attribute_values);
construct_only = find_attribute ("construct-only", attribute_names, attribute_values);
+ transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
if (name == NULL)
MISSING_ATTRIBUTE (context, error, element_name, "name");
@@ -1274,6 +1314,8 @@ start_property (GMarkupParseContext *context,
else
property->construct_only = FALSE;
+ parse_property_transfer (property, transfer, ctx);
+
iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
iface->members = g_list_append (iface->members, property);
diff --git a/girepository/girwriter.c b/girepository/girwriter.c
index 6fa892db..ca68f57b 100644
--- a/girepository/girwriter.c
+++ b/girepository/girwriter.c
@@ -187,6 +187,26 @@ write_type_name_attribute (const gchar *namespace,
xml_printf (file, "\"");
}
+ static void
+write_ownership_transfer (GITransfer transfer,
+ Xml *file)
+{
+ switch (transfer)
+ {
+ case GI_TRANSFER_NOTHING:
+ xml_printf (file, " transfer-ownership=\"none\"");
+ break;
+ case GI_TRANSFER_CONTAINER:
+ xml_printf (file, " transfer-ownership=\"container\"");
+ break;
+ case GI_TRANSFER_EVERYTHING:
+ xml_printf (file, " transfer-ownership=\"full\"");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
static void
write_type_info (const gchar *namespace,
GITypeInfo *info,
@@ -443,20 +463,7 @@ write_callable_info (const gchar *namespace,
xml_start_element (file, "return-value");
- switch (g_callable_info_get_caller_owns (info))
- {
- case GI_TRANSFER_NOTHING:
- xml_printf (file, " transfer-ownership=\"none\"");
- break;
- case GI_TRANSFER_CONTAINER:
- xml_printf (file, " transfer-ownership=\"container\"");
- break;
- case GI_TRANSFER_EVERYTHING:
- xml_printf (file, " transfer-ownership=\"full\"");
- break;
- default:
- g_assert_not_reached ();
- }
+ write_ownership_transfer (g_callable_info_get_caller_owns (info), file);
if (g_callable_info_may_return_null (info))
xml_printf (file, " allow-none=\"1\"");
@@ -477,20 +484,7 @@ write_callable_info (const gchar *namespace,
xml_printf (file, " name=\"%s\"",
g_base_info_get_name ((GIBaseInfo *) arg));
- switch (g_arg_info_get_ownership_transfer (arg))
- {
- case GI_TRANSFER_NOTHING:
- xml_printf (file, " transfer-ownership=\"none\"");
- break;
- case GI_TRANSFER_CONTAINER:
- xml_printf (file, " transfer-ownership=\"container\"");
- break;
- case GI_TRANSFER_EVERYTHING:
- xml_printf (file, " transfer-ownership=\"full\"");
- break;
- default:
- g_assert_not_reached ();
- }
+ write_ownership_transfer (g_arg_info_get_ownership_transfer (arg), file);
switch (g_arg_info_get_direction (arg))
{
@@ -968,6 +962,8 @@ write_property_info (const gchar *namespace,
if (flags & G_PARAM_CONSTRUCT_ONLY)
xml_printf (file, " construct-only=\"1\"");
+ write_ownership_transfer (g_property_info_get_ownership_transfer (info), file);
+
write_attributes (file, (GIBaseInfo*) info);
type = g_property_info_get_type (info);
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index 0524efa1..bb920ac6 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -815,17 +815,25 @@ typedef struct {
* @writable:
* @construct:
* @construct_only: The ParamFlags used when registering the property.
+ * @transfer_ownership: When writing, the type containing the property takes
+ * ownership of the value. When reading, the returned value needs to be released
+ * by the caller.
+ * @transfer_container_ownership: For container types indicates that the
+ * ownership of the container, but not of its contents, is transferred. This is
+ * typically the case when reading lists of statically allocated things.
* @type: Describes the type of the property.
*/
typedef struct {
guint32 name;
- guint32 deprecated : 1;
- guint32 readable : 1;
- guint32 writable : 1;
- guint32 construct : 1;
- guint32 construct_only : 1;
- guint32 reserved :27;
+ guint32 deprecated : 1;
+ guint32 readable : 1;
+ guint32 writable : 1;
+ guint32 construct : 1;
+ guint32 construct_only : 1;
+ guint32 transfer_ownership : 1;
+ guint32 transfer_container_ownership : 1;
+ guint32 reserved :25;
guint32 reserved2;
diff --git a/girepository/gitypes.h b/girepository/gitypes.h
index 78becaef..5ef64ca1 100644
--- a/girepository/gitypes.h
+++ b/girepository/gitypes.h
@@ -241,13 +241,29 @@ typedef enum
/**
* GITransfer:
- * @GI_TRANSFER_NOTHING: transfer nothing to the caller
- * @GI_TRANSFER_CONTAINER: transfer the container (eg list, array,
- * hashtable), but no the contents to the caller.
- * @GI_TRANSFER_EVERYTHING: transfer everything to the caller.
- *
- * Represent the transfer ownership information of a #GICallableInfo or
- * a #GIArgInfo.
+ * @GI_TRANSFER_NOTHING: transfer nothing from the callee (function or the type
+ * instance the property belongs to) to the caller. The callee retains the
+ * ownership of the transfer and the caller doesn't need to do anything to free
+ * up the resources of this transfer.
+ * @GI_TRANSFER_CONTAINER: transfer the container (list, array, hash table) from
+ * the callee to the caller. The callee retains the ownership of the individual
+ * items in the container and the caller has to free up the container resources
+ * (g_list_free()/g_hash_table_destroy() etc) of this transfer.
+ * @GI_TRANSFER_EVERYTHING: transfer everything, eg the container and its
+ * contents from the callee to the caller. This is the case when the callee
+ * creates a copy of all the data it returns. The caller is responsible for
+ * cleaning up the container and item resources of this transfer.
+ *
+ * The transfer is the exchange of data between two parts, from the callee to
+ * the caller. The callee is either a function/method/signal or an
+ * object/interface where a property is defined. The caller is the side
+ * accessing a property or calling a function.
+ * #GITransfer specifies who's responsible for freeing the resources after the
+ * ownership transfer is complete. In case of a containing type such as a list,
+ * an array or a hash table the container itself is specified differently from
+ * the items within the container itself. Each container is freed differently,
+ * check the documentation for the types themselves for information on how to
+ * free them.
*/
typedef enum {
GI_TRANSFER_NOTHING,