paramspec value_validate



This is the paramspec->value_validate I posted before, cleaned up a bit.

The main advantage is that the underlying operation is a vfunc, so the
pspec class can express strange sorts of restrictions on allowed values,
which you might want to check or enforce when doing stuff to property
values on a kinda generic basis.

(I arrived at it for my ConnectProperties thingie.  I'm now not sure I
will want it applied all the time, or by default, but it's definitely a
possible sensible way to check or clamp or round before storing a value
to a property.)

Index: GParamSpec.xs
===================================================================
--- GParamSpec.xs       (revision 1046)
+++ GParamSpec.xs       (working copy)
@@ -625,6 +625,41 @@
        RETVAL
 
 
+MODULE = Glib::ParamSpec       PACKAGE = Glib::ParamSpec       PREFIX = g_param_
+
+=for apidoc
+=signature bool = $paramspec->value_validate ($value)
+=signature (bool, newval) = $paramspec->value_validate ($value)
+In scalar context return true if $value must be modified to be valid
+for $paramspec, or false if it's valid already.  In array context
+return also a new value which is $value made valid.
+
+$value must be the right type for $paramspec (with usual stringizing,
+numizing, etc).  C<value_validate> checks the further restrictions
+such as minimum and maximum for a numeric type or allowed characters
+in a string.  The "made valid" return is then for instance clamped to
+the min/max, or offending chars replaced by a substitutor.
+=cut
+void
+g_param_value_validate (GParamSpec * pspec, SV *value)
+    PREINIT:
+       GValue v = { 0, };
+       GType type;
+       int modify, retcount=1;
+    CODE:
+       type = G_PARAM_SPEC_VALUE_TYPE (pspec);
+       g_value_init (&v, type);
+       gperl_value_from_sv (&v, value);
+       modify = g_param_value_validate (pspec, &v);
+       ST(0) = sv_2mortal (boolSV (modify));
+       if (GIMME_V == G_ARRAY) {
+               ST(1) = sv_2mortal (gperl_sv_from_value (&v));
+               retcount = 2;
+       }
+       g_value_unset (&v);
+       XSRETURN(retcount);
+
+
 MODULE = Glib::ParamSpec       PACKAGE = Glib::Param::Char
 
  ## actually for all signed integer types
Index: e.t
===================================================================
--- e.t (revision 1046)
+++ e.t (working copy)
@@ -4,7 +4,7 @@
 #
 use strict;
 use Glib ':constants';
-use Test::More tests => 232;
+use Test::More tests => 240;
 
 # first register some types with which to play below.
 
@@ -215,3 +215,21 @@
 my $object = Bar->new;
 my $x = $object->get ('param_spec');
 is ($x, undef);
+
+# value_validate()
+#
+{ my $p = Glib::ParamSpec->int ('name','nick','blurb',
+                                20, 50, 25, G_PARAM_READWRITE);
+  ok (! scalar ($p->value_validate('30')), "value 30 valid");
+  my @a = $p->value_validate('30');
+  is (@a, 2);
+  ok (! $a[0], "value 30 bool no modify (array context)");
+  is ($a[1], 30, "value 30 value unchanged");
+
+  my ($modif, $newval) = $p->value_validate(70);
+  ok ($modif, 'modify 70 to be in range');
+  is ($newval, 50, 'clamp 70 down to be in range');
+  ($modif, $newval) = $p->value_validate(-70);
+  ok ($modif, 'modify -70 to be in range');
+  is ($newval, 20, 'clamp -70 down to be in range');
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]