]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
D-Bus: support [DBus (signature = ...)] for properties
authorAbderrahim Kitouni <a.kitouni@gmail.com>
Tue, 27 Dec 2016 15:21:20 +0000 (16:21 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Jan 2017 19:04:49 +0000 (20:04 +0100)
This was working for methods and signals, but not for properties.
Also add tests for all cases.

https://bugzilla.gnome.org/show_bug.cgi?id=744595

codegen/valagdbusclientmodule.vala
codegen/valagdbusservermodule.vala
tests/Makefile.am
tests/dbus/rawvariants.test [new file with mode: 0644]

index 00ae3ecb6d90cb6e9d8d771c5be06d301412f38b..86d42595e1c6d2ea5b0bceaa6b3ec8da7e509947 100644 (file)
@@ -1045,26 +1045,33 @@ public class Vala.GDBusClientModule : GDBusModule {
                } else {
                        ccode.add_declaration (get_ccode_name (prop.get_accessor.value_type), new CCodeVariableDeclarator ("_result"));
 
-                       if (array_type != null) {
-                               for (int dim = 1; dim <= array_type.rank; dim++) {
-                                       ccode.add_declaration ("int", new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
+                       if (get_dbus_signature (prop) != null) {
+                               // raw GVariant
+                               ccode.add_assignment (new CCodeIdentifier ("_result"), new CCodeIdentifier("_inner_reply"));
+                       } else {
+                               if (array_type != null) {
+                                       for (int dim = 1; dim <= array_type.rank; dim++) {
+                                               ccode.add_declaration ("int", new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
+                                       }
                                }
-                       }
 
-                       var result = deserialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_inner_reply"), new CCodeIdentifier ("_result"));
-                       ccode.add_assignment (new CCodeIdentifier ("_result"), result);
+                               var result = deserialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_inner_reply"), new CCodeIdentifier ("_result"));
+                               ccode.add_assignment (new CCodeIdentifier ("_result"), result);
 
-                       if (array_type != null) {
-                               for (int dim = 1; dim <= array_type.rank; dim++) {
-                                       // TODO check that parameter is not NULL (out parameters are optional)
-                                       ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)));
+                               if (array_type != null) {
+                                       for (int dim = 1; dim <= array_type.rank; dim++) {
+                                               // TODO check that parameter is not NULL (out parameters are optional)
+                                               ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)));
+                                       }
                                }
                        }
                }
 
-               unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
-               unref_reply.add_argument (new CCodeIdentifier ("_inner_reply"));
-               ccode.add_expression (unref_reply);
+               if (prop.property_type.is_real_non_null_struct_type () || get_dbus_signature (prop) == null) {
+                       unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
+                       unref_reply.add_argument (new CCodeIdentifier ("_inner_reply"));
+                       ccode.add_expression (unref_reply);
+               }
 
                if (prop.property_type.is_real_non_null_struct_type ()) {
                        ccode.add_return ();
index daf2a629cb18051f169dfe4ae9c2af935357fd36..617df210b6defbe879af88861472c2fd31de3471 100644 (file)
@@ -491,15 +491,21 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                        }
                }
 
-               var reply_expr = serialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("result"));
-
                ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator ("_reply"));
-               ccode.add_assignment (new CCodeIdentifier ("_reply"), reply_expr);
 
-               if (requires_destroy (prop.get_accessor.value_type)) {
-                       // keep local alive (symbol_reference is weak)
-                       var local = new LocalVariable (prop.get_accessor.value_type, ".result");
-                       ccode.add_expression (destroy_local (local));
+               if (get_dbus_signature (prop) != null) {
+                       // raw GVariant
+                       ccode.add_assignment (new CCodeIdentifier ("_reply"), new CCodeIdentifier("result"));
+               } else {
+                       var reply_expr = serialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("result"));
+
+                       ccode.add_assignment (new CCodeIdentifier ("_reply"), reply_expr);
+
+                       if (requires_destroy (prop.get_accessor.value_type)) {
+                               // keep local alive (symbol_reference is weak)
+                               var local = new LocalVariable (prop.get_accessor.value_type, ".result");
+                               ccode.add_expression (destroy_local (local));
+                       }
                }
 
                ccode.add_return (new CCodeIdentifier ("_reply"));
@@ -546,15 +552,20 @@ public class Vala.GDBusServerModule : GDBusClientModule {
                }
 
                var target = new CCodeIdentifier ("value");
-               var expr = deserialize_expression (prop.property_type, new CCodeIdentifier ("_value"), target);
-               ccode.add_assignment (target, expr);
 
-               ccode.add_expression (ccall);
+               if (get_dbus_signature (prop) != null) {
+                       ccode.add_assignment (target, new CCodeIdentifier("_value"));
+                       ccode.add_expression (ccall);
+               } else {
+                       var expr = deserialize_expression (prop.property_type, new CCodeIdentifier ("_value"), target);
+                       ccode.add_assignment (target, expr);
+                       ccode.add_expression (ccall);
 
-               if (requires_destroy (owned_type)) {
-                       // keep local alive (symbol_reference is weak)
-                       var local = new LocalVariable (owned_type, "value");
-                       ccode.add_expression (destroy_local (local));
+                       if (requires_destroy (owned_type)) {
+                               // keep local alive (symbol_reference is weak)
+                               var local = new LocalVariable (owned_type, "value");
+                               ccode.add_expression (destroy_local (local));
+                       }
                }
 
                pop_function ();
index 7431ac60ba298931a01224cbf28cff0f5e8bf2fa..f7efca876ec441d0b98361cd919c5f1210e847bc 100644 (file)
@@ -245,6 +245,7 @@ TESTS = \
        dbus/dicts.test \
        dbus/bug596862.vala \
        dbus/bug602003.test \
+       dbus/rawvariants.test \
        gir/bug651773.test \
        gir/bug667751.test \
        gir/bug742012.test \
diff --git a/tests/dbus/rawvariants.test b/tests/dbus/rawvariants.test
new file mode 100644 (file)
index 0000000..ca80e74
--- /dev/null
@@ -0,0 +1,136 @@
+Packages: gio-2.0
+D-Bus
+
+Program: client
+
+[DBus (name = "org.example.Test")]
+public interface Test : Object {
+       public abstract string test_property { owned get; set; }
+
+       public signal void test_signal (int i);
+
+       public abstract int test_method (int j, int k) throws IOError;
+}
+
+[DBus (name = "org.example.Test")]
+public interface TestRaw : Object {
+       [DBus (signature = "s")]
+       public abstract Variant test_property { owned get; set; }
+
+       public signal void test_signal ([DBus (signature = "i")] Variant i);
+
+       [DBus (signature = "i")]
+       public abstract Variant test_method ([DBus (signature = "i")] Variant j, [DBus (signature = "i")] Variant k) throws IOError;
+}
+
+void test_raw (TestRaw test) {
+       var main_loop = new MainLoop ();
+
+       var id = test.test_signal.connect ((var_i) => {
+               var i = (int) var_i;
+               assert (i == 46);
+               main_loop.quit ();
+       });
+
+       int j = (int) test.test_method (23, 11);
+       assert (j == 42);
+
+       main_loop.run ();
+       test.disconnect (id);
+
+       test.test_property = "hello";
+       var s = (string) test.test_property;
+       assert (s == "hello");
+}
+
+void test (Test test) {
+       var main_loop = new MainLoop ();
+
+       var id = test.test_signal.connect ((i) => {
+               assert (i == 46);
+               main_loop.quit ();
+       });
+
+       int j = test.test_method (23, 11);
+       assert (j == 42);
+
+       main_loop.run ();
+       test.disconnect (id);
+
+       test.test_property = "hello";
+       var s = test.test_property;
+       assert (s == "hello");
+}
+
+void main () {
+       // raw variant server, standard client
+       Test test1 = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/testraw", DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
+       test (test1);
+
+       // standard server, raw variant client
+       TestRaw test2 = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/test", DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
+       test_raw (test2);
+
+       // raw variant server, raw variant client
+       TestRaw test3 = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/testraw", DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
+       test_raw (test3);
+}
+
+Program: server
+
+[DBus (name = "org.example.Test")]
+public class Test : Object {
+       public string test_property { owned get; set; }
+
+       public signal void test_signal (int i);
+
+       public int test_method (int j, int k) {
+               assert (j == 23);
+               assert (k == 11);
+               test_signal (46);
+               return 42;
+       }
+}
+
+[DBus (name = "org.example.Test")]
+public class TestRaw : Object {
+       [DBus (signature = "s")]
+       public Variant test_property { owned get; set; }
+
+       public signal void test_signal ([DBus (signature = "i")] Variant i);
+
+       [DBus (signature = "i")]
+       public Variant test_method ([DBus (signature = "i")] Variant j, [DBus (signature = "i")] Variant k) {
+               assert ((int) j == 23);
+               assert ((int) k == 11);
+               test_signal (46);
+               return 42;
+       }
+}
+
+MainLoop main_loop;
+
+void client_exit (Pid pid, int status) {
+       // client finished, terminate server
+       assert (status == 0);
+       main_loop.quit ();
+}
+
+void main () {
+       var conn = Bus.get_sync (BusType.SESSION);
+       conn.register_object ("/org/example/test", new Test ());
+       conn.register_object ("/org/example/testraw", new TestRaw ());
+
+       // try to register service in session bus
+       var request_result = conn.call_sync ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName",
+                                             new Variant ("(su)", "org.example.Test", 0x4), null, 0, -1);
+       assert ((uint) request_result.get_child_value (0) == 1);
+
+       // server ready, spawn client
+       Pid client_pid;
+       Process.spawn_async (null, { "test", "/dbus/rawvariants/client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid);
+       ChildWatch.add (client_pid, client_exit);
+
+       main_loop = new MainLoop ();
+       main_loop.run ();
+}