[vala] D-Bus: Support struct return values in static clients and servers
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] D-Bus: Support struct return values in static clients and servers
- Date: Sat, 19 Dec 2009 14:20:21 +0000 (UTC)
commit fb437864b4fa314c28e8d1a6135588de8283ca62
Author: Jürg Billeter <j bitron ch>
Date: Sat Dec 19 15:02:02 2009 +0100
D-Bus: Support struct return values in static clients and servers
codegen/valadbusclientmodule.vala | 133 +++++++++++++++++++++++--------------
codegen/valadbusservermodule.vala | 74 +++++++++++++-------
tests/Makefile.am | 1 +
tests/dbus/structs.test | 93 ++++++++++++++++++++++++++
4 files changed, 225 insertions(+), 76 deletions(-)
---
diff --git a/codegen/valadbusclientmodule.vala b/codegen/valadbusclientmodule.vala
index bcddb07..2b6d965 100644
--- a/codegen/valadbusclientmodule.vala
+++ b/codegen/valadbusclientmodule.vala
@@ -1475,28 +1475,34 @@ internal class Vala.DBusClientModule : DBusModule {
}
if (!(m.return_type is VoidType)) {
- cdecl = new CCodeDeclaration (m.return_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
- postfragment.append (cdecl);
+ if (m.return_type.is_real_struct_type ()) {
+ var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
+ var expr = read_expression (postfragment, m.return_type, new CCodeIdentifier ("_iter"), target);
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+ } else {
+ cdecl = new CCodeDeclaration (m.return_type.get_cname ());
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
+ postfragment.append (cdecl);
- var array_type = m.return_type as ArrayType;
+ var array_type = m.return_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
- postfragment.append (cdecl);
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ cdecl = new CCodeDeclaration ("int");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
+ postfragment.append (cdecl);
+ }
}
- }
- var target = new CCodeIdentifier ("_result");
- var expr = read_expression (postfragment, m.return_type, new CCodeIdentifier ("_iter"), target);
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+ var target = new CCodeIdentifier ("_result");
+ var expr = read_expression (postfragment, m.return_type, new CCodeIdentifier ("_iter"), target);
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- // TODO check that parameter is not NULL (out parameters are optional)
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (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)
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)))));
+ }
}
}
}
@@ -1571,7 +1577,7 @@ internal class Vala.DBusClientModule : DBusModule {
set_error_call.add_argument (new CCodeConstant ("\"Connection is closed\""));
dispose_return_block.add_statement (new CCodeExpressionStatement (set_error_call));
}
- if (m.return_type is VoidType) {
+ if (m.return_type is VoidType || m.return_type.is_real_struct_type ()) {
dispose_return_block.add_statement (new CCodeReturnStatement ());
} else {
dispose_return_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false)));
@@ -1639,7 +1645,7 @@ internal class Vala.DBusClientModule : DBusModule {
reply_unref.add_argument (new CCodeIdentifier ("_reply"));
block.add_statement (new CCodeExpressionStatement (reply_unref));
- if (!(m.return_type is VoidType)) {
+ if (!(m.return_type is VoidType || m.return_type.is_real_struct_type ())) {
block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
}
@@ -2002,20 +2008,28 @@ internal class Vala.DBusClientModule : DBusModule {
function.add_parameter (new CCodeFormalParameter ("self", "%s*".printf (iface.get_cname ())));
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- function.add_parameter (new CCodeFormalParameter ("result_length%d".printf (dim), "int*"));
+ if (prop.property_type.is_real_struct_type ()) {
+ function.add_parameter (new CCodeFormalParameter ("result", "%s*".printf (prop.set_accessor.value_type.get_cname ())));
+ } else {
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ function.add_parameter (new CCodeFormalParameter ("result_length%d".printf (dim), "int*"));
+ }
}
- }
- function.return_type = prop.get_accessor.value_type.get_cname ();
+ function.return_type = prop.get_accessor.value_type.get_cname ();
+ }
var block = new CCodeBlock ();
var prefragment = new CCodeFragment ();
var postfragment = new CCodeFragment ();
var dispose_return_block = new CCodeBlock ();
- dispose_return_block.add_statement (new CCodeReturnStatement (default_value_for_type (prop.property_type, false)));
+ if (prop.property_type.is_real_struct_type ()) {
+ dispose_return_block.add_statement (new CCodeReturnStatement ());
+ } else {
+ dispose_return_block.add_statement (new CCodeReturnStatement (default_value_for_type (prop.property_type, false)));
+ }
block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), iface.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block));
cdecl = new CCodeDeclaration ("DBusGConnection");
@@ -2061,31 +2075,37 @@ internal class Vala.DBusClientModule : DBusModule {
// property name
write_expression (prefragment, string_type, new CCodeIdentifier ("_iter"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))));
- cdecl = new CCodeDeclaration (prop.get_accessor.value_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
- postfragment.append (cdecl);
-
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
- postfragment.append (cdecl);
- }
- }
-
iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse"));
iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter")));
iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_subiter")));
postfragment.append (new CCodeExpressionStatement (iter_call));
- var target = new CCodeIdentifier ("_result");
- var expr = read_expression (postfragment, prop.get_accessor.value_type, new CCodeIdentifier ("_subiter"), target);
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+ if (prop.property_type.is_real_struct_type ()) {
+ var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
+ var expr = read_expression (postfragment, prop.get_accessor.value_type, new CCodeIdentifier ("_subiter"), target);
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+ } else {
+ cdecl = new CCodeDeclaration (prop.get_accessor.value_type.get_cname ());
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
+ postfragment.append (cdecl);
+
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ cdecl = new CCodeDeclaration ("int");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
+ postfragment.append (cdecl);
+ }
+ }
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- // TODO check that parameter is not NULL (out parameters are optional)
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)))));
+ var target = new CCodeIdentifier ("_result");
+ var expr = read_expression (postfragment, prop.get_accessor.value_type, new CCodeIdentifier ("_subiter"), target);
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
+
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ // TODO check that parameter is not NULL (out parameters are optional)
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)))));
+ }
}
}
@@ -2120,7 +2140,11 @@ internal class Vala.DBusClientModule : DBusModule {
reply_unref.add_argument (new CCodeIdentifier ("_reply"));
block.add_statement (new CCodeExpressionStatement (reply_unref));
- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+ if (prop.property_type.is_real_struct_type ()) {
+ block.add_statement (new CCodeReturnStatement ());
+ } else {
+ block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+ }
source_declarations.add_type_member_declaration (function.copy ());
function.block = block;
@@ -2142,11 +2166,16 @@ internal class Vala.DBusClientModule : DBusModule {
function.modifiers = CCodeModifiers.STATIC;
function.add_parameter (new CCodeFormalParameter ("self", "%s*".printf (iface.get_cname ())));
- function.add_parameter (new CCodeFormalParameter ("value", prop.set_accessor.value_type.get_cname ()));
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- function.add_parameter (new CCodeFormalParameter ("value_length%d".printf (dim), "int"));
+ if (prop.property_type.is_real_struct_type ()) {
+ function.add_parameter (new CCodeFormalParameter ("value", "%s*".printf (prop.set_accessor.value_type.get_cname ())));
+ } else {
+ function.add_parameter (new CCodeFormalParameter ("value", prop.set_accessor.value_type.get_cname ()));
+
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ function.add_parameter (new CCodeFormalParameter ("value_length%d".printf (dim), "int"));
+ }
}
}
@@ -2209,7 +2238,11 @@ internal class Vala.DBusClientModule : DBusModule {
iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_subiter")));
prefragment.append (new CCodeExpressionStatement (iter_call));
- write_expression (prefragment, prop.set_accessor.value_type, new CCodeIdentifier ("_subiter"), new CCodeIdentifier ("value"));
+ if (prop.property_type.is_real_struct_type ()) {
+ write_expression (prefragment, prop.set_accessor.value_type, new CCodeIdentifier ("_subiter"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("value")));
+ } else {
+ write_expression (prefragment, prop.set_accessor.value_type, new CCodeIdentifier ("_subiter"), new CCodeIdentifier ("value"));
+ }
iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container"));
iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter")));
diff --git a/codegen/valadbusservermodule.vala b/codegen/valadbusservermodule.vala
index 13f895d..cfed028 100644
--- a/codegen/valadbusservermodule.vala
+++ b/codegen/valadbusservermodule.vala
@@ -785,18 +785,26 @@ internal class Vala.DBusServerModule : DBusClientModule {
cdecl = new CCodeDeclaration (prop.property_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
postfragment.append (cdecl);
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
- var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_array_length_cname ("result", dim);
+ if (prop.property_type.is_real_struct_type ()) {
+ // structs are returned via out parameter
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator (length_cname));
- postfragment.append (cdecl);
+ postfragment.append (new CCodeExpressionStatement (ccall));
+ } else {
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
+
+ var array_type = prop.property_type as ArrayType;
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ string length_cname = get_array_length_cname ("result", dim);
+
+ cdecl = new CCodeDeclaration ("int");
+ cdecl.add_declarator (new CCodeVariableDeclarator (length_cname));
+ postfragment.append (cdecl);
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+ }
}
}
@@ -993,18 +1001,26 @@ internal class Vala.DBusServerModule : DBusClientModule {
cdecl = new CCodeDeclaration (prop.property_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
postfragment.append (cdecl);
- postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
- var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_array_length_cname ("result", dim);
+ if (prop.property_type.is_real_struct_type ()) {
+ // structs are returned via out parameter
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator (length_cname));
- postfragment.append (cdecl);
+ postfragment.append (new CCodeExpressionStatement (ccall));
+ } else {
+ postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall)));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+ var array_type = prop.property_type as ArrayType;
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ string length_cname = get_array_length_cname ("result", dim);
+
+ cdecl = new CCodeDeclaration ("int");
+ cdecl.add_declarator (new CCodeVariableDeclarator (length_cname));
+ postfragment.append (cdecl);
+
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
+ }
}
}
@@ -1168,16 +1184,22 @@ internal class Vala.DBusServerModule : DBusClientModule {
var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.set_accessor.get_cname ()));
ccall.add_argument (new CCodeIdentifier ("self"));
- ccall.add_argument (new CCodeIdentifier ("value"));
- var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator (head.get_array_length_cname ("value", dim)));
- prefragment.append (cdecl);
+ if (prop.property_type.is_real_struct_type ()) {
+ // structs are passed by reference
+ ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("value")));
+ } else {
+ ccall.add_argument (new CCodeIdentifier ("value"));
+
+ var array_type = prop.property_type as ArrayType;
+ if (array_type != null) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ cdecl = new CCodeDeclaration ("int");
+ cdecl.add_declarator (new CCodeVariableDeclarator (head.get_array_length_cname ("value", dim)));
+ prefragment.append (cdecl);
- ccall.add_argument (new CCodeIdentifier (head.get_array_length_cname ("value", dim)));
+ ccall.add_argument (new CCodeIdentifier (head.get_array_length_cname ("value", dim)));
+ }
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 87d3b72..09d0640 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -74,6 +74,7 @@ TESTS = \
asynchronous/bug601558.vala \
dbus/basic-types.test \
dbus/arrays.test \
+ dbus/structs.test \
dbus/async.test \
dbus/bug596862.vala \
$(NULL)
diff --git a/tests/dbus/structs.test b/tests/dbus/structs.test
new file mode 100644
index 0000000..744aad4
--- /dev/null
+++ b/tests/dbus/structs.test
@@ -0,0 +1,93 @@
+Packages: dbus-glib-1
+
+Program: client
+
+struct FooStruct {
+ int i;
+ string s;
+
+ public FooStruct (int i, string s) {
+ this.i = i;
+ this.s = s;
+ }
+}
+
+[DBus (name = "org.example.Test")]
+interface Test : Object {
+ public abstract FooStruct test_property { owned get; set; }
+
+ public abstract FooStruct test_struct (FooStruct f, out FooStruct g) throws DBus.Error;
+}
+
+void main () {
+ var conn = DBus.Bus.get (DBus.BusType.SESSION);
+
+ // client
+ var test = (Test) conn.get_object ("org.example.Test", "/org/example/test");
+
+ FooStruct f, g, h;
+ f = FooStruct (42, "hello");
+ h = test.test_struct (f, out g);
+ assert (g.i == 23);
+ assert (g.s == "world");
+ assert (h.i == 11);
+ assert (h.s == "vala");
+
+ test.test_property = f;
+ g = test.test_property;
+ assert (g.i == 42);
+ assert (g.s == "hello");
+}
+
+Program: server
+
+struct FooStruct {
+ int i;
+ string s;
+
+ public FooStruct (int i, string s) {
+ this.i = i;
+ this.s = s;
+ }
+}
+
+[DBus (name = "org.example.Test")]
+class Test : Object {
+ public FooStruct test_property { owned get; set; }
+
+ public FooStruct test_struct (FooStruct f, out FooStruct g) {
+ assert (f.i == 42);
+ assert (f.s == "hello");
+ g = FooStruct (23, "world");
+ return FooStruct (11, "vala");
+ }
+}
+
+MainLoop main_loop;
+
+void client_exit (Pid pid, int status) {
+ // client finished, terminate server
+ assert (status == 0);
+ main_loop.quit ();
+}
+
+void main () {
+ var conn = DBus.Bus.get (DBus.BusType.SESSION);
+ dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
+
+ // try to register service in session bus
+ uint request_name_result = bus.request_name ("org.example.Test", (uint) 0);
+ assert (request_name_result == DBus.RequestNameReply.PRIMARY_OWNER);
+
+ // start server
+ var server = new Test ();
+ conn.register_object ("/org/example/test", server);
+
+ // server ready, spawn client
+ Pid client_pid;
+ Process.spawn_async (null, { "test", "/dbus/structs/client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid);
+ ChildWatch.add (client_pid, client_exit);
+
+ main_loop = new MainLoop (null, false);
+ main_loop.run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]