3 * Copyright (C) 2008-2009 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
23 internal class Vala
.DBusModule
: GAsyncModule
{
24 struct BasicTypeInfo
{
25 public weak string signature
;
26 public weak string type_name
;
27 public weak string cname
;
28 public weak string gtype
;
29 public weak string? get_value_function
;
30 public weak string set_value_function
;
33 const BasicTypeInfo
[] basic_types
= {
34 { "y", "BYTE", "guint8", "G_TYPE_UCHAR", "g_value_get_uchar", "g_value_set_uchar" },
35 { "b", "BOOLEAN", "dbus_bool_t", "G_TYPE_BOOLEAN", "g_value_get_boolean", "g_value_set_boolean" },
36 { "n", "INT16", "dbus_int16_t", "G_TYPE_INT", null, "g_value_set_int" },
37 { "q", "UINT16", "dbus_uint16_t", "G_TYPE_UINT", null, "g_value_set_uint" },
38 { "i", "INT32", "dbus_int32_t", "G_TYPE_INT", "g_value_get_int", "g_value_set_int" },
39 { "u", "UINT32", "dbus_uint32_t", "G_TYPE_UINT", "g_value_get_uint", "g_value_set_uint" },
40 { "x", "INT64", "dbus_int64_t", "G_TYPE_INT64", "g_value_get_int64", "g_value_set_int64" },
41 { "t", "UINT64", "dbus_uint64_t", "G_TYPE_UINT64", "g_value_get_uint64", "g_value_set_uint64" },
42 { "d", "DOUBLE", "double", "G_TYPE_DOUBLE", "g_value_get_double", "g_value_set_double" },
43 { "s", "STRING", "const char*", "G_TYPE_STRING", "g_value_get_string", "g_value_take_string" },
44 { "o", "OBJECT_PATH", "const char*", "G_TYPE_STRING", null, "g_value_take_string" },
45 { "g", "SIGNATURE", "const char*", "G_TYPE_STRING", null, "g_value_take_string" }
48 public DBusModule (CCodeGenerator codegen
, CCodeModule? next
) {
52 static bool is_string_marshalled_enum (TypeSymbol? symbol
) {
53 if (symbol
!= null && symbol is Enum
) {
54 var dbus
= symbol
.get_attribute ("DBus");
55 return dbus
!= null && dbus
.get_bool ("use_string_marshalling");
60 string get_dbus_value (EnumValue value
, string default_value
) {
61 var dbus
= value
.get_attribute ("DBus");
66 string dbus_value
= dbus
.get_string ("value");
67 if (dbus_value
== null) {
73 public string?
get_dbus_name (TypeSymbol symbol
) {
74 var dbus
= symbol
.get_attribute ("DBus");
79 return dbus
.get_string ("name");
82 public string get_dbus_name_for_member (Symbol symbol
) {
83 var dbus
= symbol
.get_attribute ("DBus");
85 return dbus
.get_string ("name");
88 return Symbol
.lower_case_to_camel_case (symbol
.name
);
91 bool get_basic_type_info (string signature
, out BasicTypeInfo basic_type
) {
92 foreach (BasicTypeInfo info
in basic_types
) {
93 if (info
.signature
== signature
) {
101 public static string get_type_signature (DataType datatype
) {
102 if (is_string_marshalled_enum (datatype
.data_type
)) {
105 return datatype
.get_type_signature ();
109 public override void visit_enum (Enum en
) {
110 base.visit_enum (en
);
112 if (is_string_marshalled_enum (en
)) {
114 source_declarations
.add_include ("string.h");
115 source_declarations
.add_include ("dbus/dbus-glib.h");
117 source_type_member_definition
.append (generate_enum_from_string_function (en
));
118 source_type_member_definition
.append (generate_enum_to_string_function (en
));
122 public override bool generate_enum_declaration (Enum en
, CCodeDeclarationSpace decl_space
) {
123 if (base.generate_enum_declaration (en
, decl_space
)) {
124 if (is_string_marshalled_enum (en
)) {
125 decl_space
.add_type_member_declaration (generate_enum_from_string_function_declaration (en
));
126 decl_space
.add_type_member_declaration (generate_enum_to_string_function_declaration (en
));
133 CCodeExpression?
get_array_length (CCodeExpression expr
, int dim
) {
134 var id
= expr as CCodeIdentifier
;
135 var ma
= expr as CCodeMemberAccess
;
137 return new
CCodeIdentifier ("%s_length%d".printf (id
.name
, dim
));
138 } else if (ma
!= null) {
139 return new CCodeMemberAccess
.pointer (ma
.inner
, "%s_length%d".printf (ma
.member_name
, dim
));
144 CCodeExpression?
generate_enum_value_from_string (CCodeFragment fragment
, EnumValueType type
, CCodeExpression? expr
) {
145 var en
= type
.type_symbol as Enum
;
146 var from_string_name
= "%s_from_string".printf (en
.get_lower_case_cname (null));
148 var from_string_call
= new
CCodeFunctionCall (new
CCodeIdentifier (from_string_name
));
149 from_string_call
.add_argument (expr
);
150 from_string_call
.add_argument (new
CCodeConstant ("NULL"));
152 return from_string_call
;
155 public CCodeFunction
generate_enum_from_string_function_declaration (Enum en
) {
156 var from_string_name
= "%s_from_string".printf (en
.get_lower_case_cname (null));
158 var from_string_func
= new
CCodeFunction (from_string_name
, en
.get_cname ());
159 from_string_func
.add_parameter (new
CCodeFormalParameter ("str", "const char*"));
160 from_string_func
.add_parameter (new
CCodeFormalParameter ("error", "GError**"));
162 return from_string_func
;
165 public CCodeFunction
generate_enum_from_string_function (Enum en
) {
166 var from_string_name
= "%s_from_string".printf (en
.get_lower_case_cname (null));
168 var from_string_func
= new
CCodeFunction (from_string_name
, en
.get_cname ());
169 from_string_func
.add_parameter (new
CCodeFormalParameter ("str", "const char*"));
170 from_string_func
.add_parameter (new
CCodeFormalParameter ("error", "GError**"));
172 var from_string_block
= new
CCodeBlock ();
173 from_string_func
.block
= from_string_block
;
175 var cdecl
= new
CCodeDeclaration (en
.get_cname ());
176 cdecl
.add_declarator (new
CCodeVariableDeclarator ("value"));
177 from_string_block
.add_statement (cdecl
);
179 CCodeStatement if_else_if
= null;
180 CCodeIfStatement last_statement
= null;
181 foreach (EnumValue enum_value
in en
.get_values ()) {
182 var true_block
= new
CCodeBlock ();
183 true_block
.suppress_newline
= true;
184 true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("value"), new
CCodeIdentifier (enum_value
.get_cname ()))));
186 string dbus_value
= get_dbus_value (enum_value
, enum_value
.name
);
187 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
188 string_comparison
.add_argument (new
CCodeIdentifier ("str"));
189 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_value
)));
190 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, new
CCodeConstant ("0")), true_block
);
192 if (last_statement
!= null) {
193 last_statement
.false_statement
= stmt
;
197 last_statement
= stmt
;
200 var error_block
= new
CCodeBlock ();
201 error_block
.suppress_newline
= true;
203 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error_literal"));
204 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
205 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
206 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_INVALID_ARGS"));
207 set_error_call
.add_argument (new
CCodeConstant ("\"Invalid enumeration value\""));
208 error_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
210 last_statement
.false_statement
= error_block
;
211 from_string_block
.add_statement (if_else_if
);
213 from_string_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("value")));
215 return from_string_func
;
218 CCodeExpression
read_basic (CCodeFragment fragment
, BasicTypeInfo basic_type
, CCodeExpression iter_expr
, bool transfer
= false) {
219 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
221 var cdecl
= new
CCodeDeclaration (basic_type
.cname
);
222 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
223 fragment
.append (cdecl
);
225 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_basic"));
226 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
227 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (temp_name
)));
228 fragment
.append (new
CCodeExpressionStatement (iter_call
));
230 var temp_result
= new
CCodeIdentifier (temp_name
);
233 && (basic_type
.signature
== "s"
234 || basic_type
.signature
== "o"
235 || basic_type
.signature
== "g")) {
236 var dup_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup"));
237 dup_call
.add_argument (temp_result
);
244 CCodeExpression
read_array (CCodeFragment fragment
, ArrayType array_type
, CCodeExpression iter_expr
, CCodeExpression? expr
) {
245 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
247 var new_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_new"));
248 new_call
.add_argument (new
CCodeIdentifier (array_type
.element_type
.get_cname ()));
249 // add one extra element for NULL-termination
250 new_call
.add_argument (new
CCodeConstant ("5"));
252 var cdecl
= new
CCodeDeclaration (array_type
.get_cname ());
253 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
, new_call
));
254 fragment
.append (cdecl
);
256 cdecl
= new
CCodeDeclaration ("int");
257 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
+ "_length", new
CCodeConstant ("0")));
258 fragment
.append (cdecl
);
260 cdecl
= new
CCodeDeclaration ("int");
261 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
+ "_size", new
CCodeConstant ("4")));
262 fragment
.append (cdecl
);
264 read_array_dim (fragment
, array_type
, 1, temp_name
, iter_expr
, expr
);
266 if (array_type
.element_type
.is_reference_type_or_type_parameter ()) {
267 // NULL terminate array
268 var length
= new
CCodeIdentifier (temp_name
+ "_length");
269 var element_access
= new
CCodeElementAccess (new
CCodeIdentifier (temp_name
), length
);
270 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (element_access
, new
CCodeIdentifier ("NULL"))));
273 return new
CCodeIdentifier (temp_name
);
276 void read_array_dim (CCodeFragment fragment
, ArrayType array_type
, int dim
, string temp_name
, CCodeExpression iter_expr
, CCodeExpression? expr
) {
277 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
279 var cdecl
= new
CCodeDeclaration ("int");
280 cdecl
.add_declarator (new
CCodeVariableDeclarator ("%s_length%d".printf (temp_name
, dim
), new
CCodeConstant ("0")));
281 fragment
.append (cdecl
);
283 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
284 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
285 fragment
.append (cdecl
);
287 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
288 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
289 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
290 fragment
.append (new
CCodeExpressionStatement (iter_call
));
292 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_arg_type"));
293 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
295 var cforblock
= new
CCodeBlock ();
296 var cforfragment
= new
CCodeFragment ();
297 cforblock
.add_statement (cforfragment
);
298 var cfor
= new
CCodeForStatement (iter_call
, cforblock
);
299 cfor
.add_iterator (new
CCodeUnaryExpression (CCodeUnaryOperator
.POSTFIX_INCREMENT
, new
CCodeIdentifier ("%s_length%d".printf (temp_name
, dim
))));
301 if (dim
< array_type
.rank
) {
302 read_array_dim (cforfragment
, array_type
, dim
+ 1, temp_name
, new
CCodeIdentifier (subiter_name
), expr
);
304 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_next"));
305 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
306 cforfragment
.append (new
CCodeExpressionStatement (iter_call
));
308 var size_check
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, new
CCodeIdentifier (temp_name
+ "_size"), new
CCodeIdentifier (temp_name
+ "_length"));
309 var renew_block
= new
CCodeBlock ();
311 // tmp_size = (2 * tmp_size);
312 var new_size
= new
CCodeBinaryExpression (CCodeBinaryOperator
.MUL
, new
CCodeConstant ("2"), new
CCodeIdentifier (temp_name
+ "_size"));
313 renew_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (temp_name
+ "_size"), new_size
)));
315 var renew_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_renew"));
316 renew_call
.add_argument (new
CCodeIdentifier (array_type
.element_type
.get_cname ()));
317 renew_call
.add_argument (new
CCodeIdentifier (temp_name
));
318 // add one extra element for NULL-termination
319 renew_call
.add_argument (new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, new
CCodeIdentifier (temp_name
+ "_size"), new
CCodeConstant ("1")));
320 var renew_stmt
= new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (temp_name
), renew_call
));
321 renew_block
.add_statement (renew_stmt
);
323 var cif
= new
CCodeIfStatement (size_check
, renew_block
);
324 cforfragment
.append (cif
);
326 var element_access
= new
CCodeElementAccess (new
CCodeIdentifier (temp_name
), new
CCodeUnaryExpression (CCodeUnaryOperator
.POSTFIX_INCREMENT
, new
CCodeIdentifier (temp_name
+ "_length")));
327 var element_expr
= read_expression (cforfragment
, array_type
.element_type
, new
CCodeIdentifier (subiter_name
), null);
328 cforfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (element_access
, element_expr
)));
331 fragment
.append (cfor
);
334 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (get_array_length (expr
, dim
), new
CCodeIdentifier ("%s_length%d".printf (temp_name
, dim
)))));
338 CCodeExpression
read_struct (CCodeFragment fragment
, Struct st
, CCodeExpression iter_expr
) {
339 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
340 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
342 var cdecl
= new
CCodeDeclaration (st
.get_cname ());
343 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
344 fragment
.append (cdecl
);
346 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
347 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
348 fragment
.append (cdecl
);
350 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
351 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
352 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
353 fragment
.append (new
CCodeExpressionStatement (iter_call
));
355 foreach (Field f
in st
.get_fields ()) {
356 if (f
.binding
!= MemberBinding
.INSTANCE
) {
360 var field_expr
= read_expression (fragment
, f
.field_type
, new
CCodeIdentifier (subiter_name
), new
CCodeMemberAccess (new
CCodeIdentifier (temp_name
), f
.get_cname ()));
361 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeMemberAccess (new
CCodeIdentifier (temp_name
), f
.get_cname ()), field_expr
)));
364 return new
CCodeIdentifier (temp_name
);
367 CCodeExpression
read_value (CCodeFragment fragment
, CCodeExpression iter_expr
) {
368 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
369 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
371 // 0-initialize struct with struct initializer { 0 }
372 var cvalinit
= new
CCodeInitializerList ();
373 cvalinit
.append (new
CCodeConstant ("0"));
375 var cdecl
= new
CCodeDeclaration ("GValue");
376 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero (temp_name
, cvalinit
));
377 fragment
.append (cdecl
);
379 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
380 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
381 fragment
.append (cdecl
);
383 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
384 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
385 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
386 fragment
.append (new
CCodeExpressionStatement (iter_call
));
388 CCodeIfStatement clastif
= null;
390 foreach (BasicTypeInfo basic_type
in basic_types
) {
391 var type_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_arg_type"));
392 type_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
393 var type_check
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, type_call
, new
CCodeIdentifier ("DBUS_TYPE_" + basic_type
.type_name
));
395 var type_block
= new
CCodeBlock ();
396 var type_fragment
= new
CCodeFragment ();
397 type_block
.add_statement (type_fragment
);
398 var result
= read_basic (type_fragment
, basic_type
, new
CCodeIdentifier (subiter_name
));
400 var value_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_init"));
401 value_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (temp_name
)));
402 value_init
.add_argument (new
CCodeIdentifier (basic_type
.gtype
));
403 type_fragment
.append (new
CCodeExpressionStatement (value_init
));
405 var value_set
= new
CCodeFunctionCall (new
CCodeIdentifier (basic_type
.set_value_function
));
406 value_set
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (temp_name
)));
407 value_set
.add_argument (result
);
408 type_fragment
.append (new
CCodeExpressionStatement (value_set
));
410 var cif
= new
CCodeIfStatement (type_check
, type_block
);
411 if (clastif
== null) {
412 fragment
.append (cif
);
414 clastif
.false_statement
= cif
;
420 return new
CCodeIdentifier (temp_name
);
423 CCodeExpression
read_hash_table (CCodeFragment fragment
, ObjectType type
, CCodeExpression iter_expr
) {
424 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
425 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
426 string entryiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
428 var type_args
= type
.get_type_arguments ();
429 assert (type_args
.size
== 2);
430 var key_type
= type_args
.get (0);
431 var value_type
= type_args
.get (1);
433 var cdecl
= new
CCodeDeclaration ("GHashTable*");
434 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
435 fragment
.append (cdecl
);
437 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
438 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
439 fragment
.append (cdecl
);
441 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
442 cdecl
.add_declarator (new
CCodeVariableDeclarator (entryiter_name
));
443 fragment
.append (cdecl
);
445 var hash_table_new
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_hash_table_new_full"));
446 if (key_type
.data_type
== string_type
.data_type
) {
447 hash_table_new
.add_argument (new
CCodeIdentifier ("g_str_hash"));
448 hash_table_new
.add_argument (new
CCodeIdentifier ("g_str_equal"));
450 hash_table_new
.add_argument (new
CCodeIdentifier ("g_direct_hash"));
451 hash_table_new
.add_argument (new
CCodeIdentifier ("g_direct_equal"));
453 if (key_type
.data_type
== string_type
.data_type
) {
454 hash_table_new
.add_argument (new
CCodeIdentifier ("g_free"));
456 hash_table_new
.add_argument (new
CCodeIdentifier ("NULL"));
458 if (value_type
.data_type
== string_type
.data_type
) {
459 hash_table_new
.add_argument (new
CCodeIdentifier ("g_free"));
461 hash_table_new
.add_argument (new
CCodeIdentifier ("NULL"));
463 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (temp_name
), hash_table_new
)));
465 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
466 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
467 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
468 fragment
.append (new
CCodeExpressionStatement (iter_call
));
470 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_arg_type"));
471 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
473 var cwhileblock
= new
CCodeBlock ();
474 var cwhilefragment
= new
CCodeFragment ();
475 cwhileblock
.add_statement (cwhilefragment
);
476 var cwhile
= new
CCodeWhileStatement (iter_call
, cwhileblock
);
478 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
479 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
480 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (entryiter_name
)));
481 cwhilefragment
.append (new
CCodeExpressionStatement (iter_call
));
483 cdecl
= new
CCodeDeclaration (key_type
.get_cname ());
484 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_key"));
485 cwhilefragment
.append (cdecl
);
487 cdecl
= new
CCodeDeclaration (value_type
.get_cname ());
488 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_value"));
489 cwhilefragment
.append (cdecl
);
491 var key_expr
= read_expression (cwhilefragment
, key_type
, new
CCodeIdentifier (entryiter_name
), null);
492 cwhilefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_key"), key_expr
)));
494 var value_expr
= read_expression (cwhilefragment
, value_type
, new
CCodeIdentifier (entryiter_name
), null);
495 cwhilefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_value"), value_expr
)));
497 var hash_table_insert
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_hash_table_insert"));
498 hash_table_insert
.add_argument (new
CCodeIdentifier (temp_name
));
499 hash_table_insert
.add_argument (convert_to_generic_pointer (new
CCodeIdentifier ("_key"), key_type
));
500 hash_table_insert
.add_argument (convert_to_generic_pointer (new
CCodeIdentifier ("_value"), value_type
));
501 cwhilefragment
.append (new
CCodeExpressionStatement (hash_table_insert
));
503 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_next"));
504 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
505 cwhilefragment
.append (new
CCodeExpressionStatement (iter_call
));
507 fragment
.append (cwhile
);
509 return new
CCodeIdentifier (temp_name
);
512 public CCodeExpression?
read_expression (CCodeFragment fragment
, DataType type
, CCodeExpression iter_expr
, CCodeExpression? expr
) {
513 BasicTypeInfo basic_type
;
514 CCodeExpression result
= null;
515 if (is_string_marshalled_enum (type
.data_type
)) {
516 get_basic_type_info ("s", out basic_type
);
517 result
= read_basic (fragment
, basic_type
, iter_expr
, true);
518 result
= generate_enum_value_from_string (fragment
, type as EnumValueType
, result
);
519 } else if (get_basic_type_info (get_type_signature (type
), out basic_type
)) {
520 result
= read_basic (fragment
, basic_type
, iter_expr
);
521 } else if (type is ArrayType
) {
522 result
= read_array (fragment
, (ArrayType
) type
, iter_expr
, expr
);
523 } else if (type
.data_type is Struct
) {
524 var st
= (Struct
) type
.data_type
;
525 if (type
.data_type
.get_full_name () == "GLib.Value") {
526 result
= read_value (fragment
, iter_expr
);
528 result
= read_struct (fragment
, st
, iter_expr
);
531 var csizeof
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
532 csizeof
.add_argument (new
CCodeIdentifier (st
.get_cname ()));
533 var cdup
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_memdup"));
534 cdup
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, result
));
535 cdup
.add_argument (csizeof
);
538 } else if (type is ObjectType
) {
539 if (type
.data_type
.get_full_name () == "GLib.HashTable") {
540 result
= read_hash_table (fragment
, (ObjectType
) type
, iter_expr
);
543 Report
.error (type
.source_reference
, "D-Bus deserialization of type `%s' is not supported".printf (type
.to_string ()));
547 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_next"));
548 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
549 fragment
.append (new
CCodeExpressionStatement (iter_call
));
554 CCodeExpression?
generate_enum_value_to_string (CCodeFragment fragment
, EnumValueType type
, CCodeExpression? expr
) {
555 var en
= type
.type_symbol as Enum
;
556 var to_string_name
= "%s_to_string".printf (en
.get_lower_case_cname (null));
558 var to_string_call
= new
CCodeFunctionCall (new
CCodeIdentifier (to_string_name
));
559 to_string_call
.add_argument (expr
);
561 return to_string_call
;
564 public CCodeFunction
generate_enum_to_string_function_declaration (Enum en
) {
565 var to_string_name
= "%s_to_string".printf (en
.get_lower_case_cname (null));
567 var to_string_func
= new
CCodeFunction (to_string_name
, "const char*");
568 to_string_func
.add_parameter (new
CCodeFormalParameter ("value", en
.get_cname ()));
570 return to_string_func
;
573 public CCodeFunction
generate_enum_to_string_function (Enum en
) {
574 var to_string_name
= "%s_to_string".printf (en
.get_lower_case_cname (null));
576 var to_string_func
= new
CCodeFunction (to_string_name
, "const char*");
577 to_string_func
.add_parameter (new
CCodeFormalParameter ("value", en
.get_cname ()));
579 var to_string_block
= new
CCodeBlock ();
580 to_string_func
.block
= to_string_block
;
582 var cdecl
= new
CCodeDeclaration ("const char *");
583 cdecl
.add_declarator (new
CCodeVariableDeclarator ("str"));
584 to_string_block
.add_statement (cdecl
);
586 var cswitch
= new
CCodeSwitchStatement (new
CCodeIdentifier ("value"));
587 foreach (EnumValue enum_value
in en
.get_values ()) {
588 string dbus_value
= get_dbus_value (enum_value
, enum_value
.name
);
589 cswitch
.add_statement (new
CCodeCaseStatement (new
CCodeIdentifier (enum_value
.get_cname ())));
590 cswitch
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("str"), new
CCodeConstant ("\"%s\"".printf (dbus_value
)))));
591 cswitch
.add_statement (new
CCodeBreakStatement ());
593 to_string_block
.add_statement (cswitch
);
595 to_string_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("str")));
597 return to_string_func
;
600 void write_basic (CCodeFragment fragment
, BasicTypeInfo basic_type
, CCodeExpression iter_expr
, CCodeExpression expr
) {
601 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
603 var cdecl
= new
CCodeDeclaration (basic_type
.cname
);
604 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
605 fragment
.append (cdecl
);
607 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (temp_name
), expr
)));
609 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_append_basic"));
610 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
611 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_" + basic_type
.type_name
));
612 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (temp_name
)));
613 fragment
.append (new
CCodeExpressionStatement (iter_call
));
616 void write_array (CCodeFragment fragment
, ArrayType array_type
, CCodeExpression iter_expr
, CCodeExpression array_expr
) {
617 string array_iter_name
= "_tmp%d_".printf (next_temp_var_id
++);
619 var cdecl
= new
CCodeDeclaration (array_type
.get_cname ());
620 cdecl
.add_declarator (new
CCodeVariableDeclarator (array_iter_name
));
621 fragment
.append (cdecl
);
623 fragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (array_iter_name
), array_expr
)));
625 write_array_dim (fragment
, array_type
, 1, iter_expr
, array_expr
, new
CCodeIdentifier (array_iter_name
));
628 void write_array_dim (CCodeFragment fragment
, ArrayType array_type
, int dim
, CCodeExpression iter_expr
, CCodeExpression array_expr
, CCodeExpression array_iter_expr
) {
629 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
630 string index_name
= "_tmp%d_".printf (next_temp_var_id
++);
632 var cdecl
= new
CCodeDeclaration ("DBusMessageIter");
633 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
634 fragment
.append (cdecl
);
636 cdecl
= new
CCodeDeclaration ("int");
637 cdecl
.add_declarator (new
CCodeVariableDeclarator (index_name
));
638 fragment
.append (cdecl
);
640 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
641 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
642 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_ARRAY"));
643 iter_call
.add_argument (new
CCodeConstant ("\"%s%s\"".printf (string.nfill (array_type
.rank
- dim
, 'a'), get_type_signature (array_type
.element_type
))));
644 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
645 fragment
.append (new
CCodeExpressionStatement (iter_call
));
647 var cforblock
= new
CCodeBlock ();
648 var cforfragment
= new
CCodeFragment ();
649 cforblock
.add_statement (cforfragment
);
650 var cfor
= new
CCodeForStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.LESS_THAN
, new
CCodeIdentifier (index_name
), get_array_length (array_expr
, dim
)), cforblock
);
651 cfor
.add_initializer (new
CCodeAssignment (new
CCodeIdentifier (index_name
), new
CCodeConstant ("0")));
652 cfor
.add_iterator (new
CCodeUnaryExpression (CCodeUnaryOperator
.POSTFIX_INCREMENT
, new
CCodeIdentifier (index_name
)));
654 if (dim
< array_type
.rank
) {
655 write_array_dim (cforfragment
, array_type
, dim
+ 1, new
CCodeIdentifier (subiter_name
), array_expr
, array_iter_expr
);
657 var element_expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, array_iter_expr
);
658 write_expression (cforfragment
, array_type
.element_type
, new
CCodeIdentifier (subiter_name
), element_expr
);
660 var array_iter_incr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POSTFIX_INCREMENT
, array_iter_expr
);
661 cforfragment
.append (new
CCodeExpressionStatement (array_iter_incr
));
663 fragment
.append (cfor
);
665 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
666 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
667 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
668 fragment
.append (new
CCodeExpressionStatement (iter_call
));
671 void write_struct (CCodeFragment fragment
, Struct st
, CCodeExpression iter_expr
, CCodeExpression struct_expr
) {
672 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
674 var cdecl
= new
CCodeDeclaration ("DBusMessageIter");
675 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
676 fragment
.append (cdecl
);
678 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
679 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
680 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_STRUCT"));
681 iter_call
.add_argument (new
CCodeConstant ("NULL"));
682 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
683 fragment
.append (new
CCodeExpressionStatement (iter_call
));
685 foreach (Field f
in st
.get_fields ()) {
686 if (f
.binding
!= MemberBinding
.INSTANCE
) {
690 write_expression (fragment
, f
.field_type
, new
CCodeIdentifier (subiter_name
), new
CCodeMemberAccess (struct_expr
, f
.get_cname ()));
693 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
694 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
695 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
696 fragment
.append (new
CCodeExpressionStatement (iter_call
));
699 void write_value (CCodeFragment fragment
, CCodeExpression iter_expr
, CCodeExpression expr
) {
700 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
702 var cdecl
= new
CCodeDeclaration ("DBusMessageIter");
703 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
704 fragment
.append (cdecl
);
706 CCodeIfStatement clastif
= null;
708 foreach (BasicTypeInfo basic_type
in basic_types
) {
709 // ensure that there is only one case per GType
710 if (basic_type
.get_value_function
== null) {
714 var type_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_VALUE_TYPE"));
715 type_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, expr
));
716 var type_check
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, type_call
, new
CCodeIdentifier (basic_type
.gtype
));
718 var type_block
= new
CCodeBlock ();
719 var type_fragment
= new
CCodeFragment ();
720 type_block
.add_statement (type_fragment
);
722 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
723 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
724 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_VARIANT"));
725 iter_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (basic_type
.signature
)));
726 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
727 type_fragment
.append (new
CCodeExpressionStatement (iter_call
));
729 var value_get
= new
CCodeFunctionCall (new
CCodeIdentifier (basic_type
.get_value_function
));
730 value_get
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, expr
));
732 write_basic (type_fragment
, basic_type
, new
CCodeIdentifier (subiter_name
), value_get
);
734 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
735 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
736 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
737 type_fragment
.append (new
CCodeExpressionStatement (iter_call
));
739 var cif
= new
CCodeIfStatement (type_check
, type_block
);
740 if (clastif
== null) {
741 fragment
.append (cif
);
743 clastif
.false_statement
= cif
;
750 void write_hash_table (CCodeFragment fragment
, ObjectType type
, CCodeExpression iter_expr
, CCodeExpression hash_table_expr
) {
751 string subiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
752 string entryiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
753 string tableiter_name
= "_tmp%d_".printf (next_temp_var_id
++);
754 string key_name
= "_tmp%d_".printf (next_temp_var_id
++);
755 string value_name
= "_tmp%d_".printf (next_temp_var_id
++);
757 var type_args
= type
.get_type_arguments ();
758 assert (type_args
.size
== 2);
759 var key_type
= type_args
.get (0);
760 var value_type
= type_args
.get (1);
762 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
763 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
764 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_ARRAY"));
765 iter_call
.add_argument (new
CCodeConstant ("\"{%s%s}\"".printf (get_type_signature (key_type
), get_type_signature (value_type
))));
766 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
767 fragment
.append (new
CCodeExpressionStatement (iter_call
));
769 var cdecl
= new
CCodeDeclaration ("DBusMessageIter");
770 cdecl
.add_declarator (new
CCodeVariableDeclarator (subiter_name
));
771 cdecl
.add_declarator (new
CCodeVariableDeclarator (entryiter_name
));
772 fragment
.append (cdecl
);
774 cdecl
= new
CCodeDeclaration ("GHashTableIter");
775 cdecl
.add_declarator (new
CCodeVariableDeclarator (tableiter_name
));
776 fragment
.append (cdecl
);
778 cdecl
= new
CCodeDeclaration ("gpointer");
779 cdecl
.add_declarator (new
CCodeVariableDeclarator (key_name
));
780 cdecl
.add_declarator (new
CCodeVariableDeclarator (value_name
));
781 fragment
.append (cdecl
);
783 var iter_init_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_hash_table_iter_init"));
784 iter_init_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (tableiter_name
)));
785 iter_init_call
.add_argument (hash_table_expr
);
786 fragment
.append (new
CCodeExpressionStatement (iter_init_call
));
788 var iter_next_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_hash_table_iter_next"));
789 iter_next_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (tableiter_name
)));
790 iter_next_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (key_name
)));
791 iter_next_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (value_name
)));
793 var cwhileblock
= new
CCodeBlock ();
794 var cwhilefragment
= new
CCodeFragment ();
795 cwhileblock
.add_statement (cwhilefragment
);
796 var cwhile
= new
CCodeWhileStatement (iter_next_call
, cwhileblock
);
798 cdecl
= new
CCodeDeclaration (key_type
.get_cname ());
799 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_key"));
800 cwhilefragment
.append (cdecl
);
802 cdecl
= new
CCodeDeclaration (value_type
.get_cname ());
803 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_value"));
804 cwhilefragment
.append (cdecl
);
806 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
807 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
808 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_DICT_ENTRY"));
809 iter_call
.add_argument (new
CCodeConstant ("NULL"));
810 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (entryiter_name
)));
811 cwhilefragment
.append (new
CCodeExpressionStatement (iter_call
));
813 cwhilefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_key"), convert_from_generic_pointer (new
CCodeIdentifier (key_name
), key_type
))));
814 cwhilefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_value"), convert_from_generic_pointer (new
CCodeIdentifier (value_name
), value_type
))));
816 write_expression (cwhilefragment
, key_type
, new
CCodeIdentifier (entryiter_name
), new
CCodeIdentifier ("_key"));
817 write_expression (cwhilefragment
, value_type
, new
CCodeIdentifier (entryiter_name
), new
CCodeIdentifier ("_value"));
819 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
820 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
821 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (entryiter_name
)));
822 cwhilefragment
.append (new
CCodeExpressionStatement (iter_call
));
824 fragment
.append (cwhile
);
826 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
827 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
828 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (subiter_name
)));
829 fragment
.append (new
CCodeExpressionStatement (iter_call
));
832 public void write_expression (CCodeFragment fragment
, DataType type
, CCodeExpression iter_expr
, CCodeExpression expr
) {
833 BasicTypeInfo basic_type
;
834 if (is_string_marshalled_enum (type
.data_type
)) {
835 get_basic_type_info ("s", out basic_type
);
836 var result
= generate_enum_value_to_string (fragment
, type as EnumValueType
, expr
);
837 write_basic (fragment
, basic_type
, iter_expr
, result
);
838 } else if (get_basic_type_info (get_type_signature (type
), out basic_type
)) {
839 write_basic (fragment
, basic_type
, iter_expr
, expr
);
840 } else if (type is ArrayType
) {
841 write_array (fragment
, (ArrayType
) type
, iter_expr
, expr
);
842 } else if (type
.data_type is Struct
) {
845 st_expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, st_expr
);
847 if (type
.data_type
.get_full_name () == "GLib.Value") {
848 write_value (fragment
, iter_expr
, st_expr
);
850 write_struct (fragment
, (Struct
) type
.data_type
, iter_expr
, st_expr
);
852 } else if (type is ObjectType
) {
853 if (type
.data_type
.get_full_name () == "GLib.HashTable") {
854 write_hash_table (fragment
, (ObjectType
) type
, iter_expr
, expr
);
857 Report
.error (type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (type
.to_string ()));