From: Jürg Billeter Date: Sun, 22 Jun 2008 21:57:13 +0000 (+0000) Subject: Improve support for arrays as paramters and return values of methods and X-Git-Tag: VALA_0_3_4~23 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ffd11fe6e3f6e78b1b804ec758b3f37c0e2dc7cd;p=platform%2Fupstream%2Fvala.git Improve support for arrays as paramters and return values of methods and 2008-06-22 Jürg Billeter * gobject/valaccodedynamicmethodbinding.vala: * gobject/valaccodedynamicsignalbinding.vala: * gobject/valaccodegenerator.vala: * gobject/valaccodegeneratorsignal.vala: * gobject/valaccodeobjecttypesymbolbinding.vala: Improve support for arrays as paramters and return values of methods and signals exported over D-Bus, fixes part of bug 539357 svn path=/trunk/; revision=1630 --- diff --git a/ChangeLog b/ChangeLog index 2f47e4b..96bfc2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2008-06-22 Jürg Billeter + * gobject/valaccodedynamicmethodbinding.vala: + * gobject/valaccodedynamicsignalbinding.vala: + * gobject/valaccodegenerator.vala: + * gobject/valaccodegeneratorsignal.vala: + * gobject/valaccodeobjecttypesymbolbinding.vala: + + Improve support for arrays as paramters and return values of + methods and signals exported over D-Bus, fixes part of bug 539357 + +2008-06-22 Jürg Billeter + * gobject/valaccodeobjecttypesymbolbinding.vala: Use CamelCase for properties exported to D-Bus diff --git a/gobject/valaccodedynamicmethodbinding.vala b/gobject/valaccodedynamicmethodbinding.vala index d0e0755..28cfb6b 100644 --- a/gobject/valaccodedynamicmethodbinding.vala +++ b/gobject/valaccodedynamicmethodbinding.vala @@ -134,7 +134,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { if (param.parameter_type is ArrayType && ((ArrayType) param.parameter_type).element_type.data_type != codegen.string_type.data_type) { var array_type = (ArrayType) param.parameter_type; CCodeDeclaration cdecl; - if (dbus_use_ptr_array (array_type)) { + if (codegen.dbus_use_ptr_array (array_type)) { cdecl = new CCodeDeclaration ("GPtrArray*"); } else { cdecl = new CCodeDeclaration ("GArray*"); @@ -143,7 +143,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { 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 CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), dbus_use_ptr_array (array_type) ? "pdata" : "data")); + creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), codegen.dbus_use_ptr_array (array_type) ? "pdata" : "data")); creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len")); } else { var cdecl = new CCodeDeclaration (param.parameter_type.get_cname ()); @@ -205,7 +205,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { CCodeDeclaration cdecl; CCodeFunctionCall array_construct; - if (dbus_use_ptr_array (array_type)) { + if (codegen.dbus_use_ptr_array (array_type)) { cdecl = new CCodeDeclaration ("GPtrArray*"); array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_ptr_array_sized_new")); @@ -222,7 +222,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("dbus_%s".printf (param.name), array_construct)); block.add_statement (cdecl); - if (dbus_use_ptr_array (array_type)) { + if (codegen.dbus_use_ptr_array (array_type)) { 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)); @@ -362,7 +362,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { ccall.add_argument (get_dbus_g_type (array_type)); CCodeDeclaration cdecl; - if (dbus_use_ptr_array (array_type)) { + if (codegen.dbus_use_ptr_array (array_type)) { cdecl = new CCodeDeclaration ("GPtrArray*"); } else { cdecl = new CCodeDeclaration ("GArray*"); @@ -390,7 +390,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { 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 ()))); + block.add_statement (new CCodeReturnStatement (new CCodeCastExpression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("result"), codegen.dbus_use_ptr_array (array_type) ? "pdata" : "data"), method.return_type.get_cname ()))); } else { // string arrays or other datatypes @@ -445,26 +445,6 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { } } - bool dbus_use_ptr_array (ArrayType array_type) { - if (array_type.element_type.data_type == codegen.string_type.data_type) { - // use char** - return false; - } else if (array_type.element_type.data_type == codegen.bool_type.data_type - || array_type.element_type.data_type == codegen.int_type.data_type - || array_type.element_type.data_type == codegen.uint_type.data_type - || array_type.element_type.data_type == codegen.long_type.data_type - || array_type.element_type.data_type == codegen.ulong_type.data_type - || array_type.element_type.data_type == codegen.int64_type.data_type - || array_type.element_type.data_type == codegen.uint64_type.data_type - || array_type.element_type.data_type == codegen.double_type.data_type) { - // use GArray - return false; - } else { - // use GPtrArray - return true; - } - } - CCodeExpression get_dbus_g_type (DataType data_type) { var array_type = data_type as ArrayType; if (array_type != null) { @@ -473,7 +453,7 @@ public class Vala.CCodeDynamicMethodBinding : CCodeMethodBinding { } var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection")); - if (dbus_use_ptr_array (array_type)) { + if (codegen.dbus_use_ptr_array (array_type)) { carray_type.add_argument (new CCodeConstant ("\"GPtrArray\"")); } else { carray_type.add_argument (new CCodeConstant ("\"GArray\"")); diff --git a/gobject/valaccodedynamicsignalbinding.vala b/gobject/valaccodedynamicsignalbinding.vala index 39b6702..9b94692 100644 --- a/gobject/valaccodedynamicsignalbinding.vala +++ b/gobject/valaccodedynamicsignalbinding.vala @@ -139,7 +139,8 @@ public class Vala.CCodeDynamicSignalBinding : CCodeBinding { // FIXME should only be done once per marshaller var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller")); - register_call.add_argument (new CCodeIdentifier (codegen.get_marshaller_function (node.get_parameters (), node.return_type))); + codegen.generate_marshaller (node.get_parameters (), node.return_type, true); + register_call.add_argument (new CCodeIdentifier (codegen.get_marshaller_function (node.get_parameters (), node.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")); @@ -153,18 +154,24 @@ public class Vala.CCodeDynamicSignalBinding : CCodeBinding { first = false; continue; } - if (param.parameter_type is ArrayType && ((ArrayType) param.parameter_type).element_type.data_type != codegen.string_type.data_type) { - var array_type = (ArrayType) param.parameter_type; - if (array_type.element_type.data_type.get_type_id () == null) { - Report.error (param.source_reference, "unsupported parameter type for D-Bus signals"); - return; - } - var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection")); - carray_type.add_argument (new CCodeConstant ("\"GArray\"")); - carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ())); - register_call.add_argument (carray_type); - add_call.add_argument (carray_type); + var array_type = param.parameter_type as ArrayType; + if (array_type != null) { + if (array_type.element_type.data_type == codegen.string_type.data_type) { + register_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV")); + add_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV")); + } else { + if (array_type.element_type.data_type.get_type_id () == null) { + Report.error (param.source_reference, "unsupported parameter type for D-Bus signals"); + return; + } + + var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection")); + carray_type.add_argument (new CCodeConstant ("\"GArray\"")); + carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ())); + register_call.add_argument (carray_type); + add_call.add_argument (carray_type); + } } else { if (param.parameter_type.get_type_id () == null) { Report.error (param.source_reference, "unsupported parameter type for D-Bus signals"); diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 2d3301d..29ba37e 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -87,6 +87,7 @@ public class Vala.CCodeGenerator : CodeGenerator { public DataType bool_type; public DataType char_type; + public DataType uchar_type; public DataType unichar_type; public DataType short_type; public DataType ushort_type; @@ -96,6 +97,8 @@ public class Vala.CCodeGenerator : CodeGenerator { public DataType ulong_type; public DataType int8_type; public DataType uint8_type; + public DataType int32_type; + public DataType uint32_type; public DataType int64_type; public DataType uint64_type; public DataType string_type; @@ -210,6 +213,7 @@ public class Vala.CCodeGenerator : CodeGenerator { bool_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("bool")); char_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("char")); + uchar_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("uchar")); unichar_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("unichar")); short_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("short")); ushort_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("ushort")); @@ -219,6 +223,8 @@ public class Vala.CCodeGenerator : CodeGenerator { ulong_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("ulong")); int8_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("int8")); uint8_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("uint8")); + int32_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("int32")); + uint32_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("uint32")); int64_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("int64")); uint64_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("uint64")); float_type = new ValueType ((TypeSymbol) root_symbol.scope.lookup ("float")); @@ -3956,6 +3962,32 @@ public class Vala.CCodeGenerator : CodeGenerator { } } + 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 CodeBinding? create_namespace_binding (Namespace node) { return null; } diff --git a/gobject/valaccodegeneratorsignal.vala b/gobject/valaccodegeneratorsignal.vala index 869649b..bb996c1 100644 --- a/gobject/valaccodegeneratorsignal.vala +++ b/gobject/valaccodegeneratorsignal.vala @@ -31,11 +31,7 @@ public class Vala.CCodeGenerator { return ("POINTER"); } else if (t is ArrayType) { if (dbus) { - if (((ArrayType) t).element_type.data_type == string_type.data_type) { - return ("BOXED"); - } else { - return ("POINTER"); - } + return ("BOXED"); } else { if (((ArrayType) t).element_type.data_type == string_type.data_type) { return ("BOXED_INT"); @@ -61,7 +57,7 @@ public class Vala.CCodeGenerator { } public string get_marshaller_function (Gee.List params, DataType return_type, string? prefix = null, bool dbus = false) { - var signature = get_marshaller_signature (params, return_type); + var signature = get_marshaller_signature (params, return_type, dbus); string ret; if (prefix == null) { @@ -162,7 +158,7 @@ public class Vala.CCodeGenerator { 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); + signature = get_marshaller_signature (params, return_type, dbus); if (predefined_marshal_set.contains (signature) || user_marshal_set.contains (signature)) { return; } @@ -251,10 +247,14 @@ public class Vala.CCodeGenerator { if (p.direction != ParameterDirection.IN) { get_value_function = "g_value_get_pointer"; } else if (is_array) { - if (((ArrayType) p.parameter_type).element_type.data_type == string_type.data_type) { + if (dbus) { get_value_function = "g_value_get_boxed"; } else { - get_value_function = "g_value_get_pointer"; + if (((ArrayType) p.parameter_type).element_type.data_type == string_type.data_type) { + get_value_function = "g_value_get_boxed"; + } else { + get_value_function = "g_value_get_pointer"; + } } } else if (p.parameter_type is PointerType || p.parameter_type.type_parameter != null) { get_value_function = "g_value_get_pointer"; @@ -283,10 +283,14 @@ public class Vala.CCodeGenerator { CCodeFunctionCall set_fc; if (return_type.is_array ()) { - if (((ArrayType) return_type).element_type.data_type == string_type.data_type) { + if (dbus) { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed")); } else { - set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); + 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")); + } } } else if (return_type.type_parameter != null) { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); diff --git a/gobject/valaccodeobjecttypesymbolbinding.vala b/gobject/valaccodeobjecttypesymbolbinding.vala index e1ec54b..a14d177 100644 --- a/gobject/valaccodeobjecttypesymbolbinding.vala +++ b/gobject/valaccodeobjecttypesymbolbinding.vala @@ -219,7 +219,14 @@ public abstract class Vala.CCodeObjectTypeSymbolBinding : Vala.CCodeTypeSymbolBi function.add_parameter (new CCodeFormalParameter ("self", bindable.get_cname () + "*")); foreach (FormalParameter param in m.get_parameters ()) { - if (param.parameter_type.get_type_signature ().has_prefix ("(")) { + var array_type = param.parameter_type as ArrayType; + if (array_type != null && array_type.element_type.data_type != codegen.string_type.data_type) { + if (codegen.dbus_use_ptr_array (array_type)) { + function.add_parameter (new CCodeFormalParameter (param.name, "GPtrArray*")); + } else { + function.add_parameter (new CCodeFormalParameter (param.name, "GArray*")); + } + } else if (param.parameter_type.get_type_signature ().has_prefix ("(")) { if (param.direction == ParameterDirection.IN) { function.add_parameter (new CCodeFormalParameter ("dbus_%s".printf (param.name), "GValueArray*")); } else { @@ -231,8 +238,17 @@ public abstract class Vala.CCodeObjectTypeSymbolBinding : Vala.CCodeTypeSymbolBi } if (!(m.return_type is VoidType)) { - if (m.return_type.get_type_signature ().has_prefix ("(")) { - function.add_parameter (new CCodeFormalParameter ("result", "GValueArray**")); + var array_type = m.return_type as ArrayType; + if (array_type != null) { + if (array_type.element_type.data_type == codegen.string_type.data_type) { + function.add_parameter (new CCodeFormalParameter ("result", array_type.get_cname () + "*")); + } else if (codegen.dbus_use_ptr_array (array_type)) { + function.add_parameter (new CCodeFormalParameter ("dbus_result", "GPtrArray**")); + } else { + function.add_parameter (new CCodeFormalParameter ("dbus_result", "GArray**")); + } + } else if (m.return_type.get_type_signature ().has_prefix ("(")) { + function.add_parameter (new CCodeFormalParameter ("dbus_result", "GValueArray**")); } else { function.add_parameter (new CCodeFormalParameter ("result", m.return_type.get_cname () + "*")); } @@ -268,12 +284,41 @@ public abstract class Vala.CCodeObjectTypeSymbolBinding : Vala.CCodeTypeSymbolBi } } + if (!(m.return_type is VoidType)) { + var array_type = m.return_type as ArrayType; + if (array_type != null) { + if (array_type.element_type.data_type != codegen.string_type.data_type) { + var cdecl = new CCodeDeclaration (m.return_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator ("result")); + block.add_statement (cdecl); + } + + var len_cdecl = new CCodeDeclaration ("int"); + len_cdecl.add_declarator (new CCodeVariableDeclarator ("result_length1")); + block.add_statement (len_cdecl); + } + } + var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); ccall.add_argument (new CCodeIdentifier ("self")); foreach (FormalParameter param in m.get_parameters ()) { - if (param.parameter_type.get_type_signature ().has_prefix ("(")) { + var array_type = param.parameter_type as ArrayType; + if (array_type != null) { + if (array_type.element_type.data_type == codegen.string_type.data_type) { + ccall.add_argument (new CCodeIdentifier (param.name)); + var cstrvlen = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length")); + cstrvlen.add_argument (new CCodeIdentifier (param.name)); + ccall.add_argument (cstrvlen); + } else if (codegen.dbus_use_ptr_array (array_type)) { + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "pdata")); + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len")); + } else { + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "data")); + ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len")); + } + } else if (param.parameter_type.get_type_signature ().has_prefix ("(")) { // struct input or output parameters ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name))); } else { @@ -281,15 +326,25 @@ public abstract class Vala.CCodeObjectTypeSymbolBinding : Vala.CCodeTypeSymbolBi } } - if (m.get_error_types ().size > 0) { - ccall.add_argument (new CCodeIdentifier ("error")); - } - CCodeExpression expr; if (m.return_type is VoidType) { expr = ccall; } else { - expr = new CCodeAssignment (new CCodeIdentifier ("*result"), ccall); + var array_type = m.return_type as ArrayType; + if (array_type != null) { + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result_length1"))); + if (array_type.element_type.data_type != codegen.string_type.data_type) { + expr = new CCodeAssignment (new CCodeIdentifier ("result"), ccall); + } else { + expr = new CCodeAssignment (new CCodeIdentifier ("*result"), ccall); + } + } else { + expr = new CCodeAssignment (new CCodeIdentifier ("*result"), ccall); + } + } + + if (m.get_error_types ().size > 0) { + ccall.add_argument (new CCodeIdentifier ("error")); } block.add_statement (new CCodeExpressionStatement (expr)); @@ -347,6 +402,45 @@ public abstract class Vala.CCodeObjectTypeSymbolBinding : Vala.CCodeTypeSymbolBi } } + if (!(m.return_type is VoidType)) { + var array_type = m.return_type as ArrayType; + if (array_type != null && array_type.element_type.data_type != codegen.string_type.data_type) { + var garray = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("dbus_result")); + + var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); + sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ())); + + if (codegen.dbus_use_ptr_array (array_type)) { + var array_construct = new CCodeFunctionCall (new CCodeIdentifier ("g_ptr_array_sized_new")); + array_construct.add_argument (new CCodeIdentifier ("result_length1")); + + block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (garray, array_construct))); + + var memcpy_call = new CCodeFunctionCall (new CCodeIdentifier ("memcpy")); + memcpy_call.add_argument (new CCodeMemberAccess.pointer (garray, "pdata")); + memcpy_call.add_argument (new CCodeIdentifier ("result")); + memcpy_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("result_length1"), sizeof_call)); + block.add_statement (new CCodeExpressionStatement (memcpy_call)); + + var len_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (garray, "len"), new CCodeIdentifier ("result_length1")); + block.add_statement (new CCodeExpressionStatement (len_assignment)); + } else { + var 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); + + block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (garray, array_construct))); + + var cappend_call = new CCodeFunctionCall (new CCodeIdentifier ("g_array_append_vals")); + cappend_call.add_argument (garray); + cappend_call.add_argument (new CCodeIdentifier ("result")); + cappend_call.add_argument (new CCodeIdentifier ("result_length1")); + block.add_statement (new CCodeExpressionStatement (cappend_call)); + } + } + } + var no_error = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeIdentifier ("!error"), new CCodeIdentifier ("!*error")); block.add_statement (new CCodeReturnStatement (no_error));