[vala] D-Bus: Support string arrays in variants



commit de1e33e462a007ec9c2cab315badb8138afbd7bf
Author: Jürg Billeter <j bitron ch>
Date:   Tue Jun 15 22:38:12 2010 +0200

    D-Bus: Support string arrays in variants
    
    Fixes bug 602003.

 codegen/valadbusmodule.vala |   76 ++++++++++++++++++++++++++++++++++++++++++-
 tests/Makefile.am           |    1 +
 tests/dbus/bug602003.test   |   58 ++++++++++++++++++++++++++++++++
 3 files changed, 134 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valadbusmodule.vala b/codegen/valadbusmodule.vala
index f7b8d1f..6fbf48c 100644
--- a/codegen/valadbusmodule.vala
+++ b/codegen/valadbusmodule.vala
@@ -193,8 +193,12 @@ public class Vala.DBusModule : GAsyncModule {
 			} else {
 				return new CCodeMemberAccess (ma.inner, "%s_length%d".printf (ma.member_name, dim));
 			}
+		} else {
+			// must be NULL-terminated
+			var len_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length"));
+			len_call.add_argument (expr);
+			return len_call;
 		}
-		return null;
 	}
 
 	CCodeExpression? generate_enum_value_from_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) {
@@ -474,6 +478,41 @@ public class Vala.DBusModule : GAsyncModule {
 			clastif = cif;
 		}
 
+		// handle string arrays
+		var type_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_arg_type"));
+		type_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
+		var type_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, type_call, new CCodeIdentifier ("DBUS_TYPE_ARRAY"));
+
+		type_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_element_type"));
+		type_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
+		var element_type_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, type_call, new CCodeIdentifier ("DBUS_TYPE_STRING"));
+
+		type_check = new CCodeBinaryExpression (CCodeBinaryOperator.AND, type_check, element_type_check);
+
+		var type_block = new CCodeBlock ();
+		var type_fragment = new CCodeFragment ();
+		type_block.add_statement (type_fragment);
+		var result = read_array (type_fragment, new ArrayType (string_type, 1, null), new CCodeIdentifier (subiter_name), null);
+
+		var value_init = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+		value_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_name)));
+		value_init.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
+		type_fragment.append (new CCodeExpressionStatement (value_init));
+
+		var value_set = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed"));
+		value_set.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_name)));
+		value_set.add_argument (result);
+		type_fragment.append (new CCodeExpressionStatement (value_set));
+
+		var cif = new CCodeIfStatement (type_check, type_block);
+		if (clastif == null) {
+			fragment.append (cif);
+		} else {
+			clastif.false_statement = cif;
+		}
+
+		clastif = cif;
+
 		return new CCodeIdentifier (temp_name);
 	}
 
@@ -802,6 +841,41 @@ public class Vala.DBusModule : GAsyncModule {
 
 			clastif = cif;
 		}
+
+		// handle string arrays
+		var type_call = new CCodeFunctionCall (new CCodeIdentifier ("G_VALUE_TYPE"));
+		type_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, expr));
+		var type_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, type_call, new CCodeIdentifier ("G_TYPE_STRV"));
+
+		var type_block = new CCodeBlock ();
+		var type_fragment = new CCodeFragment ();
+		type_block.add_statement (type_fragment);
+
+		var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container"));
+		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr));
+		iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_VARIANT"));
+		iter_call.add_argument (new CCodeConstant ("\"as\""));
+		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
+		type_fragment.append (new CCodeExpressionStatement (iter_call));
+
+		var value_get = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_boxed"));
+		value_get.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, expr));
+
+		write_array (type_fragment, new ArrayType (string_type, 1, null), new CCodeIdentifier (subiter_name), value_get);
+
+		iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container"));
+		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr));
+		iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name)));
+		type_fragment.append (new CCodeExpressionStatement (iter_call));
+
+		var cif = new CCodeIfStatement (type_check, type_block);
+		if (clastif == null) {
+			fragment.append (cif);
+		} else {
+			clastif.false_statement = cif;
+		}
+
+		clastif = cif;
 	}
 
 	void write_hash_table (CCodeFragment fragment, ObjectType type, CCodeExpression iter_expr, CCodeExpression hash_table_expr) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 929be7a..1ed8950 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -87,6 +87,7 @@ TESTS = \
 	dbus/async.test \
 	dbus/signals.test \
 	dbus/bug596862.vala \
+	dbus/bug602003.test \
 	$(NULL)
 
 check-TESTS: $(TESTS)
diff --git a/tests/dbus/bug602003.test b/tests/dbus/bug602003.test
new file mode 100644
index 0000000..cf3127f
--- /dev/null
+++ b/tests/dbus/bug602003.test
@@ -0,0 +1,58 @@
+Packages: dbus-glib-1
+
+Program: client
+
+[DBus (name = "org.example.Test")]
+interface Test : Object {
+	public abstract Value test_string () 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");
+
+	Value v = test.test_string ();
+	string[] s = (string[]) v;
+	assert (s.length == 1 && s[0] == "hello");
+}
+
+Program: server
+
+[DBus (name = "org.example.Test")]
+class Test : Object {
+	public Value test_string () {
+		string[] s = { "hello" };
+		return s;
+	}
+}
+
+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/bug602003/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]