Imported Upstream version 1.2.0
[platform/upstream/dbus-python.git] / _dbus_bindings / message.c
1 /* Implementation of D-Bus Message and subclasses (but see message-get-args.h
2  * and message-append.h for unserialization and serialization code).
3  *
4  * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use, copy,
10  * modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  */
26
27 #include "dbus_bindings-internal.h"
28 #include "message-internal.h"
29
30 static PyTypeObject MessageType, SignalMessageType, ErrorMessageType;
31 static PyTypeObject MethodReturnMessageType, MethodCallMessageType;
32
33 static inline int Message_Check(PyObject *o)
34 {
35     return (Py_TYPE(o) == &MessageType)
36             || PyObject_IsInstance(o, (PyObject *)&MessageType);
37 }
38
39 PyObject *
40 DBusPy_RaiseUnusableMessage(void)
41 {
42     DBusPyException_SetString("Message object is uninitialized, or has become "
43                               "unusable due to error while appending "
44                               "arguments");
45     return NULL;
46 }
47
48 PyDoc_STRVAR(Message_tp_doc,
49 "A message to be sent or received over a D-Bus Connection.\n");
50
51 static void Message_tp_dealloc(Message *self)
52 {
53     if (self->msg) {
54         dbus_message_unref(self->msg);
55     }
56     Py_TYPE(self)->tp_free((PyObject *)self);
57 }
58
59 static PyObject *
60 Message_tp_new(PyTypeObject *type,
61                PyObject *args UNUSED,
62                PyObject *kwargs UNUSED)
63 {
64     Message *self;
65
66     self = (Message *)type->tp_alloc(type, 0);
67     if (!self) return NULL;
68     self->msg = NULL;
69     return (PyObject *)self;
70 }
71
72 static PyObject *
73 MethodCallMessage_tp_repr(PyObject *self)
74 {
75     DBusMessage *msg = ((Message *)self)->msg;
76     const char *destination = dbus_message_get_destination(msg);
77     const char *path = dbus_message_get_path(msg);
78     const char *interface = dbus_message_get_interface(msg);
79     const char *member = dbus_message_get_member(msg);
80
81     if (!path)
82         path = "n/a";
83     if (!interface)
84         interface = "n/a";
85     if (!member)
86         member = "n/a";
87     if (!destination)
88         destination = "n/a";
89
90     return PyUnicode_FromFormat(
91         "<%s path: %s, iface: %s, member: %s dest: %s>",
92         Py_TYPE(self)->tp_name,
93         path, interface, member, destination);
94 }
95
96 PyDoc_STRVAR(MethodCallMessage_tp_doc, "A method-call message.\n"
97 "\n"
98 "Constructor::\n"
99 "\n"
100 "    dbus.lowlevel.MethodCallMessage(destination: str or None, path: str,\n"
101 "                                    interface: str or None, method: str)\n"
102 "\n"
103 "``destination`` is the destination bus name, or None to send the\n"
104 "message directly to the peer (usually the bus daemon).\n"
105 "\n"
106 "``path`` is the object-path of the object whose method is to be called.\n"
107 "\n"
108 "``interface`` is the interface qualifying the method name, or None to omit\n"
109 "the interface from the message header.\n"
110 "\n"
111 "``method`` is the method name (member name).\n"
112 );
113
114 static int
115 MethodCallMessage_tp_init(Message *self, PyObject *args, PyObject *kwargs)
116 {
117     const char *destination, *path, *interface, *method;
118     static char *kwlist[] = {"destination", "path", "interface", "method", NULL};
119
120     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zszs:__init__", kwlist,
121                                      &destination, &path, &interface,
122                                      &method)) {
123         return -1;
124     }
125     if (destination && !dbus_py_validate_bus_name(destination, 1, 1)) return -1;
126     if (!dbus_py_validate_object_path(path)) return -1;
127     if (interface && !dbus_py_validate_interface_name(interface)) return -1;
128     if (!dbus_py_validate_member_name(method)) return -1;
129     if (self->msg) {
130         dbus_message_unref(self->msg);
131         self->msg = NULL;
132     }
133     self->msg = dbus_message_new_method_call(destination, path, interface,
134                                              method);
135     if (!self->msg) {
136         PyErr_NoMemory();
137         return -1;
138     }
139     return 0;
140 }
141
142 PyDoc_STRVAR(MethodReturnMessage_tp_doc, "A method-return message.\n\n"
143 "Constructor::\n\n"
144 "    dbus.lowlevel.MethodReturnMessage(method_call: MethodCallMessage)\n");
145
146 static int
147 MethodReturnMessage_tp_init(Message *self, PyObject *args, PyObject *kwargs)
148 {
149     Message *other;
150     static char *kwlist[] = {"method_call", NULL};
151
152     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!:__init__", kwlist,
153                                      &MessageType, &other)) {
154         return -1;
155     }
156     if (self->msg) {
157         dbus_message_unref(self->msg);
158         self->msg = NULL;
159     }
160     self->msg = dbus_message_new_method_return(other->msg);
161     if (!self->msg) {
162         PyErr_NoMemory();
163         return -1;
164     }
165     return 0;
166 }
167
168 PyDoc_STRVAR(SignalMessage_tp_doc, "A signal message.\n\n"
169 "Constructor::\n\n"
170 "   dbus.lowlevel.SignalMessage(path: str, interface: str, method: str)\n");
171 static int
172 SignalMessage_tp_init(Message *self, PyObject *args, PyObject *kwargs)
173 {
174     const char *path, *interface, *name;
175     static char *kwlist[] = {"path", "interface", "name", NULL};
176
177     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss:__init__", kwlist,
178                                     &path, &interface, &name)) {
179       return -1;
180     }
181     if (!dbus_py_validate_object_path(path)) return -1;
182     if (!dbus_py_validate_interface_name(interface)) return -1;
183     if (!dbus_py_validate_member_name(name)) return -1;
184     if (self->msg) {
185         dbus_message_unref(self->msg);
186         self->msg = NULL;
187     }
188     self->msg = dbus_message_new_signal(path, interface, name);
189     if (!self->msg) {
190         PyErr_NoMemory();
191         return -1;
192     }
193     return 0;
194 }
195
196 static PyObject *
197 SignalMessage_tp_repr(PyObject *self)
198 {
199     DBusMessage *msg = ((Message *)self)->msg;
200     const char *path = dbus_message_get_path(msg);
201     const char *interface = dbus_message_get_interface(msg);
202     const char *member = dbus_message_get_member(msg);
203     const char *destination = dbus_message_get_destination(msg);
204
205     if (!path)
206         path = "n/a";
207     if (!interface)
208         interface = "n/a";
209     if (!member)
210         member = "n/a";
211     if (!destination)
212         destination = "(broadcast)";
213
214     return PyUnicode_FromFormat("<%s path: %s, iface: %s, member: %s, dest: %s>",
215                                 Py_TYPE(self)->tp_name,
216                                 path, interface, member, destination);
217 }
218
219 PyDoc_STRVAR(ErrorMessage_tp_doc, "An error message.\n\n"
220 "Constructor::\n\n"
221 "   dbus.lowlevel.ErrorMessage(reply_to: Message, error_name: str,\n"
222 "                              error_message: str or None)\n");
223 static int
224 ErrorMessage_tp_init(Message *self, PyObject *args, PyObject *kwargs)
225 {
226     Message *reply_to;
227     const char *error_name, *error_message;
228     static char *kwlist[] = {"reply_to", "error_name", "error_message", NULL};
229
230     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!sz:__init__", kwlist,
231                                       &MessageType, &reply_to, &error_name,
232                                       &error_message)) {
233         return -1;
234     }
235     if (!dbus_py_validate_error_name(error_name)) return -1;
236     if (self->msg) {
237         dbus_message_unref(self->msg);
238         self->msg = NULL;
239     }
240     self->msg = dbus_message_new_error(reply_to->msg, error_name, error_message);
241     if (!self->msg) {
242         PyErr_NoMemory();
243         return -1;
244     }
245     return 0;
246 }
247
248 DBusMessage *
249 DBusPyMessage_BorrowDBusMessage(PyObject *msg)
250 {
251     if (!Message_Check(msg)) {
252         PyErr_SetString(PyExc_TypeError,
253                        "A dbus.lowlevel.Message instance is required");
254         return NULL;
255     }
256     if (!((Message *)msg)->msg) {
257         DBusPy_RaiseUnusableMessage();
258         return NULL;
259     }
260     return ((Message *)msg)->msg;
261 }
262
263 PyObject *
264 DBusPyMessage_ConsumeDBusMessage(DBusMessage *msg)
265 {
266     PyTypeObject *type;
267     Message *self;
268
269     switch (dbus_message_get_type(msg)) {
270     case DBUS_MESSAGE_TYPE_METHOD_CALL:
271         type = &MethodCallMessageType;
272         break;
273     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
274         type = &MethodReturnMessageType;
275         break;
276     case DBUS_MESSAGE_TYPE_ERROR:
277         type = &ErrorMessageType;
278         break;
279     case DBUS_MESSAGE_TYPE_SIGNAL:
280         type = &SignalMessageType;
281         break;
282     default:
283         type = &MessageType;
284     }
285
286     self = (Message *)(type->tp_new) (type, dbus_py_empty_tuple, NULL);
287     if (!self) {
288         dbus_message_unref(msg);
289         return NULL;
290     }
291     self->msg = msg;
292     return (PyObject *)self;
293 }
294
295 PyDoc_STRVAR(Message_copy__doc__,
296 "message.copy() -> Message (or subclass)\n"
297 "Deep-copy the message, resetting the serial number to zero.\n");
298 static PyObject *
299 Message_copy(Message *self, PyObject *args UNUSED)
300 {
301     DBusMessage *msg;
302     if (!self->msg) return DBusPy_RaiseUnusableMessage();
303     msg = dbus_message_copy(self->msg);
304     if (!msg) return PyErr_NoMemory();
305     return DBusPyMessage_ConsumeDBusMessage(msg);
306 }
307
308 PyDoc_STRVAR(Message_get_auto_start__doc__,
309 "message.get_auto_start() -> bool\n"
310 "Return true if this message will cause an owner for the destination name\n"
311 "to be auto-started.\n");
312 static PyObject *
313 Message_get_auto_start(Message *self, PyObject *unused UNUSED)
314 {
315     if (!self->msg) return DBusPy_RaiseUnusableMessage();
316     return PyBool_FromLong(dbus_message_get_auto_start(self->msg));
317 }
318
319 PyDoc_STRVAR(Message_set_auto_start__doc__,
320 "message.set_auto_start(bool) -> None\n"
321 "Set whether this message will cause an owner for the destination name\n"
322 "to be auto-started.\n");
323 static PyObject *
324 Message_set_auto_start(Message *self, PyObject *args)
325 {
326     int value;
327     if (!PyArg_ParseTuple(args, "i", &value)) return NULL;
328     if (!self->msg) return DBusPy_RaiseUnusableMessage();
329     dbus_message_set_auto_start(self->msg, value ? TRUE : FALSE);
330     Py_INCREF(Py_None);
331     return Py_None;
332 }
333
334 PyDoc_STRVAR(Message_get_no_reply__doc__,
335 "message.get_no_reply() -> bool\n"
336 "Return true if this message need not be replied to.\n");
337 static PyObject *
338 Message_get_no_reply(Message *self, PyObject *unused UNUSED)
339 {
340     if (!self->msg) return DBusPy_RaiseUnusableMessage();
341     return PyBool_FromLong(dbus_message_get_no_reply(self->msg));
342 }
343
344 PyDoc_STRVAR(Message_set_no_reply__doc__,
345 "message.set_no_reply(bool) -> None\n"
346 "Set whether no reply to this message is required.\n");
347 static PyObject *
348 Message_set_no_reply(Message *self, PyObject *args)
349 {
350     int value;
351     if (!PyArg_ParseTuple(args, "i", &value)) return NULL;
352     if (!self->msg) return DBusPy_RaiseUnusableMessage();
353     dbus_message_set_no_reply(self->msg, value ? TRUE : FALSE);
354     Py_RETURN_NONE;
355 }
356
357 PyDoc_STRVAR(Message_get_reply_serial__doc__,
358 "message.get_reply_serial() -> long\n"
359 "Returns the serial that the message is a reply to or 0 if none.\n");
360 static PyObject *
361 Message_get_reply_serial(Message *self, PyObject *unused UNUSED)
362 {
363     if (!self->msg) return DBusPy_RaiseUnusableMessage();
364     return PyLong_FromUnsignedLong(dbus_message_get_reply_serial(self->msg));
365 }
366
367 PyDoc_STRVAR(Message_set_reply_serial__doc__,
368 "message.set_reply_serial(bool) -> None\n"
369 "Set the serial that this message is a reply to.\n");
370 static PyObject *
371 Message_set_reply_serial(Message *self, PyObject *args)
372 {
373     dbus_uint32_t value;
374
375     if (!PyArg_ParseTuple(args, "k", &value)) return NULL;
376     if (!self->msg) return DBusPy_RaiseUnusableMessage();
377     if (!dbus_message_set_reply_serial(self->msg, value)) {
378         return PyErr_NoMemory();
379     }
380     Py_INCREF(Py_None);
381     return Py_None;
382 }
383
384 PyDoc_STRVAR(Message_get_type__doc__,
385 "message.get_type() -> int\n\n"
386 "Returns the type of the message.\n");
387 static PyObject *
388 Message_get_type(Message *self, PyObject *unused UNUSED)
389 {
390     if (!self->msg) return DBusPy_RaiseUnusableMessage();
391     return NATIVEINT_FROMLONG(dbus_message_get_type(self->msg));
392 }
393
394 PyDoc_STRVAR(Message_get_serial__doc__,
395 "message.get_serial() -> long\n"
396 "Returns the serial of a message or 0 if none has been specified.\n"
397 "\n"
398 "The message's serial number is provided by the application sending the\n"
399 "message and is used to identify replies to this message. All messages\n"
400 "received on a connection will have a serial, but messages you haven't\n"
401 "sent yet may return 0.\n");
402 static PyObject *
403 Message_get_serial(Message *self, PyObject *unused UNUSED)
404 {
405     if (!self->msg) return DBusPy_RaiseUnusableMessage();
406     return PyLong_FromUnsignedLong(dbus_message_get_serial(self->msg));
407 }
408
409 PyDoc_STRVAR(Message_is_method_call__doc__,
410 "is_method_call(interface: str, member: str) -> bool");
411 static PyObject *
412 Message_is_method_call(Message *self, PyObject *args)
413 {
414     const char *interface, *method;
415
416     if (!PyArg_ParseTuple(args, "ss:is_method_call", &interface, &method)) {
417         return NULL;
418     }
419     if (!self->msg) return DBusPy_RaiseUnusableMessage();
420     return PyBool_FromLong(dbus_message_is_method_call(self->msg, interface,
421                                                        method));
422 }
423
424 PyDoc_STRVAR(Message_is_error__doc__,
425 "is_error(error: str) -> bool");
426 static PyObject *
427 Message_is_error(Message *self, PyObject *args)
428 {
429     const char *error_name;
430
431     if (!PyArg_ParseTuple(args, "s:is_error", &error_name)) {
432         return NULL;
433     }
434     if (!self->msg) return DBusPy_RaiseUnusableMessage();
435     return PyBool_FromLong(dbus_message_is_error(self->msg, error_name));
436 }
437
438 PyDoc_STRVAR(Message_is_signal__doc__,
439 "is_signal(interface: str, member: str) -> bool");
440 static PyObject *
441 Message_is_signal(Message *self, PyObject *args)
442 {
443     const char *interface, *signal_name;
444
445     if (!PyArg_ParseTuple(args, "ss:is_signal", &interface, &signal_name)) {
446         return NULL;
447     }
448     if (!self->msg) return DBusPy_RaiseUnusableMessage();
449     return PyBool_FromLong(dbus_message_is_signal(self->msg, interface,
450                                                     signal_name));
451 }
452
453 PyDoc_STRVAR(Message_get_member__doc__,
454 "get_member() -> str or None");
455 static PyObject *
456 Message_get_member(Message *self, PyObject *unused UNUSED)
457 {
458     const char *c_str;
459
460     if (!self->msg) return DBusPy_RaiseUnusableMessage();
461     c_str = dbus_message_get_member(self->msg);
462     if (!c_str) {
463         Py_RETURN_NONE;
464     }
465     return NATIVESTR_FROMSTR(c_str);
466 }
467
468 PyDoc_STRVAR(Message_has_member__doc__,
469 "has_member(name: str or None) -> bool");
470 static PyObject *
471 Message_has_member(Message *self, PyObject *args)
472 {
473     const char *name;
474
475     if (!PyArg_ParseTuple(args, "z:has_member", &name)) {
476         return NULL;
477     }
478     if (!self->msg) return DBusPy_RaiseUnusableMessage();
479     return PyBool_FromLong(dbus_message_has_member(self->msg, name));
480 }
481
482 PyDoc_STRVAR(Message_set_member__doc__,
483 "set_member(unique_name: str or None)");
484 static PyObject *
485 Message_set_member(Message *self, PyObject *args)
486 {
487     const char *name;
488
489     if (!PyArg_ParseTuple(args, "z:set_member", &name)) {
490         return NULL;
491     }
492     if (!self->msg) return DBusPy_RaiseUnusableMessage();
493     if (!dbus_py_validate_member_name(name)) return NULL;
494     if (!dbus_message_set_member(self->msg, name)) return PyErr_NoMemory();
495     Py_RETURN_NONE;
496 }
497
498 PyDoc_STRVAR(Message_get_path__doc__,
499 "get_path() -> ObjectPath or None\n\n"
500 "Return the message's destination object path (if it's a method call) or\n"
501 "source object path (if it's a method reply or a signal) or None (if it\n"
502 "has no path).\n");
503 static PyObject *
504 Message_get_path(Message *self, PyObject *unused UNUSED)
505 {
506     const char *c_str;
507
508     if (!self->msg) return DBusPy_RaiseUnusableMessage();
509     c_str = dbus_message_get_path(self->msg);
510     if (!c_str) {
511         Py_RETURN_NONE;
512     }
513     return PyObject_CallFunction((PyObject *)&DBusPyObjectPath_Type, "(s)", c_str);
514 }
515
516 PyDoc_STRVAR(Message_get_path_decomposed__doc__,
517 "get_path_decomposed() -> list of str, or None\n\n"
518 "Return a list of path components (e.g. /foo/bar -> ['foo','bar'], / -> [])\n"
519 "or None if the message has no associated path.\n");
520 static PyObject *
521 Message_get_path_decomposed(Message *self, PyObject *unused UNUSED)
522 {
523     char **paths, **ptr;
524     PyObject *ret = PyList_New(0);
525
526     if (!ret) return NULL;
527     if (!self->msg) {
528         Py_CLEAR(ret);
529         return DBusPy_RaiseUnusableMessage();
530     }
531     if (!dbus_message_get_path_decomposed(self->msg, &paths)) {
532         Py_CLEAR(ret);
533         return PyErr_NoMemory();
534     }
535     if (!paths) {
536         Py_CLEAR(ret);
537         Py_RETURN_NONE;
538     }
539     for (ptr = paths; *ptr; ptr++) {
540         PyObject *str = NATIVESTR_FROMSTR(*ptr);
541
542         if (!str) {
543             Py_CLEAR(ret);
544             break;
545         }
546         if (PyList_Append(ret, str) < 0) {
547             Py_CLEAR(ret);
548             break;
549         }
550         Py_CLEAR(str);
551         str = NULL;
552     }
553     dbus_free_string_array(paths);
554     return ret;
555 }
556
557 PyDoc_STRVAR(Message_has_path__doc__,
558 "has_path(name: str or None) -> bool");
559 static PyObject *
560 Message_has_path(Message *self, PyObject *args)
561 {
562     const char *name;
563
564     if (!PyArg_ParseTuple(args, "z:has_path", &name)) {
565         return NULL;
566     }
567     if (!self->msg) return DBusPy_RaiseUnusableMessage();
568     return PyBool_FromLong(dbus_message_has_path(self->msg, name));
569 }
570
571 PyDoc_STRVAR(Message_set_path__doc__,
572 "set_path(name: str or None)");
573 static PyObject *
574 Message_set_path(Message *self, PyObject *args)
575 {
576     const char *name;
577
578     if (!PyArg_ParseTuple(args, "z:set_path", &name)) return NULL;
579     if (!self->msg) return DBusPy_RaiseUnusableMessage();
580     if (!dbus_message_has_path(self->msg, name)) return PyErr_NoMemory();
581     Py_RETURN_NONE;
582 }
583
584 PyDoc_STRVAR(Message_get_signature__doc__,
585 "get_signature() -> Signature or None");
586 static PyObject *
587 Message_get_signature(Message *self, PyObject *unused UNUSED)
588 {
589     const char *c_str;
590
591     if (!self->msg) return DBusPy_RaiseUnusableMessage();
592     c_str = dbus_message_get_signature(self->msg);
593     if (!c_str) {
594         return PyObject_CallFunction((PyObject *)&DBusPySignature_Type, "(s)", "");
595     }
596     return PyObject_CallFunction((PyObject *)&DBusPySignature_Type, "(s)", c_str);
597 }
598
599 PyDoc_STRVAR(Message_has_signature__doc__,
600 "has_signature(signature: str) -> bool");
601 static PyObject *
602 Message_has_signature(Message *self, PyObject *args)
603 {
604     const char *name;
605
606     if (!PyArg_ParseTuple(args, "s:has_signature", &name)) {
607         return NULL;
608     }
609     if (!self->msg) return DBusPy_RaiseUnusableMessage();
610     return PyBool_FromLong(dbus_message_has_signature(self->msg, name));
611 }
612
613 PyDoc_STRVAR(Message_get_sender__doc__,
614 "get_sender() -> str or None\n\n"
615 "Return the message's sender unique name, or None if none.\n");
616 static PyObject *
617 Message_get_sender(Message *self, PyObject *unused UNUSED)
618 {
619     const char *c_str;
620
621     if (!self->msg) return DBusPy_RaiseUnusableMessage();
622     c_str = dbus_message_get_sender(self->msg);
623     if (!c_str) {
624         Py_RETURN_NONE;
625     }
626     return NATIVESTR_FROMSTR(c_str);
627 }
628
629 PyDoc_STRVAR(Message_has_sender__doc__,
630 "has_sender(unique_name: str) -> bool");
631 static PyObject *
632 Message_has_sender(Message *self, PyObject *args)
633 {
634   const char *name;
635
636   if (!PyArg_ParseTuple(args, "s:has_sender", &name)) {
637       return NULL;
638   }
639   if (!self->msg) return DBusPy_RaiseUnusableMessage();
640   return PyBool_FromLong(dbus_message_has_sender(self->msg, name));
641 }
642
643 PyDoc_STRVAR(Message_set_sender__doc__,
644 "set_sender(unique_name: str or None)");
645 static PyObject *
646 Message_set_sender(Message *self, PyObject *args)
647 {
648     const char *name;
649
650     if (!PyArg_ParseTuple(args, "z:set_sender", &name)) {
651         return NULL;
652     }
653     if (!self->msg) return DBusPy_RaiseUnusableMessage();
654     if (!dbus_py_validate_bus_name(name, 1, 1)) return NULL;
655     if (!dbus_message_set_sender(self->msg, name)) return PyErr_NoMemory();
656     Py_RETURN_NONE;
657 }
658
659 PyDoc_STRVAR(Message_get_destination__doc__,
660 "get_destination() -> str or None\n\n"
661 "Return the message's destination bus name, or None if none.\n");
662 static PyObject *
663 Message_get_destination(Message *self, PyObject *unused UNUSED)
664 {
665     const char *c_str;
666
667     if (!self->msg) return DBusPy_RaiseUnusableMessage();
668     c_str = dbus_message_get_destination(self->msg);
669     if (!c_str) {
670         Py_RETURN_NONE;
671     }
672     return NATIVESTR_FROMSTR(c_str);
673 }
674
675 PyDoc_STRVAR(Message_has_destination__doc__,
676 "has_destination(bus_name: str) -> bool");
677 static PyObject *
678 Message_has_destination(Message *self, PyObject *args)
679 {
680     const char *name;
681
682     if (!PyArg_ParseTuple(args, "s:has_destination", &name)) {
683         return NULL;
684     }
685     if (!self->msg) return DBusPy_RaiseUnusableMessage();
686     return PyBool_FromLong(dbus_message_has_destination(self->msg, name));
687 }
688
689 PyDoc_STRVAR(Message_set_destination__doc__,
690 "set_destination(bus_name: str or None)");
691 static PyObject *
692 Message_set_destination(Message *self, PyObject *args)
693 {
694     const char *name;
695
696     if (!PyArg_ParseTuple(args, "z:set_destination", &name)) {
697         return NULL;
698     }
699     if (!self->msg) return DBusPy_RaiseUnusableMessage();
700     if (!dbus_py_validate_bus_name(name, 1, 1)) return NULL;
701     if (!dbus_message_set_destination(self->msg, name)) return PyErr_NoMemory();
702     Py_RETURN_NONE;
703 }
704
705 PyDoc_STRVAR(Message_get_interface__doc__,
706 "get_interface() -> str or None");
707 static PyObject *
708 Message_get_interface(Message *self, PyObject *unused UNUSED)
709 {
710     const char *c_str;
711
712     if (!self->msg) return DBusPy_RaiseUnusableMessage();
713     c_str = dbus_message_get_interface(self->msg);
714     if (!c_str) {
715         Py_RETURN_NONE;
716     }
717     return NATIVESTR_FROMSTR(c_str);
718 }
719
720 PyDoc_STRVAR(Message_has_interface__doc__,
721 "has_interface(interface: str or None) -> bool");
722 static PyObject *
723 Message_has_interface(Message *self, PyObject *args)
724 {
725     const char *name;
726
727     if (!PyArg_ParseTuple(args, "z:has_interface", &name)) {
728         return NULL;
729     }
730     if (!self->msg) return DBusPy_RaiseUnusableMessage();
731     return PyBool_FromLong(dbus_message_has_interface(self->msg, name));
732 }
733
734 PyDoc_STRVAR(Message_set_interface__doc__,
735 "set_interface(name: str or None)");
736 static PyObject *
737 Message_set_interface(Message *self, PyObject *args)
738 {
739     const char *name;
740
741     if (!PyArg_ParseTuple(args, "z:set_interface", &name)) {
742         return NULL;
743     }
744     if (!self->msg) return DBusPy_RaiseUnusableMessage();
745     if (!dbus_py_validate_interface_name(name)) return NULL;
746     if (!dbus_message_set_interface(self->msg, name)) return PyErr_NoMemory();
747     Py_RETURN_NONE;
748 }
749
750 PyDoc_STRVAR(Message_get_error_name__doc__,
751 "get_error_name() -> str or None");
752 static PyObject *
753 Message_get_error_name(Message *self, PyObject *unused UNUSED)
754 {
755     const char *c_str;
756
757     if (!self->msg) return DBusPy_RaiseUnusableMessage();
758     c_str = dbus_message_get_error_name(self->msg);
759     if (!c_str) {
760         Py_RETURN_NONE;
761     }
762     return NATIVESTR_FROMSTR(c_str);
763 }
764
765 PyDoc_STRVAR(Message_set_error_name__doc__,
766 "set_error_name(name: str or None)");
767 static PyObject *
768 Message_set_error_name(Message *self, PyObject *args)
769 {
770     const char *name;
771
772     if (!PyArg_ParseTuple(args, "z:set_error_name", &name)) {
773         return NULL;
774     }
775     if (!self->msg) return DBusPy_RaiseUnusableMessage();
776     if (!dbus_py_validate_error_name(name)) return NULL;
777     if (!dbus_message_set_error_name(self->msg, name)) return PyErr_NoMemory();
778     Py_RETURN_NONE;
779 }
780
781 static PyMethodDef Message_tp_methods[] = {
782     {"copy", (PyCFunction)Message_copy,
783       METH_NOARGS, Message_copy__doc__},
784     {"is_method_call", (PyCFunction)Message_is_method_call,
785       METH_VARARGS, Message_is_method_call__doc__},
786     {"is_signal", (PyCFunction)Message_is_signal,
787       METH_VARARGS, Message_is_signal__doc__},
788     {"is_error", (PyCFunction)Message_is_error,
789       METH_VARARGS, Message_is_error__doc__},
790
791     {"get_args_list", (PyCFunction)dbus_py_Message_get_args_list,
792       METH_VARARGS|METH_KEYWORDS, dbus_py_Message_get_args_list__doc__},
793     {"guess_signature", (PyCFunction)dbus_py_Message_guess_signature,
794       METH_VARARGS|METH_STATIC, dbus_py_Message_guess_signature__doc__},
795     {"append", (PyCFunction)dbus_py_Message_append,
796       METH_VARARGS|METH_KEYWORDS, dbus_py_Message_append__doc__},
797
798     {"get_auto_start", (PyCFunction)Message_get_auto_start,
799       METH_NOARGS, Message_get_auto_start__doc__},
800     {"set_auto_start", (PyCFunction)Message_set_auto_start,
801       METH_VARARGS, Message_set_auto_start__doc__},
802     {"get_destination", (PyCFunction)Message_get_destination,
803       METH_NOARGS, Message_get_destination__doc__},
804     {"set_destination", (PyCFunction)Message_set_destination,
805       METH_VARARGS, Message_set_destination__doc__},
806     {"has_destination", (PyCFunction)Message_has_destination,
807       METH_VARARGS, Message_has_destination__doc__},
808     {"get_error_name", (PyCFunction)Message_get_error_name,
809       METH_NOARGS, Message_get_error_name__doc__},
810     {"set_error_name", (PyCFunction)Message_set_error_name,
811       METH_VARARGS, Message_set_error_name__doc__},
812     {"get_interface", (PyCFunction)Message_get_interface,
813       METH_NOARGS, Message_get_interface__doc__},
814     {"set_interface", (PyCFunction)Message_set_interface,
815       METH_VARARGS, Message_set_interface__doc__},
816     {"has_interface", (PyCFunction)Message_has_interface,
817       METH_VARARGS, Message_has_interface__doc__},
818     {"get_member", (PyCFunction)Message_get_member,
819       METH_NOARGS, Message_get_member__doc__},
820     {"set_member", (PyCFunction)Message_set_member,
821       METH_VARARGS, Message_set_member__doc__},
822     {"has_member", (PyCFunction)Message_has_member,
823       METH_VARARGS, Message_has_member__doc__},
824     {"get_path", (PyCFunction)Message_get_path,
825       METH_NOARGS, Message_get_path__doc__},
826     {"get_path_decomposed", (PyCFunction)Message_get_path_decomposed,
827       METH_NOARGS, Message_get_path_decomposed__doc__},
828     {"set_path", (PyCFunction)Message_set_path,
829       METH_VARARGS, Message_set_path__doc__},
830     {"has_path", (PyCFunction)Message_has_path,
831       METH_VARARGS, Message_has_path__doc__},
832     {"get_no_reply", (PyCFunction)Message_get_no_reply,
833       METH_NOARGS, Message_get_no_reply__doc__},
834     {"set_no_reply", (PyCFunction)Message_set_no_reply,
835       METH_VARARGS, Message_set_no_reply__doc__},
836     {"get_reply_serial", (PyCFunction)Message_get_reply_serial,
837       METH_NOARGS, Message_get_reply_serial__doc__},
838     {"set_reply_serial", (PyCFunction)Message_set_reply_serial,
839       METH_VARARGS, Message_set_reply_serial__doc__},
840     {"get_sender", (PyCFunction)Message_get_sender,
841       METH_NOARGS, Message_get_sender__doc__},
842     {"set_sender", (PyCFunction)Message_set_sender,
843       METH_VARARGS, Message_set_sender__doc__},
844     {"has_sender", (PyCFunction)Message_has_sender,
845       METH_VARARGS, Message_has_sender__doc__},
846     {"get_serial", (PyCFunction)Message_get_serial,
847       METH_NOARGS, Message_get_serial__doc__},
848     {"get_signature", (PyCFunction)Message_get_signature,
849       METH_NOARGS, Message_get_signature__doc__},
850     {"has_signature", (PyCFunction)Message_has_signature,
851       METH_VARARGS, Message_has_signature__doc__},
852     {"get_type", (PyCFunction)Message_get_type,
853       METH_NOARGS, Message_get_type__doc__},
854     {NULL, NULL, 0, NULL}
855 };
856
857 static PyTypeObject MessageType = {
858     PyVarObject_HEAD_INIT(NULL, 0)
859     "dbus.lowlevel.Message",   /*tp_name*/
860     sizeof(Message),     /*tp_basicsize*/
861     0,                         /*tp_itemsize*/
862     (destructor)Message_tp_dealloc, /*tp_dealloc*/
863     0,                         /*tp_print*/
864     0,                         /*tp_getattr*/
865     0,                         /*tp_setattr*/
866     0,                         /*tp_compare*/
867     0,                         /*tp_repr*/
868     0,                         /*tp_as_number*/
869     0,                         /*tp_as_sequence*/
870     0,                         /*tp_as_mapping*/
871     0,                         /*tp_hash */
872     0,                         /*tp_call*/
873     0,                         /*tp_str*/
874     0,                         /*tp_getattro*/
875     0,                         /*tp_setattro*/
876     0,                         /*tp_as_buffer*/
877     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
878     Message_tp_doc,            /* tp_doc */
879     0,                         /* tp_traverse */
880     0,                         /* tp_clear */
881     0,                         /* tp_richcompare */
882     0,                         /* tp_weaklistoffset */
883     0,                         /* tp_iter */
884     0,                         /* tp_iternext */
885     Message_tp_methods,        /* tp_methods */
886     0,                         /* tp_members */
887     0,                         /* tp_getset */
888     0,                         /* tp_base */
889     0,                         /* tp_dict */
890     0,                         /* tp_descr_get */
891     0,                         /* tp_descr_set */
892     0,                         /* tp_dictoffset */
893     0,                         /* tp_init */
894     0,                         /* tp_alloc */
895     Message_tp_new,            /* tp_new */
896 };
897
898 static PyTypeObject MethodCallMessageType = {
899     PyVarObject_HEAD_INIT(NULL, 0)
900     "dbus.lowlevel.MethodCallMessage",  /*tp_name*/
901     0,                         /*tp_basicsize*/
902     0,                         /*tp_itemsize*/
903     0,                         /*tp_dealloc*/
904     0,                         /*tp_print*/
905     0,                         /*tp_getattr*/
906     0,                         /*tp_setattr*/
907     0,                         /*tp_compare*/
908     MethodCallMessage_tp_repr, /*tp_repr*/
909     0,                         /*tp_as_number*/
910     0,                         /*tp_as_sequence*/
911     0,                         /*tp_as_mapping*/
912     0,                         /*tp_hash */
913     0,                         /*tp_call*/
914     0,                         /*tp_str*/
915     0,                         /*tp_getattro*/
916     0,                         /*tp_setattro*/
917     0,                         /*tp_as_buffer*/
918     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
919     MethodCallMessage_tp_doc,  /* tp_doc */
920     0,                         /* tp_traverse */
921     0,                         /* tp_clear */
922     0,                         /* tp_richcompare */
923     0,                         /* tp_weaklistoffset */
924     0,                         /* tp_iter */
925     0,                         /* tp_iternext */
926     0,                         /* tp_methods */
927     0,                         /* tp_members */
928     0,                         /* tp_getset */
929     DEFERRED_ADDRESS(&MessageType),   /* tp_base */
930     0,                         /* tp_dict */
931     0,                         /* tp_descr_get */
932     0,                         /* tp_descr_set */
933     0,                         /* tp_dictoffset */
934     (initproc)MethodCallMessage_tp_init,    /* tp_init */
935     0,                         /* tp_alloc */
936     0,                         /* tp_new */
937 };
938
939 static PyTypeObject MethodReturnMessageType = {
940     PyVarObject_HEAD_INIT(NULL, 0)
941     "dbus.lowlevel.MethodReturnMessage",  /*tp_name*/
942     0,                         /*tp_basicsize*/
943     0,                         /*tp_itemsize*/
944     0,                         /*tp_dealloc*/
945     0,                         /*tp_print*/
946     0,                         /*tp_getattr*/
947     0,                         /*tp_setattr*/
948     0,                         /*tp_compare*/
949     0,                         /*tp_repr*/
950     0,                         /*tp_as_number*/
951     0,                         /*tp_as_sequence*/
952     0,                         /*tp_as_mapping*/
953     0,                         /*tp_hash */
954     0,                         /*tp_call*/
955     0,                         /*tp_str*/
956     0,                         /*tp_getattro*/
957     0,                         /*tp_setattro*/
958     0,                         /*tp_as_buffer*/
959     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
960     MethodReturnMessage_tp_doc,  /* tp_doc */
961     0,                         /* tp_traverse */
962     0,                         /* tp_clear */
963     0,                         /* tp_richcompare */
964     0,                         /* tp_weaklistoffset */
965     0,                         /* tp_iter */
966     0,                         /* tp_iternext */
967     0,                         /* tp_methods */
968     0,                         /* tp_members */
969     0,                         /* tp_getset */
970     DEFERRED_ADDRESS(&MessageType),   /* tp_base */
971     0,                         /* tp_dict */
972     0,                         /* tp_descr_get */
973     0,                         /* tp_descr_set */
974     0,                         /* tp_dictoffset */
975     (initproc)MethodReturnMessage_tp_init,    /* tp_init */
976     0,                         /* tp_alloc */
977     0,                         /* tp_new */
978 };
979
980 static PyTypeObject SignalMessageType = {
981     PyVarObject_HEAD_INIT(NULL, 0)
982     "dbus.lowlevel.SignalMessage",  /*tp_name*/
983     0,                         /*tp_basicsize*/
984     0,                         /*tp_itemsize*/
985     0,                         /*tp_dealloc*/
986     0,                         /*tp_print*/
987     0,                         /*tp_getattr*/
988     0,                         /*tp_setattr*/
989     0,                         /*tp_compare*/
990     SignalMessage_tp_repr,     /*tp_repr*/
991     0,                         /*tp_as_number*/
992     0,                         /*tp_as_sequence*/
993     0,                         /*tp_as_mapping*/
994     0,                         /*tp_hash */
995     0,                         /*tp_call*/
996     0,                         /*tp_str*/
997     0,                         /*tp_getattro*/
998     0,                         /*tp_setattro*/
999     0,                         /*tp_as_buffer*/
1000     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1001     SignalMessage_tp_doc,  /* tp_doc */
1002     0,                         /* tp_traverse */
1003     0,                         /* tp_clear */
1004     0,                         /* tp_richcompare */
1005     0,                         /* tp_weaklistoffset */
1006     0,                         /* tp_iter */
1007     0,                         /* tp_iternext */
1008     0,                         /* tp_methods */
1009     0,                         /* tp_members */
1010     0,                         /* tp_getset */
1011     DEFERRED_ADDRESS(&MessageType),   /* tp_base */
1012     0,                         /* tp_dict */
1013     0,                         /* tp_descr_get */
1014     0,                         /* tp_descr_set */
1015     0,                         /* tp_dictoffset */
1016     (initproc)SignalMessage_tp_init,    /* tp_init */
1017     0,                         /* tp_alloc */
1018     0,                         /* tp_new */
1019 };
1020
1021 static PyTypeObject ErrorMessageType = {
1022     PyVarObject_HEAD_INIT(NULL, 0)
1023     "dbus.lowlevel.ErrorMessage",  /*tp_name*/
1024     0,                         /*tp_basicsize*/
1025     0,                         /*tp_itemsize*/
1026     0,                         /*tp_dealloc*/
1027     0,                         /*tp_print*/
1028     0,                         /*tp_getattr*/
1029     0,                         /*tp_setattr*/
1030     0,                         /*tp_compare*/
1031     0,                         /*tp_repr*/
1032     0,                         /*tp_as_number*/
1033     0,                         /*tp_as_sequence*/
1034     0,                         /*tp_as_mapping*/
1035     0,                         /*tp_hash */
1036     0,                         /*tp_call*/
1037     0,                         /*tp_str*/
1038     0,                         /*tp_getattro*/
1039     0,                         /*tp_setattro*/
1040     0,                         /*tp_as_buffer*/
1041     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1042     ErrorMessage_tp_doc,  /* tp_doc */
1043     0,                         /* tp_traverse */
1044     0,                         /* tp_clear */
1045     0,                         /* tp_richcompare */
1046     0,                         /* tp_weaklistoffset */
1047     0,                         /* tp_iter */
1048     0,                         /* tp_iternext */
1049     0,                         /* tp_methods */
1050     0,                         /* tp_members */
1051     0,                         /* tp_getset */
1052     DEFERRED_ADDRESS(&MessageType),   /* tp_base */
1053     0,                         /* tp_dict */
1054     0,                         /* tp_descr_get */
1055     0,                         /* tp_descr_set */
1056     0,                         /* tp_dictoffset */
1057     (initproc)ErrorMessage_tp_init,    /* tp_init */
1058     0,                         /* tp_alloc */
1059     0,                         /* tp_new */
1060 };
1061
1062 dbus_bool_t
1063 dbus_py_init_message_types(void)
1064 {
1065     if (PyType_Ready(&MessageType) < 0) return 0;
1066
1067     MethodCallMessageType.tp_base = &MessageType;
1068     if (PyType_Ready(&MethodCallMessageType) < 0) return 0;
1069
1070     MethodReturnMessageType.tp_base = &MessageType;
1071     if (PyType_Ready(&MethodReturnMessageType) < 0) return 0;
1072
1073     SignalMessageType.tp_base = &MessageType;
1074     if (PyType_Ready(&SignalMessageType) < 0) return 0;
1075
1076     ErrorMessageType.tp_base = &MessageType;
1077     if (PyType_Ready(&ErrorMessageType) < 0) return 0;
1078
1079     return 1;
1080 }
1081
1082 dbus_bool_t
1083 dbus_py_insert_message_types(PyObject *this_module)
1084 {
1085     /* PyModule_AddObject steals a ref */
1086     Py_INCREF (&MessageType);
1087     Py_INCREF (&MethodCallMessageType);
1088     Py_INCREF (&MethodReturnMessageType);
1089     Py_INCREF (&ErrorMessageType);
1090     Py_INCREF (&SignalMessageType);
1091
1092     if (PyModule_AddObject(this_module, "Message",
1093                          (PyObject *)&MessageType) < 0) return 0;
1094
1095     if (PyModule_AddObject(this_module, "MethodCallMessage",
1096                          (PyObject *)&MethodCallMessageType) < 0) return 0;
1097
1098     if (PyModule_AddObject(this_module, "MethodReturnMessage",
1099                          (PyObject *)&MethodReturnMessageType) < 0) return 0;
1100
1101     if (PyModule_AddObject(this_module, "ErrorMessage",
1102                          (PyObject *)&ErrorMessageType) < 0) return 0;
1103
1104     if (PyModule_AddObject(this_module, "SignalMessage",
1105                          (PyObject *)&SignalMessageType) < 0) return 0;
1106
1107     return 1;
1108 }
1109
1110 /* vim:set ft=c cino< sw=4 sts=4 et: */