diff --git a/girepository/giobjectinfo.c b/girepository/giobjectinfo.c index 6211b9095..68cee822f 100644 --- a/girepository/giobjectinfo.c +++ b/girepository/giobjectinfo.c @@ -580,6 +580,22 @@ gi_object_info_get_n_signals (GIObjectInfo *info) return blob->n_signals; } +static uint32_t +object_get_signal_offset (GIObjectInfo *info, unsigned int n) +{ + GIRealInfo *rinfo = (GIRealInfo *) info; + Header *header = (Header *) rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset]; + + return rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + n * header->signal_blob_size; +} + /** * gi_object_info_get_signal: * @info: a #GIObjectInfo @@ -595,28 +611,37 @@ GISignalInfo * gi_object_info_get_signal (GIObjectInfo *info, unsigned int n) { - size_t offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header; - ObjectBlob *blob; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); g_return_val_if_fail (n <= G_MAXUINT16, NULL); - header = (Header *)rinfo->typelib->data; - blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_field_callbacks * header->callback_blob_size - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + n * header->signal_blob_size; - return (GISignalInfo *) gi_base_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, - rinfo->typelib, offset); + rinfo->typelib, object_get_signal_offset (info, n)); +} + +static GISignalInfo * +find_signal (GIRealInfo *rinfo, + uint32_t offset, + uint16_t n_signals, + const char *name) +{ + Header *header = (Header *) rinfo->typelib->data; + + for (uint16_t i = 0; i < n_signals; i++) + { + const SignalBlob *sblob = (SignalBlob *) &rinfo->typelib->data[offset]; + const char *sname = gi_typelib_get_string (rinfo->typelib, sblob->name); + + if (strcmp (name, sname) == 0) + return (GISignalInfo *) gi_base_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo *) rinfo, + rinfo->typelib, offset); + + offset += header->signal_blob_size; + } + + return NULL; } /** @@ -637,22 +662,13 @@ GISignalInfo * gi_object_info_find_signal (GIObjectInfo *info, const char *name) { - size_t n_signals; + GIRealInfo *rinfo = (GIRealInfo *) info; - n_signals = gi_object_info_get_n_signals (info); - for (size_t i = 0; i < n_signals; i++) - { - GISignalInfo *siginfo = gi_object_info_get_signal (info, i); + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); - if (g_strcmp0 (gi_base_info_get_name ((GIBaseInfo *) siginfo), name) != 0) - { - gi_base_info_unref ((GIBaseInfo*)siginfo); - continue; - } - - return siginfo; - } - return NULL; + return find_signal (rinfo, object_get_signal_offset (info, 0), + gi_object_info_get_n_signals (info), name); } diff --git a/girepository/tests/repository.c b/girepository/tests/repository.c index 312bd615c..e270e22ef 100644 --- a/girepository/tests/repository.c +++ b/girepository/tests/repository.c @@ -111,6 +111,9 @@ test_repository_info (RepositoryFixture *fx, object_info_by_gtype = GI_OBJECT_INFO (gi_repository_find_by_gtype (fx->repository, G_TYPE_OBJECT)); g_assert_nonnull (object_info); + signal_info = gi_object_info_find_signal (object_info, "does-not-exist"); + g_assert_null (signal_info); + signal_info = gi_object_info_find_signal (object_info, "notify"); g_assert_nonnull (signal_info); g_assert_true (GI_IS_SIGNAL_INFO (signal_info));