girwriter: Don't use constructor tag with structs
[vala-lang.git] / codegen / valagdbusmodule.vala
blob9f1328108d2c97592fbb97ae973287573bb4426c
1 /* valagdbusmodule.vala
3 * Copyright (C) 2010 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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 public class Vala.GDBusModule : GVariantModule {
24 public static string? get_dbus_name (TypeSymbol symbol) {
25 var dbus = symbol.get_attribute ("DBus");
26 if (dbus == null) {
27 return null;
30 return dbus.get_string ("name");
33 public static string get_dbus_name_for_member (Symbol symbol) {
34 var dbus = symbol.get_attribute ("DBus");
35 if (dbus != null && dbus.has_argument ("name")) {
36 return dbus.get_string ("name");
39 return Symbol.lower_case_to_camel_case (symbol.name);
42 public static bool is_dbus_no_reply (Method m) {
43 var dbus_attribute = m.get_attribute ("DBus");
44 if (dbus_attribute != null
45 && dbus_attribute.has_argument ("no_reply")
46 && dbus_attribute.get_bool ("no_reply")) {
47 return true;
50 return false;
53 public override void visit_error_domain (ErrorDomain edomain) {
54 var edomain_dbus_name = get_dbus_name (edomain);
55 if (edomain_dbus_name == null) {
56 base.visit_error_domain (edomain);
57 return;
60 generate_error_domain_declaration (edomain, cfile);
62 if (!edomain.is_internal_symbol ()) {
63 generate_error_domain_declaration (edomain, header_file);
65 if (!edomain.is_private_symbol ()) {
66 generate_error_domain_declaration (edomain, internal_header_file);
69 var error_entries = new CCodeInitializerList ();
70 foreach (ErrorCode ecode in edomain.get_codes ()) {
71 var ecode_dbus_name = get_dbus_name (ecode);
72 if (ecode_dbus_name == null) {
73 ecode_dbus_name = Symbol.lower_case_to_camel_case (ecode.name.down ());
76 var error_entry = new CCodeInitializerList ();
77 error_entry.append (new CCodeIdentifier (ecode.get_cname ()));
78 error_entry.append (new CCodeConstant ("\"%s.%s\"".printf (edomain_dbus_name, ecode_dbus_name)));
79 error_entries.append (error_entry);
82 var cdecl = new CCodeDeclaration ("const GDBusErrorEntry");
83 cdecl.add_declarator (new CCodeVariableDeclarator (edomain.get_lower_case_cname () + "_entries[]", error_entries));
84 cdecl.modifiers = CCodeModifiers.STATIC;
85 cfile.add_constant_declaration (cdecl);
87 string quark_fun_name = edomain.get_lower_case_cprefix () + "quark";
89 var cquark_fun = new CCodeFunction (quark_fun_name, gquark_type.data_type.get_cname ());
90 var cquark_block = new CCodeBlock ();
92 string quark_name = "%squark_volatile".printf (edomain.get_lower_case_cprefix ());
94 cdecl = new CCodeDeclaration ("gsize");
95 cdecl.add_declarator (new CCodeVariableDeclarator (quark_name, new CCodeConstant ("0")));
96 cdecl.modifiers = CCodeModifiers.STATIC | CCodeModifiers.VOLATILE;
97 cquark_block.add_statement (cdecl);
99 var register_call = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_error_register_error_domain"));
100 register_call.add_argument (new CCodeConstant ("\"" + edomain.get_lower_case_cname () + "-quark\""));
101 register_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (quark_name)));
102 register_call.add_argument (new CCodeIdentifier (edomain.get_lower_case_cname () + "_entries"));
103 var nentries = new CCodeFunctionCall (new CCodeIdentifier ("G_N_ELEMENTS"));
104 nentries.add_argument (new CCodeIdentifier (edomain.get_lower_case_cname () + "_entries"));
105 register_call.add_argument (nentries);
106 cquark_block.add_statement (new CCodeExpressionStatement (register_call));
108 cquark_block.add_statement (new CCodeReturnStatement (new CCodeCastExpression (new CCodeIdentifier (quark_name), "GQuark")));
110 cquark_fun.block = cquark_block;
111 cfile.add_function (cquark_fun);
114 bool is_file_descriptor (DataType type) {
115 if (type is ObjectType) {
116 if (type.data_type.get_full_name () == "GLib.UnixInputStream" ||
117 type.data_type.get_full_name () == "GLib.UnixOutputStream" ||
118 type.data_type.get_full_name () == "GLib.Socket") {
119 return true;
123 return false;
126 public bool dbus_method_uses_file_descriptor (Method method) {
127 foreach (Parameter param in method.get_parameters ()) {
128 if (is_file_descriptor (param.variable_type)) {
129 return true;
133 if (is_file_descriptor (method.return_type)) {
134 return true;
137 return false;
140 CCodeExpression? get_file_descriptor (DataType type, CCodeExpression expr) {
141 if (type is ObjectType) {
142 if (type.data_type.get_full_name () == "GLib.UnixInputStream") {
143 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_input_stream_get_fd"));
144 result.add_argument (expr);
145 return result;
146 } else if (type.data_type.get_full_name () == "GLib.UnixOutputStream") {
147 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_output_stream_get_fd"));
148 result.add_argument (expr);
149 return result;
150 } else if (type.data_type.get_full_name () == "GLib.Socket") {
151 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_socket_get_fd"));
152 result.add_argument (expr);
153 return result;
157 return null;
160 public void send_dbus_value (DataType type, CCodeExpression builder_expr, CCodeExpression expr, Symbol? sym) {
161 var fd = get_file_descriptor (type, expr);
162 if (fd != null) {
163 // add file descriptor to the file descriptor list
164 var fd_append = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_append"));
165 fd_append.add_argument (new CCodeIdentifier ("_fd_list"));
166 fd_append.add_argument (fd);
167 fd_append.add_argument (new CCodeConstant ("NULL"));
169 // add index to file descriptor to gvariant
170 var builder_add = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add"));
171 builder_add.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, builder_expr));
172 builder_add.add_argument (new CCodeConstant ("\"h\""));
173 builder_add.add_argument (fd_append);
174 ccode.add_expression (builder_add);
175 } else {
176 write_expression (type, builder_expr, expr, sym);
180 CCodeExpression? create_from_file_descriptor (DataType type, CCodeExpression expr) {
181 if (type is ObjectType) {
182 if (type.data_type.get_full_name () == "GLib.UnixInputStream") {
183 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_input_stream_new"));
184 result.add_argument (expr);
185 result.add_argument (new CCodeConstant ("TRUE"));
186 return new CCodeCastExpression (result, "GUnixInputStream *");
187 } else if (type.data_type.get_full_name () == "GLib.UnixOutputStream") {
188 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_output_stream_new"));
189 result.add_argument (expr);
190 result.add_argument (new CCodeConstant ("TRUE"));
191 return new CCodeCastExpression (result, "GUnixOutputStream *");
192 } else if (type.data_type.get_full_name () == "GLib.Socket") {
193 var result = new CCodeFunctionCall (new CCodeIdentifier ("g_socket_new_from_fd"));
194 result.add_argument (expr);
195 result.add_argument (new CCodeConstant ("NULL"));
196 return result;
200 return null;
203 public void receive_dbus_value (DataType type, CCodeExpression message_expr, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol? sym, CCodeExpression? error_expr = null, out bool may_fail = null) {
204 var fd_list = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_get_unix_fd_list"));
205 fd_list.add_argument (message_expr);
207 var fd = new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_get"));
208 fd.add_argument (fd_list);
209 fd.add_argument (new CCodeIdentifier ("_fd_index"));
210 fd.add_argument (new CCodeConstant ("NULL"));
212 var stream = create_from_file_descriptor (type, fd);
213 if (stream != null) {
214 var get_fd = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_next"));
215 get_fd.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, iter_expr));
216 get_fd.add_argument (new CCodeConstant ("\"h\""));
217 get_fd.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_fd_index")));
218 ccode.add_expression (get_fd);
220 ccode.add_assignment (target_expr, stream);
221 } else {
222 read_expression (type, iter_expr, target_expr, sym, error_expr, out may_fail);