* dbus/Python.pyx: Fixed memory leaks when throwing errors.
[platform/upstream/dbus.git] / python / dbus_bindings.pyx
1 # -*- Mode: Python -*-
2
3 # jdahlin is the most coolest and awesomest person in the world
4 # and wrote all the good parts of this code. all the bad parts
5 # where python conditionals have a ( ) around them, thus violating
6 # PEP-8 were written by the lame wannabe python programmer seth
7
8 #FIXME: find memory leaks that I am sure exist
9
10 cdef extern from "sys/types.h":
11     ctypedef size_t
12     ctypedef __int64_t
13     ctypedef __uint64_t
14
15 cdef extern from "sys/cdefs.h":
16     ctypedef __signed
17
18 cdef extern from "stdlib.h":
19     cdef void *malloc(size_t size)
20     cdef void free(void *ptr)
21     cdef void *calloc(size_t nmemb, size_t size)
22
23 cdef extern from "Python.h":
24     void Py_XINCREF (object)
25     void Py_XDECREF (object)
26     object PyString_FromStringAndSize(char *, int)
27     ctypedef void *PyGILState_STATE
28     void PyErr_Clear()
29     PyGILState_STATE PyGILState_Ensure()
30     void PyGILState_Release(PyGILState_STATE)
31
32 ctypedef struct DBusError:
33     char *name
34     char *message
35     unsigned int dummy1 
36     unsigned int dummy2
37     unsigned int dummy3
38     unsigned int dummy4
39     unsigned int dummy5
40     void *padding1
41     
42 ctypedef struct DBusMessageIter:
43     void *dummy1
44     void *dummy2
45     dbus_uint32_t dummy3
46     int dummy4
47     int dummy5
48     int dummy6
49     int dummy7
50     int dummy8
51     int dummy9
52     int dummy10
53     int dummy11
54     int pad1
55     int pad2
56     void *pad3
57
58 ctypedef struct DBusObjectPathVTable:
59   DBusObjectPathUnregisterFunction   unregister_function
60   DBusObjectPathMessageFunction      message_function
61   void (* dbus_internal_pad1) (void *)
62   void (* dbus_internal_pad2) (void *)
63   void (* dbus_internal_pad3) (void *)
64   void (* dbus_internal_pad4) (void *)
65
66 class DBusException(Exception):
67     pass
68
69 class ConnectionError(Exception):
70     pass
71
72 class ObjectPath(str):
73     def __init__(self, value):
74         str.__init__(self, value)
75
76 class ByteArray(str):
77     def __init__(self, value):
78         str.__init__(self, value)
79
80 class Signature(str):
81     def __init__(self, value):
82         str.__init__(self, value)
83
84 class Byte(int):
85     def __init__(self, value):
86         int.__init__(self, value)
87
88 class Boolean(int):
89     def __init__(self, value):
90         int.__init__(self, value)
91
92 class Int16(int):
93     def __init__(self, value):
94         int.__init__(self, value)
95
96 class UInt16(int):
97     def __init__(self, value):
98         if value < 0:
99             raise TypeError('Unsigned integers must not have a negitive value') 
100         int.__init__(self, value)
101
102 class Int32(int):
103     def __init__(self, value):
104         int.__init__(self, value)
105
106 class UInt32(long):
107     def __init__(self, value):
108         if value < 0:
109             raise TypeError('Unsigned integers must not have a negitive value') 
110         long.__init__(self, value)
111
112 class Int64(long):
113     def __init__(self, value):
114         long.__init__(self, value)
115
116 class UInt64(long):
117     def __init__(self, value):
118         if value < 0:
119             raise TypeError('Unsigned integers must not have a negitive value') 
120         long.__init__(self, value)
121
122 class Double(float):
123     def __init__(self, value):
124         float.__init__(self, value)
125
126 class String(str):
127     def __init__(self, value):
128         str.__init__(self, value)
129
130 class Array(list):
131     def __init__(self, value, type=None, signature=None):
132         if signature and type:
133             raise TypeError('Can not mix type and signature arguments in a D-BUS Array')
134     
135         self.type = type
136         self.signature = signature
137         list.__init__(self, value)
138
139 class Variant:
140     def __init__(self, value, type=None, signature=None):
141         self.value = value
142         if signature and type:
143             raise TypeError('Can not mix type and signature arguments in a D-BUS Variant')
144
145         self.type = type
146         self.signature = signature
147
148     def __repr__(self):
149         return repr(self.value)
150
151     def __str__(self):
152         return str(self.value)
153
154 class Struct(tuple):
155     def __init__(self, value):
156         tuple.__init__(self, value)
157
158 class Dictionary(dict):
159     def __init__(self, value, key_type=None, value_type=None, signature=None):
160         if key_type and not value_type:
161              raise TypeError('When specifying a key_type you must also have a value_type in a D-BUS Dictionary')
162         elif value_type and not key_type:
163              raise TypeError('When specifying a value_type you must also have a key_type in a D-BUS Dictionary')
164         elif key_type and signature:
165               raise TypeError('Can not mix type arguments with signature arguments in a D-BUS Dictionary')
166               
167         self.key_type = key_type
168         self.value_type = value_type
169         self.signature = signature
170         dict.__init__(self, value)
171
172 #forward delcerations
173 cdef class Message
174 cdef class PendingCall
175 cdef class Watch
176 cdef class MessageIter
177
178 cdef void _GIL_safe_cunregister_function_handler (DBusConnection *connection,
179                                                   void *user_data):
180     cdef Connection conn
181
182     tup = <object>user_data
183     assert (type(tup) == tuple)    
184     function = tup[1]
185     conn = Connection()
186     conn.__cinit__(None, connection)
187
188     args = (conn)
189     function(*args)
190     Py_XDECREF(tup) 
191
192 cdef void cunregister_function_handler (DBusConnection *connection,
193                                         void *user_data):
194     cdef PyGILState_STATE gil
195     gil = PyGILState_Ensure()
196     try:
197         _GIL_safe_cunregister_function_handler (connection, user_data);
198     finally:
199         PyGILState_Release(gil)
200
201
202
203 cdef DBusHandlerResult _GIL_safe_cmessage_function_handler ( 
204                                                   DBusConnection *connection,
205                                                   DBusMessage *msg,
206                                                   void *user_data):
207     cdef Connection conn
208     cdef Message message
209
210     tup = <object>user_data
211     assert (type(tup) == tuple)
212     function = tup[0]
213     message = EmptyMessage()
214
215     #we don't own the message so we need to ref it
216     dbus_message_ref(msg)
217     message._set_msg(msg)
218     conn = Connection()
219     conn.__cinit__(None, connection)
220     args = (conn,
221             message)
222  
223     retval = function(*args)
224
225     if (retval == None):
226         retval = DBUS_HANDLER_RESULT_HANDLED
227     return retval
228
229 cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
230                                                   DBusMessage *msg,
231                                                   void *user_data):
232     cdef PyGILState_STATE gil
233     gil = PyGILState_Ensure()
234     try:
235         return _GIL_safe_cmessage_function_handler (connection, msg, user_data);
236     finally:
237         PyGILState_Release(gil)
238
239
240 cdef class Connection:
241     def __init__(self, address=None, Connection _conn=None):
242         cdef DBusConnection *c_conn
243         cdef char *c_address
244         c_conn=NULL
245         self.conn = NULL
246         if (_conn != None):
247             c_conn = _conn.conn
248
249         if (address != None or _conn != None):
250             self.__cinit__(c_address, c_conn)
251
252     # hack to be able to pass in a c pointer to the constructor
253     # while still alowing python programs to create a Connection object
254     cdef __cinit__(self, address, DBusConnection *_conn):
255         cdef DBusError error
256         dbus_error_init(&error)
257         if _conn != NULL:
258             self.conn = _conn
259             dbus_connection_ref(self.conn)
260         else:
261             self.conn = dbus_connection_open(address,
262                                          &error)
263             if dbus_error_is_set(&error):
264                 message = error.message
265                 dbus_error_free (&error)
266                 raise DBusException, message
267
268     def __dealloc__(self):
269         if self.conn != NULL:
270             dbus_connection_unref(self.conn)
271
272     cdef _set_conn(self, DBusConnection *conn):
273         self.conn = conn
274     
275     cdef DBusConnection *_get_conn(self):
276         return self.conn
277     
278     def get_unique_name(self):
279         return bus_get_unique_name(self)
280
281     def disconnect(self):
282         dbus_connection_disconnect(self.conn)
283
284     def get_is_connected(self):
285         return dbus_connection_get_is_connected(self.conn)
286     
287     def get_is_authenticated(self):
288         return dbus_connection_get_is_authenticated(self.conn)
289
290     def flush(self):
291         dbus_connection_flush(self.conn)
292
293     def borrow_message(self):
294         cdef Message m
295         m = EmptyMessage()
296         m._set_msg(dbus_connection_borrow_message(self.conn))
297         return m
298     
299     def return_message(self, Message message):
300         cdef DBusMessage *msg
301         msg = message._get_msg()
302         dbus_connection_return_message(self.conn, msg)
303
304     def steal_borrowed_message(self, Message message):
305         cdef DBusMessage *msg
306         msg = message._get_msg()
307         dbus_connection_steal_borrowed_message(self.conn,
308                                                msg)
309     
310     def pop_message(self):
311         cdef DBusMessage *msg
312         cdef Message m
313  
314         msg = dbus_connection_pop_message(self.conn)
315         if msg != NULL:
316             m = EmptyMessage()
317             m._set_msg(msg)
318         else:
319             m = None
320         return m        
321
322     def get_dispatch_status(self):
323         return dbus_connection_get_dispatch_status(self.conn)
324     
325     def dispatch(self):
326         return dbus_connection_dispatch(self.conn)
327
328     def send(self, Message message):
329         #cdef dbus_uint32_t client_serial
330         #if type(message) != Message:
331         #    raise TypeError
332         cdef DBusMessage *msg
333         msg = message._get_msg()
334         retval = dbus_connection_send(self.conn,
335                                       msg,
336                                       NULL)
337         return retval
338
339     def send_with_reply_handlers(self, Message message, timeout_milliseconds, reply_handler, error_handler):
340         retval = False
341         try:
342             (retval, pending_call) = self.send_with_reply(message, timeout_milliseconds)
343             if pending_call:
344                 pending_call.set_notify(reply_handler, error_handler)
345         except Exception, e:
346             error_handler(e)
347             
348         return (retval, pending_call)
349
350     def send_with_reply(self, Message message, timeout_milliseconds):
351         cdef dbus_bool_t retval
352         cdef DBusPendingCall *cpending_call
353         cdef DBusMessage *msg
354         cdef PendingCall pending_call
355
356         cpending_call = NULL
357         
358         msg = message._get_msg()
359
360         retval = dbus_connection_send_with_reply(self.conn,
361                                                  msg,
362                                                  &cpending_call,
363                                                  timeout_milliseconds)
364
365         if (cpending_call != NULL):
366             pending_call = PendingCall()
367             pending_call.__cinit__(cpending_call)
368         else:
369             pending_call = None
370
371         return (retval, pending_call)
372                                 
373     def send_with_reply_and_block(self, Message message,
374                                   timeout_milliseconds=-1):
375         cdef DBusMessage * retval
376         cdef DBusError error
377         cdef DBusMessage *msg
378         cdef Message m
379
380         dbus_error_init(&error)
381
382         msg = message._get_msg()
383
384         retval = dbus_connection_send_with_reply_and_block(
385             self.conn,
386             msg,
387             timeout_milliseconds,
388             &error)
389
390         if dbus_error_is_set(&error):
391             message = error.message
392             dbus_error_free (&error)
393             raise DBusException, message
394
395         if retval == NULL:
396             raise AssertionError
397         
398         m = EmptyMessage()
399         m._set_msg(retval)
400
401         return m 
402
403     def set_watch_functions(self, add_function, remove_function, data):
404         pass
405
406     def set_timeout_functions(self, add_function, remove_function, data):
407         pass
408
409     def set_wakeup_main_function(self, wakeup_main_function, data):
410         pass
411
412     # FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
413
414     def add_filter(self, filter_function):
415         user_data = (filter_function,)
416         Py_XINCREF(user_data)
417        
418         return dbus_connection_add_filter(self.conn,
419                                           cmessage_function_handler,
420                                           <void*>user_data,
421                                           NULL)
422
423
424     #FIXME: remove_filter
425     #       this is pretty tricky, we want to only remove the filter
426     #       if we truly have no more calls to our message_function_handler...ugh
427
428     def set_data(self, slot, data):
429         pass
430
431     def get_data(self, slot):
432         pass
433
434     def set_max_message_size(self, size):
435         dbus_connection_set_max_message_size(self.conn, size)
436
437     def get_max_message_size(self):
438         return dbus_connection_get_max_message_size(self.conn)
439
440     def set_max_received_size(self, size):
441         dbus_connection_set_max_received_size(self.conn, size)
442
443     def get_max_received_size(self):
444         return dbus_connection_get_max_received_size(self.conn)
445
446     def get_outgoing_size(self):
447         return dbus_connection_get_outgoing_size(self.conn)    
448
449     # preallocate_send, free_preallocated_send, send_preallocated
450
451     def register_object_path(self, path, unregister_cb, message_cb):
452         cdef DBusObjectPathVTable cvtable
453         
454         cvtable.unregister_function = cunregister_function_handler 
455         cvtable.message_function    = cmessage_function_handler
456
457         user_data = (message_cb, unregister_cb)
458         Py_XINCREF(user_data)
459         
460         return dbus_connection_register_object_path(self.conn, path, &cvtable,
461                                                     <void*>user_data) 
462
463     def register_fallback(self, path, unregister_cb, message_cb):
464         cdef DBusObjectPathVTable cvtable
465
466         cvtable.unregister_function = cunregister_function_handler 
467         cvtable.message_function    = cmessage_function_handler
468
469         user_data = (message_cb, unregister_cb)
470         Py_XINCREF(user_data)
471        
472         return dbus_connection_register_fallback(self.conn, path, &cvtable,
473                                                  <void*>user_data) 
474
475     #FIXME: unregister_object_path , see problems with remove_filter
476
477     def list_registered (self, parent_path):
478         cdef char **cchild_entries
479         cdef dbus_bool_t retval
480         
481         retval = dbus_connection_list_registered(self.conn, parent_path, &cchild_entries)
482
483         if (not retval):
484             #FIXME: raise out of memory exception?
485             return None
486
487         i = 0
488         child_entries = []
489
490         while (cchild_entries[i] != NULL):
491             child_entries.append(cchild_entries[i])
492             i = i + 1
493
494         dbus_free_string_array(cchild_entries)
495
496         return child_entries
497
498 cdef void _GIL_safe_pending_call_notification (DBusPendingCall *pending_call, 
499                                                void *user_data):
500     cdef DBusMessage *dbus_message
501     cdef Message message
502   
503     (reply_handler, error_handler) = <object>user_data
504    
505     dbus_message = dbus_pending_call_steal_reply(pending_call)
506     message = EmptyMessage()
507     message._set_msg(dbus_message)
508
509     type = message.get_type()
510
511     if type == MESSAGE_TYPE_METHOD_RETURN:
512         args = message.get_args_list()
513         reply_handler(*args)
514     elif type == MESSAGE_TYPE_ERROR:
515         args = message.get_args_list()
516         if len(args) > 0:
517             error_handler(DBusException(args[0]))
518         else:
519             error_handler(DBusException(""))
520     else:
521         error_handler(DBusException('Unexpected Message Type: ' + message.type_to_name(type)))
522
523     dbus_pending_call_unref(pending_call)
524     Py_XDECREF(<object>user_data)
525
526 cdef void _pending_call_notification(DBusPendingCall *pending_call, 
527                                      void *user_data):
528     cdef PyGILState_STATE gil
529     gil = PyGILState_Ensure()
530     try:
531         _GIL_safe_pending_call_notification (pending_call, user_data);
532     finally:
533         PyGILState_Release(gil)
534
535 cdef void _pending_call_free_user_data(void *data):
536     call_tuple = <object>data
537     Py_XDECREF(call_tuple)
538
539 cdef class PendingCall:
540     cdef DBusPendingCall *pending_call
541
542     def __init__(self, PendingCall _pending_call=None):
543         self.pending_call = NULL
544         if (_pending_call != None):
545             self.__cinit__(_pending_call.pending_call)
546
547     cdef void __cinit__(self, DBusPendingCall *_pending_call):
548         self.pending_call = _pending_call
549         dbus_pending_call_ref(self.pending_call)
550
551     def __dealloc__(self):
552         if self.pending_call != NULL:
553             dbus_pending_call_unref(self.pending_call)
554
555     cdef DBusPendingCall *_get_pending_call(self):
556         return self.pending_call
557
558     def cancel(self):
559         dbus_pending_call_cancel(self.pending_call)
560
561     def get_completed(self):
562         return dbus_pending_call_get_completed(self.pending_call)
563
564     def get_reply(self):
565         cdef Message message
566         message = EmptyMessage()
567         message._set_msg(dbus_pending_call_steal_reply(self.pending_call))
568         return message
569
570     def block(self):
571         dbus_pending_call_block(self.pending_call)
572
573     def set_notify(self, reply_handler, error_handler):
574         user_data = (reply_handler, error_handler)
575         Py_XINCREF(user_data)
576         dbus_pending_call_ref(self.pending_call)
577         dbus_pending_call_set_notify(self.pending_call, _pending_call_notification, 
578                                      <void *>user_data, _pending_call_free_user_data)
579         
580
581 cdef class Watch:
582     cdef DBusWatch* watch
583
584     def __init__(self):
585         pass
586
587     cdef __cinit__(self, DBusWatch *cwatch):
588         self.watch = cwatch
589
590     def get_fd(self):
591         return dbus_watch_get_fd(self.watch)
592
593     # FIXME: not picked up correctly by extract.py
594     #def get_flags(self):
595     #    return dbus_watch_get_flags(self.watch)
596
597     def handle(self, flags):
598         return dbus_watch_handle(self.watch, flags)
599
600     def get_enabled(self):
601         return dbus_watch_get_enabled(self.watch)
602     
603 cdef class MessageIter:
604     cdef DBusMessageIter *iter
605     cdef DBusMessageIter real_iter
606     cdef dbus_uint32_t level
607
608     def __init__(self, level=0):
609         self.iter = &self.real_iter
610         self.level = level
611         if(self.level > 32):
612             raise TypeError, 'Type recurion is too deep' 
613
614     cdef __cinit__(self, DBusMessageIter *iter):
615         self.real_iter = iter[0]
616
617     cdef DBusMessageIter *_get_iter(self):
618         return self.iter
619
620     def has_next(self):
621         return dbus_message_iter_has_next(self.iter)
622     
623     def next(self):
624         return dbus_message_iter_next(self.iter)
625
626     def get(self, arg_type=None):
627         if(arg_type == None):
628             arg_type = self.get_arg_type()
629
630         if arg_type == TYPE_INVALID:
631             raise TypeError, 'Invalid arg type in MessageIter'
632         elif arg_type == TYPE_STRING:
633             retval = self.get_string()
634         elif arg_type == TYPE_INT16:
635             retval = self.get_int16()
636         elif arg_type == TYPE_UINT16:
637             retval = self.get_uint16()
638         elif arg_type == TYPE_INT32:
639             retval = self.get_int32()
640         elif arg_type == TYPE_UINT32:
641             retval = self.get_uint32()
642         elif arg_type == TYPE_INT64:
643             retval = self.get_int64()
644         elif arg_type == TYPE_UINT64:
645             retval = self.get_uint64()
646         elif arg_type == TYPE_DOUBLE:
647             retval = self.get_double()
648         elif arg_type == TYPE_BYTE:
649             retval = self.get_byte()
650         elif arg_type == TYPE_BOOLEAN:
651             retval = self.get_boolean()
652         elif arg_type == TYPE_SIGNATURE:
653             retval = self.get_signature()
654         elif arg_type == TYPE_ARRAY:
655             array_type = self.get_element_type()
656             if array_type == TYPE_DICT_ENTRY:
657                 retval = self.get_dict()
658             else:
659                 retval = self.get_array(array_type)
660         elif arg_type == TYPE_OBJECT_PATH:
661             retval = self.get_object_path()
662         elif arg_type == TYPE_STRUCT:
663             retval = self.get_struct()
664         elif arg_type == TYPE_VARIANT:
665             retval = self.get_variant()
666         elif arg_type == TYPE_DICT_ENTRY:
667             raise TypeError, 'Dictionary Entries can only appear as part of an array container'
668         else:
669             raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type)
670
671         return retval
672
673     def get_arg_type(self):
674         return dbus_message_iter_get_arg_type(self.iter)
675
676     def get_element_type(self):
677         return dbus_message_iter_get_element_type(self.iter)
678
679     def get_byte(self):
680         cdef char c_val
681         dbus_message_iter_get_basic(self.iter, <char *>&c_val)
682         return c_val
683         
684     def get_boolean(self):
685         cdef dbus_bool_t c_val
686         dbus_message_iter_get_basic(self.iter, <dbus_bool_t *>&c_val)
687
688         if c_val:
689             return True
690         else:
691             return False 
692
693     def get_signature(self):
694         signature_string = self.get_string()
695         return Signature(signature_string)
696
697     def get_int16(self):
698         cdef dbus_int16_t c_val
699         dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val)
700
701         return c_val
702
703     def get_uint16(self):
704         cdef dbus_uint16_t c_val
705         dbus_message_iter_get_basic(self.iter, <dbus_uint16_t *>&c_val)
706         return c_val
707
708     def get_int32(self):
709         cdef dbus_int32_t c_val
710         dbus_message_iter_get_basic(self.iter, <dbus_int32_t *>&c_val)
711         return c_val
712         
713     def get_uint32(self):
714         cdef dbus_uint32_t c_val
715         dbus_message_iter_get_basic(self.iter, <dbus_uint32_t *>&c_val)
716         return c_val
717         
718     def get_int64(self):
719         cdef dbus_int64_t c_val
720         dbus_message_iter_get_basic(self.iter, <dbus_int64_t *>&c_val)
721         return c_val
722
723     def get_uint64(self):
724         cdef dbus_uint64_t c_val
725         dbus_message_iter_get_basic(self.iter, <dbus_uint64_t *>&c_val)
726         return c_val
727
728     def get_double(self):
729         cdef double c_val
730         dbus_message_iter_get_basic(self.iter, <double *>&c_val)
731         return c_val
732
733     def get_string(self):
734         cdef char *c_str
735         dbus_message_iter_get_basic(self.iter, <char **>&c_str)
736
737         return c_str
738
739     def get_object_path(self):
740         object_path_string = self.get_string()
741         return ObjectPath(object_path_string)
742
743     def get_dict(self):
744         cdef DBusMessageIter c_dict_iter
745         cdef MessageIter dict_iter
746         level = self.level + 1
747
748         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter)
749         dict_iter = MessageIter(level)
750         dict_iter.__cinit__(&c_dict_iter)
751         
752         python_dict = {}
753         cur_arg_type = dict_iter.get_arg_type()
754         while cur_arg_type == TYPE_DICT_ENTRY:
755             if cur_arg_type != TYPE_DICT_ENTRY:
756                 raise TypeError, "Dictionary elements must be of type TYPE_DICT_ENTRY '%s != %s'" % (TYPE_DICT_ENTRY, cur_arg_type)
757                 
758             dict_entry = dict_iter.get_struct()
759             if len(dict_entry) != 2:
760                 raise TypeError, "Dictionary entries must be structs of two elements.  This entry had %i elements.'" % (len(dict_entry))
761
762             python_dict[dict_entry[0]] = dict_entry[1]
763             
764             dict_iter.next()
765             cur_arg_type = dict_iter.get_arg_type()
766
767         return python_dict
768    
769     def get_array(self, type):
770         cdef DBusMessageIter c_array_iter
771         cdef MessageIter array_iter
772         level = self.level + 1
773
774         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
775         array_iter = MessageIter(level)
776         array_iter.__cinit__(&c_array_iter)
777         
778         python_list = []
779         cur_arg_type = array_iter.get_arg_type()
780         while cur_arg_type != TYPE_INVALID:
781             if cur_arg_type != type:
782                 raise TypeError, "Array elements must be of the same type '%s != %s'" % (type, cur_arg_type)
783                 
784             value = array_iter.get(type)
785             python_list.append(value)
786             
787             array_iter.next()
788             cur_arg_type = array_iter.get_arg_type()
789
790         return python_list
791
792     def get_variant(self):
793         cdef DBusMessageIter c_var_iter
794         cdef MessageIter var_iter
795         level = self.level + 1
796
797         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter)
798         var_iter = MessageIter(level)
799         var_iter.__cinit__(&c_var_iter)
800         
801         return var_iter.get() 
802
803     def get_struct(self):
804         cdef DBusMessageIter c_struct_iter
805         cdef MessageIter struct_iter
806         level = self.level + 1
807
808         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter)
809         struct_iter = MessageIter(level)
810         struct_iter.__cinit__(&c_struct_iter)
811
812         python_list = []
813         while struct_iter.get_arg_type() != TYPE_INVALID:
814             value = struct_iter.get()
815             python_list.append(value)
816             
817             struct_iter.next()
818
819         return tuple(python_list)
820
821     def python_value_to_dbus_sig(self, value, level = 0):
822
823         if(level > 32):
824             raise TypeError, 'Type recurion is too deep' 
825
826         level = level + 1
827
828         ptype = type(value)
829         ret = ""
830         if ptype == bool:
831             ret = TYPE_BOOL
832             ret = str(chr(ret))
833         elif ptype == int:
834             ret = TYPE_INT32
835             ret = str(chr(ret))
836         elif ptype == long:
837             ret = TYPE_INT64
838             ret = str(chr(ret))
839         elif ptype == str:
840             ret = TYPE_STRING
841             ret = str(chr(ret))
842         elif ptype == float:
843             ret = TYPE_DOUBLE
844             ret = str(chr(ret))
845         elif ptype == dict:
846             dict_list = value.items()
847             key, value = dict_list[0]
848
849             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
850             ret = ret + self.python_value_to_dbus_sig(key, level)
851             ret = ret + self.python_value_to_dbus_sig(value, level)
852             ret = ret + str(chr(DICT_ENTRY_END))
853
854         elif ptype == tuple:
855             ret = str(chr(STRUCT_BEGIN))
856             for item in value:
857                 ret = ret + self.python_value_to_dbus_sig(item, level)
858             ret = ret + str(chr(STRUCT_END))
859         elif ptype == list:
860             ret = str(chr(TYPE_ARRAY))
861             ret = ret + self.python_value_to_dbus_sig(value[0], level)
862         elif isinstance(value, ObjectPath) or value == ObjectPath:
863
864             ret = TYPE_OBJECT_PATH
865             ret = str(chr(ret))
866         elif isinstance(value, ByteArray) or value == ByteArray:
867             ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE))
868         elif isinstance(value, Signature) or value == Signature:
869             ret = TYPE_SIGNATURE
870             ret = str(chr(ret))
871         elif isinstance(value, Byte) or value == Byte:
872             ret = TYPE_BYTE
873             ret = str(chr(ret))
874         elif isinstance(value, Boolean) or value == Boolean:
875             ret = TYPE_BOOL
876             ret = str(chr(ret))
877         elif isinstance(value, Int16) or value == Int16:
878             ret = TYPE_INT16
879             ret = str(chr(ret))
880         elif isinstance(value, UInt16) or value == UInt16:
881             ret = TYPE_UINT16
882             ret = str(chr(ret))
883         elif isinstance(value, Int32) or value == Int32:
884             ret = TYPE_INT32
885             ret = str(chr(ret))
886         elif isinstance(value, UInt32) or value == UInt32:
887             ret = TYPE_UINT32
888             ret = str(chr(ret))
889         elif isinstance(value, Int64) or value == Int64:
890             ret = TYPE_INT64
891             ret = str(chr(ret))
892         elif isinstance(value, UInt64) or value == UInt64:
893             ret = TYPE_UINT64
894             ret = str(chr(ret))
895         elif isinstance(value, Double) or value == Double:
896             ret = TYPE_DOUBLE
897             ret = str(chr(ret))
898         elif isinstance(value, String) or value == String:
899             ret = TYPE_STRING
900             ret = str(chr(ret))
901         elif isinstance(value, Array):
902             ret = str(chr(TYPE_ARRAY))
903             if value.type == None:
904                 if value.signature:
905                     ret = ret + value.signature
906                 else:
907                     ret = ret + self.python_value_to_dbus_sig(value[0], level)
908             else:
909                 ret = ret + self.python_value_to_dbus_sig(value.type, level)
910
911         elif isinstance(value, Struct) or value == Struct:
912             ret = str(chr(STRUCT_BEGIN))
913             for item in value:
914                 ret = ret + self.python_value_to_dbus_sig(item, level)
915             ret = ret + str(chr(STRUCT_END))
916         elif isinstance(value, Dictionary):
917             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
918             
919             if value.key_type and value.value_type:
920                 ret = ret + self.python_value_to_dbus_sig(value.key_type, level)
921                 ret = ret + self.python_value_to_dbus_sig(value.value_type, level)
922             elif value.signature:
923                 ret = ret + value.signature
924             else:
925                 dict_list = value.items()
926
927                 key, val = dict_list[0]
928                 ret = ret + self.python_value_to_dbus_sig(key, level)
929                 ret = ret + self.python_value_to_dbus_sig(val, level)
930                 
931             ret = ret + str(chr(DICT_ENTRY_END))
932         elif isinstance(value, Variant) or value == Variant:
933             ret = ret + str(chr(TYPE_VARIANT))
934         else:
935             raise TypeError, "Argument of unknown type '%s'" % (ptype)
936
937         return ret
938
939     
940     #FIXME: handle all the different types?
941     def append(self, value):
942         value_type = type(value)
943         if value_type == bool:
944             retval = self.append_boolean(value)
945         elif value_type == int:
946             retval = self.append_int32(value)
947         elif value_type == long:
948             retval = self.append_int64(value)
949         elif value_type == str:
950             retval = self.append_string(value)
951         elif value_type == float:
952             retval = self.append_double(value)
953         elif value_type == dict:
954             retval = self.append_dict(value)
955         elif value_type == tuple:
956             retval = self.append_struct(value)
957         elif value_type == list:
958              retval = self.append_array(value)
959         #elif value_type == None.__class__:
960         #    retval = self.append_nil()
961         elif isinstance(value, ObjectPath):
962             retval = self.append_object_path(value)
963         elif isinstance(value, ByteArray):
964             retval = self.append_array(value)
965         elif isinstance(value, Signature):
966             retval = self.append_signature(value)
967         elif isinstance(value, Byte):
968             retval = self.append_byte(value)
969         elif isinstance(value, Boolean):
970             retval = self.append_boolean(value)
971         elif isinstance(value, Int16):
972             retval = self.append_int16(value)
973         elif isinstance(value, UInt16):
974             retval = self.append_uint16(value)
975         elif isinstance(value, Int32):
976             retval = self.append_int32(value)
977         elif isinstance(value, UInt32):
978             retval = self.append_uint32(value)
979         elif isinstance(value, Int64):
980             retval = self.append_int64(value)
981         elif isinstance(value, UInt64):
982             retval = self.append_uint64(value)
983         elif isinstance(value, Double):
984             retval = self.append_double(value)
985         elif isinstance(value, String):
986             retval = self.append_string(value)
987         elif isinstance(value, Array):
988             retval = self.append_array(value)
989         elif isinstance(value, Struct):
990             retval = self.append_struct(value)
991         elif isinstance(value, Dictionary):
992             retval = self.append_dict(value)
993         elif isinstance(value, Variant):
994             retval = self.append_variant(value)
995         else:
996             raise TypeError, "Argument of unknown type '%s'" % (value_type)
997
998         return retval
999
1000     def append_boolean(self, value):
1001         cdef dbus_bool_t c_value
1002         c_value = value
1003         return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value)
1004
1005     def append_byte(self, value):
1006         cdef char b
1007         if type(value) == str and len(value) == 1:
1008                 b = ord(value)
1009         elif type(value) == Byte:
1010                 b = value
1011         else:
1012             raise TypeError
1013
1014         return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)
1015
1016     def append_int16(self, value):
1017         cdef dbus_int32_t c_value
1018         c_value = value
1019         return dbus_message_iter_append_basic(self.iter, TYPE_INT16, <dbus_int32_t *>&c_value)
1020
1021     def append_uint16(self, value):
1022         cdef dbus_uint32_t c_value
1023         c_value = value
1024         return dbus_message_iter_append_basic(self.iter, TYPE_UINT16, <dbus_uint32_t *>&c_value)
1025
1026     def append_int32(self, value):
1027         cdef dbus_int32_t c_value
1028         c_value = value
1029         return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value)
1030
1031     def append_uint32(self, value):
1032         cdef dbus_uint32_t c_value
1033         c_value = value
1034         return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value)
1035
1036     def append_int64(self, value):
1037         cdef dbus_int64_t c_value
1038         c_value = value
1039         return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value)
1040
1041     def append_uint64(self, value):
1042         cdef dbus_uint64_t c_value
1043         c_value = value
1044         return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value)
1045
1046     def append_double(self, value):
1047         cdef double c_value
1048         c_value = value
1049         return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value)
1050
1051     def append_string(self, value):
1052         cdef char *c_value
1053         c_value = value
1054         return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value)    
1055
1056     def append_object_path(self, value):
1057         cdef char *c_value
1058         c_value = value
1059         return dbus_message_iter_append_basic(self.iter, TYPE_OBJECT_PATH, <char **>&c_value)
1060
1061     def append_signature(self, value):
1062         cdef char *c_value
1063         c_value = value
1064         return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value)
1065
1066
1067     def append_dict(self, python_dict):
1068         cdef DBusMessageIter c_dict_iter, c_dict_entry_iter
1069         cdef MessageIter dict_iter, dict_entry_iter
1070         
1071         level = self.level + 1
1072
1073         key = None
1074         value = None
1075
1076         sig = str(chr(DICT_ENTRY_BEGIN))
1077
1078         if isinstance(python_dict, Dictionary):
1079             key = python_dict.key_type
1080             value = python_dict.value_type
1081             signature = python_dict.signature
1082
1083         dict_list = python_dict.items()
1084
1085         if signature:
1086             sig = sig + signature
1087         else: 
1088             if not (key and value):
1089                 key, value = dict_list[0]
1090
1091             sig = sig + self.python_value_to_dbus_sig(key)
1092             sig = sig + self.python_value_to_dbus_sig(value)
1093
1094         sig = sig + str(chr(DICT_ENTRY_END))
1095
1096         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter)
1097         dict_iter = MessageIter(level)
1098         dict_iter.__cinit__(&c_dict_iter)
1099
1100         for key, value in dict_list:
1101             dbus_message_iter_open_container(dict_iter.iter, TYPE_DICT_ENTRY, sig, <DBusMessageIter *>&c_dict_entry_iter)
1102             dict_entry_iter = MessageIter(level)
1103             dict_entry_iter.__cinit__(&c_dict_entry_iter)
1104
1105             if not dict_entry_iter.append(key):
1106                 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1107                 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1108                 return False
1109                 
1110             if not dict_entry_iter.append(value):
1111                 dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1112                 dbus_message_iter_close_container(self.iter, dict_iter.iter)
1113                 return False
1114
1115             dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1116
1117         dbus_message_iter_close_container(self.iter, dict_iter.iter)
1118
1119         return True
1120
1121     def append_struct(self, python_struct):
1122         cdef DBusMessageIter c_struct_iter
1123         cdef MessageIter struct_iter
1124
1125         level = self.level + 1
1126         dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter)
1127         struct_iter = MessageIter(level)
1128         struct_iter.__cinit__(&c_struct_iter)
1129         
1130         for item in python_struct:
1131             if not struct_iter.append(item):
1132                 dbus_message_iter_close_container(self.iter, struct_iter.iter)
1133                 return False
1134
1135         dbus_message_iter_close_container(self.iter, struct_iter.iter)
1136
1137         return True
1138
1139     def append_array(self, python_list):
1140         cdef DBusMessageIter c_array_iter
1141         cdef MessageIter array_iter
1142
1143         level = self.level + 1
1144
1145         sig = None
1146         if isinstance(python_list, Array):
1147             if python_list.type:
1148                 sig = self.python_value_to_dbus_sig(python_list.type)
1149             elif python_list.signature:
1150                 sig = python_list.signature
1151             else:
1152                 sig = self.python_value_to_dbus_sig(python_list[0])
1153         else:
1154             sig = self.python_value_to_dbus_sig(python_list[0])
1155
1156         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter)
1157         array_iter = MessageIter(level)
1158         array_iter.__cinit__(&c_array_iter)
1159
1160         length = len(python_list)
1161         for item in python_list:
1162             if not array_iter.append(item):
1163                 dbus_message_iter_close_container(self.iter, array_iter.iter)
1164                 return False
1165
1166         dbus_message_iter_close_container(self.iter, array_iter.iter)
1167
1168         return True
1169
1170     def append_variant(self, value):
1171         cdef DBusMessageIter c_variant_iter
1172         cdef MessageIter variant_iter
1173
1174         level = self.level + 1
1175     
1176         if value.signature:
1177             sig = value.signature
1178         elif value.type:
1179             sig = self.python_value_to_dbus_sig(value.type)
1180         else:
1181             sig = self.python_value_to_dbus_sig(value.value)
1182     
1183         dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter)
1184         
1185         variant_iter = MessageIter(level)
1186         variant_iter.__cinit__(&c_variant_iter)
1187
1188         if not variant_iter.append(value.value):
1189             dbus_message_iter_close_container(self.iter, variant_iter.iter)
1190             return False
1191
1192         dbus_message_iter_close_container(self.iter, variant_iter.iter)
1193         return True
1194
1195     def __str__(self):
1196         cdef DBusMessageIter c_array_iter
1197         cdef MessageIter array_iter
1198
1199         value_at_iter = True
1200         retval = ""
1201         while (value_at_iter):
1202             type = self.get_arg_type()
1203             if type == TYPE_INVALID:
1204                 break
1205             elif type == TYPE_STRING:
1206                 str = iter.get_string()
1207                 arg = 'string:%s\n' % (str)
1208             elif type == TYPE_OBJECT_PATH:
1209                 path = iter.get_object_path()
1210                 arg = 'object_path:%s\n' % (path)
1211             elif type == TYPE_INT32:
1212                 num = iter.get_int32()
1213                 arg = 'int32:%d\n' % (num)
1214             elif type == TYPE_UINT32:
1215                 num = iter.get_uint32()
1216                 arg = 'uint32:%u\n' % (num)
1217             elif type == TYPE_INT64:
1218                 num = iter.get_int64()
1219                 arg = 'int64:%d\n' % (num)
1220             elif type == TYPE_UINT64:
1221                 num = iter.get_uint64()
1222                 arg = 'uint64:%u\n' % (num)
1223             elif type == TYPE_DOUBLE:
1224                 num = iter.get_double()
1225                 arg = 'double:%f\n' % (num)
1226             elif type == TYPE_BYTE:
1227                 num = iter.get_byte()
1228                 arg = 'byte:%x(%s)\n' % (num, str(chr(num)))
1229             elif type == TYPE_BOOLEAN:
1230                 bool = iter.get_boolean()
1231                 if (bool):
1232                     str = "true"
1233                 else:
1234                     str = "false"
1235                 arg = 'boolean:%s\n' % (str)
1236             elif type == TYPE_ARRAY:
1237                 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
1238                 array_iter = MessageIter(self.level + 1)
1239                 array_iter.__cinit__(&c_array_iter)
1240                 if array_iter.has_next():
1241                     arg = 'array [' + str(array_iter) + ']'
1242                 else:
1243                     arg = 'array []'
1244             else:
1245                 arg = '(unknown arg type %d)\n' % type
1246
1247             retval = retval + arg
1248             value_at_iter = self.next()
1249
1250         return retval
1251
1252
1253 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
1254 (TYPE_INVALID, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT16, TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_OBJECT_PATH, TYPE_SIGNATURE, TYPE_ARRAY, TYPE_STRUCT, STRUCT_BEGIN, STRUCT_END, TYPE_VARIANT, TYPE_DICT_ENTRY, DICT_ENTRY_BEGIN, DICT_ENTRY_END) = (0, ord('y'), ord('b'), ord('n'), ord('q'), ord('i'), ord('u'), ord('x'), ord('t'), ord('d'), ord('s'), ord('o'), ord('g'), ord('a'), ord('r'), ord('('), ord(')'), ord('v'), ord('e'), ord('{'), ord('}'))
1255 (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3)
1256     
1257 cdef class Message:
1258     cdef DBusMessage *msg
1259
1260     def __init__(self, message_type=MESSAGE_TYPE_INVALID,
1261                  service=None, path=None, dbus_interface=None, method=None,
1262                  Message method_call=None,
1263                  name=None,
1264                  Message reply_to=None, error_name=None, error_message=None,
1265                  _create=1):
1266
1267         self.msg = NULL
1268
1269         cdef char *cservice
1270         cdef char *ciface
1271         cdef DBusMessage *cmsg
1272
1273         ciface = NULL
1274         if (dbus_interface != None):
1275             ciface = dbus_interface
1276
1277         cservice = NULL
1278         if (service != None):
1279             cservice = service
1280             
1281         if _create:
1282             if message_type == MESSAGE_TYPE_METHOD_CALL:
1283                 self.msg = dbus_message_new_method_call(cservice, path, ciface, method)
1284             elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1285                 cmsg = method_call._get_msg()
1286                 self.msg = dbus_message_new_method_return(cmsg)
1287             elif message_type == MESSAGE_TYPE_SIGNAL:
1288                 self.msg = dbus_message_new_signal(path, ciface, name)
1289             elif message_type == MESSAGE_TYPE_ERROR:
1290                 cmsg = reply_to._get_msg()
1291                 self.msg = dbus_message_new_error(cmsg, error_name, error_message)
1292  
1293
1294     def __dealloc__(self):
1295         if self.msg != NULL:
1296             dbus_message_unref(self.msg)
1297             
1298     def type_to_name(self, type):
1299         if type == MESSAGE_TYPE_SIGNAL:
1300             return "signal"
1301         elif type == MESSAGE_TYPE_METHOD_CALL:
1302             return "method call"
1303         elif type == MESSAGE_TYPE_METHOD_RETURN:
1304             return "method return"
1305         elif type == MESSAGE_TYPE_ERROR:
1306             return "error"
1307         else:
1308             return "(unknown message type)"
1309
1310     def __str__(self):
1311         message_type = self.get_type()
1312         sender = self.get_sender()
1313
1314         if sender == None:
1315             sender = "(no sender)"
1316
1317         if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
1318             retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
1319                                                                 self.get_interface(),
1320                                                                 self.get_member(),
1321                                                                 sender)
1322         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1323             retval = '%s sender=%s' % (self.type_to_name(message_type),
1324                                         sender)
1325         elif message_type == MESSAGE_TYPE_ERROR:
1326             retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
1327                                                 self.get_error_name(),
1328                                                 sender)
1329         else:
1330             retval = "Message of unknown type %d" % (message_type)
1331
1332
1333         # FIXME: should really use self.convert_to_tuple() here
1334         
1335         iter = self.get_iter()
1336
1337         retval = retval + "\n" + str(iter) 
1338
1339         return retval
1340     
1341     cdef _set_msg(self, DBusMessage *msg):
1342         self.msg = msg
1343
1344     cdef DBusMessage *_get_msg(self):
1345         return self.msg
1346
1347     def get_iter(self, append=False):
1348         cdef DBusMessageIter iter
1349         cdef MessageIter message_iter
1350         cdef DBusMessage *msg
1351
1352         msg = self._get_msg()
1353
1354         if append:
1355             dbus_message_iter_init_append(msg, &iter)
1356         else:
1357             dbus_message_iter_init(msg, &iter)
1358
1359         message_iter = MessageIter(0)
1360         message_iter.__cinit__(&iter)
1361
1362         return message_iter
1363
1364     def get_args_list(self):
1365         retval = [ ]
1366
1367         iter = self.get_iter()
1368         try:
1369             retval.append(iter.get())
1370         except TypeError, e:
1371             return [ ]
1372             
1373         value_at_iter = iter.next()
1374         while (value_at_iter):
1375             retval.append(iter.get())
1376             value_at_iter = iter.next()        
1377
1378         return retval
1379             
1380     # FIXME: implement dbus_message_copy?
1381
1382     def get_type(self):
1383         return dbus_message_get_type(self.msg)
1384
1385     def set_path(self, object_path):
1386         return dbus_message_set_path(self.msg, object_path)
1387     
1388     def get_path(self):
1389         return dbus_message_get_path(self.msg)
1390     
1391     def set_interface(self, interface):
1392         return dbus_message_set_interface(self.msg, interface)
1393
1394     def get_interface(self):
1395         return dbus_message_get_interface(self.msg)    
1396
1397     def set_member(self, member):
1398         return dbus_message_set_member(self.msg, member)
1399
1400     def get_member(self):
1401         return dbus_message_get_member(self.msg)
1402
1403     def set_error_name(self, name):
1404         return dbus_message_set_error_name(self.msg, name)
1405
1406     def get_error_name(self):
1407         return dbus_message_get_error_name(self.msg)
1408
1409     def set_destination(self, destination):
1410         return dbus_message_set_destination(self.msg, destination)
1411
1412     def get_destination(self):
1413         return dbus_message_get_destination(self.msg)
1414
1415     def set_sender(self, sender):
1416         return dbus_message_set_sender(self.msg, sender)
1417     
1418     def get_sender(self):
1419         cdef char *sender
1420         sender = dbus_message_get_sender(self.msg)
1421         if (sender == NULL):
1422             return None
1423         else:
1424             return sender
1425
1426     def set_no_reply(self, no_reply):
1427         dbus_message_set_no_reply(self.msg, no_reply)
1428
1429     def get_no_reply(self):
1430         return dbus_message_get_no_reply(self.msg)
1431
1432     def is_method_call(self, interface, method):
1433         return dbus_message_is_method_call(self.msg, interface, method)
1434
1435     def is_signal(self, interface, signal_name):
1436         return dbus_message_is_signal(self.msg, interface, signal_name)
1437
1438     def is_error(self, error_name):
1439         return dbus_message_is_error(self.msg, error_name)
1440
1441     def has_destination(self, service):
1442         return dbus_message_has_destination(self.msg, service)
1443
1444     def has_sender(self, service):
1445         return dbus_message_has_sender(self.msg, service)
1446
1447     def get_serial(self):
1448         return dbus_message_get_serial(self.msg)
1449
1450     def set_reply_serial(self, reply_serial):
1451         return dbus_message_set_reply_serial(self.msg, reply_serial)
1452
1453     def get_reply_serial(self):
1454         return dbus_message_get_reply_serial(self.msg)    
1455
1456     #FIXME: dbus_message_get_path_decomposed
1457     
1458     # FIXME: all the different dbus_message_*args* methods
1459
1460 class Signal(Message):
1461     def __init__(self, spath, sinterface, sname):
1462         Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, dbus_interface=sinterface, name=sname)
1463
1464 class EmptyMessage(Message):
1465     def __init__(self):
1466         Message.__init__(self, _create=False)
1467
1468 class MethodCall(Message):
1469     def __init__(self, mpath, minterface, mmethod):
1470         Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, dbus_interface=minterface, method=mmethod)
1471
1472 class MethodReturn(Message):
1473     def __init__(self, method_call):
1474         Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
1475
1476 class Error(Message):
1477     def __init__(self, reply_to, error_name, error_message):
1478         Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
1479         
1480 cdef class Server:
1481     cdef DBusServer *server
1482     def __init__(self, address):
1483         cdef DBusError error
1484         dbus_error_init(&error)
1485         self.server = dbus_server_listen(address,
1486                                          &error)
1487         if dbus_error_is_set(&error):
1488             message = error.message
1489             dbus_error_free (&error)
1490             raise DBusException, message
1491
1492     def disconnect(self):
1493         dbus_server_disconnect(self.server)
1494
1495     def get_is_connected(self):
1496         return dbus_server_get_is_connected(self.server)
1497
1498 #    def set_new_connection_function(self, function, data):
1499 #        dbus_server_set_new_connection_function(self.conn, function,
1500 #                                                data, NULL)
1501         
1502 #    def set_watch_functions(self, add_function, remove_function, data):
1503 #        dbus_server_set_watch_functions(self.server,
1504 #                                        add_function, remove_function,
1505 #                                        data, NULL)
1506         
1507 #    def set_timeout_functions(self, add_function, remove_function, data):
1508 #        dbus_server_set_timeout_functions(self.server,
1509 #                                          add_function, remove_function,
1510 #                                          data, NULL)
1511         
1512 #    def handle_watch(self, watch, condition):
1513 #        dbus_server_handle_watch(self.conn, watch, condition)
1514
1515 BUS_SESSION = DBUS_BUS_SESSION
1516 BUS_SYSTEM = DBUS_BUS_SYSTEM
1517 BUS_STARTER = DBUS_BUS_STARTER
1518
1519 def bus_get (bus_type):
1520     cdef DBusError error
1521     cdef Connection conn
1522     dbus_error_init(&error)
1523     cdef DBusConnection *connection
1524
1525     connection = dbus_bus_get(bus_type,
1526                               &error)
1527
1528     if dbus_error_is_set(&error):
1529         message = error.message
1530         dbus_error_free(&error)
1531         raise DBusException, message
1532
1533     conn = Connection()
1534     conn.__cinit__(None, connection)
1535     return conn 
1536
1537 def bus_get_unique_name(Connection connection):
1538     cdef DBusConnection *conn
1539     conn = connection._get_conn()
1540     return dbus_bus_get_unique_name(conn)
1541
1542 def bus_get_unix_user(Connection connection, service_name):
1543     cdef DBusError error
1544     dbus_error_init(&error)
1545     cdef int retval
1546     cdef DBusConnection *conn
1547
1548     conn = connection._get_conn()
1549     retval = dbus_bus_get_unix_user(conn, service_name, &error)
1550
1551     if dbus_error_is_set(&error):
1552         message = error.message
1553         dbus_error_free(&error)
1554         raise DBusException, message
1555
1556     return retval
1557
1558 #These are defines, not enums so they aren't auto generated
1559 DBUS_START_REPLY_SUCCESS = 0 
1560 DBUS_START_REPLY_ALREADY_RUNNING = 1 
1561     
1562 def bus_start_service_by_name(Connection connection, service_name, flags=0):
1563     cdef DBusError error
1564     dbus_error_init(&error)
1565     cdef dbus_bool_t retval
1566     cdef dbus_uint32_t results
1567     cdef DBusConnection *conn
1568
1569     conn = connection._get_conn()
1570
1571     retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
1572
1573     if dbus_error_is_set(&error):
1574         message = error.message
1575         dbus_error_free(&error)
1576         raise DBusException, message
1577
1578     return (retval, results) 
1579
1580 def bus_register(Connection connection):
1581     cdef DBusError error
1582     dbus_error_init(&error)
1583     cdef dbus_bool_t retval
1584     cdef DBusConnection *conn
1585
1586     conn = connection._get_conn()
1587     retval = dbus_bus_register(conn,
1588                                &error)
1589     if dbus_error_is_set(&error):
1590         message = error.message
1591         dbus_error_free(&error)
1592         raise DBusException, message
1593
1594     return retval
1595
1596 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
1597 SERVICE_FLAG_REPLACE_EXISTING     = 0x2
1598
1599 def bus_request_name(Connection connection, service_name, flags=0):
1600     cdef DBusError error
1601     dbus_error_init(&error)
1602     cdef int retval
1603     cdef DBusConnection *conn
1604
1605     conn = connection._get_conn()
1606     retval = dbus_bus_request_name(conn,
1607                                    service_name,
1608                                    flags,
1609                                    &error)
1610     if dbus_error_is_set(&error):
1611         message = error.message
1612         dbus_error_free(&error)
1613         raise DBusException, message
1614         
1615     return retval
1616     
1617 def bus_name_has_owner(Connection connection, service_name):
1618     cdef DBusError error
1619     dbus_error_init(&error)
1620     cdef dbus_bool_t retval
1621     cdef DBusConnection *conn
1622
1623     conn = connection._get_conn()
1624     retval = dbus_bus_name_has_owner(conn,
1625                                      service_name,
1626                                      &error)
1627     if dbus_error_is_set(&error):
1628         message = error.message
1629         dbus_error_free(&error)
1630         raise DBusException, message
1631         
1632     return retval
1633
1634 def bus_add_match(Connection connection, rule):
1635     cdef DBusError error
1636     cdef DBusConnection *conn
1637
1638     dbus_error_init(&error)
1639     
1640     conn = connection._get_conn()
1641     dbus_bus_add_match (conn, rule, &error)
1642     
1643     if dbus_error_is_set(&error):
1644         message = error.message
1645         dbus_error_free(&error)
1646         raise DBusException, message
1647
1648 def bus_remove_match(Connection connection, rule):
1649     cdef DBusError error
1650     cdef DBusConnection *conn
1651
1652     dbus_error_init(&error)
1653
1654     conn = connection._get_conn()
1655     dbus_bus_remove_match (conn, rule, &error)
1656     
1657     if dbus_error_is_set(&error):
1658         message = error.message
1659         dbus_error_free(&error)
1660         raise DBusException, message
1661