2008-06-22 Jürg Billeter <j@bitron.ch>
+ * 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 <j@bitron.ch>
+
* gobject/valaccodeobjecttypesymbolbinding.vala:
Use CamelCase for properties exported to D-Bus
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*");
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 ());
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"));
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));
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*");
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
}
}
- 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) {
}
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\""));
// 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"));
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");
public DataType bool_type;
public DataType char_type;
+ public DataType uchar_type;
public DataType unichar_type;
public DataType short_type;
public DataType ushort_type;
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;
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"));
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"));
}
}
+ 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;
}
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");
}
public string get_marshaller_function (Gee.List<FormalParameter> params, DataType return_type, string? prefix = null, bool dbus = false) {
- var signature = get_marshaller_signature (params, return_type);
+ var signature = get_marshaller_signature (params, return_type, dbus);
string ret;
if (prefix == null) {
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;
}
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";
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"));
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 {
}
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 () + "*"));
}
}
}
+ 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 {
}
}
- 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));
}
}
+ 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));