2005-10-24 Robert McQueen <robot101@debian.org>
[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(unicode):
127     def __init__(self, value):
128         unicode.__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                 errormsg = error.message
265                 dbus_error_free (&error)
266                 raise DBusException, errormsg
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 close(self):
282         dbus_connection_close(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             errormsg = error.message
392             dbus_error_free (&error)
393             raise DBusException, errormsg
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         ret = c_str.decode('utf8')
737
738         return ret
739
740     def get_object_path(self):
741         object_path_string = self.get_string()
742         return ObjectPath(object_path_string)
743
744     def get_dict(self):
745         cdef DBusMessageIter c_dict_iter
746         cdef MessageIter dict_iter
747         level = self.level + 1
748
749         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter)
750         dict_iter = MessageIter(level)
751         dict_iter.__cinit__(&c_dict_iter)
752         
753         python_dict = {}
754         cur_arg_type = dict_iter.get_arg_type()
755         while cur_arg_type == TYPE_DICT_ENTRY:
756             if cur_arg_type != TYPE_DICT_ENTRY:
757                 raise TypeError, "Dictionary elements must be of type TYPE_DICT_ENTRY '%s != %s'" % (TYPE_DICT_ENTRY, cur_arg_type)
758                 
759             dict_entry = dict_iter.get_struct()
760             if len(dict_entry) != 2:
761                 raise TypeError, "Dictionary entries must be structs of two elements.  This entry had %i elements.'" % (len(dict_entry))
762
763             python_dict[dict_entry[0]] = dict_entry[1]
764             
765             dict_iter.next()
766             cur_arg_type = dict_iter.get_arg_type()
767
768         return python_dict
769    
770     def get_array(self, type):
771         cdef DBusMessageIter c_array_iter
772         cdef MessageIter array_iter
773         level = self.level + 1
774
775         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
776         array_iter = MessageIter(level)
777         array_iter.__cinit__(&c_array_iter)
778         
779         python_list = []
780         cur_arg_type = array_iter.get_arg_type()
781         while cur_arg_type != TYPE_INVALID:
782             if cur_arg_type != type:
783                 raise TypeError, "Array elements must be of the same type '%s != %s'" % (type, cur_arg_type)
784                 
785             value = array_iter.get(type)
786             python_list.append(value)
787             
788             array_iter.next()
789             cur_arg_type = array_iter.get_arg_type()
790
791         return python_list
792
793     def get_variant(self):
794         cdef DBusMessageIter c_var_iter
795         cdef MessageIter var_iter
796         level = self.level + 1
797
798         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter)
799         var_iter = MessageIter(level)
800         var_iter.__cinit__(&c_var_iter)
801         
802         return var_iter.get() 
803
804     def get_struct(self):
805         cdef DBusMessageIter c_struct_iter
806         cdef MessageIter struct_iter
807         level = self.level + 1
808
809         dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter)
810         struct_iter = MessageIter(level)
811         struct_iter.__cinit__(&c_struct_iter)
812
813         python_list = []
814         while struct_iter.get_arg_type() != TYPE_INVALID:
815             value = struct_iter.get()
816             python_list.append(value)
817             
818             struct_iter.next()
819
820         return tuple(python_list)
821
822     def python_value_to_dbus_sig(self, value, level = 0):
823
824         if(level > 32):
825             raise TypeError, 'Type recurion is too deep' 
826
827         level = level + 1
828
829         ptype = type(value)
830         ret = ""
831         if ptype == bool:
832             ret = TYPE_BOOL
833             ret = str(chr(ret))
834         elif ptype == int:
835             ret = TYPE_INT32
836             ret = str(chr(ret))
837         elif ptype == long:
838             ret = TYPE_INT64
839             ret = str(chr(ret))
840         elif (ptype == str or ptype == unicode):
841             ret = TYPE_STRING
842             ret = str(chr(ret))
843         elif ptype == float:
844             ret = TYPE_DOUBLE
845             ret = str(chr(ret))
846         elif ptype == dict:
847             dict_list = value.items()
848             key, value = dict_list[0]
849
850             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
851             ret = ret + self.python_value_to_dbus_sig(key, level)
852             ret = ret + self.python_value_to_dbus_sig(value, level)
853             ret = ret + str(chr(DICT_ENTRY_END))
854
855         elif ptype == tuple:
856             ret = str(chr(STRUCT_BEGIN))
857             for item in value:
858                 ret = ret + self.python_value_to_dbus_sig(item, level)
859             ret = ret + str(chr(STRUCT_END))
860         elif ptype == list:
861             ret = str(chr(TYPE_ARRAY))
862             ret = ret + self.python_value_to_dbus_sig(value[0], level)
863         elif isinstance(value, ObjectPath) or value == ObjectPath:
864
865             ret = TYPE_OBJECT_PATH
866             ret = str(chr(ret))
867         elif isinstance(value, ByteArray) or value == ByteArray:
868             ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE))
869         elif isinstance(value, Signature) or value == Signature:
870             ret = TYPE_SIGNATURE
871             ret = str(chr(ret))
872         elif isinstance(value, Byte) or value == Byte:
873             ret = TYPE_BYTE
874             ret = str(chr(ret))
875         elif isinstance(value, Boolean) or value == Boolean:
876             ret = TYPE_BOOL
877             ret = str(chr(ret))
878         elif isinstance(value, Int16) or value == Int16:
879             ret = TYPE_INT16
880             ret = str(chr(ret))
881         elif isinstance(value, UInt16) or value == UInt16:
882             ret = TYPE_UINT16
883             ret = str(chr(ret))
884         elif isinstance(value, Int32) or value == Int32:
885             ret = TYPE_INT32
886             ret = str(chr(ret))
887         elif isinstance(value, UInt32) or value == UInt32:
888             ret = TYPE_UINT32
889             ret = str(chr(ret))
890         elif isinstance(value, Int64) or value == Int64:
891             ret = TYPE_INT64
892             ret = str(chr(ret))
893         elif isinstance(value, UInt64) or value == UInt64:
894             ret = TYPE_UINT64
895             ret = str(chr(ret))
896         elif isinstance(value, Double) or value == Double:
897             ret = TYPE_DOUBLE
898             ret = str(chr(ret))
899         elif isinstance(value, String) or value == String:
900             ret = TYPE_STRING
901             ret = str(chr(ret))
902         elif isinstance(value, Array):
903             ret = str(chr(TYPE_ARRAY))
904             if value.type == None:
905                 if value.signature:
906                     ret = ret + value.signature
907                 else:
908                     ret = ret + self.python_value_to_dbus_sig(value[0], level)
909             else:
910                 ret = ret + self.python_value_to_dbus_sig(value.type, level)
911
912         elif isinstance(value, Struct) or value == Struct:
913             ret = str(chr(STRUCT_BEGIN))
914             for item in value:
915                 ret = ret + self.python_value_to_dbus_sig(item, level)
916             ret = ret + str(chr(STRUCT_END))
917         elif isinstance(value, Dictionary):
918             ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN))
919             
920             if value.key_type and value.value_type:
921                 ret = ret + self.python_value_to_dbus_sig(value.key_type, level)
922                 ret = ret + self.python_value_to_dbus_sig(value.value_type, level)
923             elif value.signature:
924                 ret = ret + value.signature
925             else:
926                 dict_list = value.items()
927
928                 key, val = dict_list[0]
929                 ret = ret + self.python_value_to_dbus_sig(key, level)
930                 ret = ret + self.python_value_to_dbus_sig(val, level)
931                 
932             ret = ret + str(chr(DICT_ENTRY_END))
933         elif isinstance(value, Variant) or value == Variant:
934             ret = ret + str(chr(TYPE_VARIANT))
935         else:
936             raise TypeError, "Argument of unknown type '%s'" % (ptype)
937
938         return ret
939
940     def parse_signature_block(self, signature):
941         remainder = ''
942         sig = ''
943         block_depth = 0
944         block_type = None
945        
946         for marker in range(0, len(signature)):
947             cur_sig = ord(signature[marker])
948
949             if cur_sig == TYPE_ARRAY:
950                 pass
951             elif cur_sig == DICT_ENTRY_BEGIN or cur_sig == STRUCT_BEGIN:
952                 if block_type == None:
953                     block_type = cur_sig
954
955                 if block_type == cur_sig:
956                     block_depth = block_depth + 1
957
958             elif cur_sig == DICT_ENTRY_END:
959                 if block_type == DICT_ENTRY_BEGIN:
960                     block_depth = block_depth - 1
961
962                 if block_depth == 0:
963                     break
964
965             elif cur_sig == STRUCT_END:
966                 if block_type == STRUCT_BEGIN:
967                     block_depth = block_depth - 1
968
969                 if block_depth == 0:
970                     break
971
972             else:
973                 if block_depth == 0:
974                     break
975         
976         marker = marker + 1
977         sig = signature[0:marker]
978         remainder = signature[marker:]
979         return (sig, remainder)
980   
981     def append_strict(self, value, sig):
982     
983         if sig == TYPE_INVALID or sig == None:
984             raise TypeError, 'Invalid arg type sent to append_strict'
985
986         sig_type = ord(sig[0])
987             
988         if sig_type == TYPE_STRING:
989             retval = self.append(value)
990         elif sig_type == TYPE_INT16:
991             retval = self.append_int16(value)
992         elif sig_type == TYPE_UINT16:
993             retval = self.append_uint16(value)
994         elif sig_type == TYPE_INT32:
995             retval = self.append_int32(value)
996         elif sig_type == TYPE_UINT32:
997             retval = self.append_uint32(value)
998         elif sig_type == TYPE_INT64:
999             retval = self.append_int64(value)
1000         elif sig_type == TYPE_UINT64:
1001             retval = self.append_uint64(value)
1002         elif sig_type == TYPE_DOUBLE:
1003             retval = self.append_double(value)
1004         elif sig_type == TYPE_BYTE:
1005             retval = self.append_byte(value)
1006         elif sig_type == TYPE_BOOLEAN:
1007             retval = self.append_boolean(value)
1008         elif sig_type == TYPE_SIGNATURE:
1009             retval = self.append_signature(value)
1010         elif sig_type == TYPE_ARRAY:
1011             if len(sig) < 2:
1012                 raise TypeError, "Invalid array signature in append_strict.  Arrays must be followed by a type."
1013
1014             array_type = ord(sig[1])            
1015             if array_type == DICT_ENTRY_BEGIN:
1016                 if ord(sig[-1]) != DICT_ENTRY_END:
1017                     raise TypeError, "Invalid dict entry in append_strict.  No termination in signature %s."%(sig)
1018
1019                 tmp_sig = sig[2:-1]
1020                 retval = self.append_dict(Dictionary(value, signature=tmp_sig))
1021             else:
1022                 tmp_sig = sig[1:]
1023                 retval = self.append_array(Array(value, signature=tmp_sig))
1024         elif sig_type == TYPE_OBJECT_PATH:
1025             retval = self.append_object_path(value)
1026         elif sig_type == STRUCT_BEGIN:
1027             tmp_sig = sig[1:-1]
1028             retval = self.append_struct(value, signature = tmp_sig)
1029         elif sig_type == TYPE_VARIANT:
1030             retval = self.append_variant(Variant(value))
1031         elif sig_type == DICT_ENTRY_BEGIN:
1032             raise TypeError, "Signiture is invalid in append_strict. A dict entry must be part of an array." 
1033         else:
1034             raise TypeError, "Argument of unknown type '%s' in append_strict" % (sig)
1035
1036         return retval
1037
1038     def append(self, value):
1039         value_type = type(value)
1040         if value_type == bool:
1041             retval = self.append_boolean(value)
1042         elif value_type == int:
1043             retval = self.append_int32(value)
1044         elif value_type == long:
1045             retval = self.append_int64(value)
1046         elif (value_type == str or value_type == unicode):
1047             retval = self.append_string(value)
1048         elif value_type == float:
1049             retval = self.append_double(value)
1050         elif value_type == dict:
1051             retval = self.append_dict(value)
1052         elif value_type == tuple:
1053             retval = self.append_struct(value)
1054         elif value_type == list:
1055              retval = self.append_array(value)
1056         #elif value_type == None.__class__:
1057         #    retval = self.append_nil()
1058         elif isinstance(value, ObjectPath):
1059             retval = self.append_object_path(value)
1060         elif isinstance(value, ByteArray):
1061             retval = self.append_array(value)
1062         elif isinstance(value, Signature):
1063             retval = self.append_signature(value)
1064         elif isinstance(value, Byte):
1065             retval = self.append_byte(value)
1066         elif isinstance(value, Boolean):
1067             retval = self.append_boolean(value)
1068         elif isinstance(value, Int16):
1069             retval = self.append_int16(value)
1070         elif isinstance(value, UInt16):
1071             retval = self.append_uint16(value)
1072         elif isinstance(value, Int32):
1073             retval = self.append_int32(value)
1074         elif isinstance(value, UInt32):
1075             retval = self.append_uint32(value)
1076         elif isinstance(value, Int64):
1077             retval = self.append_int64(value)
1078         elif isinstance(value, UInt64):
1079             retval = self.append_uint64(value)
1080         elif isinstance(value, Double):
1081             retval = self.append_double(value)
1082         elif isinstance(value, String):
1083             retval = self.append_string(value)
1084         elif isinstance(value, Array):
1085             retval = self.append_array(value)
1086         elif isinstance(value, Struct):
1087             retval = self.append_struct(value)
1088         elif isinstance(value, Dictionary):
1089             retval = self.append_dict(value)
1090         elif isinstance(value, Variant):
1091             retval = self.append_variant(value)
1092         else:
1093             raise TypeError, "Argument of unknown type '%s'" % (value_type)
1094
1095         return retval
1096
1097     def append_boolean(self, value):
1098         cdef dbus_bool_t c_value
1099         c_value = value
1100         return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value)
1101
1102     def append_byte(self, value):
1103         cdef char b
1104         if type(value) == str and len(value) == 1:
1105                 b = ord(value)
1106         elif type(value) == Byte:
1107                 b = value
1108         else:
1109             raise TypeError
1110
1111         return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b)
1112
1113     def append_int16(self, value):
1114         cdef dbus_int32_t c_value
1115         c_value = value
1116         return dbus_message_iter_append_basic(self.iter, TYPE_INT16, <dbus_int32_t *>&c_value)
1117
1118     def append_uint16(self, value):
1119         cdef dbus_uint32_t c_value
1120         c_value = value
1121         return dbus_message_iter_append_basic(self.iter, TYPE_UINT16, <dbus_uint32_t *>&c_value)
1122
1123     def append_int32(self, value):
1124         cdef dbus_int32_t c_value
1125         c_value = value
1126         return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value)
1127
1128     def append_uint32(self, value):
1129         cdef dbus_uint32_t c_value
1130         c_value = value
1131         return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value)
1132
1133     def append_int64(self, value):
1134         cdef dbus_int64_t c_value
1135         c_value = value
1136         return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value)
1137
1138     def append_uint64(self, value):
1139         cdef dbus_uint64_t c_value
1140         c_value = value
1141         return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value)
1142
1143     def append_double(self, value):
1144         cdef double c_value
1145         c_value = value
1146         return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value)
1147
1148     def append_string(self, value):
1149         cdef char *c_value
1150         tmp = value.encode('utf8')
1151         c_value = tmp
1152         return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value)
1153
1154     def append_object_path(self, value):
1155         cdef char *c_value
1156         c_value = value
1157         return dbus_message_iter_append_basic(self.iter, TYPE_OBJECT_PATH, <char **>&c_value)
1158
1159     def append_signature(self, value):
1160         cdef char *c_value
1161         c_value = value
1162         return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value)
1163
1164
1165     def append_dict(self, python_dict):
1166         cdef DBusMessageIter c_dict_iter, c_dict_entry_iter
1167         cdef MessageIter dict_iter, dict_entry_iter
1168         
1169         level = self.level + 1
1170
1171         key = None
1172         value = None
1173
1174         sig = str(chr(DICT_ENTRY_BEGIN))
1175
1176         if isinstance(python_dict, Dictionary):
1177             key = python_dict.key_type
1178             value = python_dict.value_type
1179             signature = python_dict.signature
1180
1181         dict_list = python_dict.items()
1182
1183         if signature:
1184             sig = sig + signature
1185         else: 
1186             if not (key and value):
1187                 key, value = dict_list[0]
1188
1189             sig = sig + self.python_value_to_dbus_sig(key)
1190             sig = sig + self.python_value_to_dbus_sig(value)
1191
1192         sig = sig + str(chr(DICT_ENTRY_END))
1193
1194         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter)
1195         dict_iter = MessageIter(level)
1196         dict_iter.__cinit__(&c_dict_iter)
1197
1198         for key, value in dict_list:
1199             dbus_message_iter_open_container(dict_iter.iter, TYPE_DICT_ENTRY, sig, <DBusMessageIter *>&c_dict_entry_iter)
1200             dict_entry_iter = MessageIter(level)
1201             dict_entry_iter.__cinit__(&c_dict_entry_iter)
1202
1203             if signature:
1204                 (tmp_sig, remainder) = self.parse_signature_block(signature)
1205                 if not dict_entry_iter.append_strict(key, tmp_sig):
1206                     dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1207                     dbus_message_iter_close_container(self.iter, dict_iter.iter)
1208                     return False
1209
1210                 (tmp_sig, remainder) = self.parse_signature_block(remainder)
1211                 if not dict_entry_iter.append_strict(value, tmp_sig):
1212                     dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1213                     dbus_message_iter_close_container(self.iter, dict_iter.iter)
1214                     return False
1215
1216             else:
1217                 if not dict_entry_iter.append(key):
1218                     dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1219                     dbus_message_iter_close_container(self.iter, dict_iter.iter)
1220                     return False
1221                 
1222                 if not dict_entry_iter.append(value):
1223                     dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1224                     dbus_message_iter_close_container(self.iter, dict_iter.iter)
1225                     return False
1226
1227             dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter)
1228
1229         dbus_message_iter_close_container(self.iter, dict_iter.iter)
1230
1231         return True
1232
1233     def append_struct(self, python_struct, signature = None):
1234         cdef DBusMessageIter c_struct_iter
1235         cdef MessageIter struct_iter
1236
1237         level = self.level + 1
1238         dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter)
1239         struct_iter = MessageIter(level)
1240         struct_iter.__cinit__(&c_struct_iter)
1241
1242         remainder = signature
1243         for item in python_struct:
1244             if signature:
1245                 (sig, remainder) = self.parse_signature_block(remainder)
1246
1247                 if sig == '':
1248                     dbus_message_iter_close_container(self.iter, struct_iter.iter)
1249                     return False
1250
1251                 if not struct_iter.append_strict(item, sig):
1252                     dbus_message_iter_close_container(self.iter, struct_iter.iter)
1253                     return False
1254             else:
1255                 if not struct_iter.append(item):
1256                     dbus_message_iter_close_container(self.iter, struct_iter.iter)
1257                     return False
1258
1259         dbus_message_iter_close_container(self.iter, struct_iter.iter)
1260
1261         return True
1262
1263     def append_array(self, python_list):
1264         cdef DBusMessageIter c_array_iter
1265         cdef MessageIter array_iter
1266
1267         level = self.level + 1
1268
1269         sig = None
1270         if isinstance(python_list, Array):
1271             if python_list.type:
1272                 sig = self.python_value_to_dbus_sig(python_list.type)
1273             elif python_list.signature:
1274                 sig = python_list.signature
1275             else:
1276                 sig = self.python_value_to_dbus_sig(python_list[0])
1277         else:
1278             sig = self.python_value_to_dbus_sig(python_list[0])
1279
1280         dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter)
1281         array_iter = MessageIter(level)
1282         array_iter.__cinit__(&c_array_iter)
1283
1284         length = len(python_list)
1285         for item in python_list:
1286             if not array_iter.append_strict(item, sig):
1287                 dbus_message_iter_close_container(self.iter, array_iter.iter)
1288                 return False
1289
1290         dbus_message_iter_close_container(self.iter, array_iter.iter)
1291
1292         return True
1293
1294     def append_variant(self, value):
1295         cdef DBusMessageIter c_variant_iter
1296         cdef MessageIter variant_iter
1297
1298         level = self.level + 1
1299     
1300         if value.signature:
1301             sig = value.signature
1302         elif value.type:
1303             sig = self.python_value_to_dbus_sig(value.type)
1304         else:
1305             sig = self.python_value_to_dbus_sig(value.value)
1306     
1307         dbus_message_iter_open_container(self.iter, TYPE_VARIANT, sig, <DBusMessageIter *>&c_variant_iter)
1308         
1309         variant_iter = MessageIter(level)
1310         variant_iter.__cinit__(&c_variant_iter)
1311
1312         if not variant_iter.append(value.value):
1313             dbus_message_iter_close_container(self.iter, variant_iter.iter)
1314             return False
1315
1316         dbus_message_iter_close_container(self.iter, variant_iter.iter)
1317         return True
1318
1319     def __str__(self):
1320         cdef DBusMessageIter c_array_iter
1321         cdef MessageIter array_iter
1322
1323         value_at_iter = True
1324         retval = ""
1325         while (value_at_iter):
1326             type = self.get_arg_type()
1327             if type == TYPE_INVALID:
1328                 break
1329             elif type == TYPE_STRING:
1330                 str = iter.get_string()
1331                 arg = 'string:%s\n' % (str)
1332             elif type == TYPE_OBJECT_PATH:
1333                 path = iter.get_object_path()
1334                 arg = 'object_path:%s\n' % (path)
1335             elif type == TYPE_INT32:
1336                 num = iter.get_int32()
1337                 arg = 'int32:%d\n' % (num)
1338             elif type == TYPE_UINT32:
1339                 num = iter.get_uint32()
1340                 arg = 'uint32:%u\n' % (num)
1341             elif type == TYPE_INT64:
1342                 num = iter.get_int64()
1343                 arg = 'int64:%d\n' % (num)
1344             elif type == TYPE_UINT64:
1345                 num = iter.get_uint64()
1346                 arg = 'uint64:%u\n' % (num)
1347             elif type == TYPE_DOUBLE:
1348                 num = iter.get_double()
1349                 arg = 'double:%f\n' % (num)
1350             elif type == TYPE_BYTE:
1351                 num = iter.get_byte()
1352                 arg = 'byte:%x(%s)\n' % (num, str(chr(num)))
1353             elif type == TYPE_BOOLEAN:
1354                 bool = iter.get_boolean()
1355                 if (bool):
1356                     str = "true"
1357                 else:
1358                     str = "false"
1359                 arg = 'boolean:%s\n' % (str)
1360             elif type == TYPE_ARRAY:
1361                 dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter)
1362                 array_iter = MessageIter(self.level + 1)
1363                 array_iter.__cinit__(&c_array_iter)
1364                 if array_iter.has_next():
1365                     arg = 'array [' + str(array_iter) + ']'
1366                 else:
1367                     arg = 'array []'
1368             else:
1369                 arg = '(unknown arg type %d)\n' % type
1370
1371             retval = retval + arg
1372             value_at_iter = self.next()
1373
1374         return retval
1375
1376
1377 (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5)
1378 (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('}'))
1379 (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3)
1380     
1381 cdef class Message:
1382     cdef DBusMessage *msg
1383
1384     def __init__(self, message_type=MESSAGE_TYPE_INVALID,
1385                  service=None, path=None, dbus_interface=None, method=None,
1386                  Message method_call=None,
1387                  name=None,
1388                  Message reply_to=None, error_name=None, error_message=None,
1389                  _create=1):
1390
1391         self.msg = NULL
1392
1393         cdef char *cservice
1394         cdef char *ciface
1395         cdef DBusMessage *cmsg
1396
1397         ciface = NULL
1398         if (dbus_interface != None):
1399             ciface = dbus_interface
1400
1401         cservice = NULL
1402         if (service != None):
1403             cservice = service
1404             
1405         if _create:
1406             if message_type == MESSAGE_TYPE_METHOD_CALL:
1407                 self.msg = dbus_message_new_method_call(cservice, path, ciface, method)
1408             elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1409                 cmsg = method_call._get_msg()
1410                 self.msg = dbus_message_new_method_return(cmsg)
1411             elif message_type == MESSAGE_TYPE_SIGNAL:
1412                 self.msg = dbus_message_new_signal(path, ciface, name)
1413             elif message_type == MESSAGE_TYPE_ERROR:
1414                 cmsg = reply_to._get_msg()
1415                 self.msg = dbus_message_new_error(cmsg, error_name, error_message)
1416  
1417
1418     def __dealloc__(self):
1419         if self.msg != NULL:
1420             dbus_message_unref(self.msg)
1421             
1422     def type_to_name(self, type):
1423         if type == MESSAGE_TYPE_SIGNAL:
1424             return "signal"
1425         elif type == MESSAGE_TYPE_METHOD_CALL:
1426             return "method call"
1427         elif type == MESSAGE_TYPE_METHOD_RETURN:
1428             return "method return"
1429         elif type == MESSAGE_TYPE_ERROR:
1430             return "error"
1431         else:
1432             return "(unknown message type)"
1433
1434     def __str__(self):
1435         message_type = self.get_type()
1436         sender = self.get_sender()
1437
1438         if sender == None:
1439             sender = "(no sender)"
1440
1441         if (message_type == MESSAGE_TYPE_METHOD_CALL) or (message_type == MESSAGE_TYPE_SIGNAL):
1442             retval = '%s interface=%s; member=%s; sender=%s' % (self.type_to_name(message_type),
1443                                                                 self.get_interface(),
1444                                                                 self.get_member(),
1445                                                                 sender)
1446         elif message_type == MESSAGE_TYPE_METHOD_RETURN:
1447             retval = '%s sender=%s' % (self.type_to_name(message_type),
1448                                         sender)
1449         elif message_type == MESSAGE_TYPE_ERROR:
1450             retval = '%s name=%s; sender=%s' % (self.type_to_name(message_type),
1451                                                 self.get_error_name(),
1452                                                 sender)
1453         else:
1454             retval = "Message of unknown type %d" % (message_type)
1455
1456
1457         # FIXME: should really use self.convert_to_tuple() here
1458         
1459         iter = self.get_iter()
1460
1461         retval = retval + "\n" + str(iter) 
1462
1463         return retval
1464     
1465     cdef _set_msg(self, DBusMessage *msg):
1466         self.msg = msg
1467
1468     cdef DBusMessage *_get_msg(self):
1469         return self.msg
1470
1471     def get_iter(self, append=False):
1472         cdef DBusMessageIter iter
1473         cdef MessageIter message_iter
1474         cdef DBusMessage *msg
1475
1476         msg = self._get_msg()
1477
1478         if append:
1479             dbus_message_iter_init_append(msg, &iter)
1480         else:
1481             dbus_message_iter_init(msg, &iter)
1482
1483         message_iter = MessageIter(0)
1484         message_iter.__cinit__(&iter)
1485
1486         return message_iter
1487
1488     def get_args_list(self):
1489         retval = [ ]
1490
1491         iter = self.get_iter()
1492         try:
1493             retval.append(iter.get())
1494         except TypeError, e:
1495             return [ ]
1496             
1497         value_at_iter = iter.next()
1498         while (value_at_iter):
1499             retval.append(iter.get())
1500             value_at_iter = iter.next()        
1501
1502         return retval
1503             
1504     # FIXME: implement dbus_message_copy?
1505
1506     def get_type(self):
1507         return dbus_message_get_type(self.msg)
1508
1509     def set_path(self, object_path):
1510         return dbus_message_set_path(self.msg, object_path)
1511     
1512     def get_path(self):
1513         return dbus_message_get_path(self.msg)
1514     
1515     def set_interface(self, interface):
1516         return dbus_message_set_interface(self.msg, interface)
1517
1518     def get_interface(self):
1519         return dbus_message_get_interface(self.msg)    
1520
1521     def set_member(self, member):
1522         return dbus_message_set_member(self.msg, member)
1523
1524     def get_member(self):
1525         return dbus_message_get_member(self.msg)
1526
1527     def set_error_name(self, name):
1528         return dbus_message_set_error_name(self.msg, name)
1529
1530     def get_error_name(self):
1531         return dbus_message_get_error_name(self.msg)
1532
1533     def set_destination(self, destination):
1534         return dbus_message_set_destination(self.msg, destination)
1535
1536     def get_destination(self):
1537         return dbus_message_get_destination(self.msg)
1538
1539     def set_sender(self, sender):
1540         return dbus_message_set_sender(self.msg, sender)
1541     
1542     def get_sender(self):
1543         cdef char *sender
1544         sender = dbus_message_get_sender(self.msg)
1545         if (sender == NULL):
1546             return None
1547         else:
1548             return sender
1549
1550     def set_no_reply(self, no_reply):
1551         dbus_message_set_no_reply(self.msg, no_reply)
1552
1553     def get_no_reply(self):
1554         return dbus_message_get_no_reply(self.msg)
1555
1556     def is_method_call(self, interface, method):
1557         return dbus_message_is_method_call(self.msg, interface, method)
1558
1559     def is_signal(self, interface, signal_name):
1560         return dbus_message_is_signal(self.msg, interface, signal_name)
1561
1562     def is_error(self, error_name):
1563         return dbus_message_is_error(self.msg, error_name)
1564
1565     def has_destination(self, service):
1566         return dbus_message_has_destination(self.msg, service)
1567
1568     def has_sender(self, service):
1569         return dbus_message_has_sender(self.msg, service)
1570
1571     def get_serial(self):
1572         return dbus_message_get_serial(self.msg)
1573
1574     def set_reply_serial(self, reply_serial):
1575         return dbus_message_set_reply_serial(self.msg, reply_serial)
1576
1577     def get_reply_serial(self):
1578         return dbus_message_get_reply_serial(self.msg)    
1579
1580     #FIXME: dbus_message_get_path_decomposed
1581     
1582     # FIXME: all the different dbus_message_*args* methods
1583
1584 class Signal(Message):
1585     def __init__(self, spath, sinterface, sname):
1586         Message.__init__(self, MESSAGE_TYPE_SIGNAL, path=spath, dbus_interface=sinterface, name=sname)
1587
1588 class EmptyMessage(Message):
1589     def __init__(self):
1590         Message.__init__(self, _create=False)
1591
1592 class MethodCall(Message):
1593     def __init__(self, mpath, minterface, mmethod):
1594         Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, dbus_interface=minterface, method=mmethod)
1595
1596 class MethodReturn(Message):
1597     def __init__(self, method_call):
1598         Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call)
1599
1600 class Error(Message):
1601     def __init__(self, reply_to, error_name, error_message):
1602         Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message)
1603         
1604 cdef class Server:
1605     cdef DBusServer *server
1606     def __init__(self, address):
1607         cdef DBusError error
1608         dbus_error_init(&error)
1609         self.server = dbus_server_listen(address,
1610                                          &error)
1611         if dbus_error_is_set(&error):
1612             errormsg = error.message
1613             dbus_error_free (&error)
1614             raise DBusException, errormsg
1615
1616     def disconnect(self):
1617         dbus_server_disconnect(self.server)
1618
1619     def get_is_connected(self):
1620         return dbus_server_get_is_connected(self.server)
1621
1622 #    def set_new_connection_function(self, function, data):
1623 #        dbus_server_set_new_connection_function(self.conn, function,
1624 #                                                data, NULL)
1625         
1626 #    def set_watch_functions(self, add_function, remove_function, data):
1627 #        dbus_server_set_watch_functions(self.server,
1628 #                                        add_function, remove_function,
1629 #                                        data, NULL)
1630         
1631 #    def set_timeout_functions(self, add_function, remove_function, data):
1632 #        dbus_server_set_timeout_functions(self.server,
1633 #                                          add_function, remove_function,
1634 #                                          data, NULL)
1635         
1636 #    def handle_watch(self, watch, condition):
1637 #        dbus_server_handle_watch(self.conn, watch, condition)
1638
1639 BUS_SESSION = DBUS_BUS_SESSION
1640 BUS_SYSTEM = DBUS_BUS_SYSTEM
1641 BUS_STARTER = DBUS_BUS_STARTER
1642
1643 def bus_get (bus_type, private=False):
1644     cdef DBusError error
1645     cdef Connection conn
1646     cdef DBusConnection *connection
1647
1648     dbus_error_init(&error)
1649     if private:
1650         connection = dbus_bus_get_private(bus_type,
1651                                           &error)
1652     else:
1653         connection = dbus_bus_get(bus_type,
1654                                   &error)
1655
1656     if dbus_error_is_set(&error):
1657         errormsg = error.message
1658         dbus_error_free(&error)
1659         raise DBusException, errormsg 
1660
1661     conn = Connection()
1662     conn.__cinit__(None, connection)
1663     return conn 
1664
1665 def bus_get_unique_name(Connection connection):
1666     cdef DBusConnection *conn
1667     conn = connection._get_conn()
1668     return dbus_bus_get_unique_name(conn)
1669
1670 def bus_get_unix_user(Connection connection, service_name):
1671     cdef DBusError error
1672     dbus_error_init(&error)
1673     cdef int retval
1674     cdef DBusConnection *conn
1675
1676     conn = connection._get_conn()
1677     retval = dbus_bus_get_unix_user(conn, service_name, &error)
1678
1679     if dbus_error_is_set(&error):
1680         errormsg = error.message
1681         dbus_error_free(&error)
1682         raise DBusException, errormsg 
1683
1684     return retval
1685
1686 #These are defines, not enums so they aren't auto generated
1687 DBUS_START_REPLY_SUCCESS = 0 
1688 DBUS_START_REPLY_ALREADY_RUNNING = 1 
1689     
1690 def bus_start_service_by_name(Connection connection, service_name, flags=0):
1691     cdef DBusError error
1692     dbus_error_init(&error)
1693     cdef dbus_bool_t retval
1694     cdef dbus_uint32_t results
1695     cdef DBusConnection *conn
1696
1697     conn = connection._get_conn()
1698
1699     retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error)
1700
1701     if dbus_error_is_set(&error):
1702         errormsg = error.message
1703         dbus_error_free(&error)
1704         raise DBusException, errormsg
1705
1706     return (retval, results) 
1707
1708 def bus_register(Connection connection):
1709     cdef DBusError error
1710     dbus_error_init(&error)
1711     cdef dbus_bool_t retval
1712     cdef DBusConnection *conn
1713
1714     conn = connection._get_conn()
1715     retval = dbus_bus_register(conn,
1716                                &error)
1717     if dbus_error_is_set(&error):
1718         msg = error.message
1719         dbus_error_free(&error)
1720         raise DBusException, errormsg 
1721
1722     return retval
1723
1724 SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1
1725 SERVICE_FLAG_REPLACE_EXISTING     = 0x2
1726
1727 def bus_request_name(Connection connection, service_name, flags=0):
1728     cdef DBusError error
1729     dbus_error_init(&error)
1730     cdef int retval
1731     cdef DBusConnection *conn
1732
1733     conn = connection._get_conn()
1734     retval = dbus_bus_request_name(conn,
1735                                    service_name,
1736                                    flags,
1737                                    &error)
1738     if dbus_error_is_set(&error):
1739         errormsg = error.message
1740         dbus_error_free(&error)
1741         raise DBusException, errormsg
1742         
1743     return retval
1744     
1745 def bus_name_has_owner(Connection connection, service_name):
1746     cdef DBusError error
1747     dbus_error_init(&error)
1748     cdef dbus_bool_t retval
1749     cdef DBusConnection *conn
1750
1751     conn = connection._get_conn()
1752     retval = dbus_bus_name_has_owner(conn,
1753                                      service_name,
1754                                      &error)
1755     if dbus_error_is_set(&error):
1756         errormsg = error.message
1757         dbus_error_free(&error)
1758         raise DBusException, errormsg
1759         
1760     return retval
1761
1762 def bus_add_match(Connection connection, rule):
1763     cdef DBusError error
1764     cdef DBusConnection *conn
1765
1766     dbus_error_init(&error)
1767     
1768     conn = connection._get_conn()
1769     dbus_bus_add_match (conn, rule, &error)
1770     
1771     if dbus_error_is_set(&error):
1772         errormsg = error.message
1773         dbus_error_free(&error)
1774         raise DBusException, errormsg
1775
1776 def bus_remove_match(Connection connection, rule):
1777     cdef DBusError error
1778     cdef DBusConnection *conn
1779
1780     dbus_error_init(&error)
1781
1782     conn = connection._get_conn()
1783     dbus_bus_remove_match (conn, rule, &error)
1784     
1785     if dbus_error_is_set(&error):
1786         errormsg = error.message
1787         dbus_error_free(&error)
1788         raise DBusException, errormsg
1789