vala r1520 - in trunk: . gobject vala



Author: juergbi
Date: Sat May 31 18:49:17 2008
New Revision: 1520
URL: http://svn.gnome.org/viewvc/vala?rev=1520&view=rev

Log:
2008-05-31  JÃrg Billeter  <j bitron ch>

	* vala/valastruct.vala:
	* gobject/valaccodedynamicmethodbinding.vala:
	* gobject/valaccodegeneratorsignal.vala:
	* gobject/valaccodeobjecttypesymbolbinding.vala:

	Add support for structs in D-Bus service and client methods,
	fixes bug 534548 and bug 534549


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodedynamicmethodbinding.vala
   trunk/gobject/valaccodegeneratorsignal.vala
   trunk/gobject/valaccodeobjecttypesymbolbinding.vala
   trunk/vala/valastruct.vala

Modified: trunk/gobject/valaccodedynamicmethodbinding.vala
==============================================================================
--- trunk/gobject/valaccodedynamicmethodbinding.vala	(original)
+++ trunk/gobject/valaccodedynamicmethodbinding.vala	Sat May 31 18:49:17 2008
@@ -184,12 +184,119 @@
 				break;
 			}
 
-			ccall.add_argument (new CCodeIdentifier (param.parameter_type.data_type.get_type_id ()));
-			ccall.add_argument (new CCodeIdentifier (param.name));
+			if (param.direction != ParameterDirection.IN) {
+				continue;
+			}
+
+			if (param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				// struct parameter
+				var st = (Struct) param.parameter_type.data_type;
+
+				var array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_new"));
+				array_construct.add_argument (new CCodeConstant ("0"));
+
+				var cdecl = new CCodeDeclaration ("GValueArray*");
+				cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("dbus_%s".printf (param.name), array_construct));
+				block.add_statement (cdecl);
+
+				var type_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_struct"));
+				type_call.add_argument (new CCodeConstant ("\"GValueArray\""));
+
+				foreach (Field f in st.get_fields ()) {
+					if (f.binding != MemberBinding.INSTANCE) {
+						continue;
+					}
+
+					string val_name = "val_%s_%s".printf (param.name, f.name);
+
+					// 0-initialize struct with struct initializer { 0 }
+					var cvalinit = new CCodeInitializerList ();
+					cvalinit.append (new CCodeConstant ("0"));
+
+					var cval_decl = new CCodeDeclaration ("GValue");
+					cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer (val_name, cvalinit));
+					block.add_statement (cval_decl);
+
+					var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (val_name));
+
+					var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+					cinit_call.add_argument (val_ptr);
+					cinit_call.add_argument (new CCodeIdentifier (f.field_type.data_type.get_type_id ()));
+					block.add_statement (new CCodeExpressionStatement (cinit_call));
+
+					var cset_call = new CCodeFunctionCall (new CCodeIdentifier (f.field_type.data_type.get_set_value_function ()));
+					cset_call.add_argument (val_ptr);
+					cset_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), f.name));
+					block.add_statement (new CCodeExpressionStatement (cset_call));
+
+					var cappend_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_append"));
+					cappend_call.add_argument (new CCodeIdentifier ("dbus_%s".printf (param.name)));
+					cappend_call.add_argument (val_ptr);
+					block.add_statement (new CCodeExpressionStatement (cappend_call));
+
+					type_call.add_argument (new CCodeIdentifier (f.field_type.data_type.get_type_id ()));
+				}
+
+				type_call.add_argument (new CCodeConstant ("G_TYPE_INVALID"));
+
+				ccall.add_argument (type_call);
+				ccall.add_argument (new CCodeIdentifier ("dbus_%s".printf (param.name)));
+			} else {
+				ccall.add_argument (new CCodeIdentifier (param.parameter_type.data_type.get_type_id ()));
+				ccall.add_argument (new CCodeIdentifier (param.name));
+			}
 		}
 
 		ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
 
+		var out_marshalling_fragment = new CCodeFragment ();
+
+		foreach (FormalParameter param in method.get_parameters ()) {
+			if (param.parameter_type is MethodType) {
+				// callback parameter
+				break;
+			}
+
+			if (param.direction != ParameterDirection.OUT) {
+				continue;
+			}
+
+			if (param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				// struct output parameter
+				var st = (Struct) param.parameter_type.data_type;
+
+				var cdecl = new CCodeDeclaration ("GValueArray*");
+				cdecl.add_declarator (new CCodeVariableDeclarator ("dbus_%s".printf (param.name)));
+				block.add_statement (cdecl);
+
+				var type_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_struct"));
+				type_call.add_argument (new CCodeConstant ("\"GValueArray\""));
+
+				int i = 0;
+				foreach (Field f in st.get_fields ()) {
+					if (f.binding != MemberBinding.INSTANCE) {
+						continue;
+					}
+
+					var cget_call = new CCodeFunctionCall (new CCodeIdentifier (f.field_type.data_type.get_get_value_function ()));
+					cget_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeElementAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dbus_%s".printf (param.name)), "values"), new CCodeConstant (i.to_string ()))));
+					var assign = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), f.name), cget_call);
+					out_marshalling_fragment.append (new CCodeExpressionStatement (assign));
+
+					type_call.add_argument (new CCodeIdentifier (f.field_type.data_type.get_type_id ()));
+					i++;
+				}
+
+				type_call.add_argument (new CCodeConstant ("G_TYPE_INVALID"));
+
+				ccall.add_argument (type_call);
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("dbus_%s".printf (param.name))));
+			} else {
+				ccall.add_argument (new CCodeIdentifier (param.parameter_type.data_type.get_type_id ()));
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+			}
+		}
+
 		if (!(method.return_type is VoidType)) {
 			// synchronous D-Bus method call with reply
 			var array_type = method.return_type as ArrayType;
@@ -207,6 +314,8 @@
 
 				block.add_statement (new CCodeExpressionStatement (ccall));
 
+				block.add_statement (out_marshalling_fragment);
+
 				// *result_length1 = result->len;
 				var garray_length = new CCodeMemberAccess.pointer (new CCodeIdentifier ("result"), "len");
 				var result_length = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length1"));
@@ -235,6 +344,8 @@
 
 				block.add_statement (new CCodeExpressionStatement (ccall));
 
+				block.add_statement (out_marshalling_fragment);
+
 				if (array_type != null) {
 					// special case string array
 
@@ -250,6 +361,8 @@
 			}
 		} else {
 			block.add_statement (new CCodeExpressionStatement (ccall));
+
+			block.add_statement (out_marshalling_fragment);
 		}
 	}
 

Modified: trunk/gobject/valaccodegeneratorsignal.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorsignal.vala	(original)
+++ trunk/gobject/valaccodegeneratorsignal.vala	Sat May 31 18:49:17 2008
@@ -24,7 +24,7 @@
 using GLib;
 
 public class Vala.CCodeGenerator {
-	private string get_marshaller_type_name (DataType t) {
+	private string get_marshaller_type_name (DataType t, bool dbus = false) {
 		if (t is PointerType || t.type_parameter != null) {
 			return ("POINTER");
 		} else if (t is ErrorType) {
@@ -37,20 +37,22 @@
 			}
 		} else if (t is VoidType) {
 			return ("VOID");
+		} else if (dbus && t.get_type_signature ().has_prefix ("(")) {
+			return ("BOXED");
 		} else {
 			return t.data_type.get_marshaller_type_name ();
 		}
 	}
 	
-	private string get_marshaller_type_name_for_parameter (FormalParameter param) {
+	private string get_marshaller_type_name_for_parameter (FormalParameter param, bool dbus = false) {
 		if (param.direction != ParameterDirection.IN) {
 			return ("POINTER");
 		} else {
-			return get_marshaller_type_name (param.parameter_type);
+			return get_marshaller_type_name (param.parameter_type, dbus);
 		}
 	}
 	
-	public string get_marshaller_function (Gee.List<FormalParameter> params, DataType return_type, string? prefix = null) {
+	public string get_marshaller_function (Gee.List<FormalParameter> params, DataType return_type, string? prefix = null, bool dbus = false) {
 		var signature = get_marshaller_signature (params, return_type);
 		string ret;
 
@@ -62,13 +64,13 @@
 			}
 		}
 		
-		ret = "%s_%s_".printf (prefix, get_marshaller_type_name (return_type));
+		ret = "%s_%s_".printf (prefix, get_marshaller_type_name (return_type, dbus));
 		
 		if (params == null || params.size == 0) {
 			ret = ret + "_VOID";
 		} else {
 			foreach (FormalParameter p in params) {
-				ret = "%s_%s".printf (ret, get_marshaller_type_name_for_parameter (p));
+				ret = "%s_%s".printf (ret, get_marshaller_type_name_for_parameter (p, dbus));
 			}
 		}
 		
@@ -110,20 +112,20 @@
 		}
 	}
 	
-	private string get_marshaller_signature (Gee.List<FormalParameter> params, DataType return_type) {
+	private string get_marshaller_signature (Gee.List<FormalParameter> params, DataType return_type, bool dbus = false) {
 		string signature;
 		
-		signature = "%s:".printf (get_marshaller_type_name (return_type));
+		signature = "%s:".printf (get_marshaller_type_name (return_type, dbus));
 		if (params == null || params.size == 0) {
 			signature = signature + "VOID";
 		} else {
 			bool first = true;
 			foreach (FormalParameter p in params) {
 				if (first) {
-					signature = signature + get_marshaller_type_name_for_parameter (p);
+					signature = signature + get_marshaller_type_name_for_parameter (p, dbus);
 					first = false;
 				} else {
-					signature = "%s,%s".printf (signature, get_marshaller_type_name_for_parameter (p));
+					signature = "%s,%s".printf (signature, get_marshaller_type_name_for_parameter (p, dbus));
 				}
 			}
 		}
@@ -147,7 +149,7 @@
 		generate_marshaller (sig.get_parameters (), sig.return_type);
 	}
 
-	public void generate_marshaller (Gee.List<FormalParameter> params, DataType return_type) {
+	public void generate_marshaller (Gee.List<FormalParameter> params, DataType return_type, bool dbus = false) {
 		string signature;
 		int n_params, i;
 		
@@ -157,7 +159,7 @@
 			return;
 		}
 		
-		var signal_marshaller = new CCodeFunction (get_marshaller_function (params, return_type), "void");
+		var signal_marshaller = new CCodeFunction (get_marshaller_function (params, return_type, null, dbus), "void");
 		signal_marshaller.modifiers = CCodeModifiers.STATIC;
 		
 		signal_marshaller.add_parameter (new CCodeFormalParameter ("closure", "GClosure *"));
@@ -171,7 +173,7 @@
 		
 		var marshaller_body = new CCodeBlock ();
 		
-		var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (params, return_type, "GMarshalFunc"));
+		var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (params, return_type, "GMarshalFunc", dbus));
 		callback_decl.add_parameter (new CCodeFormalParameter ("data1", "gpointer"));
 		n_params = 1;
 		foreach (FormalParameter p in params) {
@@ -181,7 +183,7 @@
 		callback_decl.add_parameter (new CCodeFormalParameter ("data2", "gpointer"));
 		marshaller_body.add_statement (new CCodeTypeDefinition (get_value_type_name_from_type_reference (return_type), callback_decl));
 		
-		var var_decl = new CCodeDeclaration (get_marshaller_function (params, return_type, "GMarshalFunc"));
+		var var_decl = new CCodeDeclaration (get_marshaller_function (params, return_type, "GMarshalFunc", dbus));
 		var_decl.modifiers = CCodeModifiers.REGISTER;
 		var_decl.add_declarator (new CCodeVariableDeclarator ("callback"));
 		marshaller_body.add_statement (var_decl);
@@ -225,7 +227,7 @@
 		false_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data2"), data)));
 		marshaller_body.add_statement (new CCodeIfStatement (cond, true_block, false_block));
 		
-		var c_assign = new CCodeAssignment (new CCodeIdentifier ("callback"), new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_marshaller_function (params, return_type, "GMarshalFunc")));
+		var c_assign = new CCodeAssignment (new CCodeIdentifier ("callback"), new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_marshaller_function (params, return_type, "GMarshalFunc", dbus)));
 		marshaller_body.add_statement (new CCodeExpressionStatement (c_assign));
 		
 		fc = new CCodeFunctionCall (new CCodeIdentifier ("callback"));
@@ -237,6 +239,8 @@
 				get_value_function = "g_value_get_pointer";
 			} else if (p.parameter_type is ErrorType) {
 				get_value_function = "g_value_get_pointer";
+			} else if (dbus && p.parameter_type.get_type_signature ().has_prefix ("(")) {
+				get_value_function = "g_value_get_boxed";
 			} else {
 				get_value_function = p.parameter_type.data_type.get_get_value_function ();
 			}
@@ -265,6 +269,8 @@
 				set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_string"));
 			} else if (return_type.data_type is Class || return_type.data_type is Interface) {
 				set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
+			} else if (dbus && return_type.get_type_signature ().has_prefix ("(")) {
+				set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed"));
 			} else {
 				set_fc = new CCodeFunctionCall (new CCodeIdentifier (return_type.data_type.get_set_value_function ()));
 			}

Modified: trunk/gobject/valaccodeobjecttypesymbolbinding.vala
==============================================================================
--- trunk/gobject/valaccodeobjecttypesymbolbinding.vala	(original)
+++ trunk/gobject/valaccodeobjecttypesymbolbinding.vala	Sat May 31 18:49:17 2008
@@ -79,12 +79,12 @@
 			dbus_methods.append ("{ (GCallback) ");
 			dbus_methods.append (generate_dbus_wrapper (m, bindable));
 			dbus_methods.append (", ");
-			dbus_methods.append (codegen.get_marshaller_function (parameters, codegen.bool_type));
+			dbus_methods.append (codegen.get_marshaller_function (parameters, codegen.bool_type, null, true));
 			dbus_methods.append (", ");
 			dbus_methods.append (blob_len.to_string ());
 			dbus_methods.append (" },\n");
 
-			codegen.generate_marshaller (parameters, codegen.bool_type);
+			codegen.generate_marshaller (parameters, codegen.bool_type, true);
 
 			long start = blob.len;
 
@@ -219,23 +219,66 @@
 		function.add_parameter (new CCodeFormalParameter ("self", bindable.get_cname () + "*"));
 
 		foreach (FormalParameter param in m.get_parameters ()) {
-			function.add_parameter ((CCodeFormalParameter) param.ccodenode);
+			if (param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				if (param.direction == ParameterDirection.IN) {
+					function.add_parameter (new CCodeFormalParameter ("dbus_%s".printf (param.name), "GValueArray*"));
+				} else {
+					function.add_parameter (new CCodeFormalParameter ("dbus_%s".printf (param.name), "GValueArray**"));
+				}
+			} else {
+				function.add_parameter ((CCodeFormalParameter) param.ccodenode);
+			}
 		}
 
 		if (!(m.return_type is VoidType)) {
-			function.add_parameter (new CCodeFormalParameter ("result", m.return_type.get_cname () + "*"));
+			if (m.return_type.get_type_signature ().has_prefix ("(")) {
+				function.add_parameter (new CCodeFormalParameter ("result", "GValueArray**"));
+			} else {
+				function.add_parameter (new CCodeFormalParameter ("result", m.return_type.get_cname () + "*"));
+			}
 		}
 
 		function.add_parameter (new CCodeFormalParameter ("error", "GError**"));
 
 		// definition
 
+		var block = new CCodeBlock ();
+
+		foreach (FormalParameter param in m.get_parameters ()) {
+			if (param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				var st = (Struct) param.parameter_type.data_type;
+
+				var cdecl = new CCodeDeclaration (st.get_cname ());
+				cdecl.add_declarator (new CCodeVariableDeclarator (param.name));
+				block.add_statement (cdecl);
+
+				if (param.direction == ParameterDirection.IN) {
+					// struct input parameter
+					int i = 0;
+					foreach (Field f in st.get_fields ()) {
+						if (f.binding == MemberBinding.INSTANCE) {
+							var cget_call = new CCodeFunctionCall (new CCodeIdentifier (f.field_type.data_type.get_get_value_function ()));
+							cget_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeElementAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dbus_%s".printf (param.name)), "values"), new CCodeConstant (i.to_string ()))));
+							var assign = new CCodeAssignment (new CCodeMemberAccess (new CCodeIdentifier (param.name), f.name), cget_call);
+							block.add_statement (new CCodeExpressionStatement (assign));
+							i++;
+						}
+					}
+				}
+			}
+		}
+
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
 
 		ccall.add_argument (new CCodeIdentifier ("self"));
 
 		foreach (FormalParameter param in m.get_parameters ()) {
-			ccall.add_argument (new CCodeIdentifier (param.name));
+			if (param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				// struct input or output parameters
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+			} else {
+				ccall.add_argument (new CCodeIdentifier (param.name));
+			}
 		}
 
 		if (m.get_error_types ().size > 0) {
@@ -249,8 +292,61 @@
 			expr = new CCodeAssignment (new CCodeIdentifier ("*result"), ccall);
 		}
 
-		var block = new CCodeBlock ();
 		block.add_statement (new CCodeExpressionStatement (expr));
+
+		foreach (FormalParameter param in m.get_parameters ()) {
+			if (param.direction == ParameterDirection.OUT
+			    && param.parameter_type.get_type_signature ().has_prefix ("(")) {
+				// struct output parameter
+				var st = (Struct) param.parameter_type.data_type;
+
+				var array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_new"));
+				array_construct.add_argument (new CCodeConstant ("0"));
+
+				var dbus_param = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("dbus_%s".printf (param.name)));
+
+				block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (dbus_param, array_construct)));
+
+				var type_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_struct"));
+				type_call.add_argument (new CCodeConstant ("\"GValueArray\""));
+
+				foreach (Field f in st.get_fields ()) {
+					if (f.binding != MemberBinding.INSTANCE) {
+						continue;
+					}
+
+					string val_name = "val_%s_%s".printf (param.name, f.name);
+
+					// 0-initialize struct with struct initializer { 0 }
+					var cvalinit = new CCodeInitializerList ();
+					cvalinit.append (new CCodeConstant ("0"));
+
+					var cval_decl = new CCodeDeclaration ("GValue");
+					cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer (val_name, cvalinit));
+					block.add_statement (cval_decl);
+
+					var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (val_name));
+
+					var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
+					cinit_call.add_argument (val_ptr);
+					cinit_call.add_argument (new CCodeIdentifier (f.field_type.data_type.get_type_id ()));
+					block.add_statement (new CCodeExpressionStatement (cinit_call));
+
+					var cset_call = new CCodeFunctionCall (new CCodeIdentifier (f.field_type.data_type.get_set_value_function ()));
+					cset_call.add_argument (val_ptr);
+					cset_call.add_argument (new CCodeMemberAccess (new CCodeIdentifier (param.name), f.name));
+					block.add_statement (new CCodeExpressionStatement (cset_call));
+
+					var cappend_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_append"));
+					cappend_call.add_argument (dbus_param);
+					cappend_call.add_argument (val_ptr);
+					block.add_statement (new CCodeExpressionStatement (cappend_call));
+
+					type_call.add_argument (new CCodeIdentifier (f.field_type.data_type.get_type_id ()));
+				}
+			}
+		}
+
 		var no_error = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeIdentifier ("!error"), new CCodeIdentifier ("!*error"));
 		block.add_statement (new CCodeReturnStatement (no_error));
 

Modified: trunk/vala/valastruct.vala
==============================================================================
--- trunk/vala/valastruct.vala	(original)
+++ trunk/vala/valastruct.vala	Sat May 31 18:49:17 2008
@@ -243,6 +243,17 @@
 	}
 
 	public override string? get_type_signature () {
+		if (type_signature == null) {
+			var str = new StringBuilder ();
+			str.append_c ('(');
+			foreach (Field f in fields) {
+				if (f.binding == MemberBinding.INSTANCE) {
+					str.append (f.field_type.get_type_signature ());
+				}
+			}
+			str.append_c (')');
+			return str.str;
+		}
 		return type_signature;
 	}
 



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