From b5b756b817bddb15407349158b69b7e58a699ee6 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 19 Aug 2018 22:42:26 +0200 Subject: [PATCH] Add vips_object_get_args Handy for language bindings. --- ChangeLog | 1 + libvips/include/vips/object.h | 2 ++ libvips/iofuncs/object.c | 60 +++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0f5c899f..ffa10e12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,7 @@ - mapim could fail for float index images with coordinates out of int range - scale openexr alpha to 0 - 255 - close input earlier, when we can [kleisauke] +- add vips_object_get_args() for language bindings [kleisauke] 12/3/18 started 8.6.4 - better fitting of fonts with overhanging edges [AdriĆ ] diff --git a/libvips/include/vips/object.h b/libvips/include/vips/object.h index 3041ea0e..ab2ebb72 100644 --- a/libvips/include/vips/object.h +++ b/libvips/include/vips/object.h @@ -302,6 +302,8 @@ typedef void *(*VipsArgumentMapFn)( VipsObject *object, GParamSpec *pspec, VipsArgumentInstance *argument_instance, void *a, void *b ); void *vips_argument_map( VipsObject *object, VipsArgumentMapFn fn, void *a, void *b ); +void vips_object_get_args( VipsObject *object, + const char ***names, int **flags, int *n_args ); typedef void *(*VipsArgumentClassMapFn)( VipsObjectClass *object_class, GParamSpec *pspec, VipsArgumentClass *argument_class, void *a, void *b ); diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 911aa7a6..00e05a16 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -2210,6 +2210,66 @@ vips_object_find_required( VipsObject *object ) vips_argument_is_required, NULL, NULL ) ); } +typedef struct _VipsNameFlagsPair { + const char **names; + int *flags; +} VipsNameFlagsPair; + +static void * +vips_object_find_args( VipsObject *object, + GParamSpec *pspec, + VipsArgumentClass *argument_class, + VipsArgumentInstance *argument_instance, + void *a, void *b ) +{ + VipsNameFlagsPair *pair = (VipsNameFlagsPair *) a; + int *i = (int *) b; + + pair->names[*i] = g_param_spec_get_name( pspec ); + pair->flags[*i] = (int) argument_class->flags; + + *i += 1; + + return( NULL ); +} + +/** + * vips_object_get_args: (skip) + * @object: object whose args should be retrieved + * @names: (out)(array length=n_args): output array of GParamSpec names + * @flags: (out)(array length=n_args): output array of VipsArgumentFlags + * @n_args: length of output arrays + * + * Get all GParamSpec names and VipsArgumentFlags for an object. + * + * This is handy for language bindings. From C, it's usually more convenient to + * use vips_argument_map(). + */ +void +vips_object_get_args( VipsObject *object, + const char ***names, int **flags, int *n_args) +{ + VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); + + int n = g_slist_length( object_class->argument_table_traverse ); + + VipsNameFlagsPair pair; + pair.names = VIPS_ARRAY( object, n, const char * ); + pair.flags = VIPS_ARRAY( object, n, int ); + + int i = 0; + + (void) vips_argument_map( object, + vips_object_find_args, &pair, &i ); + + if( names ) + *names = pair.names; + if( flags ) + *flags = pair.flags; + if( n_args ) + *n_args = n; +} + /** * vips_object_new: (skip) * @type: object to create