diff options
author | Tomeu Vizoso <tomeu.vizoso@collabora.co.uk> | 2010-06-08 16:40:35 +0200 |
---|---|---|
committer | Tomeu Vizoso <tomeu.vizoso@collabora.co.uk> | 2010-06-08 17:35:12 +0200 |
commit | 22ae017ffd3052c0b81822b2ca6e41626b76b9c4 (patch) | |
tree | b280bde67eaa4096bd8a83ad539a8fe9c7c14f5c /girepository | |
parent | 862cdbe9ed2464c722e566238980895d08a48106 (diff) | |
download | gobject-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.c | 27 | ||||
-rw-r--r-- | girepository/gipropertyinfo.h | 1 | ||||
-rw-r--r-- | girepository/girnode.c | 2 | ||||
-rw-r--r-- | girepository/girnode.h | 2 | ||||
-rw-r--r-- | girepository/girparser.c | 42 | ||||
-rw-r--r-- | girepository/girwriter.c | 52 | ||||
-rw-r--r-- | girepository/gitypelib-internal.h | 20 | ||||
-rw-r--r-- | girepository/gitypes.h | 30 |
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, |