From: Jürg Billeter Date: Mon, 4 Apr 2011 07:44:26 +0000 (+0200) Subject: Drop deprecated support for D-Bus GLib X-Git-Tag: 0.13.0~314 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c9b78ab70fd38f6bb3dfcd0f28074f407fd261f;p=thirdparty%2Fvala.git Drop deprecated support for D-Bus GLib GDBus should be used instead. --- diff --git a/codegen/Makefile.am b/codegen/Makefile.am index 323284947..c2dafce56 100644 --- a/codegen/Makefile.am +++ b/codegen/Makefile.am @@ -27,9 +27,6 @@ libvala_la_VALASOURCES = \ valaccodestructmodule.vala \ valaclassregisterfunction.vala \ valactype.vala \ - valadbusclientmodule.vala \ - valadbusmodule.vala \ - valadbusservermodule.vala \ valadovaarraymodule.vala \ valadovaassignmentmodule.vala \ valadovabasemodule.vala \ diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 764815cc6..69b26590d 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -291,7 +291,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { public Struct mutex_type; public TypeSymbol type_module_type; public TypeSymbol dbus_proxy_type; - public TypeSymbol dbus_object_type; public bool in_plugin = false; public string module_init_param_name; @@ -448,11 +447,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } dbus_proxy_type = (TypeSymbol) glib_ns.scope.lookup ("DBusProxy"); - - var dbus_ns = root_symbol.scope.lookup ("DBus"); - if (dbus_ns != null) { - dbus_object_type = (TypeSymbol) dbus_ns.scope.lookup ("Object"); - } } header_file = new CCodeFile (); @@ -5879,13 +5873,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return ""; } - public virtual void generate_marshaller (List params, DataType return_type, bool dbus = false) { - } - - public virtual string get_marshaller_function (List params, DataType return_type, string? prefix = null, bool dbus = false) { - return ""; - } - public virtual string get_array_length_cname (string array_cname, int dim) { return ""; } diff --git a/codegen/valadbusclientmodule.vala b/codegen/valadbusclientmodule.vala deleted file mode 100644 index 810217195..000000000 --- a/codegen/valadbusclientmodule.vala +++ /dev/null @@ -1,2831 +0,0 @@ -/* valadbusclientmodule.vala - * - * Copyright (C) 2007-2010 Jürg Billeter -* Copyright (C) 2008 Philip Van Hoof - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Philip Van Hoof - */ - -using GLib; - -/** - * The link between a dynamic method and generated code. - */ -public class Vala.DBusClientModule : DBusModule { - int dynamic_property_id; - - string get_dynamic_dbus_name (string vala_name) { - // TODO switch default to no transformation as soon as we have static D-Bus client support - // keep transformation by default for static D-Bus client and server support - if (context.dbus_transformation) { - return Symbol.lower_case_to_camel_case (vala_name); - } else { - return vala_name; - } - } - - public CCodeConstant get_dbus_timeout (Symbol symbol) { - int timeout = -1; - - var dbus = symbol.get_attribute ("DBus"); - if (dbus != null && dbus.has_argument ("timeout")) { - timeout = dbus.get_integer ("timeout"); - } else if (symbol.parent_symbol != null) { - return get_dbus_timeout (symbol.parent_symbol); - } - - return new CCodeConstant (timeout.to_string ()); - } - - public static bool is_dbus_no_reply (CodeNode node) { - var dbus_attribute = node.get_attribute ("DBus"); - if (dbus_attribute != null - && dbus_attribute.has_argument ("no_reply") - && dbus_attribute.get_bool ("no_reply")) { - return true; - } - - return false; - } - - bool has_dbus_error (List error_types) { - foreach (DataType error_type in error_types) { - if (((ErrorType) error_type).error_domain.get_full_name () == "DBus.Error") { - return true; - } - } - return false; - } - - public override void generate_dynamic_method_wrapper (DynamicMethod method) { - var dynamic_method = (DynamicMethod) method; - - var func = new CCodeFunction (method.get_cname ()); - func.modifiers = CCodeModifiers.STATIC; - - var cparam_map = new HashMap (direct_hash, direct_equal); - - generate_cparameters (method, cfile, cparam_map, func); - - var block = new CCodeBlock (); - if (dynamic_method.dynamic_type.data_type == dbus_object_type) { - generate_dbus_method_wrapper (method, block); - } else { - Report.error (method.source_reference, "dynamic methods are not supported for `%s'".printf (dynamic_method.dynamic_type.to_string ())); - } - - // append to C source file - cfile.add_function_declaration (func); - - func.block = block; - cfile.add_function (func); - } - - void generate_dbus_method_wrapper (Method method, CCodeBlock block) { - var dynamic_method = (DynamicMethod) method; - - var expr = dynamic_method.invocation; - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_begin_call")); - - ccall.add_argument (new CCodeIdentifier ("self")); - - bool found_out = false; - Expression callback = null; - int callback_index = -1; - int arg_index = 1; - foreach (Expression arg in expr.get_argument_list ()) { - if (arg.symbol_reference is Method) { - // callback - if (callback != null) { - Report.error (expr.source_reference, "only one reply callback may be specified in invocation of DBus method"); - expr.error = true; - return; - } else if (found_out) { - Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method"); - expr.error = true; - return; - } - callback = arg; - callback_index = arg_index; - } else if (arg is UnaryExpression && ((UnaryExpression) arg).operator == UnaryOperator.OUT) { - // out arg - if (callback != null) { - Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method"); - expr.error = true; - return; - } - found_out = true; - } else { - // in arg - if (callback != null || found_out) { - Report.error (expr.source_reference, "in argument must not follow out argument or reply callback in invocation of DBus method"); - expr.error = true; - return; - } - } - arg_index++; - } - - ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (method.name)))); - - if (callback != null) { - var reply_method = (Method) callback.symbol_reference; - - var cb_fun = new CCodeFunction ("_%s_cb".printf (reply_method.get_cname ()), "void"); - cb_fun.modifiers = CCodeModifiers.STATIC; - cb_fun.add_parameter (new CCodeParameter ("proxy", "DBusGProxy*")); - cb_fun.add_parameter (new CCodeParameter ("call", "DBusGProxyCall*")); - cb_fun.add_parameter (new CCodeParameter ("user_data", "void*")); - cb_fun.block = new CCodeBlock (); - var cerrdecl = new CCodeDeclaration ("GError*"); - cerrdecl.add_declarator (new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL"))); - cb_fun.block.add_statement (cerrdecl); - var cend_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_end_call")); - cend_call.add_argument (new CCodeIdentifier ("proxy")); - cend_call.add_argument (new CCodeIdentifier ("call")); - cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error"))); - var creply_call = new CCodeFunctionCall (get_cvalue (callback)); - if (reply_method.binding != MemberBinding.STATIC) { - creply_call.add_argument (new CCodeIdentifier ("user_data")); - } - int param_count = reply_method.get_parameters ().size; - int i = 0; - foreach (Parameter param in reply_method.get_parameters ()) { - if ((++i) == param_count) { - if (!(param.variable_type is ErrorType)) { - Report.error (null, "DBus reply callbacks must end with GLib.Error argument"); - return; - } - - break; - } - if (param.variable_type is ArrayType && ((ArrayType) param.variable_type).element_type.data_type != string_type.data_type) { - var array_type = (ArrayType) param.variable_type; - CCodeDeclaration cdecl; - if (dbus_use_ptr_array (array_type)) { - cdecl = new CCodeDeclaration ("GPtrArray*"); - } else { - cdecl = new CCodeDeclaration ("GArray*"); - } - cdecl.add_declarator (new CCodeVariableDeclarator (param.name)); - cb_fun.block.add_statement (cdecl); - cend_call.add_argument (get_dbus_g_type (array_type)); - cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - creply_call.add_argument (new CCodeCastExpression (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), dbus_use_ptr_array (array_type) ? "pdata" : "data"), array_type.get_cname ())); - creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len")); - } else { - var cdecl = new CCodeDeclaration (param.variable_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (param.name)); - cb_fun.block.add_statement (cdecl); - cend_call.add_argument (get_dbus_g_type (param.variable_type)); - cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - creply_call.add_argument (new CCodeIdentifier (param.name)); - - if (param.variable_type is ArrayType && ((ArrayType) param.variable_type).element_type.data_type == string_type.data_type) { - var cstrvlen = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length")); - cstrvlen.add_argument (new CCodeIdentifier (param.name)); - creply_call.add_argument (cstrvlen); - } - - } - } - cend_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - cb_fun.block.add_statement (new CCodeExpressionStatement (cend_call)); - creply_call.add_argument (new CCodeIdentifier ("error")); - cb_fun.block.add_statement (new CCodeExpressionStatement (creply_call)); - - CCodeExpression target = new CCodeConstant ("param%d_target".printf (callback_index)); - var ma = (MemberAccess) callback; - if (reply_method.binding != MemberBinding.STATIC && ma.inner.value_type.data_type != null && ma.inner.value_type.data_type.is_reference_counting ()) { - // unref user_data after creply_call - var unref_call = new CCodeFunctionCall (get_destroy_func_expression (ma.inner.value_type)); - unref_call.add_argument (new CCodeIdentifier ("user_data")); - cb_fun.block.add_statement (new CCodeExpressionStatement (unref_call)); - - // ref target for ccall - var ref_call = new CCodeFunctionCall (get_dup_func_expression (ma.inner.value_type, callback.source_reference)); - ref_call.add_argument (target); - target = ref_call; - } - - if (!cfile.add_declaration (cb_fun.name)) { - // avoid duplicate function definition - cfile.add_function (cb_fun); - } - - ccall.add_argument (new CCodeIdentifier (cb_fun.name)); - ccall.add_argument (target); - ccall.add_argument (new CCodeConstant ("NULL")); - } else { - ccall.call = new CCodeIdentifier ("dbus_g_proxy_call"); - - ccall.add_argument (new CCodeIdentifier ("error")); - } - - foreach (Parameter param in method.get_parameters ()) { - if (param.variable_type is MethodType - || param.variable_type is DelegateType) { - // callback parameter - break; - } - - if (param.direction != ParameterDirection.IN) { - continue; - } - - var array_type = param.variable_type as ArrayType; - if (array_type != null) { - // array parameter - if (array_type.element_type.data_type != string_type.data_type) { - // non-string arrays (use GArray) - ccall.add_argument (get_dbus_g_type (array_type)); - - var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ())); - - CCodeDeclaration cdecl; - CCodeFunctionCall array_construct; - if (dbus_use_ptr_array (array_type)) { - cdecl = new CCodeDeclaration ("GPtrArray*"); - - array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_ptr_array_sized_new")); - array_construct.add_argument (new CCodeIdentifier (get_parameter_array_length_cname (param, 1))); - } else { - cdecl = new CCodeDeclaration ("GArray*"); - - array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_array_new")); - array_construct.add_argument (new CCodeConstant ("TRUE")); - array_construct.add_argument (new CCodeConstant ("TRUE")); - array_construct.add_argument (sizeof_call); - } - - cdecl.add_declarator (new CCodeVariableDeclarator ("dbus_%s".printf (param.name), array_construct)); - block.add_statement (cdecl); - - if (dbus_use_ptr_array (array_type)) { - cfile.add_include ("string.h"); - - var memcpy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy")); - memcpy_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dbus_%s".printf (param.name)), "pdata")); - memcpy_call.add_argument (new CCodeIdentifier (param.name)); - memcpy_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier (get_parameter_array_length_cname (param, 1)), sizeof_call)); - block.add_statement (new CCodeExpressionStatement (memcpy_call)); - - var len_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dbus_%s".printf (param.name)), "len"), new CCodeIdentifier (get_parameter_array_length_cname (param, 1))); - block.add_statement (new CCodeExpressionStatement (len_assignment)); - } else { - var cappend_call = new CCodeFunctionCall (new CCodeIdentifier ("g_array_append_vals")); - cappend_call.add_argument (new CCodeIdentifier ("dbus_%s".printf (param.name))); - cappend_call.add_argument (new CCodeIdentifier (param.name)); - cappend_call.add_argument (new CCodeIdentifier (get_parameter_array_length_cname (param, 1))); - block.add_statement (new CCodeExpressionStatement (cappend_call)); - } - - ccall.add_argument (new CCodeIdentifier ("dbus_%s".printf (param.name))); - } else { - // string arrays - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRV")); - ccall.add_argument (new CCodeIdentifier (param.name)); - } - } else if (get_type_signature (param.variable_type).has_prefix ("(")) { - // struct parameter - var st = (Struct) param.variable_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 ("dbus_%s".printf (param.name), array_construct)); - block.add_statement (cdecl); - - 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.zero (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.variable_type.data_type.get_type_id ())); - block.add_statement (new CCodeExpressionStatement (cinit_call)); - - var cset_call = new CCodeFunctionCall (new CCodeIdentifier (f.variable_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)); - } - - ccall.add_argument (get_dbus_g_type (param.variable_type)); - ccall.add_argument (new CCodeIdentifier ("dbus_%s".printf (param.name))); - } else { - ccall.add_argument (get_dbus_g_type (param.variable_type)); - ccall.add_argument (new CCodeIdentifier (param.name)); - } - } - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - var out_marshalling_fragment = new CCodeFragment (); - - foreach (Parameter param in method.get_parameters ()) { - if (param.variable_type is MethodType) { - // callback parameter - break; - } - - if (param.direction != ParameterDirection.OUT) { - continue; - } - - if (get_type_signature (param.variable_type).has_prefix ("(")) { - // struct output parameter - var st = (Struct) param.variable_type.data_type; - - var cdecl = new CCodeDeclaration ("GValueArray*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("dbus_%s".printf (param.name))); - block.add_statement (cdecl); - - int i = 0; - foreach (Field f in st.get_fields ()) { - if (f.binding != MemberBinding.INSTANCE) { - continue; - } - - var cget_call = new CCodeFunctionCall (new CCodeIdentifier (f.variable_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 converted_value = cget_call; - - if (requires_copy (f.variable_type)) { - var dupexpr = get_dup_func_expression (f.variable_type, expr.source_reference); - converted_value = new CCodeFunctionCall (dupexpr); - converted_value.add_argument (cget_call); - } - - var assign = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), f.name), converted_value); - out_marshalling_fragment.append (new CCodeExpressionStatement (assign)); - - i++; - } - - ccall.add_argument (get_dbus_g_type (param.variable_type)); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("dbus_%s".printf (param.name)))); - } else { - ccall.add_argument (get_dbus_g_type (param.variable_type)); - ccall.add_argument (new CCodeIdentifier (param.name)); - } - } - - if (!(method.return_type is VoidType)) { - // synchronous D-Bus method call with reply - ccall.add_argument (get_dbus_g_type (method.return_type)); - - var array_type = method.return_type as ArrayType; - if (array_type != null && array_type.element_type.data_type != string_type.data_type) { - // non-string arrays (use GArray) - CCodeDeclaration cdecl; - if (dbus_use_ptr_array (array_type)) { - cdecl = new CCodeDeclaration ("GPtrArray*"); - } else { - cdecl = new CCodeDeclaration ("GArray*"); - } - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - block.add_statement (cdecl); - - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // don't access result when error occured - var creturnblock = new CCodeBlock (); - creturnblock.add_statement (new CCodeReturnStatement (default_value_for_type (method.return_type, false))); - var cerrorif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error")), creturnblock); - block.add_statement (cerrorif); - - 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")); - var assign = new CCodeAssignment (result_length, garray_length); - block.add_statement (new CCodeExpressionStatement (assign)); - - // return result->data; - block.add_statement (new CCodeReturnStatement (new CCodeCastExpression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("result"), dbus_use_ptr_array (array_type) ? "pdata" : "data"), method.return_type.get_cname ()))); - } else if (method.return_type.is_real_non_null_struct_type ()) { - // structs are returned via out parameter - var st = (Struct) method.return_type.data_type; - - if (st.get_full_name () == "GLib.Value") { - ccall.add_argument (new CCodeIdentifier ("result")); - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - } else { - var cdecl = new CCodeDeclaration ("GValueArray*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("dbus_result")); - block.add_statement (cdecl); - - int i = 0; - foreach (Field f in st.get_fields ()) { - if (f.binding != MemberBinding.INSTANCE) { - continue; - } - - var cget_call = new CCodeFunctionCall (new CCodeIdentifier (f.variable_type.data_type.get_get_value_function ())); - cget_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeElementAccess (new CCodeMemberAccess.pointer (new CCodeIdentifier ("dbus_result"), "values"), new CCodeConstant (i.to_string ())))); - - var converted_value = cget_call; - - if (requires_copy (f.variable_type)) { - var dupexpr = get_dup_func_expression (f.variable_type, expr.source_reference); - converted_value = new CCodeFunctionCall (dupexpr); - converted_value.add_argument (cget_call); - } - - var assign = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("result"), f.name), converted_value); - out_marshalling_fragment.append (new CCodeExpressionStatement (assign)); - - i++; - } - - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("dbus_result"))); - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - } - - // don't access result when error occured - var creturnblock = new CCodeBlock (); - creturnblock.add_statement (new CCodeReturnStatement ()); - var cerrorif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error")), creturnblock); - block.add_statement (cerrorif); - - block.add_statement (out_marshalling_fragment); - } else { - // string arrays or other datatypes - var cdecl = new CCodeDeclaration (method.return_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - block.add_statement (cdecl); - - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // don't access result when error occured - var creturnblock = new CCodeBlock (); - creturnblock.add_statement (new CCodeReturnStatement (default_value_for_type (method.return_type, false))); - var cerrorif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error")), creturnblock); - block.add_statement (cerrorif); - - block.add_statement (out_marshalling_fragment); - - if (array_type != null) { - // special case string array - - // *result_length1 = g_strv_length (result); - var cstrvlen = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length")); - cstrvlen.add_argument (new CCodeIdentifier ("result")); - var result_length = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length1")); - var assign = new CCodeAssignment (result_length, cstrvlen); - block.add_statement (new CCodeExpressionStatement (assign)); - } - - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - } else { - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // don't access result when error occured - var creturnblock = new CCodeBlock (); - creturnblock.add_statement (new CCodeReturnStatement ()); - var cerrorif = new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error")), creturnblock); - block.add_statement (cerrorif); - - block.add_statement (out_marshalling_fragment); - } - } - - public override CCodeExpression get_dbus_g_type (DataType data_type) { - if (data_type is ArrayType) { - var array_type = data_type as ArrayType; - if (array_type.element_type.data_type == string_type.data_type) { - return new CCodeIdentifier ("G_TYPE_STRV"); - } - - var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection")); - if (dbus_use_ptr_array (array_type)) { - carray_type.add_argument (new CCodeConstant ("\"GPtrArray\"")); - } else { - carray_type.add_argument (new CCodeConstant ("\"GArray\"")); - } - carray_type.add_argument (get_dbus_g_type (array_type.element_type)); - return carray_type; - } else if (data_type.data_type is Enum) { - var en = (Enum) data_type.data_type; - if (en.is_flags) { - return new CCodeIdentifier ("G_TYPE_UINT"); - } else { - return new CCodeIdentifier ("G_TYPE_INT"); - } - } else if (data_type.data_type == null) { - critical ("Internal error during DBus type generation with: %s", data_type.to_string ()); - return new CCodeIdentifier ("G_TYPE_NONE"); - } else if (data_type.data_type.get_full_name () == "GLib.HashTable") { - var cmap_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_map")); - var type_args = data_type.get_type_arguments (); - - cmap_type.add_argument (new CCodeConstant ("\"GHashTable\"")); - foreach (DataType type_arg in type_args) { - cmap_type.add_argument (get_dbus_g_type (type_arg)); - } - - return cmap_type; - } else if (get_type_signature (data_type).has_prefix ("(")) { - // struct parameter - var st = (Struct) data_type.data_type; - - 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; - } - - type_call.add_argument (get_dbus_g_type (f.variable_type)); - } - - type_call.add_argument (new CCodeConstant ("G_TYPE_INVALID")); - - return type_call; - } else { - return new CCodeIdentifier (data_type.data_type.get_type_id ()); - } - } - - public bool dbus_use_ptr_array (ArrayType array_type) { - if (array_type.element_type.data_type == string_type.data_type) { - // use char** - return false; - } else if (array_type.element_type.data_type == bool_type.data_type - || array_type.element_type.data_type == char_type.data_type - || array_type.element_type.data_type == uchar_type.data_type - || array_type.element_type.data_type == int_type.data_type - || array_type.element_type.data_type == uint_type.data_type - || array_type.element_type.data_type == long_type.data_type - || array_type.element_type.data_type == ulong_type.data_type - || array_type.element_type.data_type == int8_type.data_type - || array_type.element_type.data_type == uint8_type.data_type - || array_type.element_type.data_type == int32_type.data_type - || array_type.element_type.data_type == uint32_type.data_type - || array_type.element_type.data_type == int64_type.data_type - || array_type.element_type.data_type == uint64_type.data_type - || array_type.element_type.data_type == double_type.data_type) { - // use GArray - return false; - } else { - // use GPtrArray - return true; - } - } - - public override string get_dynamic_property_getter_cname (DynamicProperty prop) { - if (prop.dynamic_type.data_type != dbus_object_type) { - return base.get_dynamic_property_getter_cname (prop); - } - - string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++); - - if (get_type_signature (prop.property_type) == null) { - Report.error (prop.property_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (prop.property_type.to_string ())); - return getter_cname; - } - - var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ()); - func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; - - func.add_parameter (new CCodeParameter ("obj", prop.dynamic_type.get_cname ())); - - var block = new CCodeBlock (); - generate_dbus_property_getter_wrapper (prop, block); - - // append to C source file - cfile.add_function_declaration (func); - - func.block = block; - cfile.add_function (func); - - return getter_cname; - } - - public override string get_dynamic_property_setter_cname (DynamicProperty prop) { - if (prop.dynamic_type.data_type != dbus_object_type) { - return base.get_dynamic_property_setter_cname (prop); - } - - string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++); - - if (get_type_signature (prop.property_type) == null) { - Report.error (prop.property_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (prop.property_type.to_string ())); - return setter_cname; - } - - var func = new CCodeFunction (setter_cname, "void"); - func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE; - - func.add_parameter (new CCodeParameter ("obj", prop.dynamic_type.get_cname ())); - func.add_parameter (new CCodeParameter ("value", prop.property_type.get_cname ())); - - var block = new CCodeBlock (); - generate_dbus_property_setter_wrapper (prop, block); - - // append to C source file - cfile.add_function_declaration (func); - - func.block = block; - cfile.add_function (func); - - return setter_cname; - } - - void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) { - var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy")); - prop_proxy_call.add_argument (new CCodeIdentifier ("obj")); - prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES")); - prop_proxy_call.add_argument (new CCodeConstant ("NULL")); - - var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*"); - prop_proxy_decl.add_declarator (new CCodeVariableDeclarator ("property_proxy", prop_proxy_call)); - block.add_statement (prop_proxy_decl); - } - - void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) { - create_dbus_property_proxy (node, block); - - // initialize GValue - var cvalinit = new CCodeInitializerList (); - cvalinit.append (new CCodeConstant ("0")); - - var cval_decl = new CCodeDeclaration ("GValue"); - cval_decl.add_declarator (new CCodeVariableDeclarator.zero ("gvalue", cvalinit)); - block.add_statement (cval_decl); - - var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); - - // call Get method on property proxy - var cdecl = new CCodeDeclaration (node.property_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - block.add_statement (cdecl); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); - ccall.add_argument (new CCodeIdentifier ("property_proxy")); - ccall.add_argument (new CCodeConstant ("\"Get\"")); - ccall.add_argument (new CCodeConstant ("NULL")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); - get_iface.add_argument (new CCodeIdentifier ("obj")); - ccall.add_argument (get_iface); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node.name)))); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); - ccall.add_argument (val_ptr); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // unref property proxy - var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); - block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); - - // assign value to result variable - var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ())); - cget_call.add_argument (val_ptr); - var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call); - block.add_statement (new CCodeExpressionStatement (assign)); - - // return result - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - } - - void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) { - create_dbus_property_proxy (node, block); - - // initialize GValue - var cvalinit = new CCodeInitializerList (); - cvalinit.append (new CCodeConstant ("0")); - - var cval_decl = new CCodeDeclaration ("GValue"); - cval_decl.add_declarator (new CCodeVariableDeclarator.zero ("gvalue", cvalinit)); - block.add_statement (cval_decl); - - var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue")); - - var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init")); - cinit_call.add_argument (val_ptr); - cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ())); - block.add_statement (new CCodeExpressionStatement (cinit_call)); - - var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ())); - cset_call.add_argument (val_ptr); - cset_call.add_argument (new CCodeIdentifier ("value")); - block.add_statement (new CCodeExpressionStatement (cset_call)); - - // call Set method on property proxy - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call")); - ccall.add_argument (new CCodeIdentifier ("property_proxy")); - ccall.add_argument (new CCodeConstant ("\"Set\"")); - ccall.add_argument (new CCodeConstant ("NULL")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface")); - get_iface.add_argument (new CCodeIdentifier ("obj")); - ccall.add_argument (get_iface); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING")); - ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node.name)))); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE")); - ccall.add_argument (val_ptr); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - // unref property proxy - var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy")); - block.add_statement (new CCodeExpressionStatement (prop_proxy_unref)); - } - - public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig) { - if (sig.dynamic_type.data_type != dbus_object_type) { - return base.get_dynamic_signal_connect_wrapper_name (sig); - } - - string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (sig)); - var func = new CCodeFunction (connect_wrapper_name, "void"); - func.add_parameter (new CCodeParameter ("obj", "gpointer")); - func.add_parameter (new CCodeParameter ("signal_name", "const char *")); - func.add_parameter (new CCodeParameter ("handler", "GCallback")); - func.add_parameter (new CCodeParameter ("data", "gpointer")); - var block = new CCodeBlock (); - generate_dbus_connect_wrapper (sig, block); - - // append to C source file - cfile.add_function_declaration (func); - - func.block = block; - cfile.add_function (func); - - return connect_wrapper_name; - } - - public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal sig) { - if (sig.dynamic_type.data_type != dbus_object_type) { - return base.get_dynamic_signal_disconnect_wrapper_name (sig); - } - - string disconnect_wrapper_name = "_%sdisconnect".printf (get_dynamic_signal_cname (sig)); - var func = new CCodeFunction (disconnect_wrapper_name, "void"); - func.add_parameter (new CCodeParameter ("obj", "gpointer")); - func.add_parameter (new CCodeParameter ("signal_name", "const char *")); - func.add_parameter (new CCodeParameter ("handler", "GCallback")); - func.add_parameter (new CCodeParameter ("data", "gpointer")); - var block = new CCodeBlock (); - generate_dbus_disconnect_wrapper (sig, block); - - // append to C source file - cfile.add_function_declaration (func); - - func.block = block; - cfile.add_function (func); - - return disconnect_wrapper_name; - } - - void generate_dbus_connect_wrapper (DynamicSignal sig, CCodeBlock block) { - var m = (Method) sig.handler.symbol_reference; - - sig.accept (this); - - // FIXME should only be done once per marshaller - var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller")); - generate_marshaller (sig.get_parameters (), sig.return_type, true); - register_call.add_argument (new CCodeIdentifier (get_marshaller_function (sig.get_parameters (), sig.return_type, null, true))); - register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE")); - - var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal")); - add_call.add_argument (new CCodeIdentifier ("obj")); - add_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig.name)))); - - bool first = true; - foreach (Parameter param in m.get_parameters ()) { - if (first) { - // skip sender parameter - first = false; - continue; - } - - register_call.add_argument (get_dbus_g_type (param.variable_type)); - add_call.add_argument (get_dbus_g_type (param.variable_type)); - } - register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID")); - - block.add_statement (new CCodeExpressionStatement (register_call)); - block.add_statement (new CCodeExpressionStatement (add_call)); - - var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_connect_signal")); - call.add_argument (new CCodeIdentifier ("obj")); - call.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig.name)))); - call.add_argument (new CCodeIdentifier ("handler")); - call.add_argument (new CCodeIdentifier ("data")); - call.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (call)); - } - - void generate_dbus_disconnect_wrapper (DynamicSignal sig, CCodeBlock block) { - var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_disconnect_signal")); - call.add_argument (new CCodeIdentifier ("obj")); - call.add_argument (new CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig.name)))); - call.add_argument (new CCodeIdentifier ("handler")); - call.add_argument (new CCodeIdentifier ("data")); - block.add_statement (new CCodeExpressionStatement (call)); - } - - public override void visit_cast_expression (CastExpression expr) { - // handles casting DBus.Object instances to DBus interfaces - - var type = expr.type_reference as ObjectType; - var call = expr.inner as MethodCall; - if (type == null || !(type.type_symbol is Interface) - || type.type_symbol.get_attribute ("DBus") == null || call == null) { - base.visit_cast_expression (expr); - return; - } - - var mtype = call.call.value_type as MethodType; - if (mtype == null || mtype.method_symbol.get_cname () != "dbus_g_proxy_new_for_name") { - base.visit_cast_expression (expr); - return; - } - - var args = call.get_argument_list (); - Expression connection = ((MemberAccess) call.call).inner; - Expression bus_name = args.get (0); - Expression object_path = args.get (1); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (type.type_symbol.get_lower_case_cprefix () + "dbus_proxy_new")); - connection.emit (this); - ccall.add_argument (get_cvalue (connection)); - bus_name.emit (this); - ccall.add_argument (get_cvalue (bus_name)); - object_path.emit (this); - ccall.add_argument (get_cvalue (object_path)); - set_cvalue (expr, ccall); - } - - void generate_proxy_interface_init (Interface main_iface, Interface iface) { - // also generate proxy for prerequisites - foreach (var prereq in iface.get_prerequisites ()) { - if (prereq.data_type is Interface) { - generate_proxy_interface_init (main_iface, (Interface) prereq.data_type); - } - } - - string lower_cname = main_iface.get_lower_case_cprefix () + "dbus_proxy"; - - var proxy_iface_init = new CCodeFunction (lower_cname + "_" + iface.get_lower_case_cprefix () + "_interface_init", "void"); - proxy_iface_init.add_parameter (new CCodeParameter ("iface", iface.get_cname () + "Iface*")); - - var iface_block = new CCodeBlock (); - - foreach (Method m in iface.get_methods ()) { - var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.vfunc_name); - if (is_dbus_no_reply (m)) { - if (m.coroutine) { - Report.error (m.source_reference, "No-reply DBus methods must not be async"); - } - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_noreply_dbus_proxy_method (main_iface, iface, m))))); - } else if (!m.coroutine) { - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_method (main_iface, iface, m))))); - } else { - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_async_dbus_proxy_method (main_iface, iface, m))))); - vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.get_finish_vfunc_name ()); - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_finish_dbus_proxy_method (main_iface, iface, m))))); - } - } - - foreach (Property prop in iface.get_properties ()) { - if (prop.get_accessor != null) { - var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), "get_" + prop.name); - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_property_get (main_iface, iface, prop))))); - } - if (prop.set_accessor != null) { - var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), "set_" + prop.name); - iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_property_set (main_iface, iface, prop))))); - } - } - - proxy_iface_init.modifiers = CCodeModifiers.STATIC; - cfile.add_function_declaration (proxy_iface_init); - proxy_iface_init.block = iface_block; - cfile.add_function (proxy_iface_init); - } - - string implement_interface (CCodeFunctionCall define_type, Interface main_iface, Interface iface) { - string result = ""; - - // also implement prerequisites - foreach (var prereq in iface.get_prerequisites ()) { - if (prereq.data_type is Interface) { - result += implement_interface (define_type, main_iface, (Interface) prereq.data_type); - } - } - - result += "G_IMPLEMENT_INTERFACE (%s, %sdbus_proxy_%s_interface_init) ".printf ( - iface.get_upper_case_cname ("TYPE_"), - main_iface.get_lower_case_cprefix (), - iface.get_lower_case_cprefix ()); - return result; - } - - void implement_property (CCodeBlock block, Interface main_iface, Interface iface) { - // also implement prerequisites - foreach (var prereq in iface.get_prerequisites ()) { - if (prereq.data_type is Interface) { - implement_property (block, main_iface, (Interface) prereq.data_type); - } - } - - var gobject_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); - gobject_class.add_argument (new CCodeIdentifier ("klass")); - - foreach (Property prop in iface.get_properties ()) { - if (!prop.is_abstract) { - continue; - } - - if (!is_gobject_property (prop)) { - continue; - } - - string prop_ev = "%s_dbus_proxy_%s".printf (main_iface.get_lower_case_cname (null), Symbol.camel_case_to_lower_case (prop.name)).up (); - - var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property")); - cinst.add_argument (gobject_class); - cinst.add_argument (new CCodeConstant (prop_ev)); - cinst.add_argument (prop.get_canonical_cconstant ()); - block.add_statement (new CCodeExpressionStatement (cinst)); - - prop_enum.add_value (new CCodeEnumValue (prop_ev)); - } - } - - public override void generate_interface_declaration (Interface iface, CCodeFile decl_space) { - base.generate_interface_declaration (iface, decl_space); - - string dbus_iface_name = get_dbus_name (iface); - if (dbus_iface_name == null) { - return; - } - - string lower_cname = iface.get_lower_case_cprefix () + "dbus_proxy"; - - if (add_symbol_declaration (decl_space, iface, lower_cname + "_new")) { - return; - } - - decl_space.add_include ("dbus/dbus-glib.h"); - - // declare proxy_new function - var proxy_new = new CCodeFunction (lower_cname + "_new", iface.get_cname () + "*"); - proxy_new.add_parameter (new CCodeParameter ("connection", "DBusGConnection*")); - proxy_new.add_parameter (new CCodeParameter ("name", "const char*")); - proxy_new.add_parameter (new CCodeParameter ("path", "const char*")); - - decl_space.add_function_declaration (proxy_new); - } - - public override void visit_interface (Interface iface) { - base.visit_interface (iface); - - string dbus_iface_name = get_dbus_name (iface); - if (dbus_iface_name == null) { - return; - } - - // strcmp - cfile.add_include ("string.h"); - - // create proxy class - string cname = iface.get_cname () + "DBusProxy"; - string lower_cname = iface.get_lower_case_cprefix () + "dbus_proxy"; - - add_dbus_helpers (); - - cfile.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cname), new CCodeVariableDeclarator (cname))); - cfile.add_type_declaration (new CCodeTypeDefinition ("DBusGProxyClass", new CCodeVariableDeclarator (cname + "Class"))); - - var instance_struct = new CCodeStruct ("_%s".printf (cname)); - instance_struct.add_field ("DBusGProxy", "parent_instance"); - instance_struct.add_field ("gboolean", "disposed"); - - cfile.add_type_definition (instance_struct); - - var type_fun = new CCodeFunction(lower_cname + "_get_type", "GType"); - type_fun.attributes = "G_GNUC_CONST"; - cfile.add_function_declaration (type_fun); - - var define_type = new CCodeFunctionCall (new CCodeIdentifier ("G_DEFINE_TYPE_EXTENDED")); - define_type.add_argument (new CCodeIdentifier (cname)); - define_type.add_argument (new CCodeIdentifier (lower_cname)); - define_type.add_argument (new CCodeIdentifier ("DBUS_TYPE_G_PROXY")); - define_type.add_argument (new CCodeConstant ("0")); - define_type.add_argument (new CCodeIdentifier (implement_interface (define_type, iface, iface))); - - cfile.add_type_member_definition (new CCodeExpressionStatement (define_type)); - - // generate proxy_new function - var proxy_new = new CCodeFunction (lower_cname + "_new", iface.get_cname () + "*"); - proxy_new.add_parameter (new CCodeParameter ("connection", "DBusGConnection*")); - proxy_new.add_parameter (new CCodeParameter ("name", "const char*")); - proxy_new.add_parameter (new CCodeParameter ("path", "const char*")); - - var new_block = new CCodeBlock (); - - // create proxy object - var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new")); - new_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier (lower_cname + "_get_type"))); - new_call.add_argument (new CCodeConstant ("\"connection\"")); - new_call.add_argument (new CCodeIdentifier ("connection")); - new_call.add_argument (new CCodeConstant ("\"name\"")); - new_call.add_argument (new CCodeIdentifier ("name")); - new_call.add_argument (new CCodeConstant ("\"path\"")); - new_call.add_argument (new CCodeIdentifier ("path")); - new_call.add_argument (new CCodeConstant ("\"interface\"")); - new_call.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - new_call.add_argument (new CCodeConstant ("NULL")); - - var cdecl = new CCodeDeclaration (iface.get_cname () + "*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("self", new_call)); - new_block.add_statement (cdecl); - new_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("self"))); - - proxy_new.block = new_block; - cfile.add_function (proxy_new); - - // dbus proxy construct - var proxy_construct = new CCodeFunction (lower_cname + "_construct", "GObject*"); - proxy_construct.add_parameter (new CCodeParameter ("gtype", "GType")); - proxy_construct.add_parameter (new CCodeParameter ("n_properties", "guint")); - proxy_construct.add_parameter (new CCodeParameter ("properties", "GObjectConstructParam*")); - proxy_construct.modifiers = CCodeModifiers.STATIC; - proxy_construct.block = new CCodeBlock (); - - // chain up - var parent_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); - parent_class.add_argument (new CCodeIdentifier (lower_cname + "_parent_class")); - var chainup = new CCodeFunctionCall (new CCodeMemberAccess.pointer (parent_class, "constructor")); - chainup.add_argument (new CCodeIdentifier ("gtype")); - chainup.add_argument (new CCodeIdentifier ("n_properties")); - chainup.add_argument (new CCodeIdentifier ("properties")); - - cdecl = new CCodeDeclaration ("GObject*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("self", chainup)); - proxy_construct.block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*connection")); - proxy_construct.block.add_statement (cdecl); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (gconnection)); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("path")); - proxy_construct.block.add_statement (cdecl); - - var path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - path.add_argument (new CCodeIdentifier ("self")); - path.add_argument (new CCodeConstant ("\"path\"")); - path.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("path"))); - path.add_argument (new CCodeConstant ("NULL")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (path)); - - var raw_connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - raw_connection.add_argument (new CCodeIdentifier ("connection")); - - // add filter to handle signals from the remote object - var filter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_add_filter")); - filter_call.add_argument (raw_connection); - filter_call.add_argument (new CCodeIdentifier (lower_cname + "_filter")); - filter_call.add_argument (new CCodeIdentifier ("self")); - filter_call.add_argument (new CCodeConstant ("NULL")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (filter_call)); - - var filter_printf = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup_printf")); - filter_printf.add_argument (new CCodeConstant ("\"type='signal',path='%s',interface='" + dbus_iface_name + "'\"")); - filter_printf.add_argument (new CCodeIdentifier ("path")); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("filter", filter_printf)); - proxy_construct.block.add_statement (cdecl); - - // ensure we receive signals from the remote object - var match_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_bus_add_match")); - match_call.add_argument (raw_connection); - match_call.add_argument (new CCodeIdentifier ("filter")); - match_call.add_argument (new CCodeConstant ("NULL")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (match_call)); - - var connection_free = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - connection_free.add_argument (new CCodeIdentifier ("connection")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (connection_free)); - - var path_free = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - path_free.add_argument (new CCodeIdentifier ("path")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (path_free)); - - var filter_free = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - filter_free.add_argument (new CCodeIdentifier ("filter")); - proxy_construct.block.add_statement (new CCodeExpressionStatement (filter_free)); - - proxy_construct.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("self"))); - - cfile.add_function (proxy_construct); - - // dbus proxy filter function - generate_proxy_filter_function (iface); - - // dbus proxy dispose - var proxy_dispose = new CCodeFunction (lower_cname + "_dispose", "void"); - proxy_dispose.add_parameter (new CCodeParameter ("self", "GObject*")); - proxy_dispose.modifiers = CCodeModifiers.STATIC; - proxy_dispose.block = new CCodeBlock (); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*connection")); - proxy_dispose.block.add_statement (cdecl); - - // return if proxy is already disposed - var dispose_return_block = new CCodeBlock (); - dispose_return_block.add_statement (new CCodeReturnStatement ()); - proxy_dispose.block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), cname + "*"), "disposed"), dispose_return_block)); - - // mark proxy as disposed - proxy_dispose.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), cname + "*"), "disposed"), new CCodeConstant ("TRUE")))); - - gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - proxy_dispose.block.add_statement (new CCodeExpressionStatement (gconnection)); - - // remove filter - filter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_remove_filter")); - filter_call.add_argument (raw_connection); - filter_call.add_argument (new CCodeIdentifier (lower_cname + "_filter")); - filter_call.add_argument (new CCodeIdentifier ("self")); - proxy_dispose.block.add_statement (new CCodeExpressionStatement (filter_call)); - - // chain up - parent_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); - parent_class.add_argument (new CCodeIdentifier (lower_cname + "_parent_class")); - chainup = new CCodeFunctionCall (new CCodeMemberAccess.pointer (parent_class, "dispose")); - chainup.add_argument (new CCodeIdentifier ("self")); - proxy_dispose.block.add_statement (new CCodeExpressionStatement (chainup)); - - cfile.add_function (proxy_dispose); - - var proxy_class_init = new CCodeFunction (lower_cname + "_class_init", "void"); - proxy_class_init.add_parameter (new CCodeParameter ("klass", cname + "Class*")); - proxy_class_init.modifiers = CCodeModifiers.STATIC; - proxy_class_init.block = new CCodeBlock (); - var gobject_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); - gobject_class.add_argument (new CCodeIdentifier ("klass")); - proxy_class_init.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (gobject_class, "constructor"), new CCodeIdentifier (lower_cname + "_construct")))); - proxy_class_init.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (gobject_class, "dispose"), new CCodeIdentifier (lower_cname + "_dispose")))); - proxy_class_init.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (gobject_class, "get_property"), new CCodeIdentifier ("_vala_%s_get_property".printf (lower_cname))))); - proxy_class_init.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (gobject_class, "set_property"), new CCodeIdentifier ("_vala_%s_set_property".printf (lower_cname))))); - cfile.add_function (proxy_class_init); - - prop_enum = new CCodeEnum (); - prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (lower_cname.up ()))); - - implement_property (proxy_class_init.block, iface, iface); - - cfile.add_type_member_declaration (prop_enum); - - var proxy_instance_init = new CCodeFunction (lower_cname + "_init", "void"); - proxy_instance_init.add_parameter (new CCodeParameter ("self", cname + "*")); - proxy_instance_init.modifiers = CCodeModifiers.STATIC; - proxy_instance_init.block = new CCodeBlock (); - cfile.add_function (proxy_instance_init); - - generate_proxy_interface_init (iface, iface); - - // dbus proxy get/set_property stubs - // TODO add actual implementation - var get_prop = new CCodeFunction ("_vala_%s_get_property".printf (lower_cname), "void"); - get_prop.modifiers = CCodeModifiers.STATIC; - get_prop.add_parameter (new CCodeParameter ("object", "GObject *")); - get_prop.add_parameter (new CCodeParameter ("property_id", "guint")); - get_prop.add_parameter (new CCodeParameter ("value", "GValue *")); - get_prop.add_parameter (new CCodeParameter ("pspec", "GParamSpec *")); - cfile.add_function_declaration (get_prop); - get_prop.block = new CCodeBlock (); - cfile.add_function (get_prop); - - var set_prop = new CCodeFunction ("_vala_%s_set_property".printf (lower_cname), "void"); - set_prop.modifiers = CCodeModifiers.STATIC; - set_prop.add_parameter (new CCodeParameter ("object", "GObject *")); - set_prop.add_parameter (new CCodeParameter ("property_id", "guint")); - set_prop.add_parameter (new CCodeParameter ("value", "const GValue *")); - set_prop.add_parameter (new CCodeParameter ("pspec", "GParamSpec *")); - cfile.add_function_declaration (set_prop); - set_prop.block = new CCodeBlock (); - cfile.add_function (set_prop); - } - - string generate_get_all_function (Method m) { - string get_all_func = "_dbus_g_proxy_get_all"; - - if (!add_wrapper (get_all_func)) { - // wrapper already defined - return get_all_func; - } - - var function = new CCodeFunction (get_all_func, "GHashTable*"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", "DBusGProxy*")); - function.add_parameter (new CCodeParameter ("interface_name", "const gchar*")); - function.add_parameter (new CCodeParameter ("error", "GError**")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - var cdecl = new CCodeDeclaration ("DBusError"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error")); - block.add_statement (cdecl); - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - generate_marshalling (m, "org.freedesktop.DBus.Properties", prefragment, postfragment); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init")); - dbus_error_init.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (dbus_error_init)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply_and_block")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (get_dbus_timeout (m)); - ccall.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall))); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - check_error_reply (m, block); - check_reply_signature (m, block); - - block.add_statement (postfragment); - - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (reply_unref)); - - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result"))); - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return get_all_func; - } - - public override void visit_method_call (MethodCall expr) { - var mtype = expr.call.value_type as MethodType; - bool proxy_new_from_type = (mtype != null && mtype.method_symbol.get_cname () == "dbus_g_proxy_new_from_type"); - bool proxy_get_all = (mtype != null && mtype.method_symbol.get_cname () == "dbus_g_proxy_get_all"); - - bool proxy_new_for_name = (mtype != null && mtype.method_symbol.get_cname () == "dbus_g_proxy_new_for_name"); - if (proxy_new_for_name && expr.parent_node is CastExpression) { - // method call handled by visit_cast_expression - return; - } - - if (!proxy_new_from_type && !proxy_get_all) { - base.visit_method_call (expr); - return; - } - - if (proxy_get_all) { - var ma = expr.call as MemberAccess; - var instance = ma.inner; - instance.emit (this); - - var args = expr.get_argument_list (); - Expression interface_name = args.get (0); - interface_name.emit (this); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_get_all_function (mtype.method_symbol))); - ccall.add_argument (get_cvalue (instance)); - ccall.add_argument (get_cvalue (interface_name)); - - current_method_inner_error = true; - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_"))); - - set_cvalue (expr, ccall); - return; - } - - var args = expr.get_argument_list (); - Expression connection = ((MemberAccess) expr.call).inner; - Expression bus_name = args.get (0); - Expression object_path = args.get (1); - Expression interface_name = args.get (2); - Expression type = args.get (3); - - var quark_call = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string")); - quark_call.add_argument (new CCodeConstant ("\"ValaDBusInterfaceProxyType\"")); - - var qdata_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_get_qdata")); - type.emit (this); - qdata_call.add_argument (get_cvalue (type)); - qdata_call.add_argument (quark_call); - - var get_type_call = new CCodeFunctionCall (new CCodeCastExpression (qdata_call, "GType (*)(void)")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new")); - ccall.add_argument (get_type_call); - ccall.add_argument (new CCodeConstant ("\"connection\"")); - connection.emit (this); - ccall.add_argument (get_cvalue (connection)); - ccall.add_argument (new CCodeConstant ("\"name\"")); - bus_name.emit (this); - ccall.add_argument (get_cvalue (bus_name)); - ccall.add_argument (new CCodeConstant ("\"path\"")); - object_path.emit (this); - ccall.add_argument (get_cvalue (object_path)); - ccall.add_argument (new CCodeConstant ("\"interface\"")); - interface_name.emit (this); - ccall.add_argument (get_cvalue (interface_name)); - ccall.add_argument (new CCodeConstant ("NULL")); - set_cvalue (expr, ccall); - } - - void generate_proxy_filter_function (Interface iface) { - string lower_cname = iface.get_lower_case_cprefix () + "dbus_proxy"; - - var proxy_filter = new CCodeFunction (lower_cname + "_filter", "DBusHandlerResult"); - proxy_filter.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - proxy_filter.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - proxy_filter.add_parameter (new CCodeParameter ("user_data", "void*")); - - var filter_block = new CCodeBlock (); - - // only handle signals concering the object path - var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path")); - path.add_argument (new CCodeIdentifier ("user_data")); - - var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_has_path")); - ccheck.add_argument (new CCodeIdentifier ("message")); - ccheck.add_argument (path); - - var object_filter_block = new CCodeBlock (); - filter_block.add_statement (new CCodeIfStatement (ccheck, object_filter_block)); - - handle_signals (iface, object_filter_block); - - filter_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - - cfile.add_function_declaration (proxy_filter); - proxy_filter.block = filter_block; - cfile.add_function (proxy_filter); - } - - string generate_dbus_signal_handler (Signal sig, ObjectTypeSymbol sym) { - string wrapper_name = "_dbus_handle_%s_%s".printf (sym.get_lower_case_cname (), sig.get_cname ()); - - // declaration - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (wrapper_name, "void"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("message")); - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - var signature_error_block = new CCodeBlock (); - signature_error_block.add_statement (new CCodeReturnStatement ()); - prefragment.append (new CCodeIfStatement (signature_check, signature_error_block)); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name")); - ccall.add_argument (new CCodeIdentifier ("self")); - ccall.add_argument (sig.get_canonical_cconstant ()); - - // expected type signature for input parameters - string type_signature = ""; - - foreach (Parameter param in sig.get_parameters ()) { - var owned_type = param.variable_type.copy (); - owned_type.value_owned = true; - - cdecl = new CCodeDeclaration (owned_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true))); - prefragment.append (cdecl); - - if (get_type_signature (param.variable_type) == null) { - Report.error (param.variable_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (param.variable_type.to_string ())); - continue; - } - - var st = param.variable_type.data_type as Struct; - if (st != null && !st.is_simple_type ()) { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - } else { - ccall.add_argument (new CCodeIdentifier (param.name)); - } - - if (param.variable_type is ArrayType) { - var array_type = (ArrayType) param.variable_type; - - for (int dim = 1; dim <= array_type.rank; dim++) { - string length_cname = get_parameter_array_length_cname (param, dim); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0"))); - prefragment.append (cdecl); - ccall.add_argument (new CCodeIdentifier (length_cname)); - } - } - - type_signature += get_type_signature (param.variable_type); - - var target = new CCodeIdentifier (param.name); - var expr = read_expression (prefragment, param.variable_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - if (requires_destroy (owned_type)) { - // keep local alive (symbol_reference is weak) - var local = new LocalVariable (owned_type, param.name); - var stmt = new CCodeExpressionStatement (destroy_local (local)); - postfragment.append (stmt); - } - } - - signature_check.add_argument (new CCodeConstant ("\"%s\"".printf (type_signature))); - - block.add_statement (new CCodeExpressionStatement (ccall)); - - block.add_statement (postfragment); - - cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - block.add_statement (cdecl); - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - void handle_signal (string dbus_iface_name, string dbus_signal_name, string handler_name, CCodeBlock block, ref CCodeIfStatement clastif) { - var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_is_signal")); - ccheck.add_argument (new CCodeIdentifier ("message")); - ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_signal_name))); - - var callblock = new CCodeBlock (); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (handler_name)); - ccall.add_argument (new CCodeIdentifier ("user_data")); - ccall.add_argument (new CCodeIdentifier ("connection")); - ccall.add_argument (new CCodeIdentifier ("message")); - - callblock.add_statement (new CCodeExpressionStatement (ccall)); - - var cif = new CCodeIfStatement (ccheck, callblock); - if (clastif == null) { - block.add_statement (cif); - } else { - clastif.false_statement = cif; - } - - clastif = cif; - } - - void handle_signals (Interface iface, CCodeBlock block) { - string dbus_iface_name = get_dbus_name (iface); - - CCodeIfStatement clastif = null; - foreach (Signal sig in iface.get_signals ()) { - if (sig.access != SymbolAccessibility.PUBLIC) { - continue; - } - - handle_signal (dbus_iface_name, get_dbus_name_for_member (sig), generate_dbus_signal_handler (sig, iface), block, ref clastif); - } - } - - void generate_marshalling (Method m, string dbus_iface_name, CCodeFragment prefragment, CCodeFragment postfragment) { - CCodeDeclaration cdecl; - - var no_reply = is_dbus_no_reply (m); - - var destination = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_bus_name")); - destination.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path")); - path.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_call")); - msgcall.add_argument (destination); - msgcall.add_argument (path); - msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m)))); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), msgcall))); - - if (no_reply) { - var noreplycall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_set_no_reply")); - noreplycall.add_argument (new CCodeIdentifier ("_message")); - noreplycall.add_argument (new CCodeConstant ("TRUE")); - prefragment.append (new CCodeExpressionStatement (noreplycall)); - } - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("_message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - if (!no_reply) { - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("_reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - } - - foreach (Parameter param in m.get_parameters ()) { - if (param.direction == ParameterDirection.IN) { - if (param.variable_type.data_type != null - && param.variable_type.data_type.get_full_name () == "DBus.BusName") { - // ignore BusName sender parameters - continue; - } - CCodeExpression expr = new CCodeIdentifier (param.name); - if (param.variable_type.is_real_struct_type ()) { - expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr); - } - write_expression (prefragment, param.variable_type, new CCodeIdentifier ("_iter"), expr); - } else { - if (no_reply) { - Report.error (param.source_reference, "No-reply DBus methods must not have out parameters"); - break; - } - cdecl = new CCodeDeclaration (param.variable_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("_" + param.name)); - postfragment.append (cdecl); - - var array_type = param.variable_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 ("_%s_length%d".printf (param.name, dim), new CCodeConstant ("0"))); - postfragment.append (cdecl); - } - } - - var target = new CCodeIdentifier ("_" + param.name); - var expr = read_expression (postfragment, param.variable_type, new CCodeIdentifier ("_iter"), target); - postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - // TODO check that parameter is not NULL (out parameters are optional) - // free value if parameter is NULL - postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), target))); - - - 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 ("%s_length%d".printf (param.name, dim))), new CCodeIdentifier ("_%s_length%d".printf (param.name, dim))))); - } - } - } - } - - if (!(m.return_type is VoidType)) { - if (no_reply) { - Report.error (m.return_type.source_reference, "No-reply DBus methods must return void"); - } - if (m.return_type.is_real_non_null_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; - - 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))); - - 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))))); - } - } - } - } - } - - void check_error_reply (Method m, CCodeBlock block) { - var error_types = m.get_error_types (); - if (!has_dbus_error (error_types)) { - Report.error (m.source_reference, "D-Bus methods must throw DBus.Error"); - return; - } - if (is_dbus_no_reply (m)) { - // no-reply messages throw no error - return; - } - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - var error_block = new CCodeBlock (); - - var cdecl = new CCodeDeclaration ("GQuark"); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("_edomain", new CCodeConstant ("0"))); - error_block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("gint"); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("_ecode", new CCodeConstant ("0"))); - error_block.add_statement (cdecl); - - generate_client_error_cases (error_block, error_types, new CCodeMemberAccess (new CCodeIdentifier ("_dbus_error"), "name"), new CCodeIdentifier ("_edomain"), new CCodeIdentifier ("_ecode")); - - var g_set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - g_set_error.add_argument (new CCodeIdentifier ("error")); - g_set_error.add_argument (new CCodeIdentifier ("_edomain")); - g_set_error.add_argument (new CCodeIdentifier ("_ecode")); - g_set_error.add_argument (new CCodeConstant ("\"%s\"")); - g_set_error.add_argument (new CCodeMemberAccess (new CCodeIdentifier ("_dbus_error"), "message")); - error_block.add_statement (new CCodeExpressionStatement (g_set_error)); - - var dbus_error_free = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_free")); - dbus_error_free.add_argument (dbus_error); - error_block.add_statement (new CCodeExpressionStatement (dbus_error_free)); - - if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) { - error_block.add_statement (new CCodeReturnStatement ()); - } else { - error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false))); - } - - var dbus_error_is_set = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_is_set")); - dbus_error_is_set.add_argument (dbus_error); - block.add_statement (new CCodeIfStatement (dbus_error_is_set, error_block)); - } - - string generate_dbus_proxy_method (Interface main_iface, Interface iface, Method m) { - string proxy_name = "%sdbus_proxy_%s".printf (main_iface.get_lower_case_cprefix (), m.name); - - string dbus_iface_name = get_dbus_name (iface); - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (proxy_name); - function.modifiers = CCodeModifiers.STATIC; - - var cparam_map = new HashMap (direct_hash, direct_equal); - - generate_cparameters (m, cfile, cparam_map, function); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - // throw error and return if proxy is disposed - var dispose_return_block = new CCodeBlock (); - if (m.get_error_types ().size > 0) { - var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - set_error_call.add_argument (new CCodeIdentifier ("error")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_DISCONNECTED")); - set_error_call.add_argument (new CCodeConstant ("\"%s\"")); - 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 || m.return_type.is_real_non_null_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))); - } - block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), iface.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block)); - - cdecl = new CCodeDeclaration ("DBusError"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error")); - block.add_statement (cdecl); - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - generate_marshalling (m, dbus_iface_name, prefragment, postfragment); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init")); - dbus_error_init.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (dbus_error_init)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply_and_block")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (get_dbus_timeout (m)); - ccall.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall))); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - check_error_reply (m, block); - check_reply_signature (m, block); - - block.add_statement (postfragment); - - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (reply_unref)); - - if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) { - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result"))); - } - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return proxy_name; - } - - string generate_noreply_dbus_proxy_method (Interface main_iface, Interface iface, Method m) { - string proxy_name = "%sdbus_proxy_%s".printf (main_iface.get_lower_case_cprefix (), m.name); - - string dbus_iface_name = get_dbus_name (iface); - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (proxy_name); - function.modifiers = CCodeModifiers.STATIC; - - var cparam_map = new HashMap (direct_hash, direct_equal); - - generate_cparameters (m, cfile, cparam_map, function); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - // throw error and return if proxy is disposed - var dispose_return_block = new CCodeBlock (); - if (m.get_error_types ().size > 0) { - var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - set_error_call.add_argument (new CCodeIdentifier ("error")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_DISCONNECTED")); - set_error_call.add_argument (new CCodeConstant ("\"%s\"")); - set_error_call.add_argument (new CCodeConstant ("\"Connection is closed\"")); - dispose_return_block.add_statement (new CCodeExpressionStatement (set_error_call)); - dispose_return_block.add_statement (new CCodeReturnStatement ()); - } - 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"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - generate_marshalling (m, dbus_iface_name, prefragment, postfragment); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var oom_return_block = new CCodeBlock (); - if (m.get_error_types ().size > 0) { - var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - set_error_call.add_argument (new CCodeIdentifier ("error")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_NO_MEMORY")); - set_error_call.add_argument (new CCodeConstant ("\"%s\"")); - set_error_call.add_argument (new CCodeConstant ("\"Out of memory\"")); - oom_return_block.add_statement (new CCodeExpressionStatement (set_error_call)); - oom_return_block.add_statement (new CCodeReturnStatement ()); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeIfStatement (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, ccall), oom_return_block)); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - check_error_reply (m, block); - - block.add_statement (postfragment); - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return proxy_name; - } - - void generate_client_error_cases (CCodeBlock error_block, List error_types, CCodeExpression dbus_error_name, CCodeExpression result_edomain, CCodeExpression result_ecode) { - CCodeStatement if_else_if = null; - CCodeIfStatement last_statement = null; - - foreach (DataType error_type in error_types) { - var edomain = ((ErrorType) error_type).error_domain; - - if (edomain == null) { - Report.error (error_type.source_reference, "Generic errors cannot be serialized over DBus"); - continue; - } - - var edomain_dbus_name = get_dbus_name (edomain); - if (edomain_dbus_name == null) { - Report.error (edomain.source_reference, "Errordomain must have a DBus.name annotation to be serialized over DBus"); - } - - var true_block = new CCodeBlock (); - true_block.suppress_newline = true; - - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration ("const char*"); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name)); - true_block.add_statement (cdecl); - - true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (result_edomain, new CCodeIdentifier (edomain.get_upper_case_cname ())))); - - true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dbus_error_name, new CCodeConstant ("%ld".printf (edomain_dbus_name.length + 1)))))); - - CCodeStatement inner_if_else_if = null; - CCodeIfStatement inner_last_statement = null; - foreach (ErrorCode ecode in edomain.get_codes ()) { - var inner_true_block = new CCodeBlock (); - inner_true_block.suppress_newline = true; - inner_true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (result_ecode, new CCodeIdentifier (ecode.get_cname ())))); - - var ecode_dbus_name = get_dbus_name (ecode); - if (ecode_dbus_name == null) { - ecode_dbus_name = Symbol.lower_case_to_camel_case (ecode.name.down ()); - } - - var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - string_comparison.add_argument (new CCodeIdentifier (temp_name)); - string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (ecode_dbus_name))); - var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, new CCodeConstant ("0")), inner_true_block); - - if (inner_last_statement != null) { - inner_last_statement.false_statement = stmt; - } else { - inner_if_else_if = stmt; - } - inner_last_statement = stmt; - } - true_block.add_statement (inner_if_else_if); - - var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strstr")); - string_comparison.add_argument (dbus_error_name); - string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (edomain_dbus_name))); - var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, dbus_error_name), true_block); - - if (last_statement != null) { - last_statement.false_statement = stmt; - } else { - if_else_if = stmt; - } - last_statement = stmt; - } - error_block.add_statement (if_else_if); - } - - string generate_async_dbus_proxy_method (Interface main_iface, Interface iface, Method m) { - string proxy_name = "%sdbus_proxy_%s_async".printf (main_iface.get_lower_case_cprefix (), m.name); - - string dbus_iface_name = get_dbus_name (iface); - - CCodeDeclaration cdecl; - - - // generate data struct - - string dataname = "%sDBusProxy%sData".printf (iface.get_cname (), Symbol.lower_case_to_camel_case (m.name)); - var datastruct = new CCodeStruct ("_" + dataname); - - datastruct.add_field ("GAsyncReadyCallback", "_callback_"); - datastruct.add_field ("gpointer", "_user_data_"); - datastruct.add_field ("DBusPendingCall*", "pending"); - - cfile.add_type_definition (datastruct); - cfile.add_type_declaration (new CCodeTypeDefinition ("struct _" + dataname, new CCodeVariableDeclarator (dataname))); - - - // generate async function - - var function = new CCodeFunction (proxy_name, "void"); - function.modifiers = CCodeModifiers.STATIC; - - var cparam_map = new HashMap (direct_hash, direct_equal); - - cparam_map.set (get_param_pos (-1), new CCodeParameter ("_callback_", "GAsyncReadyCallback")); - cparam_map.set (get_param_pos (-0.9), new CCodeParameter ("_user_data_", "gpointer")); - - generate_cparameters (m, cfile, cparam_map, function, null, null, null, 1); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusPendingCall"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_pending")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - generate_marshalling (m, dbus_iface_name, prefragment, postfragment); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_pending"))); - ccall.add_argument (get_dbus_timeout (m)); - block.add_statement (new CCodeExpressionStatement (ccall)); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - var dataalloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0")); - dataalloc.add_argument (new CCodeIdentifier (dataname)); - - var datadecl = new CCodeDeclaration (dataname + "*"); - datadecl.add_declarator (new CCodeVariableDeclarator ("_data_")); - block.add_statement (datadecl); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_data_"), dataalloc))); - - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_callback_"), new CCodeIdentifier ("_callback_")))); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_user_data_"), new CCodeIdentifier ("_user_data_")))); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "pending"), new CCodeIdentifier ("_pending")))); - - var pending = new CCodeFunctionCall (new CCodeIdentifier ("dbus_pending_call_set_notify")); - pending.add_argument (new CCodeIdentifier ("_pending")); - pending.add_argument (new CCodeIdentifier ("%sdbus_proxy_%s_ready".printf (iface.get_lower_case_cprefix (), m.name))); - pending.add_argument (new CCodeIdentifier ("_data_")); - pending.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (pending)); - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - - // generate ready function - - function = new CCodeFunction ("%sdbus_proxy_%s_ready".printf (iface.get_lower_case_cprefix (), m.name), "void"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("pending", "DBusPendingCall*")); - function.add_parameter (new CCodeParameter ("user_data", "void*")); - - block = new CCodeBlock (); - - datadecl = new CCodeDeclaration (dataname + "*"); - datadecl.add_declarator (new CCodeVariableDeclarator ("_data_")); - block.add_statement (datadecl); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_data_"), new CCodeIdentifier ("user_data")))); - - // complete async call by invoking callback - var obj_decl = new CCodeDeclaration ("GObject *"); - obj_decl.add_declarator (new CCodeVariableDeclarator ("_obj_")); - block.add_statement (obj_decl); - - var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv")); - object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT")); - object_creation.add_argument (new CCodeConstant ("0")); - object_creation.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_obj_"), object_creation))); - - var async_result_decl = new CCodeDeclaration ("GSimpleAsyncResult *"); - async_result_decl.add_declarator (new CCodeVariableDeclarator ("_res_")); - block.add_statement (async_result_decl); - - var async_result_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new")); - async_result_creation.add_argument (new CCodeIdentifier ("_obj_")); - async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_callback_")); - async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_user_data_")); - async_result_creation.add_argument (new CCodeIdentifier ("_data_")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_res_"), async_result_creation))); - - var completecall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete")); - completecall.add_argument (new CCodeIdentifier ("_res_")); - block.add_statement (new CCodeExpressionStatement (completecall)); - - var obj_free = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - obj_free.add_argument (new CCodeIdentifier ("_obj_")); - block.add_statement (new CCodeExpressionStatement (obj_free)); - - var async_result_free = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref")); - async_result_free.add_argument (new CCodeIdentifier ("_res_")); - block.add_statement (new CCodeExpressionStatement (async_result_free)); - - var datafree = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free")); - datafree.add_argument (new CCodeIdentifier (dataname)); - datafree.add_argument (new CCodeIdentifier ("_data_")); - block.add_statement (new CCodeExpressionStatement (datafree)); - - var pendingfree = new CCodeFunctionCall (new CCodeIdentifier ("dbus_pending_call_unref")); - pendingfree.add_argument (new CCodeIdentifier ("pending")); - block.add_statement (new CCodeExpressionStatement (pendingfree)); - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - - return proxy_name; - } - - CCodeConstant get_reply_signature (Method m) { - // expected type signature for output parameters - string type_signature = ""; - - foreach (Parameter param in m.get_parameters ()) { - if (param.direction == ParameterDirection.OUT) { - type_signature += get_type_signature (param.variable_type); - } - } - - if (!(m.return_type is VoidType)) { - type_signature += get_type_signature (m.return_type); - } - - return (new CCodeConstant ("\"%s\"".printf (type_signature))); - } - - void check_reply_signature (Method m, CCodeBlock block) { - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("_reply")); - - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - signature_check.add_argument (get_reply_signature (m)); - - var signature_error_block = new CCodeBlock (); - var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - set_error_call.add_argument (new CCodeIdentifier ("error")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_INVALID_SIGNATURE")); - set_error_call.add_argument (new CCodeConstant ("\"Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\"")); - set_error_call.add_argument (get_reply_signature (m)); - set_error_call.add_argument (message_signature); - signature_error_block.add_statement (new CCodeExpressionStatement (set_error_call)); - signature_error_block.add_statement (new CCodeExpressionStatement (reply_unref)); - signature_error_block.add_statement (new CCodeReturnStatement (default_value_for_type (m.return_type, false))); - - block.add_statement (new CCodeIfStatement (signature_check, signature_error_block)); - } - - string generate_finish_dbus_proxy_method (Interface main_iface, Interface iface, Method m) { - string proxy_name = "%sdbus_proxy_%s_finish".printf (main_iface.get_lower_case_cprefix (), m.name); - - string dbus_iface_name = get_dbus_name (iface); - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (proxy_name); - function.modifiers = CCodeModifiers.STATIC; - - var cparam_map = new HashMap (direct_hash, direct_equal); - - cparam_map.set (get_param_pos (0.1), new CCodeParameter ("_res_", "GAsyncResult*")); - - generate_cparameters (m, cfile, cparam_map, function, null, null, null, 2); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - var postfragment = new CCodeFragment (); - - string dataname = "%sDBusProxy%sData".printf (iface.get_cname (), Symbol.lower_case_to_camel_case (m.name)); - cdecl = new CCodeDeclaration (dataname + "*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_data_")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusError"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error")); - block.add_statement (cdecl); - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - var get_source_tag = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_get_source_tag")); - get_source_tag.add_argument (new CCodeCastExpression (new CCodeIdentifier ("_res_"), "GSimpleAsyncResult *")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_data_"), get_source_tag))); - - var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init")); - dbus_error_init.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (dbus_error_init)); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_pending_call_steal_reply")); - ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "pending")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall))); - - var set_error_from_message = new CCodeFunctionCall (new CCodeIdentifier ("dbus_set_error_from_message")); - set_error_from_message.add_argument (dbus_error); - set_error_from_message.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (set_error_from_message)); - - check_error_reply (m, block); - check_reply_signature (m, block); - - generate_marshalling (m, dbus_iface_name, prefragment, postfragment); - - block.add_statement (postfragment); - - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (reply_unref)); - - if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) { - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result"))); - } - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return proxy_name; - } - - void check_property_error_reply (PropertyAccessor acc, CCodeBlock block) { - var dbus_error = new CCodeIdentifier ("_dbus_error"); - var dbus_error_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, dbus_error); - - var error_block = new CCodeBlock (); - - var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical")); - ccritical.add_argument (new CCodeConstant ("\"file %s: line %d: uncaught error: %s (%s)\"")); - ccritical.add_argument (new CCodeConstant ("__FILE__")); - ccritical.add_argument (new CCodeConstant ("__LINE__")); - ccritical.add_argument (new CCodeMemberAccess (dbus_error, "message")); - ccritical.add_argument (new CCodeMemberAccess (dbus_error, "name")); - - error_block.add_statement (new CCodeExpressionStatement (ccritical)); - - var dbus_error_free = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_free")); - dbus_error_free.add_argument (dbus_error_ptr); - error_block.add_statement (new CCodeExpressionStatement (dbus_error_free)); - - if (acc.readable && !acc.value_type.is_real_non_null_struct_type ()) { - error_block.add_statement (new CCodeReturnStatement (default_value_for_type (acc.value_type, false))); - } else { - error_block.add_statement (new CCodeReturnStatement ()); - } - - var dbus_error_is_set = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_is_set")); - dbus_error_is_set.add_argument (dbus_error_ptr); - block.add_statement (new CCodeIfStatement (dbus_error_is_set, error_block)); - } - - CCodeConstant get_property_reply_signature (PropertyAccessor acc) { - if (acc.readable) { - return new CCodeConstant ("\"v\""); - } else { - return new CCodeConstant ("\"\""); - } - } - - CCodeConstant get_property_inner_signature (PropertyAccessor acc) { - return new CCodeConstant ("\"%s\"".printf (get_type_signature (acc.value_type))); - } - - void check_property_reply_signature (PropertyAccessor acc, CCodeBlock block) { - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("_reply")); - - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - signature_check.add_argument (get_property_reply_signature (acc)); - - var signature_error_block = new CCodeBlock (); - - var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical")); - ccritical.add_argument (new CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\"")); - ccritical.add_argument (new CCodeConstant ("__FILE__")); - ccritical.add_argument (new CCodeConstant ("__LINE__")); - ccritical.add_argument (get_property_reply_signature (acc)); - ccritical.add_argument (message_signature); - - signature_error_block.add_statement (new CCodeExpressionStatement (ccritical)); - signature_error_block.add_statement (new CCodeExpressionStatement (reply_unref)); - - if (acc.readable && !acc.value_type.is_real_non_null_struct_type ()) { - signature_error_block.add_statement (new CCodeReturnStatement (default_value_for_type (acc.value_type, false))); - } else { - signature_error_block.add_statement (new CCodeReturnStatement ()); - } - - block.add_statement (new CCodeIfStatement (signature_check, signature_error_block)); - } - - void check_property_inner_signature (PropertyAccessor acc, CCodeFragment fragment) { - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - - var iter_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_signature")); - iter_signature.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_subiter"))); - - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (iter_signature); - signature_check.add_argument (get_property_inner_signature (acc)); - - var signature_error_block = new CCodeBlock (); - - var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical")); - ccritical.add_argument (new CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\"")); - ccritical.add_argument (new CCodeConstant ("__FILE__")); - ccritical.add_argument (new CCodeConstant ("__LINE__")); - ccritical.add_argument (get_property_inner_signature (acc)); - ccritical.add_argument (iter_signature); - - signature_error_block.add_statement (new CCodeExpressionStatement (ccritical)); - signature_error_block.add_statement (new CCodeExpressionStatement (reply_unref)); - - if (!acc.value_type.is_real_non_null_struct_type ()) { - signature_error_block.add_statement (new CCodeReturnStatement (default_value_for_type (acc.value_type, false))); - } else { - signature_error_block.add_statement (new CCodeReturnStatement ()); - } - - fragment.append (new CCodeIfStatement (signature_check, signature_error_block)); - } - - string generate_dbus_proxy_property_get (Interface main_iface, Interface iface, Property prop) { - string proxy_name = "%sdbus_proxy_get_%s".printf (main_iface.get_lower_case_cprefix (), prop.name); - - string dbus_iface_name = get_dbus_name (iface); - - var owned_type = prop.get_accessor.value_type.copy (); - owned_type.value_owned = true; - if (owned_type.is_disposable () && !prop.get_accessor.value_type.value_owned) { - Report.error (prop.get_accessor.value_type.source_reference, "Properties used in D-Bus clients require owned get accessor"); - } - - var array_type = prop.get_accessor.value_type as ArrayType; - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (proxy_name); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", "%s*".printf (iface.get_cname ()))); - - if (prop.property_type.is_real_non_null_struct_type ()) { - function.add_parameter (new CCodeParameter ("result", "%s*".printf (prop.get_accessor.value_type.get_cname ()))); - } else { - if (array_type != null) { - for (int dim = 1; dim <= array_type.rank; dim++) { - function.add_parameter (new CCodeParameter ("result_length%d".printf (dim), "int*")); - } - } - - 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 (); - if (prop.property_type.is_real_non_null_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 ("DBusError"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error")); - block.add_statement (cdecl); - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("_subiter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - var destination = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_bus_name")); - destination.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path")); - path.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_call")); - msgcall.add_argument (destination); - msgcall.add_argument (path); - msgcall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties\"")); - msgcall.add_argument (new CCodeConstant ("\"Get\"")); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), msgcall))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("_message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("_reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - // interface name - write_expression (prefragment, string_type, new CCodeIdentifier ("_iter"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - // property name - write_expression (prefragment, string_type, new CCodeIdentifier ("_iter"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop)))); - - 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)); - - check_property_inner_signature (prop.get_accessor, postfragment); - - if (prop.property_type.is_real_non_null_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); - } - } - - 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))))); - } - } - } - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init")); - dbus_error_init.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (dbus_error_init)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply_and_block")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (get_dbus_timeout (prop)); - ccall.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall))); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - check_property_error_reply (prop.get_accessor, block); - check_property_reply_signature (prop.get_accessor, block); - - block.add_statement (postfragment); - - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (reply_unref)); - - if (prop.property_type.is_real_non_null_struct_type ()) { - block.add_statement (new CCodeReturnStatement ()); - } else { - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result"))); - } - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return proxy_name; - } - - string generate_dbus_proxy_property_set (Interface main_iface, Interface iface, Property prop) { - string proxy_name = "%sdbus_proxy_set_%s".printf (main_iface.get_lower_case_cprefix (), prop.name); - - string dbus_iface_name = get_dbus_name (iface); - - var array_type = prop.set_accessor.value_type as ArrayType; - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (proxy_name); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", "%s*".printf (iface.get_cname ()))); - - if (prop.property_type.is_real_non_null_struct_type ()) { - function.add_parameter (new CCodeParameter ("value", "%s*".printf (prop.set_accessor.value_type.get_cname ()))); - } else { - function.add_parameter (new CCodeParameter ("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 CCodeParameter ("value_length%d".printf (dim), "int")); - } - } - } - - 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 ()); - block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), iface.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block)); - - cdecl = new CCodeDeclaration ("DBusError"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error")); - block.add_statement (cdecl); - - var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error")); - - cdecl = new CCodeDeclaration ("DBusGConnection"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("_subiter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - var destination = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_bus_name")); - destination.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path")); - path.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*")); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_call")); - msgcall.add_argument (destination); - msgcall.add_argument (path); - msgcall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties\"")); - msgcall.add_argument (new CCodeConstant ("\"Set\"")); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), msgcall))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("_message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("_reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - // interface name - write_expression (prefragment, string_type, new CCodeIdentifier ("_iter"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - // property name - write_expression (prefragment, string_type, new CCodeIdentifier ("_iter"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop)))); - - // property value (as variant) - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_VARIANT")); - iter_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_signature (prop.property_type)))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_subiter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - if (prop.property_type.is_real_non_null_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"))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_subiter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get")); - gconnection.add_argument (new CCodeIdentifier ("self")); - gconnection.add_argument (new CCodeConstant ("\"connection\"")); - gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection"))); - gconnection.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (gconnection)); - - var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init")); - dbus_error_init.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (dbus_error_init)); - - var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - connection.add_argument (new CCodeIdentifier ("_connection")); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply_and_block")); - ccall.add_argument (connection); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (get_dbus_timeout (prop)); - ccall.add_argument (dbus_error); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall))); - - var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref")); - conn_unref.add_argument (new CCodeIdentifier ("_connection")); - block.add_statement (new CCodeExpressionStatement (conn_unref)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - check_property_error_reply (prop.set_accessor, block); - check_property_reply_signature (prop.set_accessor, block); - - block.add_statement (postfragment); - - var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - reply_unref.add_argument (new CCodeIdentifier ("_reply")); - block.add_statement (new CCodeExpressionStatement (reply_unref)); - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return proxy_name; - } - - public override void register_dbus_info (CCodeBlock block, ObjectTypeSymbol sym) { - if (!(sym is Interface)) { - return; - } - - string dbus_iface_name = get_dbus_name (sym); - if (dbus_iface_name == null) { - return; - } - - var quark_dbus_proxy = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string")); - quark_dbus_proxy.add_argument (new CCodeConstant ("\"ValaDBusInterfaceProxyType\"")); - - var func = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata")); - func.add_argument (new CCodeIdentifier ("%s_type_id".printf (sym.get_lower_case_cname (null)))); - func.add_argument (quark_dbus_proxy); - func.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("%s_dbus_proxy_get_type".printf (sym.get_lower_case_cname (null))))); - - block.add_statement (new CCodeExpressionStatement (func)); - } -} diff --git a/codegen/valadbusmodule.vala b/codegen/valadbusmodule.vala deleted file mode 100644 index 8c658f49b..000000000 --- a/codegen/valadbusmodule.vala +++ /dev/null @@ -1,1077 +0,0 @@ -/* valadbusmodule.vala - * - * Copyright (C) 2008-2010 Jürg Billeter - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - */ - -public class Vala.DBusModule : GAsyncModule { - struct BasicTypeInfo { - public weak string signature; - public weak string type_name; - public weak string cname; - public weak string gtype; - public weak string? get_value_function; - public weak string set_value_function; - } - - const BasicTypeInfo[] basic_types = { - { "y", "BYTE", "guint8", "G_TYPE_UCHAR", "g_value_get_uchar", "g_value_set_uchar" }, - { "b", "BOOLEAN", "dbus_bool_t", "G_TYPE_BOOLEAN", "g_value_get_boolean", "g_value_set_boolean" }, - { "n", "INT16", "dbus_int16_t", "G_TYPE_INT", null, "g_value_set_int" }, - { "q", "UINT16", "dbus_uint16_t", "G_TYPE_UINT", null, "g_value_set_uint" }, - { "i", "INT32", "dbus_int32_t", "G_TYPE_INT", "g_value_get_int", "g_value_set_int" }, - { "u", "UINT32", "dbus_uint32_t", "G_TYPE_UINT", "g_value_get_uint", "g_value_set_uint" }, - { "x", "INT64", "dbus_int64_t", "G_TYPE_INT64", "g_value_get_int64", "g_value_set_int64" }, - { "t", "UINT64", "dbus_uint64_t", "G_TYPE_UINT64", "g_value_get_uint64", "g_value_set_uint64" }, - { "d", "DOUBLE", "double", "G_TYPE_DOUBLE", "g_value_get_double", "g_value_set_double" }, - { "s", "STRING", "const char*", "G_TYPE_STRING", "g_value_get_string", "g_value_take_string" }, - { "o", "OBJECT_PATH", "const char*", "G_TYPE_STRING", null, "g_value_take_string" }, - { "g", "SIGNATURE", "const char*", "G_TYPE_STRING", null, "g_value_take_string" } - }; - - static bool is_string_marshalled_enum (TypeSymbol? symbol) { - if (symbol != null && symbol is Enum) { - var dbus = symbol.get_attribute ("DBus"); - return dbus != null && dbus.get_bool ("use_string_marshalling"); - } - return false; - } - - string get_dbus_value (EnumValue value, string default_value) { - var dbus = value.get_attribute ("DBus"); - if (dbus == null) { - return default_value; - } - - string dbus_value = dbus.get_string ("value"); - if (dbus_value == null) { - return default_value; - } - return dbus_value; - } - - public static string? get_dbus_name (TypeSymbol symbol) { - var dbus = symbol.get_attribute ("DBus"); - if (dbus == null) { - return null; - } - - return dbus.get_string ("name"); - } - - public static string get_dbus_name_for_member (Symbol symbol) { - var dbus = symbol.get_attribute ("DBus"); - if (dbus != null && dbus.has_argument ("name")) { - return dbus.get_string ("name"); - } - - return Symbol.lower_case_to_camel_case (symbol.name); - } - - bool get_basic_type_info (string signature, out BasicTypeInfo basic_type) { - foreach (BasicTypeInfo info in basic_types) { - if (info.signature == signature) { - basic_type = info; - return true; - } - } - return false; - } - - public static string? get_type_signature (DataType datatype) { - var array_type = datatype as ArrayType; - - if (array_type != null) { - string element_type_signature = get_type_signature (array_type.element_type); - - if (element_type_signature == null) { - return null; - } - - return string.nfill (array_type.rank, 'a') + element_type_signature; - } else if (is_string_marshalled_enum (datatype.data_type)) { - return "s"; - } else if (datatype.data_type != null) { - string sig = null; - - var ccode = datatype.data_type.get_attribute ("CCode"); - if (ccode != null) { - sig = ccode.get_string ("type_signature"); - } - - var st = datatype.data_type as Struct; - var en = datatype.data_type as Enum; - if (sig == null && st != null) { - var str = new StringBuilder (); - str.append_c ('('); - foreach (Field f in st.get_fields ()) { - if (f.binding == MemberBinding.INSTANCE) { - str.append (get_type_signature (f.variable_type)); - } - } - str.append_c (')'); - sig = str.str; - } else if (sig == null && en != null) { - if (en.is_flags) { - return "u"; - } else { - return "i"; - } - } - - var type_args = datatype.get_type_arguments (); - if (sig != null && "%s" in sig && type_args.size > 0) { - string element_sig = ""; - foreach (DataType type_arg in type_args) { - var s = get_type_signature (type_arg); - if (s != null) { - element_sig += s; - } - } - - sig = sig.printf (element_sig); - } - - return sig; - } else { - return null; - } - } - - public override void visit_enum (Enum en) { - base.visit_enum (en); - - if (is_string_marshalled_enum (en)) { - // strcmp - cfile.add_include ("string.h"); - cfile.add_include ("dbus/dbus-glib.h"); - - cfile.add_function (generate_enum_from_string_function (en)); - cfile.add_function (generate_enum_to_string_function (en)); - } - } - - public override bool generate_enum_declaration (Enum en, CCodeFile decl_space) { - if (base.generate_enum_declaration (en, decl_space)) { - if (is_string_marshalled_enum (en)) { - decl_space.add_function_declaration (generate_enum_from_string_function_declaration (en)); - decl_space.add_function_declaration (generate_enum_to_string_function_declaration (en)); - } - return true; - } - return false; - } - - CCodeExpression? get_array_length (CCodeExpression expr, int dim) { - var id = expr as CCodeIdentifier; - var ma = expr as CCodeMemberAccess; - if (id != null) { - return new CCodeIdentifier ("%s_length%d".printf (id.name, dim)); - } else if (ma != null) { - if (ma.is_pointer) { - return new CCodeMemberAccess.pointer (ma.inner, "%s_length%d".printf (ma.member_name, dim)); - } 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; - } - } - - CCodeExpression? generate_enum_value_from_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) { - var en = type.type_symbol as Enum; - var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null)); - - var from_string_call = new CCodeFunctionCall (new CCodeIdentifier (from_string_name)); - from_string_call.add_argument (expr); - from_string_call.add_argument (new CCodeConstant ("NULL")); - - return from_string_call; - } - - public CCodeFunction generate_enum_from_string_function_declaration (Enum en) { - var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null)); - - var from_string_func = new CCodeFunction (from_string_name, en.get_cname ()); - from_string_func.add_parameter (new CCodeParameter ("str", "const char*")); - from_string_func.add_parameter (new CCodeParameter ("error", "GError**")); - - return from_string_func; - } - - public CCodeFunction generate_enum_from_string_function (Enum en) { - var from_string_name = "%s_from_string".printf (en.get_lower_case_cname (null)); - - var from_string_func = new CCodeFunction (from_string_name, en.get_cname ()); - from_string_func.add_parameter (new CCodeParameter ("str", "const char*")); - from_string_func.add_parameter (new CCodeParameter ("error", "GError**")); - - var from_string_block = new CCodeBlock (); - from_string_func.block = from_string_block; - - var cdecl = new CCodeDeclaration (en.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("value", new CCodeConstant ("0"))); - from_string_block.add_statement (cdecl); - - CCodeStatement if_else_if = null; - CCodeIfStatement last_statement = null; - foreach (EnumValue enum_value in en.get_values ()) { - var true_block = new CCodeBlock (); - true_block.suppress_newline = true; - true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("value"), new CCodeIdentifier (enum_value.get_cname ())))); - - string dbus_value = get_dbus_value (enum_value, enum_value.name); - var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - string_comparison.add_argument (new CCodeIdentifier ("str")); - string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_value))); - var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, new CCodeConstant ("0")), true_block); - - if (last_statement != null) { - last_statement.false_statement = stmt; - } else { - if_else_if = stmt; - } - last_statement = stmt; - } - - var error_block = new CCodeBlock (); - error_block.suppress_newline = true; - - var set_error_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - set_error_call.add_argument (new CCodeIdentifier ("error")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR")); - set_error_call.add_argument (new CCodeIdentifier ("DBUS_GERROR_INVALID_ARGS")); - set_error_call.add_argument (new CCodeConstant ("\"%s\"")); - set_error_call.add_argument (new CCodeConstant ("\"Invalid enumeration value\"")); - error_block.add_statement (new CCodeExpressionStatement (set_error_call)); - - last_statement.false_statement = error_block; - from_string_block.add_statement (if_else_if); - - from_string_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("value"))); - - return from_string_func; - } - - CCodeExpression read_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression iter_expr, bool transfer = false) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration (basic_type.cname); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name)); - fragment.append (cdecl); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_basic")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - var temp_result = new CCodeIdentifier (temp_name); - - if (!transfer - && (basic_type.signature == "s" - || basic_type.signature == "o" - || basic_type.signature == "g")) { - var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup")); - dup_call.add_argument (temp_result); - return dup_call; - } else { - return temp_result; - } - } - - CCodeExpression read_array (CCodeFragment fragment, ArrayType array_type, CCodeExpression iter_expr, CCodeExpression? expr) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - - var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new")); - new_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ())); - // add one extra element for NULL-termination - new_call.add_argument (new CCodeConstant ("5")); - - var cdecl = new CCodeDeclaration (array_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name, new_call)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name + "_length", new CCodeConstant ("0"))); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name + "_size", new CCodeConstant ("4"))); - fragment.append (cdecl); - - read_array_dim (fragment, array_type, 1, temp_name, iter_expr, expr); - - if (array_type.element_type.is_reference_type_or_type_parameter ()) { - // NULL terminate array - var length = new CCodeIdentifier (temp_name + "_length"); - var element_access = new CCodeElementAccess (new CCodeIdentifier (temp_name), length); - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (element_access, new CCodeIdentifier ("NULL")))); - } - - return new CCodeIdentifier (temp_name); - } - - void read_array_dim (CCodeFragment fragment, ArrayType array_type, int dim, string temp_name, CCodeExpression iter_expr, CCodeExpression? expr) { - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator ("%s_length%d".printf (temp_name, dim), new CCodeConstant ("0"))); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_arg_type")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - - var cforblock = new CCodeBlock (); - var cforfragment = new CCodeFragment (); - cforblock.add_statement (cforfragment); - var cfor = new CCodeForStatement (iter_call, cforblock); - cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("%s_length%d".printf (temp_name, dim)))); - - if (dim < array_type.rank) { - read_array_dim (cforfragment, array_type, dim + 1, temp_name, new CCodeIdentifier (subiter_name), expr); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_next")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - cforfragment.append (new CCodeExpressionStatement (iter_call)); - } else { - var size_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (temp_name + "_size"), new CCodeIdentifier (temp_name + "_length")); - var renew_block = new CCodeBlock (); - - // tmp_size = (2 * tmp_size); - var new_size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("2"), new CCodeIdentifier (temp_name + "_size")); - renew_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name + "_size"), new_size))); - - var renew_call = new CCodeFunctionCall (new CCodeIdentifier ("g_renew")); - renew_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ())); - renew_call.add_argument (new CCodeIdentifier (temp_name)); - // add one extra element for NULL-termination - renew_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (temp_name + "_size"), new CCodeConstant ("1"))); - var renew_stmt = new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), renew_call)); - renew_block.add_statement (renew_stmt); - - var cif = new CCodeIfStatement (size_check, renew_block); - cforfragment.append (cif); - - var element_access = new CCodeElementAccess (new CCodeIdentifier (temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier (temp_name + "_length"))); - var element_expr = read_expression (cforfragment, array_type.element_type, new CCodeIdentifier (subiter_name), null); - cforfragment.append (new CCodeExpressionStatement (new CCodeAssignment (element_access, element_expr))); - } - - fragment.append (cfor); - - if (expr != null) { - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (get_array_length (expr, dim), new CCodeIdentifier ("%s_length%d".printf (temp_name, dim))))); - } - } - - CCodeExpression read_struct (CCodeFragment fragment, Struct st, CCodeExpression iter_expr) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration (st.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - foreach (Field f in st.get_fields ()) { - if (f.binding != MemberBinding.INSTANCE) { - continue; - } - - var field_expr = read_expression (fragment, f.variable_type, new CCodeIdentifier (subiter_name), new CCodeMemberAccess (new CCodeIdentifier (temp_name), f.get_cname ())); - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess (new CCodeIdentifier (temp_name), f.get_cname ()), field_expr))); - } - - return new CCodeIdentifier (temp_name); - } - - CCodeExpression read_value (CCodeFragment fragment, CCodeExpression iter_expr) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - - // 0-initialize struct with struct initializer { 0 } - var cvalinit = new CCodeInitializerList (); - cvalinit.append (new CCodeConstant ("0")); - - var cdecl = new CCodeDeclaration ("GValue"); - cdecl.add_declarator (new CCodeVariableDeclarator.zero (temp_name, cvalinit)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - CCodeIfStatement clastif = null; - - foreach (BasicTypeInfo basic_type in basic_types) { - 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_" + basic_type.type_name)); - - var type_block = new CCodeBlock (); - var type_fragment = new CCodeFragment (); - type_block.add_statement (type_fragment); - var result = read_basic (type_fragment, basic_type, new CCodeIdentifier (subiter_name)); - - 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 (basic_type.gtype)); - type_fragment.append (new CCodeExpressionStatement (value_init)); - - var value_set = new CCodeFunctionCall (new CCodeIdentifier (basic_type.set_value_function)); - 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; - } - - // 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); - } - - CCodeExpression read_hash_table (CCodeFragment fragment, ObjectType type, CCodeExpression iter_expr) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - string entryiter_name = "_tmp%d_".printf (next_temp_var_id++); - - var type_args = type.get_type_arguments (); - assert (type_args.size == 2); - var key_type = type_args.get (0); - var value_type = type_args.get (1); - - var cdecl = new CCodeDeclaration ("GHashTable*"); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (entryiter_name)); - fragment.append (cdecl); - - var hash_table_new = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_new_full")); - if (key_type.data_type == string_type.data_type) { - hash_table_new.add_argument (new CCodeIdentifier ("g_str_hash")); - hash_table_new.add_argument (new CCodeIdentifier ("g_str_equal")); - } else { - hash_table_new.add_argument (new CCodeIdentifier ("g_direct_hash")); - hash_table_new.add_argument (new CCodeIdentifier ("g_direct_equal")); - } - if (key_type.data_type == string_type.data_type) { - hash_table_new.add_argument (new CCodeIdentifier ("g_free")); - } else { - hash_table_new.add_argument (new CCodeIdentifier ("NULL")); - } - if (value_type.data_type == string_type.data_type) { - hash_table_new.add_argument (new CCodeIdentifier ("g_free")); - } else { - hash_table_new.add_argument (new CCodeIdentifier ("NULL")); - } - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), hash_table_new))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_get_arg_type")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - - var cwhileblock = new CCodeBlock (); - var cwhilefragment = new CCodeFragment (); - cwhileblock.add_statement (cwhilefragment); - var cwhile = new CCodeWhileStatement (iter_call, cwhileblock); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_recurse")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (entryiter_name))); - cwhilefragment.append (new CCodeExpressionStatement (iter_call)); - - cdecl = new CCodeDeclaration (key_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("_key")); - cwhilefragment.append (cdecl); - - cdecl = new CCodeDeclaration (value_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("_value")); - cwhilefragment.append (cdecl); - - var key_expr = read_expression (cwhilefragment, key_type, new CCodeIdentifier (entryiter_name), null); - cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_key"), key_expr))); - - var value_expr = read_expression (cwhilefragment, value_type, new CCodeIdentifier (entryiter_name), null); - cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_value"), value_expr))); - - var hash_table_insert = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_insert")); - hash_table_insert.add_argument (new CCodeIdentifier (temp_name)); - hash_table_insert.add_argument (convert_to_generic_pointer (new CCodeIdentifier ("_key"), key_type)); - hash_table_insert.add_argument (convert_to_generic_pointer (new CCodeIdentifier ("_value"), value_type)); - cwhilefragment.append (new CCodeExpressionStatement (hash_table_insert)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_next")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - cwhilefragment.append (new CCodeExpressionStatement (iter_call)); - - fragment.append (cwhile); - - return new CCodeIdentifier (temp_name); - } - - public CCodeExpression? read_expression (CCodeFragment fragment, DataType type, CCodeExpression iter_expr, CCodeExpression? expr) { - BasicTypeInfo basic_type; - CCodeExpression result = null; - if (is_string_marshalled_enum (type.data_type)) { - get_basic_type_info ("s", out basic_type); - result = read_basic (fragment, basic_type, iter_expr, true); - result = generate_enum_value_from_string (fragment, type as EnumValueType, result); - } else if (get_basic_type_info (get_type_signature (type), out basic_type)) { - result = read_basic (fragment, basic_type, iter_expr); - } else if (type is ArrayType) { - result = read_array (fragment, (ArrayType) type, iter_expr, expr); - } else if (type.data_type is Struct) { - var st = (Struct) type.data_type; - if (type.data_type.get_full_name () == "GLib.Value") { - result = read_value (fragment, iter_expr); - } else { - result = read_struct (fragment, st, iter_expr); - } - if (type.nullable) { - var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); - csizeof.add_argument (new CCodeIdentifier (st.get_cname ())); - var cdup = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup")); - cdup.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, result)); - cdup.add_argument (csizeof); - result = cdup; - } - } else if (type is ObjectType) { - if (type.data_type.get_full_name () == "GLib.HashTable") { - result = read_hash_table (fragment, (ObjectType) type, iter_expr); - } - } else { - Report.error (type.source_reference, "D-Bus deserialization of type `%s' is not supported".printf (type.to_string ())); - return null; - } - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_next")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - fragment.append (new CCodeExpressionStatement (iter_call)); - - return result; - } - - CCodeExpression? generate_enum_value_to_string (CCodeFragment fragment, EnumValueType type, CCodeExpression? expr) { - var en = type.type_symbol as Enum; - var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null)); - - var to_string_call = new CCodeFunctionCall (new CCodeIdentifier (to_string_name)); - to_string_call.add_argument (expr); - - return to_string_call; - } - - public CCodeFunction generate_enum_to_string_function_declaration (Enum en) { - var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null)); - - var to_string_func = new CCodeFunction (to_string_name, "const char*"); - to_string_func.add_parameter (new CCodeParameter ("value", en.get_cname ())); - - return to_string_func; - } - - public CCodeFunction generate_enum_to_string_function (Enum en) { - var to_string_name = "%s_to_string".printf (en.get_lower_case_cname (null)); - - var to_string_func = new CCodeFunction (to_string_name, "const char*"); - to_string_func.add_parameter (new CCodeParameter ("value", en.get_cname ())); - - var to_string_block = new CCodeBlock (); - to_string_func.block = to_string_block; - - var cdecl = new CCodeDeclaration ("const char *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("str")); - to_string_block.add_statement (cdecl); - - var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("value")); - foreach (EnumValue enum_value in en.get_values ()) { - string dbus_value = get_dbus_value (enum_value, enum_value.name); - cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (enum_value.get_cname ()))); - cswitch.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("str"), new CCodeConstant ("\"%s\"".printf (dbus_value))))); - cswitch.add_statement (new CCodeBreakStatement ()); - } - to_string_block.add_statement (cswitch); - - to_string_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("str"))); - - return to_string_func; - } - - void write_basic (CCodeFragment fragment, BasicTypeInfo basic_type, CCodeExpression iter_expr, CCodeExpression expr) { - string temp_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration (basic_type.cname); - cdecl.add_declarator (new CCodeVariableDeclarator (temp_name)); - fragment.append (cdecl); - - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), expr))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_append_basic")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr)); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_" + basic_type.type_name)); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - } - - void write_array (CCodeFragment fragment, ArrayType array_type, CCodeExpression iter_expr, CCodeExpression array_expr) { - string array_iter_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration (array_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator (array_iter_name)); - fragment.append (cdecl); - - fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (array_iter_name), array_expr))); - - write_array_dim (fragment, array_type, 1, iter_expr, array_expr, new CCodeIdentifier (array_iter_name)); - } - - void write_array_dim (CCodeFragment fragment, ArrayType array_type, int dim, CCodeExpression iter_expr, CCodeExpression array_expr, CCodeExpression array_iter_expr) { - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - string index_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator (index_name)); - fragment.append (cdecl); - - 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_ARRAY")); - iter_call.add_argument (new CCodeConstant ("\"%s%s\"".printf (string.nfill (array_type.rank - dim, 'a'), get_type_signature (array_type.element_type)))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - var cforblock = new CCodeBlock (); - var cforfragment = new CCodeFragment (); - cforblock.add_statement (cforfragment); - var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (index_name), get_array_length (array_expr, dim)), cforblock); - cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (index_name), new CCodeConstant ("0"))); - cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier (index_name))); - - if (dim < array_type.rank) { - write_array_dim (cforfragment, array_type, dim + 1, new CCodeIdentifier (subiter_name), array_expr, array_iter_expr); - } else { - var element_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, array_iter_expr); - write_expression (cforfragment, array_type.element_type, new CCodeIdentifier (subiter_name), element_expr); - - var array_iter_incr = new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, array_iter_expr); - cforfragment.append (new CCodeExpressionStatement (array_iter_incr)); - } - fragment.append (cfor); - - 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))); - fragment.append (new CCodeExpressionStatement (iter_call)); - } - - void write_struct (CCodeFragment fragment, Struct st, CCodeExpression iter_expr, CCodeExpression struct_expr) { - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - 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_STRUCT")); - iter_call.add_argument (new CCodeConstant ("NULL")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - foreach (Field f in st.get_fields ()) { - if (f.binding != MemberBinding.INSTANCE) { - continue; - } - - write_expression (fragment, f.variable_type, new CCodeIdentifier (subiter_name), new CCodeMemberAccess (struct_expr, f.get_cname ())); - } - - 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))); - fragment.append (new CCodeExpressionStatement (iter_call)); - } - - void write_value (CCodeFragment fragment, CCodeExpression iter_expr, CCodeExpression expr) { - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - - var cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - fragment.append (cdecl); - - CCodeIfStatement clastif = null; - - foreach (BasicTypeInfo basic_type in basic_types) { - // ensure that there is only one case per GType - if (basic_type.get_value_function == null) { - continue; - } - - 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 (basic_type.gtype)); - - 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 ("\"%s\"".printf (basic_type.signature))); - 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 (basic_type.get_value_function)); - value_get.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, expr)); - - write_basic (type_fragment, basic_type, 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; - } - - // 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) { - string subiter_name = "_tmp%d_".printf (next_temp_var_id++); - string entryiter_name = "_tmp%d_".printf (next_temp_var_id++); - string tableiter_name = "_tmp%d_".printf (next_temp_var_id++); - string key_name = "_tmp%d_".printf (next_temp_var_id++); - string value_name = "_tmp%d_".printf (next_temp_var_id++); - - var type_args = type.get_type_arguments (); - assert (type_args.size == 2); - var key_type = type_args.get (0); - var value_type = type_args.get (1); - - 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_ARRAY")); - iter_call.add_argument (new CCodeConstant ("\"{%s%s}\"".printf (get_type_signature (key_type), get_type_signature (value_type)))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - fragment.append (new CCodeExpressionStatement (iter_call)); - - var cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (subiter_name)); - cdecl.add_declarator (new CCodeVariableDeclarator (entryiter_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("GHashTableIter"); - cdecl.add_declarator (new CCodeVariableDeclarator (tableiter_name)); - fragment.append (cdecl); - - cdecl = new CCodeDeclaration ("gpointer"); - cdecl.add_declarator (new CCodeVariableDeclarator (key_name)); - cdecl.add_declarator (new CCodeVariableDeclarator (value_name)); - fragment.append (cdecl); - - var iter_init_call = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_iter_init")); - iter_init_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (tableiter_name))); - iter_init_call.add_argument (hash_table_expr); - fragment.append (new CCodeExpressionStatement (iter_init_call)); - - var iter_next_call = new CCodeFunctionCall (new CCodeIdentifier ("g_hash_table_iter_next")); - iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (tableiter_name))); - iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (key_name))); - iter_next_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (value_name))); - - var cwhileblock = new CCodeBlock (); - var cwhilefragment = new CCodeFragment (); - cwhileblock.add_statement (cwhilefragment); - var cwhile = new CCodeWhileStatement (iter_next_call, cwhileblock); - - cdecl = new CCodeDeclaration (key_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("_key")); - cwhilefragment.append (cdecl); - - cdecl = new CCodeDeclaration (value_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("_value")); - cwhilefragment.append (cdecl); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (subiter_name))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_DICT_ENTRY")); - iter_call.add_argument (new CCodeConstant ("NULL")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (entryiter_name))); - cwhilefragment.append (new CCodeExpressionStatement (iter_call)); - - cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_key"), convert_from_generic_pointer (new CCodeIdentifier (key_name), key_type)))); - cwhilefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_value"), convert_from_generic_pointer (new CCodeIdentifier (value_name), value_type)))); - - write_expression (cwhilefragment, key_type, new CCodeIdentifier (entryiter_name), new CCodeIdentifier ("_key")); - write_expression (cwhilefragment, value_type, new CCodeIdentifier (entryiter_name), 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 (subiter_name))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (entryiter_name))); - cwhilefragment.append (new CCodeExpressionStatement (iter_call)); - - fragment.append (cwhile); - - 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))); - fragment.append (new CCodeExpressionStatement (iter_call)); - } - - public void write_expression (CCodeFragment fragment, DataType type, CCodeExpression iter_expr, CCodeExpression expr) { - BasicTypeInfo basic_type; - if (is_string_marshalled_enum (type.data_type)) { - get_basic_type_info ("s", out basic_type); - var result = generate_enum_value_to_string (fragment, type as EnumValueType, expr); - write_basic (fragment, basic_type, iter_expr, result); - } else if (get_basic_type_info (get_type_signature (type), out basic_type)) { - write_basic (fragment, basic_type, iter_expr, expr); - } else if (type is ArrayType) { - write_array (fragment, (ArrayType) type, iter_expr, expr); - } else if (type.data_type is Struct) { - var st_expr = expr; - if (type.nullable) { - st_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, st_expr); - } - if (type.data_type.get_full_name () == "GLib.Value") { - write_value (fragment, iter_expr, st_expr); - } else { - write_struct (fragment, (Struct) type.data_type, iter_expr, st_expr); - } - } else if (type is ObjectType) { - if (type.data_type.get_full_name () == "GLib.HashTable") { - write_hash_table (fragment, (ObjectType) type, iter_expr, expr); - } - } else { - Report.error (type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (type.to_string ())); - } - } - - public void add_dbus_helpers () { - if (cfile.add_declaration ("_vala_dbus_register_object")) { - return; - } - - cfile.add_include ("dbus/dbus.h"); - cfile.add_include ("dbus/dbus-glib.h"); - cfile.add_include ("dbus/dbus-glib-lowlevel.h"); - - var dbusvtable = new CCodeStruct ("_DBusObjectVTable"); - dbusvtable.add_field ("void", "(*register_object) (DBusConnection*, const char*, void*)"); - cfile.add_type_definition (dbusvtable); - - cfile.add_type_declaration (new CCodeTypeDefinition ("struct _DBusObjectVTable", new CCodeVariableDeclarator ("_DBusObjectVTable"))); - - var cfunc = new CCodeFunction ("_vala_dbus_register_object", "void"); - cfunc.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - cfunc.add_parameter (new CCodeParameter ("path", "const char*")); - cfunc.add_parameter (new CCodeParameter ("object", "void*")); - - cfunc.modifiers |= CCodeModifiers.STATIC; - cfile.add_function_declaration (cfunc); - - var block = new CCodeBlock (); - cfunc.block = block; - - var cdecl = new CCodeDeclaration ("const _DBusObjectVTable *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("vtable")); - block.add_statement (cdecl); - - var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string")); - quark.add_argument (new CCodeConstant ("\"DBusObjectVTable\"")); - - var get_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_get_qdata")); - get_qdata.add_argument (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE (object)")); - get_qdata.add_argument (quark); - - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("vtable"), get_qdata))); - - var cregister = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("vtable"), "register_object")); - cregister.add_argument (new CCodeIdentifier ("connection")); - cregister.add_argument (new CCodeIdentifier ("path")); - cregister.add_argument (new CCodeIdentifier ("object")); - - var ifblock = new CCodeBlock (); - ifblock.add_statement (new CCodeExpressionStatement (cregister)); - - var elseblock = new CCodeBlock (); - - var warn = new CCodeFunctionCall (new CCodeIdentifier ("g_warning")); - warn.add_argument (new CCodeConstant ("\"Object does not implement any D-Bus interface\"")); - - elseblock.add_statement (new CCodeExpressionStatement(warn)); - - block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("vtable"), ifblock, elseblock)); - - cfile.add_function (cfunc); - - // unregister function - cfunc = new CCodeFunction ("_vala_dbus_unregister_object", "void"); - cfunc.add_parameter (new CCodeParameter ("connection", "gpointer")); - cfunc.add_parameter (new CCodeParameter ("object", "GObject*")); - - cfunc.modifiers |= CCodeModifiers.STATIC; - cfile.add_function_declaration (cfunc); - - block = new CCodeBlock (); - cfunc.block = block; - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("path")); - block.add_statement (cdecl); - - var path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_steal_data")); - path.add_argument (new CCodeCastExpression (new CCodeIdentifier ("object"), "GObject*")); - path.add_argument (new CCodeConstant ("\"dbus_object_path\"")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("path"), path))); - - var unregister_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_unregister_object_path")); - unregister_call.add_argument (new CCodeIdentifier ("connection")); - unregister_call.add_argument (new CCodeIdentifier ("path")); - block.add_statement (new CCodeExpressionStatement (unregister_call)); - - var path_free = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - path_free.add_argument (new CCodeIdentifier ("path")); - block.add_statement (new CCodeExpressionStatement (path_free)); - - cfile.add_function (cfunc); - } -} diff --git a/codegen/valadbusservermodule.vala b/codegen/valadbusservermodule.vala deleted file mode 100644 index 544b0b54c..000000000 --- a/codegen/valadbusservermodule.vala +++ /dev/null @@ -1,1705 +0,0 @@ -/* valadbusservermodule.vala - * - * Copyright (C) 2007-2010 Jürg Billeter -* Copyright (C) 2008 Philip Van Hoof - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Author: - * Jürg Billeter - * Philip Van Hoof - */ - -using GLib; - -/** - * The link between a dynamic method and generated code. - */ -public class Vala.DBusServerModule : DBusClientModule { - public static bool is_dbus_visible (CodeNode node) { - var dbus_attribute = node.get_attribute ("DBus"); - if (dbus_attribute != null - && dbus_attribute.has_argument ("visible") - && !dbus_attribute.get_bool ("visible")) { - return false; - } - - return true; - } - - public static string dbus_result_name (Method m) { - var dbus_attribute = m.get_attribute ("DBus"); - if (dbus_attribute != null - && dbus_attribute.has_argument ("result")) { - var result_name = dbus_attribute.get_string ("result"); - if (result_name != null && result_name != "") { - return result_name; - } - } - - return "result"; - } - - void send_reply (CCodeBlock block) { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send")); - ccall.add_argument (new CCodeIdentifier ("connection")); - ccall.add_argument (new CCodeIdentifier ("reply")); - ccall.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (ccall)); - ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - ccall.add_argument (new CCodeIdentifier ("reply")); - block.add_statement (new CCodeExpressionStatement (ccall)); - } - - void handle_reply (CCodeBlock block) { - var handled = new CCodeBlock (); - send_reply (handled); - handled.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED"))); - - var not_handled = new CCodeBlock (); - not_handled.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - - block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("reply"), handled, not_handled)); - } - - string generate_dbus_wrapper (Method m, ObjectTypeSymbol sym) { - string wrapper_name = "_dbus_%s".printf (m.get_cname ()); - - // declaration - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (wrapper_name, "DBusHandlerResult"); - function.modifiers = CCodeModifiers.STATIC; - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - var block = new CCodeBlock (); - - CCodeFunction ready_function = null; - CCodeBlock ready_block = null; - if (m.coroutine) { - // GAsyncResult - cfile.add_include ("gio/gio.h"); - - ready_function = new CCodeFunction (wrapper_name + "_ready", "void"); - ready_function.modifiers = CCodeModifiers.STATIC; - ready_function.add_parameter (new CCodeParameter ("source_object", "GObject *")); - ready_function.add_parameter (new CCodeParameter ("_res_", "GAsyncResult *")); - ready_function.add_parameter (new CCodeParameter ("_user_data_", "gpointer *")); - ready_block = new CCodeBlock (); - - cdecl = new CCodeDeclaration ("DBusConnection *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("connection", new CCodeIdentifier ("_user_data_[0]"))); - ready_block.add_statement (cdecl); - cdecl = new CCodeDeclaration ("DBusMessage *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("message", new CCodeIdentifier ("_user_data_[1]"))); - ready_block.add_statement (cdecl); - } - - var in_prefragment = new CCodeFragment (); - var in_postfragment = new CCodeFragment (); - var out_prefragment = in_prefragment; - var out_postfragment = in_postfragment; - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - block.add_statement (cdecl); - if (m.coroutine) { - out_prefragment = new CCodeFragment (); - out_postfragment = new CCodeFragment (); - ready_block.add_statement (cdecl); - } - - cdecl = new CCodeDeclaration ("GError*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("error", new CCodeConstant ("NULL"))); - if (m.coroutine) { - ready_block.add_statement (cdecl); - } else { - block.add_statement (cdecl); - } - - block.add_statement (in_prefragment); - if (m.coroutine) { - ready_block.add_statement (out_prefragment); - } - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("message")); - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - var signature_error_block = new CCodeBlock (); - signature_error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - in_prefragment.append (new CCodeIfStatement (signature_check, signature_error_block)); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - in_prefragment.append (new CCodeExpressionStatement (iter_call)); - - cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - out_postfragment.append (cdecl); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_return")); - msgcall.add_argument (new CCodeIdentifier ("message")); - out_postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), msgcall))); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - out_postfragment.append (new CCodeExpressionStatement (iter_call)); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); - - CCodeFunctionCall finish_ccall = null; - if (m.coroutine) { - finish_ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ())); - finish_ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("source_object"), sym.get_cname () + "*")); - finish_ccall.add_argument (new CCodeIdentifier ("_res_")); - } - - ccall.add_argument (new CCodeIdentifier ("self")); - - // expected type signature for input parameters - string type_signature = ""; - - foreach (Parameter param in m.get_parameters ()) { - var owned_type = param.variable_type.copy (); - owned_type.value_owned = true; - - cdecl = new CCodeDeclaration (owned_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator.zero (param.name, default_value_for_type (param.variable_type, true))); - if (param.direction == ParameterDirection.IN) { - in_prefragment.append (cdecl); - } else { - out_prefragment.append (cdecl); - } - if (type_signature == "" - && param.direction == ParameterDirection.IN - && param.variable_type.data_type != null - && param.variable_type.data_type.get_full_name () == "DBus.BusName") { - // first parameter is a string parameter called 'sender' - // pass bus name of sender - var get_sender = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_sender")); - get_sender.add_argument (new CCodeIdentifier ("message")); - ccall.add_argument (get_sender); - continue; - } - - if (get_type_signature (param.variable_type) == null) { - Report.error (param.variable_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (param.variable_type.to_string ())); - continue; - } - - if (!m.coroutine || param.direction == ParameterDirection.IN) { - var st = param.variable_type.data_type as Struct; - if (param.direction != ParameterDirection.IN - || (st != null && !st.is_simple_type ())) { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - } else { - ccall.add_argument (new CCodeIdentifier (param.name)); - } - } else { - finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); - } - - if (param.variable_type is ArrayType) { - var array_type = (ArrayType) param.variable_type; - - for (int dim = 1; dim <= array_type.rank; dim++) { - string length_cname = get_parameter_array_length_cname (param, dim); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0"))); - if (!m.coroutine || param.direction == ParameterDirection.IN) { - if (param.direction != ParameterDirection.IN) { - out_prefragment.append (cdecl); - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname))); - } else { - in_prefragment.append (cdecl); - ccall.add_argument (new CCodeIdentifier (length_cname)); - } - } else { - out_prefragment.append (cdecl); - finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname))); - } - } - } - - if (param.direction == ParameterDirection.IN) { - type_signature += get_type_signature (param.variable_type); - - var target = new CCodeIdentifier (param.name); - var expr = read_expression (in_prefragment, param.variable_type, new CCodeIdentifier ("iter"), target); - in_prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - } else { - write_expression (out_postfragment, param.variable_type, new CCodeIdentifier ("iter"), new CCodeIdentifier (param.name)); - } - - if (requires_destroy (owned_type)) { - // keep local alive (symbol_reference is weak) - var local = new LocalVariable (owned_type, param.name); - var stmt = new CCodeExpressionStatement (destroy_local (local)); - if (param.direction == ParameterDirection.IN) { - in_postfragment.append (stmt); - } else { - out_postfragment.append (stmt); - } - } - } - - signature_check.add_argument (new CCodeConstant ("\"%s\"".printf (type_signature))); - - if (!(m.return_type is VoidType)) { - if (get_type_signature (m.return_type) == null) { - Report.error (m.return_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (m.return_type.to_string ())); - } else if (m.return_type.is_real_non_null_struct_type ()) { - cdecl = new CCodeDeclaration (m.return_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true))); - out_prefragment.append (cdecl); - - if (!m.coroutine) { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - } else { - finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - } - - write_expression (out_postfragment, m.return_type, new CCodeIdentifier ("iter"), new CCodeIdentifier ("result")); - - if (requires_destroy (m.return_type)) { - // keep local alive (symbol_reference is weak) - // space before `result' is work around to not trigger - // variable renaming, we really mean C identifier `result' here - var local = new LocalVariable (m.return_type, " result"); - var ma = new MemberAccess.simple ("result"); - ma.symbol_reference = local; - ma.value_type = m.return_type.copy (); - visit_member_access (ma); - out_postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma))); - } - - block.add_statement (new CCodeExpressionStatement (ccall)); - if (m.coroutine) { - ready_block.add_statement (new CCodeExpressionStatement (finish_ccall)); - } - } else { - cdecl = new CCodeDeclaration (m.return_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - out_prefragment.append (cdecl); - if (!m.coroutine) { - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall))); - } else { - block.add_statement (new CCodeExpressionStatement (ccall)); - ready_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), finish_ccall))); - } - - if (m.return_type is ArrayType) { - var array_type = (ArrayType) m.return_type; - - 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, new CCodeConstant ("0"))); - out_prefragment.append (cdecl); - if (!m.coroutine) { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname))); - } else { - finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname))); - } - } - } - - write_expression (out_postfragment, m.return_type, new CCodeIdentifier ("iter"), new CCodeIdentifier ("result")); - - if (requires_destroy (m.return_type)) { - // keep local alive (symbol_reference is weak) - // space before `result' is work around to not trigger - // variable renaming, we really mean C identifier `result' here - var local = new LocalVariable (m.return_type, " result"); - var ma = new MemberAccess.simple ("result"); - ma.symbol_reference = local; - ma.value_type = m.return_type.copy (); - visit_member_access (ma); - out_postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), m.return_type, ma))); - } - } - } else { - block.add_statement (new CCodeExpressionStatement (ccall)); - if (m.coroutine) { - ready_block.add_statement (new CCodeExpressionStatement (finish_ccall)); - } - } - - if (m.coroutine) { - ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (wrapper_name + "_ready"), "GAsyncReadyCallback")); - - var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); - new_call.add_argument (new CCodeIdentifier ("gpointer")); - new_call.add_argument (new CCodeConstant ("2")); - cdecl = new CCodeDeclaration ("gpointer *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_user_data_", new_call)); - in_prefragment.append (cdecl); - - var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_ref")); - ref_call.add_argument (new CCodeIdentifier ("connection")); - in_prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_user_data_[0]"), ref_call))); - ref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_ref")); - ref_call.add_argument (new CCodeIdentifier ("message")); - in_prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_user_data_[1]"), ref_call))); - - ccall.add_argument (new CCodeIdentifier ("_user_data_")); - } - - if (m.get_error_types ().size > 0) { - if (m.coroutine) { - finish_ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error"))); - } else { - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error"))); - } - - var error_block = new CCodeBlock (); - - generate_server_error_cases (error_block, m.get_error_types (), new CCodeIdentifier ("error"), new CCodeIdentifier ("message"), new CCodeIdentifier ("reply")); - - send_reply (error_block); - - if (m.coroutine) { - error_block.add_statement (new CCodeReturnStatement ()); - ready_block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("error"), error_block)); - } else { - error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED"))); - block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("error"), error_block)); - } - } - - block.add_statement (in_postfragment); - - if (!m.coroutine) { - handle_reply (block); - } else { - block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED"))); - - ready_block.add_statement (out_postfragment); - - send_reply (ready_block); - - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_unref")); - unref_call.add_argument (new CCodeIdentifier ("connection")); - ready_block.add_statement (new CCodeExpressionStatement (unref_call)); - unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - unref_call.add_argument (new CCodeIdentifier ("message")); - ready_block.add_statement (new CCodeExpressionStatement (unref_call)); - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("_user_data_")); - ready_block.add_statement (new CCodeExpressionStatement (free_call)); - } - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - if (m.coroutine) { - cfile.add_function_declaration (ready_function); - - ready_function.block = ready_block; - cfile.add_function (ready_function); - } - - return wrapper_name; - } - - void generate_server_error_cases (CCodeBlock error_block, List error_types, CCodeExpression error, CCodeExpression message, CCodeExpression reply) { - CCodeStatement if_else_if = null; - CCodeIfStatement last_statement = null; - - foreach (DataType error_type in error_types) { - var edomain = ((ErrorType) error_type).error_domain; - - if (edomain == null) { - Report.error (error_type.source_reference, "Generic errors cannot be serialized over DBus"); - continue; - } - - var edomain_dbus_name = get_dbus_name (edomain); - if (edomain_dbus_name == null) { - Report.error (edomain.source_reference, "Errordomain must have a DBus.name annotation to be serialized over DBus"); - } - - var true_block = new CCodeBlock (); - true_block.suppress_newline = true; - - var cswitch = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (error, "code")); - foreach (ErrorCode ecode in edomain.get_codes ()) { - cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (ecode.get_cname ()))); - - var ecode_dbus_name = get_dbus_name (ecode); - if (ecode_dbus_name == null) { - ecode_dbus_name = Symbol.lower_case_to_camel_case (ecode.name.down ()); - } - - string dbus_name = "%s.%s".printf (edomain_dbus_name, ecode_dbus_name); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_error")); - msgcall.add_argument (message); - msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_name))); - msgcall.add_argument (new CCodeMemberAccess.pointer (error, "message")); - cswitch.add_statement (new CCodeExpressionStatement (new CCodeAssignment (reply, msgcall))); - - cswitch.add_statement (new CCodeBreakStatement ()); - } - true_block.add_statement (cswitch); - - var equal_test = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeMemberAccess.pointer (error, "domain"), new CCodeIdentifier (edomain.get_upper_case_cname ())); - var stmt = new CCodeIfStatement (equal_test, true_block); - - if (last_statement != null) { - last_statement.false_statement = stmt; - } else { - if_else_if = stmt; - } - last_statement = stmt; - } - error_block.add_statement (if_else_if); - } - - string generate_dbus_signal_wrapper (Signal sig, ObjectTypeSymbol sym, string dbus_iface_name) { - string wrapper_name = "_dbus_%s_%s".printf (sym.get_lower_case_cname (), sig.get_cname ()); - - // declaration - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (wrapper_name, "void"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("_sender", "GObject*")); - - foreach (var param in sig.get_parameters ()) { - // ensure ccodenode of parameter is set - var cparam = generate_parameter (param, cfile, new HashMap (), null); - - function.add_parameter (cparam); - if (param.variable_type is ArrayType) { - var array_type = (ArrayType) param.variable_type; - for (int dim = 1; dim <= array_type.rank; dim++) { - function.add_parameter (new CCodeParameter (get_parameter_array_length_cname (param, dim), "int")); - } - } - } - - function.add_parameter (new CCodeParameter ("_connection", "DBusConnection*")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - - var path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get_data")); - path.add_argument (new CCodeIdentifier ("_sender")); - path.add_argument (new CCodeConstant ("\"dbus_object_path\"")); - - cdecl = new CCodeDeclaration ("const char *"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_path", path)); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessage"); - cdecl.add_declarator (new CCodeVariableDeclarator ("*_message")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_iter")); - block.add_statement (cdecl); - - block.add_statement (prefragment); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_signal")); - msgcall.add_argument (new CCodeIdentifier ("_path")); - msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - msgcall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig)))); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_message"), msgcall))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("_message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_iter"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - foreach (Parameter param in sig.get_parameters ()) { - CCodeExpression expr = new CCodeIdentifier (param.name); - if (param.variable_type.is_real_struct_type ()) { - expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr); - } - write_expression (prefragment, param.variable_type, new CCodeIdentifier ("_iter"), expr); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send")); - ccall.add_argument (new CCodeIdentifier ("_connection")); - ccall.add_argument (new CCodeIdentifier ("_message")); - ccall.add_argument (new CCodeConstant ("NULL")); - block.add_statement (new CCodeExpressionStatement (ccall)); - - var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - message_unref.add_argument (new CCodeIdentifier ("_message")); - block.add_statement (new CCodeExpressionStatement (message_unref)); - - cfile.add_function_declaration (function); - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - void generate_register_function (ObjectType object_type) { - // strcmp - cfile.add_include ("string.h"); - - var sym = object_type.type_symbol; - - var cfunc = new CCodeFunction (sym.get_lower_case_cprefix () + "dbus_register_object", "void"); - cfunc.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - cfunc.add_parameter (new CCodeParameter ("path", "const char*")); - cfunc.add_parameter (new CCodeParameter ("object", "void*")); - - add_dbus_helpers (); - - if (sym.is_private_symbol ()) { - cfunc.modifiers |= CCodeModifiers.STATIC; - } - - cfile.add_function_declaration (cfunc); - - var block = new CCodeBlock (); - cfunc.block = block; - - var get_path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get_data")); - get_path.add_argument (new CCodeIdentifier ("object")); - get_path.add_argument (new CCodeConstant ("\"dbus_object_path\"")); - var register_check = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, get_path); - - var register_block = new CCodeBlock (); - - var path_dup = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup")); - path_dup.add_argument (new CCodeIdentifier ("path")); - - var set_path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set_data")); - set_path.add_argument (new CCodeIdentifier ("object")); - set_path.add_argument (new CCodeConstant ("\"dbus_object_path\"")); - set_path.add_argument (path_dup); - register_block.add_statement (new CCodeExpressionStatement (set_path)); - - var cregister = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_register_object_path")); - cregister.add_argument (new CCodeIdentifier ("connection")); - cregister.add_argument (new CCodeIdentifier ("path")); - cregister.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_path_vtable (object_type))); - cregister.add_argument (new CCodeIdentifier ("object")); - register_block.add_statement (new CCodeExpressionStatement (cregister)); - - var weak_unregister = new CCodeFunctionCall (new CCodeIdentifier ("g_object_weak_ref")); - weak_unregister.add_argument (new CCodeIdentifier ("object")); - weak_unregister.add_argument (new CCodeIdentifier ("_vala_dbus_unregister_object")); - weak_unregister.add_argument (new CCodeIdentifier ("connection")); - register_block.add_statement (new CCodeExpressionStatement (weak_unregister)); - - block.add_statement (new CCodeIfStatement (register_check, register_block)); - - handle_signals (object_type.type_symbol, block); - - var cl = sym as Class; - if (cl != null) { - foreach (DataType base_type in cl.get_base_types ()) { - var base_obj_type = base_type as ObjectType; - if (type_implements_dbus_interface (base_obj_type.type_symbol)) { - var base_register = new CCodeFunctionCall (new CCodeIdentifier (base_obj_type.type_symbol.get_lower_case_cprefix () + "dbus_register_object")); - base_register.add_argument (new CCodeIdentifier ("connection")); - base_register.add_argument (new CCodeIdentifier ("path")); - base_register.add_argument (new CCodeIdentifier ("object")); - block.add_statement (new CCodeExpressionStatement (base_register)); - } - } - } - - cfile.add_function (cfunc); - } - - void generate_unregister_function (ObjectType object_type) { - var sym = object_type.type_symbol; - - var cfunc = new CCodeFunction ("_" + sym.get_lower_case_cprefix () + "dbus_unregister", "void"); - cfunc.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - cfunc.add_parameter (new CCodeParameter ("_user_data_", "void*")); - - cfile.add_function_declaration (cfunc); - - var block = new CCodeBlock (); - cfunc.block = block; - - cfile.add_function (cfunc); - } - - void handle_method (string dbus_iface_name, string dbus_method_name, string handler_name, CCodeBlock block, ref CCodeIfStatement clastif) { - var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_is_method_call")); - ccheck.add_argument (new CCodeIdentifier ("message")); - ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_method_name))); - - var callblock = new CCodeBlock (); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (handler_name)); - ccall.add_argument (new CCodeIdentifier ("object")); - ccall.add_argument (new CCodeIdentifier ("connection")); - ccall.add_argument (new CCodeIdentifier ("message")); - - callblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), ccall))); - - var cif = new CCodeIfStatement (ccheck, callblock); - if (clastif == null) { - block.add_statement (cif); - } else { - clastif.false_statement = cif; - } - - clastif = cif; - } - - void handle_methods (ObjectTypeSymbol sym, string dbus_iface_name, CCodeBlock block, ref CCodeIfStatement clastif) { - foreach (Method m in sym.get_methods ()) { - if (m is CreationMethod || m.binding != MemberBinding.INSTANCE - || m.overrides || m.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (m)) { - continue; - } - - handle_method (dbus_iface_name, get_dbus_name_for_member (m), generate_dbus_wrapper (m, sym), block, ref clastif); - } - } - - string generate_dbus_property_get_wrapper (ObjectTypeSymbol sym, string dbus_iface_name) { - string wrapper_name = "_dbus_%s_property_get".printf (sym.get_lower_case_cname ()); - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (wrapper_name, "DBusHandlerResult"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - - cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply_iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("subiter")); - block.add_statement (cdecl); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("message")); - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - signature_check.add_argument (new CCodeConstant ("\"ss\"")); - var signature_error_block = new CCodeBlock (); - signature_error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - block.add_statement (new CCodeIfStatement (signature_check, signature_error_block)); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_return")); - msgcall.add_argument (new CCodeIdentifier ("message")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), msgcall))); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - block.add_statement (prefragment); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("interface_name")); - prefragment.append (cdecl); - var target = new CCodeIdentifier ("interface_name"); - var expr = read_expression (prefragment, string_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("property_name")); - prefragment.append (cdecl); - target = new CCodeIdentifier ("property_name"); - expr = read_expression (prefragment, string_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - CCodeIfStatement clastif = null; - - foreach (Property prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - if (prop.get_accessor == null) { - continue; - } - - var prop_block = new CCodeBlock (); - var postfragment = new CCodeFragment (); - prop_block.add_statement (postfragment); - - var ccmp = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - ccmp.add_argument (new CCodeIdentifier ("interface_name")); - ccmp.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - var ccheck1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccmp, new CCodeConstant ("0")); - - ccmp = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - ccmp.add_argument (new CCodeIdentifier ("property_name")); - ccmp.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop)))); - var ccheck2 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccmp, new CCodeConstant ("0")); - - var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccheck1, ccheck2); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_VARIANT")); - iter_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_signature (prop.property_type)))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.get_accessor.get_cname ())); - ccall.add_argument (new CCodeIdentifier ("self")); - - cdecl = new CCodeDeclaration (prop.property_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - postfragment.append (cdecl); - - if (prop.property_type.is_real_non_null_struct_type ()) { - // structs are returned via out parameter - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - - 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))); - } - } - } - - write_expression (postfragment, prop.property_type, new CCodeIdentifier ("subiter"), new CCodeIdentifier ("result")); - - if (requires_destroy (prop.get_accessor.value_type)) { - // keep local alive (symbol_reference is weak) - // space before `result' is work around to not trigger - // variable renaming, we really mean C identifier `result' here - var local = new LocalVariable (prop.get_accessor.value_type, " result"); - var ma = new MemberAccess.simple ("result"); - ma.symbol_reference = local; - ma.value_type = local.variable_type.copy (); - visit_member_access (ma); - postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), prop.get_accessor.value_type, ma))); - } - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - var cif = new CCodeIfStatement (ccheck, prop_block); - if (clastif == null) { - block.add_statement (cif); - } else { - clastif.false_statement = cif; - } - - clastif = cif; - } - - // free interface_name and property_name - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("interface_name")); - block.add_statement (new CCodeExpressionStatement (free_call)); - - free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("property_name")); - block.add_statement (new CCodeExpressionStatement (free_call)); - - if (clastif == null) { - block = new CCodeBlock (); - block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL"))); - } else { - var else_block = new CCodeBlock (); - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - unref_call.add_argument (new CCodeIdentifier ("reply")); - else_block.add_statement (new CCodeExpressionStatement (unref_call)); - else_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), new CCodeConstant ("NULL")))); - clastif.false_statement = else_block; - - handle_reply (block); - } - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - string generate_dbus_property_get_all_wrapper (ObjectTypeSymbol sym, string dbus_iface_name) { - string wrapper_name = "_dbus_%s_property_get_all".printf (sym.get_lower_case_cname ()); - - bool has_readable_properties = false; - foreach (Property prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - if (prop.get_accessor != null) { - has_readable_properties = true; - } - } - - CCodeDeclaration cdecl; - - var function = new CCodeFunction (wrapper_name, "DBusHandlerResult"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - - cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply_iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("subiter")); - if (has_readable_properties) { - cdecl.add_declarator (new CCodeVariableDeclarator ("entry_iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("value_iter")); - } - block.add_statement (cdecl); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("message")); - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - signature_check.add_argument (new CCodeConstant ("\"s\"")); - var signature_error_block = new CCodeBlock (); - signature_error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - block.add_statement (new CCodeIfStatement (signature_check, signature_error_block)); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_return")); - msgcall.add_argument (new CCodeIdentifier ("message")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), msgcall))); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - block.add_statement (prefragment); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("interface_name")); - prefragment.append (cdecl); - var target = new CCodeIdentifier ("interface_name"); - var expr = read_expression (prefragment, string_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - if (has_readable_properties) { - cdecl = new CCodeDeclaration ("const char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("property_name")); - prefragment.append (cdecl); - } - - var prop_block = new CCodeBlock (); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_ARRAY")); - iter_call.add_argument (new CCodeConstant ("\"{sv}\"")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - prop_block.add_statement (new CCodeExpressionStatement (iter_call)); - - foreach (Property prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - if (prop.get_accessor == null) { - continue; - } - - var inner_block = new CCodeBlock (); - prop_block.add_statement (inner_block); - var postfragment = new CCodeFragment (); - inner_block.add_statement (postfragment); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_DICT_ENTRY")); - iter_call.add_argument (new CCodeConstant ("NULL")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("entry_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("property_name"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop)))))); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_append_basic")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("entry_iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_STRING")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("property_name"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_open_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("entry_iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_VARIANT")); - iter_call.add_argument (new CCodeConstant ("\"%s\"".printf (get_type_signature (prop.property_type)))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("value_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.get_accessor.get_cname ())); - ccall.add_argument (new CCodeIdentifier ("self")); - - cdecl = new CCodeDeclaration (prop.property_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("result")); - postfragment.append (cdecl); - - if (prop.property_type.is_real_non_null_struct_type ()) { - // structs are returned via out parameter - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result"))); - - 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))); - } - } - } - - write_expression (postfragment, prop.property_type, new CCodeIdentifier ("value_iter"), new CCodeIdentifier ("result")); - - if (requires_destroy (prop.get_accessor.value_type)) { - // keep local alive (symbol_reference is weak) - // space before `result' is work around to not trigger - // variable renaming, we really mean C identifier `result' here - var local = new LocalVariable (prop.get_accessor.value_type, " result"); - var ma = new MemberAccess.simple ("result"); - ma.symbol_reference = local; - ma.value_type = local.variable_type.copy (); - visit_member_access (ma); - postfragment.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("result"), prop.get_accessor.value_type, ma))); - } - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("entry_iter"))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("value_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("entry_iter"))); - postfragment.append (new CCodeExpressionStatement (iter_call)); - } - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_close_container")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("reply_iter"))); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("subiter"))); - prop_block.add_statement (new CCodeExpressionStatement (iter_call)); - - var ccmp = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - ccmp.add_argument (new CCodeIdentifier ("interface_name")); - ccmp.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccmp, new CCodeConstant ("0")); - - var else_block = new CCodeBlock (); - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - unref_call.add_argument (new CCodeIdentifier ("reply")); - else_block.add_statement (new CCodeExpressionStatement (unref_call)); - else_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), new CCodeConstant ("NULL")))); - - block.add_statement (new CCodeIfStatement (ccheck, prop_block, else_block)); - - // free interface_name - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("interface_name")); - block.add_statement (new CCodeExpressionStatement (free_call)); - - handle_reply (block); - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - string generate_dbus_property_set_wrapper (ObjectTypeSymbol sym, string dbus_iface_name) { - string wrapper_name = "_dbus_%s_property_set".printf (sym.get_lower_case_cname ()); - - var function = new CCodeFunction (wrapper_name, "DBusHandlerResult"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - - var block = new CCodeBlock (); - var prefragment = new CCodeFragment (); - - var cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - cdecl.add_declarator (new CCodeVariableDeclarator ("subiter")); - block.add_statement (cdecl); - - var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature")); - message_signature.add_argument (new CCodeIdentifier ("message")); - var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - signature_check.add_argument (message_signature); - signature_check.add_argument (new CCodeConstant ("\"ssv\"")); - var signature_error_block = new CCodeBlock (); - signature_error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - block.add_statement (new CCodeIfStatement (signature_check, signature_error_block)); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init")); - iter_call.add_argument (new CCodeIdentifier ("message")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_return")); - msgcall.add_argument (new CCodeIdentifier ("message")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), msgcall))); - - block.add_statement (prefragment); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("interface_name")); - prefragment.append (cdecl); - var target = new CCodeIdentifier ("interface_name"); - var expr = read_expression (prefragment, string_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - cdecl = new CCodeDeclaration ("char*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("property_name")); - prefragment.append (cdecl); - target = new CCodeIdentifier ("property_name"); - expr = read_expression (prefragment, string_type, new CCodeIdentifier ("iter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - 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"))); - prefragment.append (new CCodeExpressionStatement (iter_call)); - - CCodeIfStatement clastif = null; - - foreach (Property prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - if (prop.set_accessor == null) { - continue; - } - - var prop_block = new CCodeBlock (); - prefragment = new CCodeFragment (); - prop_block.add_statement (prefragment); - - var ccmp = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - ccmp.add_argument (new CCodeIdentifier ("interface_name")); - ccmp.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name))); - var ccheck1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccmp, new CCodeConstant ("0")); - - ccmp = new CCodeFunctionCall (new CCodeIdentifier ("strcmp")); - ccmp.add_argument (new CCodeIdentifier ("property_name")); - ccmp.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop)))); - var ccheck2 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccmp, new CCodeConstant ("0")); - - var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccheck1, ccheck2); - - var owned_type = prop.property_type.copy (); - owned_type.value_owned = true; - - cdecl = new CCodeDeclaration (owned_type.get_cname ()); - cdecl.add_declarator (new CCodeVariableDeclarator ("value")); - prefragment.append (cdecl); - - target = new CCodeIdentifier ("value"); - expr = read_expression (prefragment, prop.property_type, new CCodeIdentifier ("subiter"), target); - prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr))); - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (prop.set_accessor.get_cname ())); - ccall.add_argument (new CCodeIdentifier ("self")); - - if (prop.property_type.is_real_non_null_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 (get_array_length_cname ("value", dim))); - prefragment.append (cdecl); - - ccall.add_argument (new CCodeIdentifier (get_array_length_cname ("value", dim))); - } - } - } - - prop_block.add_statement (new CCodeExpressionStatement (ccall)); - - if (requires_destroy (owned_type)) { - // keep local alive (symbol_reference is weak) - var local = new LocalVariable (owned_type, "value"); - var ma = new MemberAccess.simple ("value"); - ma.symbol_reference = local; - ma.value_type = local.variable_type.copy (); - visit_member_access (ma); - prop_block.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier ("value"), owned_type, ma))); - } - - var cif = new CCodeIfStatement (ccheck, prop_block); - if (clastif == null) { - block.add_statement (cif); - } else { - clastif.false_statement = cif; - } - - clastif = cif; - } - - // free interface_name and property_name - var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("interface_name")); - block.add_statement (new CCodeExpressionStatement (free_call)); - - free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free")); - free_call.add_argument (new CCodeIdentifier ("property_name")); - block.add_statement (new CCodeExpressionStatement (free_call)); - - if (clastif == null) { - block = new CCodeBlock (); - block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL"))); - } else { - var else_block = new CCodeBlock (); - var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref")); - unref_call.add_argument (new CCodeIdentifier ("reply")); - else_block.add_statement (new CCodeExpressionStatement (unref_call)); - else_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), new CCodeIdentifier ("NULL")))); - clastif.false_statement = else_block; - - handle_reply (block); - } - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - string get_dbus_type_introspection (ObjectTypeSymbol sym) { - string result = ""; - - var cl = sym as Class; - if (cl != null) { - foreach (DataType base_type in cl.get_base_types ()) { - var base_obj_type = base_type as ObjectType; - result += get_dbus_type_introspection (base_obj_type.type_symbol); - } - } - - string dbus_iface_name = get_dbus_name (sym); - if (dbus_iface_name == null) { - return result; - } - - result += "\n".printf (dbus_iface_name); - - foreach (var m in sym.get_methods ()) { - if (m is CreationMethod || m.binding != MemberBinding.INSTANCE - || m.overrides || m.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (m)) { - continue; - } - - result += " \n".printf (get_dbus_name_for_member (m)); - - foreach (var param in m.get_parameters ()) { - if (param.variable_type.data_type != null - && param.variable_type.data_type.get_full_name () == "DBus.BusName") { - // skip sender parameter - // (implicit in D-Bus) - continue; - } - - string direction = param.direction == ParameterDirection.IN ? "in" : "out"; - result += " \n".printf (param.name, get_type_signature (param.variable_type), direction); - } - if (!(m.return_type is VoidType)) { - result += " \n".printf (dbus_result_name (m), get_type_signature (m.return_type)); - } - - result += " \n"; - } - - foreach (var prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - - string access = (prop.get_accessor != null ? "read" : "") + (prop.set_accessor != null ? "write" : ""); - result += " \n".printf (get_dbus_name_for_member (prop), get_type_signature (prop.property_type), access); - } - - foreach (var sig in sym.get_signals ()) { - if (sig.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (sig)) { - continue; - } - - result += " \n".printf (get_dbus_name_for_member (sig)); - - foreach (var param in sig.get_parameters ()) { - result += " \n".printf (param.name, get_type_signature (param.variable_type)); - } - - result += " \n"; - } - - result += "\n"; - - return result; - } - - string generate_dbus_introspect (ObjectTypeSymbol sym) { - string wrapper_name = "_dbus_%s_introspect".printf (sym.get_lower_case_cname ()); - - var function = new CCodeFunction (wrapper_name, "DBusHandlerResult"); - function.modifiers = CCodeModifiers.STATIC; - - function.add_parameter (new CCodeParameter ("self", sym.get_cname () + "*")); - function.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - function.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - - var block = new CCodeBlock (); - - var cdecl = new CCodeDeclaration ("DBusMessage*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("reply")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("DBusMessageIter"); - cdecl.add_declarator (new CCodeVariableDeclarator ("iter")); - block.add_statement (cdecl); - - var msgcall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_new_method_return")); - msgcall.add_argument (new CCodeIdentifier ("message")); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("reply"), msgcall))); - - var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init_append")); - iter_call.add_argument (new CCodeIdentifier ("reply")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - cdecl = new CCodeDeclaration ("GString*"); - cdecl.add_declarator (new CCodeVariableDeclarator ("xml_data")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("char**"); - cdecl.add_declarator (new CCodeVariableDeclarator ("children")); - block.add_statement (cdecl); - - cdecl = new CCodeDeclaration ("int"); - cdecl.add_declarator (new CCodeVariableDeclarator ("i")); - block.add_statement (cdecl); - - string xml_data = "\n"; - var str_call = new CCodeFunctionCall (new CCodeIdentifier ("g_string_new")); - str_call.add_argument (new CCodeConstant ("\"%s\"".printf (xml_data.escape ("")))); - block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("xml_data"), str_call))); - - xml_data = "\n"; - xml_data += -""" - - - - - - - - - - - - - - - - - - - - -"""; - xml_data += get_dbus_type_introspection (sym); - str_call = new CCodeFunctionCall (new CCodeIdentifier ("g_string_append")); - str_call.add_argument (new CCodeIdentifier ("xml_data")); - str_call.add_argument (new CCodeConstant ("\"%s\"".printf (xml_data.escape ("")))); - block.add_statement (new CCodeExpressionStatement (str_call)); - - var get_path = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get_data")); - get_path.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GObject *")); - get_path.add_argument (new CCodeConstant ("\"dbus_object_path\"")); - - var list_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_list_registered")); - list_call.add_argument (new CCodeIdentifier ("connection")); - list_call.add_argument (get_path); - list_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("children"))); - block.add_statement (new CCodeExpressionStatement (list_call)); - - // add child nodes - var child_block = new CCodeBlock (); - str_call = new CCodeFunctionCall (new CCodeIdentifier ("g_string_append_printf")); - str_call.add_argument (new CCodeIdentifier ("xml_data")); - str_call.add_argument (new CCodeConstant ("\"%s\"".printf ("\n".escape ("")))); - str_call.add_argument (new CCodeElementAccess (new CCodeIdentifier ("children"), new CCodeIdentifier ("i"))); - child_block.add_statement (new CCodeExpressionStatement (str_call)); - var cfor = new CCodeForStatement (new CCodeElementAccess (new CCodeIdentifier ("children"), new CCodeIdentifier ("i")), child_block); - cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0"))); - cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i"))); - block.add_statement (cfor); - - var list_free_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_free_string_array")); - list_free_call.add_argument (new CCodeIdentifier ("children")); - block.add_statement (new CCodeExpressionStatement (list_free_call)); - - xml_data = "\n"; - str_call = new CCodeFunctionCall (new CCodeIdentifier ("g_string_append")); - str_call.add_argument (new CCodeIdentifier ("xml_data")); - str_call.add_argument (new CCodeConstant ("\"%s\"".printf (xml_data.escape ("")))); - block.add_statement (new CCodeExpressionStatement (str_call)); - - iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_append_basic")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); - iter_call.add_argument (new CCodeIdentifier ("DBUS_TYPE_STRING")); - iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (new CCodeIdentifier ("xml_data"), "str"))); - block.add_statement (new CCodeExpressionStatement (iter_call)); - - str_call = new CCodeFunctionCall (new CCodeIdentifier ("g_string_free")); - str_call.add_argument (new CCodeIdentifier ("xml_data")); - str_call.add_argument (new CCodeConstant ("TRUE")); - block.add_statement (new CCodeExpressionStatement (str_call)); - - handle_reply (block); - - cfile.add_function_declaration (function); - - function.block = block; - cfile.add_function (function); - - return wrapper_name; - } - - void handle_signals (ObjectTypeSymbol sym, CCodeBlock block) { - string dbus_iface_name = get_dbus_name (sym); - if (dbus_iface_name == null) { - return; - } - - foreach (Signal sig in sym.get_signals ()) { - if (sig.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (sig)) { - continue; - } - - var connect = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_connect")); - connect.add_argument (new CCodeIdentifier ("object")); - connect.add_argument (sig.get_canonical_cconstant ()); - connect.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_dbus_signal_wrapper (sig, sym, dbus_iface_name)), "GCallback")); - connect.add_argument (new CCodeIdentifier ("connection")); - block.add_statement (new CCodeExpressionStatement (connect)); - } - } - - void generate_message_function (ObjectType object_type) { - var sym = object_type.type_symbol; - - add_dbus_helpers (); - - var cfunc = new CCodeFunction (sym.get_lower_case_cprefix () + "dbus_message", "DBusHandlerResult"); - cfunc.add_parameter (new CCodeParameter ("connection", "DBusConnection*")); - cfunc.add_parameter (new CCodeParameter ("message", "DBusMessage*")); - cfunc.add_parameter (new CCodeParameter ("object", "void*")); - - if (sym.is_private_symbol ()) { - cfunc.modifiers |= CCodeModifiers.STATIC; - } - - cfile.add_function_declaration (cfunc); - - var block = new CCodeBlock (); - cfunc.block = block; - - var cdecl = new CCodeDeclaration ("DBusHandlerResult"); - cdecl.add_declarator (new CCodeVariableDeclarator ("result", new CCodeConstant ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - block.add_statement (cdecl); - - CCodeIfStatement clastif = null; - - handle_method ("org.freedesktop.DBus.Introspectable", "Introspect", generate_dbus_introspect (sym), block, ref clastif); - - string dbus_iface_name = get_dbus_name (sym); - if (dbus_iface_name != null) { - bool need_property_get = false; - bool need_property_set = false; - foreach (Property prop in sym.get_properties ()) { - if (prop.binding != MemberBinding.INSTANCE - || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) { - continue; - } - if (!is_dbus_visible (prop)) { - continue; - } - if (prop.get_accessor != null) { - need_property_get = true; - } - if (prop.set_accessor != null) { - need_property_set = true; - } - } - - if (need_property_get) { - handle_method ("org.freedesktop.DBus.Properties", "Get", generate_dbus_property_get_wrapper (sym, dbus_iface_name), block, ref clastif); - } - if (need_property_set) { - handle_method ("org.freedesktop.DBus.Properties", "Set", generate_dbus_property_set_wrapper (sym, dbus_iface_name), block, ref clastif); - } - handle_method ("org.freedesktop.DBus.Properties", "GetAll", generate_dbus_property_get_all_wrapper (sym, dbus_iface_name), block, ref clastif); - - handle_methods (sym, dbus_iface_name, block, ref clastif); - } - - var resultblock = new CCodeBlock (); - resultblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result"))); - var cif = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("result"), new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED")), resultblock); - block.add_statement (cif); - clastif = cif; - - var cl = sym as Class; - if (cl != null) { - foreach (DataType base_type in cl.get_base_types ()) { - var base_obj_type = base_type as ObjectType; - if (type_implements_dbus_interface (base_obj_type.type_symbol)) { - var base_call = new CCodeFunctionCall (new CCodeIdentifier (base_obj_type.type_symbol.get_lower_case_cprefix () + "dbus_message")); - base_call.add_argument (new CCodeIdentifier ("connection")); - base_call.add_argument (new CCodeIdentifier ("message")); - base_call.add_argument (new CCodeIdentifier ("object")); - - var ccheck = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, base_call, new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED")); - - var base_block = new CCodeBlock (); - base_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_HANDLED"))); - - cif = new CCodeIfStatement (ccheck, base_block); - clastif.false_statement = cif; - - clastif = cif; - } - } - } - - var retblock = new CCodeBlock (); - retblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED"))); - clastif.false_statement = retblock; - - cfile.add_function (cfunc); - } - - CCodeExpression get_vtable (ObjectType object_type) { - var sym = object_type.type_symbol; - - if (add_wrapper ("_" + sym.get_lower_case_cprefix () + "dbus_vtable")) { - var vtable = new CCodeInitializerList (); - vtable.append (new CCodeIdentifier (sym.get_lower_case_cprefix () + "dbus_register_object")); - - generate_register_function (object_type); - - var cdecl = new CCodeDeclaration ("const _DBusObjectVTable"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_" + sym.get_lower_case_cprefix () + "dbus_vtable", vtable)); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_constant_declaration (cdecl); - } - - return new CCodeIdentifier ("_" + sym.get_lower_case_cprefix () + "dbus_vtable"); - } - - CCodeExpression get_path_vtable (ObjectType object_type) { - var sym = object_type.type_symbol; - - var vtable = new CCodeInitializerList (); - vtable.append (new CCodeIdentifier ("_" + sym.get_lower_case_cprefix () + "dbus_unregister")); - vtable.append (new CCodeIdentifier (sym.get_lower_case_cprefix () + "dbus_message")); - - generate_unregister_function (object_type); - generate_message_function (object_type); - - var cdecl = new CCodeDeclaration ("const DBusObjectPathVTable"); - cdecl.add_declarator (new CCodeVariableDeclarator ("_" + sym.get_lower_case_cprefix () + "dbus_path_vtable", vtable)); - cdecl.modifiers = CCodeModifiers.STATIC; - cfile.add_constant_declaration (cdecl); - - return new CCodeIdentifier ("_" + sym.get_lower_case_cprefix () + "dbus_path_vtable"); - } - - public override void visit_method_call (MethodCall expr) { - var mtype = expr.call.value_type as MethodType; - if (mtype == null || (mtype.method_symbol.get_cname () != "dbus_connection_register_g_object" && - mtype.method_symbol.get_cname () != "dbus_g_connection_register_g_object")) { - base.visit_method_call (expr); - return; - } - - add_dbus_helpers (); - - var ma = (MemberAccess) expr.call; - - var raw_conn = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection")); - raw_conn.add_argument (get_cvalue (ma.inner)); - - var args_it = expr.get_argument_list ().iterator (); - args_it.next (); - var path_arg = args_it.get (); - args_it.next (); - var obj_arg = args_it.get (); - - var cregister = new CCodeFunctionCall (new CCodeIdentifier ("_vala_dbus_register_object")); - if (mtype.method_symbol.get_cname () == "dbus_g_connection_register_g_object") { - cregister.add_argument (raw_conn); - } else { - cregister.add_argument (get_cvalue (ma.inner)); - } - cregister.add_argument (get_cvalue (path_arg)); - cregister.add_argument (get_cvalue (obj_arg)); - - ccode.add_expression (cregister); - } - - bool type_implements_dbus_interface (ObjectTypeSymbol sym) { - var dbus = sym.get_attribute ("DBus"); - if (dbus != null) { - return true; - } - - var cl = sym as Class; - if (cl != null) { - foreach (DataType base_type in cl.get_base_types ()) { - var base_obj_type = base_type as ObjectType; - if (type_implements_dbus_interface (base_obj_type.type_symbol)) { - return true; - } - } - } - - return false; - } - - public override void register_dbus_info (CCodeBlock block, ObjectTypeSymbol sym) { - if (!type_implements_dbus_interface (sym)) { - return; - } - - base.register_dbus_info (block, sym); - - var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string")); - quark.add_argument (new CCodeConstant ("\"DBusObjectVTable\"")); - - var set_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata")); - set_qdata.add_argument (new CCodeIdentifier ("%s_type_id".printf (sym.get_lower_case_cname (null)))); - set_qdata.add_argument (quark); - set_qdata.add_argument (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_vtable (new ObjectType (sym))), "void*")); - - block.add_statement (new CCodeExpressionStatement (set_qdata)); - } -} diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala index 5ee461e7c..faf6e8598 100644 --- a/codegen/valagsignalmodule.vala +++ b/codegen/valagsignalmodule.vala @@ -24,51 +24,37 @@ public class Vala.GSignalModule : GObjectModule { - private string get_marshaller_type_name (DataType t, bool dbus = false) { + private string get_marshaller_type_name (DataType t) { if (t is PointerType || t.type_parameter != null) { return ("POINTER"); } else if (t is ErrorType) { return ("POINTER"); } else if (t is ArrayType) { - if (dbus) { - return ("BOXED"); + if (((ArrayType) t).element_type.data_type == string_type.data_type) { + return ("BOXED,INT"); } else { - if (((ArrayType) t).element_type.data_type == string_type.data_type) { - return ("BOXED,INT"); - } else { - return ("POINTER,INT"); - } + return ("POINTER,INT"); } } else if (t is VoidType) { return ("VOID"); - } else if (dbus && DBusModule.get_type_signature (t).has_prefix ("(")) { - return ("BOXED"); } else if (t.data_type is Enum) { var en = (Enum) t.data_type; - if (dbus) { - if (en.is_flags) { - return ("UINT"); - } else { - return ("INT"); - } - } else { - return en.get_marshaller_type_name (); - } + return en.get_marshaller_type_name (); } else { return t.data_type.get_marshaller_type_name (); } } - private string get_marshaller_type_name_for_parameter (Parameter param, bool dbus = false) { + private string get_marshaller_type_name_for_parameter (Parameter param) { if (param.direction != ParameterDirection.IN) { return ("POINTER"); } else { - return get_marshaller_type_name (param.variable_type, dbus); + return get_marshaller_type_name (param.variable_type); } } - public override string get_marshaller_function (List params, DataType return_type, string? prefix = null, bool dbus = false) { - var signature = get_marshaller_signature (params, return_type, dbus); + string get_marshaller_function (List params, DataType return_type, string? prefix = null) { + var signature = get_marshaller_signature (params, return_type); string ret; if (prefix == null) { @@ -79,13 +65,13 @@ public class Vala.GSignalModule : GObjectModule { } } - ret = "%s_%s_".printf (prefix, get_marshaller_type_name (return_type, dbus)); + ret = "%s_%s_".printf (prefix, get_marshaller_type_name (return_type)); if (params == null || params.size == 0) { ret = ret + "_VOID"; } else { foreach (Parameter p in params) { - ret = "%s_%s".printf (ret, get_marshaller_type_name_for_parameter (p, dbus).replace (",", "_")); + ret = "%s_%s".printf (ret, get_marshaller_type_name_for_parameter (p).replace (",", "_")); } } @@ -127,20 +113,20 @@ public class Vala.GSignalModule : GObjectModule { } } - private string get_marshaller_signature (List params, DataType return_type, bool dbus = false) { + private string get_marshaller_signature (List params, DataType return_type) { string signature; - signature = "%s:".printf (get_marshaller_type_name (return_type, dbus)); + signature = "%s:".printf (get_marshaller_type_name (return_type)); if (params == null || params.size == 0) { signature = signature + "VOID"; } else { bool first = true; foreach (Parameter p in params) { if (first) { - signature = signature + get_marshaller_type_name_for_parameter (p, dbus); + signature = signature + get_marshaller_type_name_for_parameter (p); first = false; } else { - signature = "%s,%s".printf (signature, get_marshaller_type_name_for_parameter (p, dbus)); + signature = "%s,%s".printf (signature, get_marshaller_type_name_for_parameter (p)); } } } @@ -206,17 +192,17 @@ public class Vala.GSignalModule : GObjectModule { generate_marshaller (sig.get_parameters (), sig.return_type); } - public override void generate_marshaller (List params, DataType return_type, bool dbus = false) { + void generate_marshaller (List params, DataType return_type) { string signature; int n_params, i; /* check whether a signal with the same signature already exists for this source file (or predefined) */ - signature = get_marshaller_signature (params, return_type, dbus); + signature = get_marshaller_signature (params, return_type); if (predefined_marshal_set.contains (signature) || user_marshal_set.contains (signature)) { return; } - var signal_marshaller = new CCodeFunction (get_marshaller_function (params, return_type, null, dbus), "void"); + var signal_marshaller = new CCodeFunction (get_marshaller_function (params, return_type, null), "void"); signal_marshaller.modifiers = CCodeModifiers.STATIC; signal_marshaller.add_parameter (new CCodeParameter ("closure", "GClosure *")); @@ -230,13 +216,13 @@ public class Vala.GSignalModule : GObjectModule { var marshaller_body = new CCodeBlock (); - var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (params, return_type, "GMarshalFunc", dbus)); + var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (params, return_type, "GMarshalFunc")); callback_decl.add_parameter (new CCodeParameter ("data1", "gpointer")); n_params = 1; foreach (Parameter p in params) { callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), get_value_type_name_from_parameter (p))); n_params++; - if (p.variable_type.is_array () && !dbus) { + if (p.variable_type.is_array ()) { callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), "gint")); n_params++; } @@ -244,7 +230,7 @@ public class Vala.GSignalModule : GObjectModule { callback_decl.add_parameter (new CCodeParameter ("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", dbus)); + var var_decl = new CCodeDeclaration (get_marshaller_function (params, return_type, "GMarshalFunc")); var_decl.modifiers = CCodeModifiers.REGISTER; var_decl.add_declarator (new CCodeVariableDeclarator ("callback")); marshaller_body.add_statement (var_decl); @@ -288,7 +274,7 @@ public class Vala.GSignalModule : GObjectModule { 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", dbus))); + 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"))); marshaller_body.add_statement (new CCodeExpressionStatement (c_assign)); fc = new CCodeFunctionCall (new CCodeIdentifier ("callback")); @@ -300,28 +286,15 @@ public class Vala.GSignalModule : GObjectModule { if (p.direction != ParameterDirection.IN) { get_value_function = "g_value_get_pointer"; } else if (is_array) { - if (dbus) { + if (((ArrayType) p.variable_type).element_type.data_type == string_type.data_type) { get_value_function = "g_value_get_boxed"; } else { - if (((ArrayType) p.variable_type).element_type.data_type == string_type.data_type) { - get_value_function = "g_value_get_boxed"; - } else { - get_value_function = "g_value_get_pointer"; - } + get_value_function = "g_value_get_pointer"; } } else if (p.variable_type is PointerType || p.variable_type.type_parameter != null) { get_value_function = "g_value_get_pointer"; } else if (p.variable_type is ErrorType) { get_value_function = "g_value_get_pointer"; - } else if (dbus && DBusModule.get_type_signature (p.variable_type).has_prefix ("(")) { - get_value_function = "g_value_get_boxed"; - } else if (dbus && p.variable_type.data_type is Enum) { - var en = (Enum) p.variable_type.data_type; - if (en.is_flags) { - get_value_function = "g_value_get_uint"; - } else { - get_value_function = "g_value_get_int"; - } } else { get_value_function = p.variable_type.data_type.get_get_value_function (); } @@ -329,7 +302,7 @@ public class Vala.GSignalModule : GObjectModule { inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ()))); fc.add_argument (inner_fc); i++; - if (is_array && !dbus) { + if (is_array) { inner_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_int")); inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ()))); fc.add_argument (inner_fc); @@ -343,14 +316,10 @@ public class Vala.GSignalModule : GObjectModule { CCodeFunctionCall set_fc; if (return_type.is_array ()) { - if (dbus) { + if (((ArrayType) return_type).element_type.data_type == string_type.data_type) { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed")); } else { - if (((ArrayType) return_type).element_type.data_type == string_type.data_type) { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed")); - } else { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); - } + set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); } } else if (return_type.type_parameter != null) { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); @@ -360,15 +329,6 @@ public class Vala.GSignalModule : GObjectModule { 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 && DBusModule.get_type_signature (return_type).has_prefix ("(")) { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed")); - } else if (dbus && return_type.data_type is Enum) { - var en = (Enum) return_type.data_type; - if (en.is_flags) { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_uint")); - } else { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_int")); - } } else { set_fc = new CCodeFunctionCall (new CCodeIdentifier (return_type.data_type.get_set_value_function ())); } @@ -475,10 +435,6 @@ public class Vala.GSignalModule : GObjectModule { return csignew; } - public virtual CCodeExpression get_dbus_g_type (DataType data_type) { - return new CCodeConstant (data_type.data_type.get_type_id ()); - } - public override void visit_element_access (ElementAccess expr) { if (expr.container is MemberAccess && expr.container.symbol_reference is Signal && expr.parent_node is MethodCall) { // detailed signal emission diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala index 02f230378..e268bb690 100644 --- a/compiler/valacompiler.vala +++ b/compiler/valacompiler.vala @@ -60,7 +60,6 @@ class Vala.Compiler { static bool deprecated; static bool experimental; static bool experimental_non_null; - static bool disable_dbus_transformation; static bool disable_warnings; static string cc_command; [CCode (array_length = false, array_null_terminated = true)] @@ -119,7 +118,6 @@ class Vala.Compiler { { "disable-warnings", 0, 0, OptionArg.NONE, ref disable_warnings, "Disable warnings", null }, { "fatal-warnings", 0, 0, OptionArg.NONE, ref fatal_warnings, "Treat warnings as fatal", null }, { "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null }, - { "disable-dbus-transformation", 0, 0, OptionArg.NONE, ref disable_dbus_transformation, "Disable transformation of D-Bus member names", null }, { "cc", 0, 0, OptionArg.STRING, ref cc_command, "Use COMMAND as C compiler command", "COMMAND" }, { "Xcc", 'X', 0, OptionArg.STRING_ARRAY, ref cc_options, "Pass OPTION to the C compiler", "OPTION..." }, { "dump-tree", 0, 0, OptionArg.FILENAME, ref dump_tree, "Write code tree to FILE", "FILE" }, @@ -170,7 +168,6 @@ class Vala.Compiler { context.deprecated = deprecated; context.experimental = experimental; context.experimental_non_null = experimental_non_null; - context.dbus_transformation = !disable_dbus_transformation; context.report.enable_warnings = !disable_warnings; context.report.set_verbose_errors (!quiet_mode); context.verbose_mode = verbose_mode; @@ -270,9 +267,6 @@ class Vala.Compiler { if (packages != null) { foreach (string package in packages) { context.add_external_package (package); - if (context.profile == Profile.GOBJECT && package == "dbus-glib-1") { - context.add_define ("DBUS_GLIB"); - } } packages = null; } @@ -290,14 +284,7 @@ class Vala.Compiler { } if (context.profile == Profile.GOBJECT) { - if (context.has_package ("dbus-glib-1")) { - if (!context.deprecated) { - Report.warning (null, "D-Bus GLib is deprecated, use GDBus"); - } - context.codegen = new DBusServerModule (); - } else { - context.codegen = new GDBusServerModule (); - } + context.codegen = new GDBusServerModule (); } else if (context.profile == Profile.DOVA) { context.codegen = new DovaErrorModule (); } else { diff --git a/doc/valac.1 b/doc/valac.1 index aa0e2629b..98d2e0390 100644 --- a/doc/valac.1 +++ b/doc/valac.1 @@ -111,9 +111,6 @@ Treat warnings as fatal .B \--enable-experimental-non-null Enable experimental enhancements for non-null types .TP -.B \--disable-dbus-transformation -Disable transformation of D-Bus member names -.TP .B \--cc=\fICOMMAND\fR Use \fICOMMAND\fR as C compiler command .TP diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala index 30d05f391..da6df1ff9 100644 --- a/vala/valacodecontext.vala +++ b/vala/valacodecontext.vala @@ -51,11 +51,6 @@ public class Vala.CodeContext { */ public bool experimental_non_null { get; set; } - /** - * Enable transformation of D-Bus member names in dynamic client support. - */ - public bool dbus_transformation { get; set; } - /** * Output C code, don't compile to object code. */ diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi index afa0b90f1..ecac60674 100644 --- a/vapi/glib-2.0.vapi +++ b/vapi/glib-2.0.vapi @@ -4515,7 +4515,6 @@ namespace GLib { public Variant end (); } -#if !DBUS_GLIB [CCode (cname = "char", const_cname = "const char", copy_function = "g_strdup", free_function = "g_free", cheader_filename = "stdlib.h,string.h,glib.h", type_id = "G_TYPE_STRING", marshaller_type_name = "STRING", param_spec_function = "g_param_spec_string", get_value_function = "g_value_get_string", set_value_function = "g_value_set_string", take_value_function = "g_value_take_string", type_signature = "o")] public class ObjectPath : string { [CCode (cname = "g_strdup")] @@ -4527,7 +4526,6 @@ namespace GLib { [CCode (cname = "g_strdup")] public BusName (string bus_name); } -#endif [CCode (cname = "G_LIKELY", cheader_filename = "glib.h")] public static bool likely (bool expression);