dbustypes.py 17.2 KB
Newer Older
David Zeuthen's avatar
David Zeuthen committed
1 2
# -*- Mode: Python -*-

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# GDBus - GLib D-Bus Library
#
# Copyright (C) 2008-2011 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA 02111-1307, USA.
#
# Author: David Zeuthen <davidz@redhat.com>

24
from . import utils
David Zeuthen's avatar
David Zeuthen committed
25 26 27 28 29 30 31 32 33 34 35 36 37

class Annotation:
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.annotations = []

class Arg:
    def __init__(self, name, signature):
        self.name = name
        self.signature = signature
        self.annotations = []
        self.doc_string = ''
38
        self.since = ''
David Zeuthen's avatar
David Zeuthen committed
39

40
    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, arg_number):
David Zeuthen's avatar
David Zeuthen committed
41 42
        if len(self.doc_string) == 0:
            self.doc_string = utils.lookup_docs(self.annotations)
43 44
        if len(self.since) == 0:
            self.since = utils.lookup_since(self.annotations)
David Zeuthen's avatar
David Zeuthen committed
45 46 47 48 49 50

        if self.name == None:
            self.name = 'unnamed_arg%d'%arg_number
        # default to GVariant
        self.ctype_in_g  = 'GVariant *'
        self.ctype_in  = 'GVariant *'
51
        self.ctype_in_dup  = 'GVariant *'
David Zeuthen's avatar
David Zeuthen committed
52 53 54 55 56
        self.ctype_out = 'GVariant **'
        self.gtype = 'G_TYPE_VARIANT'
        self.free_func = 'g_variant_unref'
        self.format_in = '@' + self.signature
        self.format_out = '@' + self.signature
57 58
        self.gvariant_get = 'XXX'
        self.gvalue_get = 'g_value_get_variant'
David Zeuthen's avatar
David Zeuthen committed
59 60 61 62 63 64 65 66 67
        if not utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.ForceGVariant'):
            if self.signature == 'b':
                self.ctype_in_g  = 'gboolean '
                self.ctype_in  = 'gboolean '
                self.ctype_out = 'gboolean *'
                self.gtype = 'G_TYPE_BOOLEAN'
                self.free_func = None
                self.format_in = 'b'
                self.format_out = 'b'
68 69
                self.gvariant_get = 'g_variant_get_boolean'
                self.gvalue_get = 'g_value_get_boolean'
David Zeuthen's avatar
David Zeuthen committed
70 71 72 73 74 75 76 77
            elif self.signature == 'y':
                self.ctype_in_g  = 'guchar '
                self.ctype_in  = 'guchar '
                self.ctype_out = 'guchar *'
                self.gtype = 'G_TYPE_UCHAR'
                self.free_func = None
                self.format_in = 'y'
                self.format_out = 'y'
78 79
                self.gvariant_get = 'g_variant_get_byte'
                self.gvalue_get = 'g_value_get_uchar'
David Zeuthen's avatar
David Zeuthen committed
80 81 82 83 84 85 86 87
            elif self.signature == 'n':
                self.ctype_in_g  = 'gint '
                self.ctype_in  = 'gint16 '
                self.ctype_out = 'gint16 *'
                self.gtype = 'G_TYPE_INT'
                self.free_func = None
                self.format_in = 'n'
                self.format_out = 'n'
88 89
                self.gvariant_get = 'g_variant_get_int16'
                self.gvalue_get = 'g_value_get_int'
David Zeuthen's avatar
David Zeuthen committed
90 91 92 93 94 95 96 97
            elif self.signature == 'q':
                self.ctype_in_g  = 'guint '
                self.ctype_in  = 'guint16 '
                self.ctype_out = 'guint16 *'
                self.gtype = 'G_TYPE_UINT'
                self.free_func = None
                self.format_in = 'q'
                self.format_out = 'q'
98 99
                self.gvariant_get = 'g_variant_get_uint16'
                self.gvalue_get = 'g_value_get_uint'
David Zeuthen's avatar
David Zeuthen committed
100 101 102 103 104 105 106 107
            elif self.signature == 'i':
                self.ctype_in_g  = 'gint '
                self.ctype_in  = 'gint '
                self.ctype_out = 'gint *'
                self.gtype = 'G_TYPE_INT'
                self.free_func = None
                self.format_in = 'i'
                self.format_out = 'i'
108 109
                self.gvariant_get = 'g_variant_get_int32'
                self.gvalue_get = 'g_value_get_int'
David Zeuthen's avatar
David Zeuthen committed
110 111 112 113 114 115 116 117
            elif self.signature == 'u':
                self.ctype_in_g  = 'guint '
                self.ctype_in  = 'guint '
                self.ctype_out = 'guint *'
                self.gtype = 'G_TYPE_UINT'
                self.free_func = None
                self.format_in = 'u'
                self.format_out = 'u'
118 119
                self.gvariant_get = 'g_variant_get_uint32'
                self.gvalue_get = 'g_value_get_uint'
David Zeuthen's avatar
David Zeuthen committed
120 121 122 123 124 125 126 127
            elif self.signature == 'x':
                self.ctype_in_g  = 'gint64 '
                self.ctype_in  = 'gint64 '
                self.ctype_out = 'gint64 *'
                self.gtype = 'G_TYPE_INT64'
                self.free_func = None
                self.format_in = 'x'
                self.format_out = 'x'
128 129
                self.gvariant_get = 'g_variant_get_int64'
                self.gvalue_get = 'g_value_get_int64'
David Zeuthen's avatar
David Zeuthen committed
130 131 132 133 134 135 136 137
            elif self.signature == 't':
                self.ctype_in_g  = 'guint64 '
                self.ctype_in  = 'guint64 '
                self.ctype_out = 'guint64 *'
                self.gtype = 'G_TYPE_UINT64'
                self.free_func = None
                self.format_in = 't'
                self.format_out = 't'
138 139
                self.gvariant_get = 'g_variant_get_uint64'
                self.gvalue_get = 'g_value_get_uint64'
David Zeuthen's avatar
David Zeuthen committed
140 141 142 143 144 145 146 147
            elif self.signature == 'd':
                self.ctype_in_g  = 'gdouble '
                self.ctype_in  = 'gdouble '
                self.ctype_out = 'gdouble *'
                self.gtype = 'G_TYPE_DOUBLE'
                self.free_func = None
                self.format_in = 'd'
                self.format_out = 'd'
148 149
                self.gvariant_get = 'g_variant_get_double'
                self.gvalue_get = 'g_value_get_double'
David Zeuthen's avatar
David Zeuthen committed
150 151 152
            elif self.signature == 's':
                self.ctype_in_g  = 'const gchar *'
                self.ctype_in  = 'const gchar *'
153
                self.ctype_in_dup  = 'gchar *'
David Zeuthen's avatar
David Zeuthen committed
154 155 156 157 158
                self.ctype_out = 'gchar **'
                self.gtype = 'G_TYPE_STRING'
                self.free_func = 'g_free'
                self.format_in = 's'
                self.format_out = 's'
159 160
                self.gvariant_get = 'g_variant_get_string'
                self.gvalue_get = 'g_value_get_string'
David Zeuthen's avatar
David Zeuthen committed
161 162 163
            elif self.signature == 'o':
                self.ctype_in_g  = 'const gchar *'
                self.ctype_in  = 'const gchar *'
164
                self.ctype_in_dup  = 'gchar *'
David Zeuthen's avatar
David Zeuthen committed
165 166 167 168 169
                self.ctype_out = 'gchar **'
                self.gtype = 'G_TYPE_STRING'
                self.free_func = 'g_free'
                self.format_in = 'o'
                self.format_out = 'o'
170 171
                self.gvariant_get = 'g_variant_get_string'
                self.gvalue_get = 'g_value_get_string'
David Zeuthen's avatar
David Zeuthen committed
172 173 174
            elif self.signature == 'g':
                self.ctype_in_g  = 'const gchar *'
                self.ctype_in  = 'const gchar *'
175
                self.ctype_in_dup  = 'gchar *'
David Zeuthen's avatar
David Zeuthen committed
176 177 178 179 180
                self.ctype_out = 'gchar **'
                self.gtype = 'G_TYPE_STRING'
                self.free_func = 'g_free'
                self.format_in = 'g'
                self.format_out = 'g'
181 182
                self.gvariant_get = 'g_variant_get_string'
                self.gvalue_get = 'g_value_get_string'
David Zeuthen's avatar
David Zeuthen committed
183 184 185
            elif self.signature == 'ay':
                self.ctype_in_g  = 'const gchar *'
                self.ctype_in  = 'const gchar *'
186
                self.ctype_in_dup  = 'gchar *'
David Zeuthen's avatar
David Zeuthen committed
187 188 189 190 191
                self.ctype_out = 'gchar **'
                self.gtype = 'G_TYPE_STRING'
                self.free_func = 'g_free'
                self.format_in = '^ay'
                self.format_out = '^ay'
192 193
                self.gvariant_get = 'g_variant_get_bytestring'
                self.gvalue_get = 'g_value_get_string'
David Zeuthen's avatar
David Zeuthen committed
194 195 196
            elif self.signature == 'as':
                self.ctype_in_g  = 'const gchar *const *'
                self.ctype_in  = 'const gchar *const *'
197
                self.ctype_in_dup  = 'gchar **'
David Zeuthen's avatar
David Zeuthen committed
198 199 200 201 202
                self.ctype_out = 'gchar ***'
                self.gtype = 'G_TYPE_STRV'
                self.free_func = 'g_strfreev'
                self.format_in = '^as'
                self.format_out = '^as'
203 204
                self.gvariant_get = 'g_variant_get_strv'
                self.gvalue_get = 'g_value_get_boxed'
205 206 207
            elif self.signature == 'ao':
                self.ctype_in_g  = 'const gchar *const *'
                self.ctype_in  = 'const gchar *const *'
208
                self.ctype_in_dup  = 'gchar **'
209 210 211 212 213
                self.ctype_out = 'gchar ***'
                self.gtype = 'G_TYPE_STRV'
                self.free_func = 'g_strfreev'
                self.format_in = '^ao'
                self.format_out = '^ao'
214 215
                self.gvariant_get = 'g_variant_get_objv'
                self.gvalue_get = 'g_value_get_boxed'
David Zeuthen's avatar
David Zeuthen committed
216 217 218
            elif self.signature == 'aay':
                self.ctype_in_g  = 'const gchar *const *'
                self.ctype_in  = 'const gchar *const *'
219
                self.ctype_in_dup  = 'gchar **'
David Zeuthen's avatar
David Zeuthen committed
220 221 222 223 224
                self.ctype_out = 'gchar ***'
                self.gtype = 'G_TYPE_STRV'
                self.free_func = 'g_strfreev'
                self.format_in = '^aay'
                self.format_out = '^aay'
225 226
                self.gvariant_get = 'g_variant_get_bytestring_array'
                self.gvalue_get = 'g_value_get_boxed'
David Zeuthen's avatar
David Zeuthen committed
227 228 229 230 231 232 233 234

class Method:
    def __init__(self, name):
        self.name = name
        self.in_args = []
        self.out_args = []
        self.annotations = []
        self.doc_string = ''
235
        self.since = ''
236
        self.deprecated = False
David Zeuthen's avatar
David Zeuthen committed
237

238
    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
David Zeuthen's avatar
David Zeuthen committed
239 240
        if len(self.doc_string) == 0:
            self.doc_string = utils.lookup_docs(self.annotations)
241 242
        if len(self.since) == 0:
            self.since = utils.lookup_since(self.annotations)
243 244
            if len(self.since) == 0:
                self.since = containing_iface.since
David Zeuthen's avatar
David Zeuthen committed
245 246

        name = self.name
247 248 249 250 251 252 253
        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
        if utils.is_ugly_case(overridden_name):
            self.name_lower = overridden_name.lower()
        else:
            if overridden_name:
                name = overridden_name
            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
David Zeuthen's avatar
David Zeuthen committed
254 255 256 257
        self.name_hyphen = self.name_lower.replace('_', '-')

        arg_count = 0
        for a in self.in_args:
258
            a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
David Zeuthen's avatar
David Zeuthen committed
259 260 261
            arg_count += 1

        for a in self.out_args:
262
            a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
David Zeuthen's avatar
David Zeuthen committed
263 264
            arg_count += 1

265 266 267
        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
            self.deprecated = True

David Zeuthen's avatar
David Zeuthen committed
268 269 270 271 272 273
class Signal:
    def __init__(self, name):
        self.name = name
        self.args = []
        self.annotations = []
        self.doc_string = ''
274
        self.since = ''
275
        self.deprecated = False
David Zeuthen's avatar
David Zeuthen committed
276

277
    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
David Zeuthen's avatar
David Zeuthen committed
278 279
        if len(self.doc_string) == 0:
            self.doc_string = utils.lookup_docs(self.annotations)
280 281
        if len(self.since) == 0:
            self.since = utils.lookup_since(self.annotations)
282 283
            if len(self.since) == 0:
                self.since = containing_iface.since
David Zeuthen's avatar
David Zeuthen committed
284 285

        name = self.name
286 287 288 289 290 291 292
        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
        if utils.is_ugly_case(overridden_name):
            self.name_lower = overridden_name.lower()
        else:
            if overridden_name:
                name = overridden_name
            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
David Zeuthen's avatar
David Zeuthen committed
293 294 295 296
        self.name_hyphen = self.name_lower.replace('_', '-')

        arg_count = 0
        for a in self.args:
297
            a.post_process(interface_prefix, cns, cns_upper, cns_lower, arg_count)
David Zeuthen's avatar
David Zeuthen committed
298 299
            arg_count += 1

300 301 302
        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
            self.deprecated = True

David Zeuthen's avatar
David Zeuthen committed
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
class Property:
    def __init__(self, name, signature, access):
        self.name = name
        self.signature = signature
        self.access = access
        self.annotations = []
        self.arg = Arg('value', self.signature)
        self.arg.annotations = self.annotations
        self.readable = False
        self.writable = False
        if self.access == 'readwrite':
            self.readable = True
            self.writable = True
        elif self.access == 'read':
            self.readable = True
        elif self.access == 'write':
            self.writable = True
        else:
            raise RuntimeError('Invalid access type %s'%self.access)
        self.doc_string = ''
323
        self.since = ''
324
        self.deprecated = False
David Zeuthen's avatar
David Zeuthen committed
325

326
    def post_process(self, interface_prefix, cns, cns_upper, cns_lower, containing_iface):
David Zeuthen's avatar
David Zeuthen committed
327 328
        if len(self.doc_string) == 0:
            self.doc_string = utils.lookup_docs(self.annotations)
329 330
        if len(self.since) == 0:
            self.since = utils.lookup_since(self.annotations)
331 332
            if len(self.since) == 0:
                self.since = containing_iface.since
David Zeuthen's avatar
David Zeuthen committed
333 334

        name = self.name
335 336 337 338 339 340 341
        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
        if utils.is_ugly_case(overridden_name):
            self.name_lower = overridden_name.lower()
        else:
            if overridden_name:
                name = overridden_name
            self.name_lower = utils.camel_case_to_uscore(name).lower().replace('-', '_')
342 343
        self.name_hyphen = self.name_lower.replace('_', '-')
        # don't clash with the GType getter, e.g.: GType foo_bar_get_type (void); G_GNUC_CONST
344 345
        if self.name_lower == 'type':
            self.name_lower = 'type_'
David Zeuthen's avatar
David Zeuthen committed
346 347 348

        # recalculate arg
        self.arg.annotations = self.annotations
349
        self.arg.post_process(interface_prefix, cns, cns_upper, cns_lower, 0)
David Zeuthen's avatar
David Zeuthen committed
350

351 352 353
        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
            self.deprecated = True

David Zeuthen's avatar
David Zeuthen committed
354 355 356 357 358 359 360 361 362
class Interface:
    def __init__(self, name):
        self.name = name
        self.methods = []
        self.signals = []
        self.properties = []
        self.annotations = []
        self.doc_string = ''
        self.doc_string_brief = ''
363
        self.since = ''
364
        self.deprecated = False
David Zeuthen's avatar
David Zeuthen committed
365 366 367 368 369 370

    def post_process(self, interface_prefix, c_namespace):
        if len(self.doc_string) == 0:
            self.doc_string = utils.lookup_docs(self.annotations)
        if len(self.doc_string_brief) == 0:
            self.doc_string_brief = utils.lookup_brief_docs(self.annotations)
371 372
        if len(self.since) == 0:
            self.since = utils.lookup_since(self.annotations)
David Zeuthen's avatar
David Zeuthen committed
373

374 375 376 377 378 379 380 381 382 383 384 385 386 387
        if len(c_namespace) > 0:
            if utils.is_ugly_case(c_namespace):
                cns = c_namespace.replace('_', '')
                cns_upper = c_namespace.upper() + '_'
                cns_lower = c_namespace.lower() + '_'
            else:
                cns = c_namespace
                cns_upper = utils.camel_case_to_uscore(c_namespace).upper() + '_'
                cns_lower = utils.camel_case_to_uscore(c_namespace).lower() + '_'
        else:
            cns = ''
            cns_upper = ''
            cns_lower = ''

388 389 390
        overridden_name = utils.lookup_annotation(self.annotations, 'org.gtk.GDBus.C.Name')
        if utils.is_ugly_case(overridden_name):
            name = overridden_name.replace('_', '')
391
            name_with_ns = cns + name
392 393
            self.name_without_prefix = name
            self.camel_name = name_with_ns
394 395
            self.ns_upper = cns_upper
            self.name_lower = cns_lower + overridden_name.lower()
396
            self.name_upper = overridden_name.upper()
David Zeuthen's avatar
David Zeuthen committed
397

398
            #raise RuntimeError('handle Ugly_Case ', overridden_name)
David Zeuthen's avatar
David Zeuthen committed
399
        else:
400 401 402 403 404 405 406 407
            if overridden_name:
                name = overridden_name
            else:
                name = self.name
                if name.startswith(interface_prefix):
                    name = name[len(interface_prefix):]
            self.name_without_prefix = name
            name = utils.strip_dots(name)
408
            name_with_ns = utils.strip_dots(cns + '.' + name)
409
            self.camel_name = name_with_ns
410 411
            self.ns_upper = cns_upper
            self.name_lower = cns_lower + utils.camel_case_to_uscore(name)
412
            self.name_upper = utils.camel_case_to_uscore(name).upper()
David Zeuthen's avatar
David Zeuthen committed
413

414 415
        self.name_hyphen = self.name_upper.lower().replace('_', '-')

416 417 418
        if utils.lookup_annotation(self.annotations, 'org.freedesktop.DBus.Deprecated') == 'true':
            self.deprecated = True

David Zeuthen's avatar
David Zeuthen committed
419
        for m in self.methods:
420
            m.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
David Zeuthen's avatar
David Zeuthen committed
421 422

        for s in self.signals:
423
            s.post_process(interface_prefix, cns, cns_upper, cns_lower, self)
David Zeuthen's avatar
David Zeuthen committed
424 425

        for p in self.properties:
426
            p.post_process(interface_prefix, cns, cns_upper, cns_lower, self)