_dbus_bindings: debug-impl.h -> debug.c
[dbus-python-phuang.git] / _dbus_bindings / types-impl.h
blobe4bb5678729fd11385be85985cf5974f4557911c
1 /* Simple D-Bus types: integers of various sizes, and ObjectPath.
3 * Copyright (C) 2006 Collabora Ltd.
5 * Licensed under the Academic Free License version 2.1
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <stdint.h>
27 /* Specific types =================================================== */
29 /* Boolean, a subclass of DBusPythonInt ============================= */
31 static PyTypeObject BooleanType;
33 DEFINE_CHECK(Boolean)
35 PyDoc_STRVAR(Boolean_tp_doc,
36 "A boolean, represented as a subtype of `int` (not `bool`, because `bool`\n"
37 "cannot be subclassed).\n"
38 "\n"
39 ":SupportedUsage:\n"
40 " ``from dbus import Boolean`` or ``from dbus.types import Boolean``\n"
41 "\n"
42 ":Constructor:\n"
43 " Boolean(value: int[, variant_level: int]) -> Boolean\n"
44 "\n"
45 " value is converted to 0 or 1.\n"
46 "\n"
47 " variant_level must be non-negative; the default is 0.\n"
48 "\n"
49 ":IVariables:\n"
50 " `variant_level` : int\n"
51 " Indicates how many nested Variant containers this object\n"
52 " is contained in: if a message's wire format has a variant containing a\n"
53 " variant containing a boolean, this is represented in Python by a\n"
54 " Boolean with variant_level==2.\n"
57 static PyObject *
58 Boolean_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
60 PyObject *tuple, *self, *value = Py_None;
61 long variantness = 0;
62 static char *argnames[] = {"_", "variant_level", NULL};
64 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ol:__new__", argnames,
65 &value, &variantness)) return NULL;
66 if (variantness < 0) {
67 PyErr_SetString(PyExc_ValueError,
68 "variant_level must be non-negative");
69 return NULL;
71 tuple = Py_BuildValue("(i)", PyObject_IsTrue(value) ? 1 : 0);
72 if (!tuple) return NULL;
73 self = (DBusPythonIntType.tp_new)(cls, tuple, kwargs);
74 Py_DECREF(tuple);
75 return self;
78 static PyObject *
79 Boolean_tp_repr (PyObject *self)
81 long variant_level = ((DBusPythonInt *)self)->variant_level;
82 if (variant_level > 0) {
83 return PyString_FromFormat("%s(%s, variant_level=%ld)",
84 self->ob_type->tp_name,
85 PyInt_AsLong(self) ? "True" : "False",
86 variant_level);
88 return PyString_FromFormat("%s(%s)",
89 self->ob_type->tp_name,
90 PyInt_AsLong(self) ? "True" : "False");
93 static PyTypeObject BooleanType = {
94 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
96 "dbus.Boolean",
99 0, /* tp_dealloc */
100 0, /* tp_print */
101 0, /* tp_getattr */
102 0, /* tp_setattr */
103 0, /* tp_compare */
104 Boolean_tp_repr, /* tp_repr */
105 0, /* tp_as_number */
106 0, /* tp_as_sequence */
107 0, /* tp_as_mapping */
108 0, /* tp_hash */
109 0, /* tp_call */
110 0, /* tp_str */
111 0, /* tp_getattro */
112 0, /* tp_setattro */
113 0, /* tp_as_buffer */
114 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
115 Boolean_tp_doc, /* tp_doc */
116 0, /* tp_traverse */
117 0, /* tp_clear */
118 0, /* tp_richcompare */
119 0, /* tp_weaklistoffset */
120 0, /* tp_iter */
121 0, /* tp_iternext */
122 0, /* tp_methods */
123 0, /* tp_members */
124 0, /* tp_getset */
125 DEFERRED_ADDRESS(&DBusPythonInt_Type), /* tp_base */
126 0, /* tp_dict */
127 0, /* tp_descr_get */
128 0, /* tp_descr_set */
129 0, /* tp_dictoffset */
130 0, /* tp_init */
131 0, /* tp_alloc */
132 Boolean_tp_new, /* tp_new */
135 /* Int16 ============================================================ */
137 static PyTypeObject Int16Type;
139 DEFINE_CHECK(Int16)
141 PyDoc_STRVAR(Int16_tp_doc,
142 "A signed 16-bit integer between -0x8000 and +0x7FFF, represented as\n"
143 "a subtype of `int`.\n"
144 "\n"
145 ":SupportedUsage:\n"
146 " ``from dbus import Int16`` or ``from dbus.types import Int16``\n"
147 "\n"
148 ":Constructor:\n"
149 " Int16(value: int[, variant_level: int]) -> Int16\n"
150 " value must be within the allowed range, or OverflowError will be\n"
151 " raised.\n"
152 " variant_level must be non-negative; the default is 0.\n"
153 "\n"
154 ":IVariables:\n"
155 " `variant_level` : int\n"
156 " Indicates how many nested Variant containers this object\n"
157 " is contained in: if a message's wire format has a variant containing a\n"
158 " variant containing an int16, this is represented in Python by an\n"
159 " Int16 with variant_level==2.\n"
162 static dbus_int16_t
163 int16_range_check(PyObject *obj)
165 long i = PyInt_AsLong (obj);
166 if (i == -1 && PyErr_Occurred ()) return -1;
167 if (i < -0x8000 || i > 0x7fff) {
168 PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int16",
169 (int)i);
170 return -1;
172 return i;
175 static PyObject *
176 Int16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
178 PyObject *self = (DBusPythonIntType.tp_new)(cls, args, kwargs);
179 if (self && int16_range_check(self) == -1 && PyErr_Occurred()) {
180 Py_DECREF(self);
181 return NULL;
183 return self;
186 static PyTypeObject Int16Type = {
187 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
189 "dbus.Int16",
192 0, /* tp_dealloc */
193 0, /* tp_print */
194 0, /* tp_getattr */
195 0, /* tp_setattr */
196 0, /* tp_compare */
197 0, /* tp_repr */
198 0, /* tp_as_number */
199 0, /* tp_as_sequence */
200 0, /* tp_as_mapping */
201 0, /* tp_hash */
202 0, /* tp_call */
203 0, /* tp_str */
204 0, /* tp_getattro */
205 0, /* tp_setattro */
206 0, /* tp_as_buffer */
207 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
208 Int16_tp_doc, /* tp_doc */
209 0, /* tp_traverse */
210 0, /* tp_clear */
211 0, /* tp_richcompare */
212 0, /* tp_weaklistoffset */
213 0, /* tp_iter */
214 0, /* tp_iternext */
215 0, /* tp_methods */
216 0, /* tp_members */
217 0, /* tp_getset */
218 DEFERRED_ADDRESS(&DBusPythonIntType), /* tp_base */
219 0, /* tp_dict */
220 0, /* tp_descr_get */
221 0, /* tp_descr_set */
222 0, /* tp_dictoffset */
223 0, /* tp_init */
224 0, /* tp_alloc */
225 Int16_tp_new, /* tp_new */
228 /* UInt16 =========================================================== */
230 static PyTypeObject UInt16Type;
232 DEFINE_CHECK(UInt16)
234 PyDoc_STRVAR(UInt16_tp_doc,
235 "An unsigned 16-bit integer between 0 and 0xFFFF, represented as\n"
236 "a subtype of `int`.\n"
237 "\n"
238 ":SupportedUsage:\n"
239 " ``from dbus import UInt16`` or ``from dbus.types import UInt16``\n"
240 "\n"
241 ":Constructor:\n"
242 " UInt16(value: int[, variant_level: int]) -> UInt16\n"
243 " value must be within the allowed range, or OverflowError will be\n"
244 " raised.\n"
245 " variant_level must be non-negative; the default is 0.\n"
246 "\n"
247 ":IVariables:\n"
248 " `variant_level` : int\n"
249 " Indicates how many nested Variant containers this object\n"
250 " is contained in: if a message's wire format has a variant containing a\n"
251 " variant containing a uint16, this is represented in Python by a\n"
252 " UInt16 with variant_level==2.\n"
255 static dbus_uint16_t
256 uint16_range_check(PyObject *obj)
258 long i = PyInt_AsLong(obj);
259 if (i == -1 && PyErr_Occurred()) return (dbus_uint16_t)(-1);
260 if (i < 0 || i > 0xffff) {
261 PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt16",
262 (int)i);
263 return (dbus_uint16_t)(-1);
265 return i;
268 static PyObject *
269 UInt16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
271 PyObject *self = (DBusPythonIntType.tp_new)(cls, args, kwargs);
272 if (self && uint16_range_check(self) == (dbus_uint16_t)(-1)
273 && PyErr_Occurred()) {
274 Py_DECREF (self);
275 return NULL;
277 return self;
280 static PyTypeObject UInt16Type = {
281 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
283 "dbus.UInt16",
286 0, /* tp_dealloc */
287 0, /* tp_print */
288 0, /* tp_getattr */
289 0, /* tp_setattr */
290 0, /* tp_compare */
291 0, /* tp_repr */
292 0, /* tp_as_number */
293 0, /* tp_as_sequence */
294 0, /* tp_as_mapping */
295 0, /* tp_hash */
296 0, /* tp_call */
297 0, /* tp_str */
298 0, /* tp_getattro */
299 0, /* tp_setattro */
300 0, /* tp_as_buffer */
301 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
302 UInt16_tp_doc, /* tp_doc */
303 0, /* tp_traverse */
304 0, /* tp_clear */
305 0, /* tp_richcompare */
306 0, /* tp_weaklistoffset */
307 0, /* tp_iter */
308 0, /* tp_iternext */
309 0, /* tp_methods */
310 0, /* tp_members */
311 0, /* tp_getset */
312 DEFERRED_ADDRESS(&DBusPythonIntType), /* tp_base */
313 0, /* tp_dict */
314 0, /* tp_descr_get */
315 0, /* tp_descr_set */
316 0, /* tp_dictoffset */
317 0, /* tp_init */
318 0, /* tp_alloc */
319 UInt16_tp_new, /* tp_new */
322 /* Int32 ============================================================ */
324 static PyTypeObject Int32Type;
326 DEFINE_CHECK(Int32)
328 PyDoc_STRVAR(Int32_tp_doc,
329 "A signed 32-bit integer between -0x8000 0000 and +0x7FFF FFFF, represented as\n"
330 "a subtype of `int`.\n"
331 "\n"
332 ":SupportedUsage:\n"
333 " ``from dbus import Int32`` or ``from dbus.types import Int32``\n"
334 "\n"
335 ":Constructor:\n"
336 " Int32(value: int[, variant_level: int]) -> Int32\n"
337 " value must be within the allowed range, or OverflowError will be\n"
338 " raised.\n"
339 " variant_level must be non-negative; the default is 0.\n"
340 "\n"
341 ":IVariables:\n"
342 " `variant_level` : int\n"
343 " Indicates how many nested Variant containers this object\n"
344 " is contained in: if a message's wire format has a variant containing a\n"
345 " variant containing an int32, this is represented in Python by an\n"
346 " Int32 with variant_level==2.\n"
349 static dbus_int32_t
350 int32_range_check(PyObject *obj)
352 long i = PyInt_AsLong(obj);
353 if (i == -1 && PyErr_Occurred()) return -1;
354 if (i < INT32_MIN || i > INT32_MAX) {
355 PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int32",
356 (int)i);
357 return -1;
359 return i;
362 static PyObject *
363 Int32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
365 PyObject *self = (DBusPythonIntType.tp_new)(cls, args, kwargs);
366 if (self && int32_range_check(self) == -1 && PyErr_Occurred()) {
367 Py_DECREF(self);
368 return NULL;
370 return self;
373 static PyTypeObject Int32Type = {
374 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
376 "dbus.Int32",
379 0, /* tp_dealloc */
380 0, /* tp_print */
381 0, /* tp_getattr */
382 0, /* tp_setattr */
383 0, /* tp_compare */
384 0, /* tp_repr */
385 0, /* tp_as_number */
386 0, /* tp_as_sequence */
387 0, /* tp_as_mapping */
388 0, /* tp_hash */
389 0, /* tp_call */
390 0, /* tp_str */
391 0, /* tp_getattro */
392 0, /* tp_setattro */
393 0, /* tp_as_buffer */
394 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
395 Int32_tp_doc, /* tp_doc */
396 0, /* tp_traverse */
397 0, /* tp_clear */
398 0, /* tp_richcompare */
399 0, /* tp_weaklistoffset */
400 0, /* tp_iter */
401 0, /* tp_iternext */
402 0, /* tp_methods */
403 0, /* tp_members */
404 0, /* tp_getset */
405 DEFERRED_ADDRESS(&DBusPythonIntType), /* tp_base */
406 0, /* tp_dict */
407 0, /* tp_descr_get */
408 0, /* tp_descr_set */
409 0, /* tp_dictoffset */
410 0, /* tp_init */
411 0, /* tp_alloc */
412 Int32_tp_new, /* tp_new */
415 /* UInt32 =========================================================== */
417 static PyTypeObject UInt32Type;
419 DEFINE_CHECK(UInt32)
421 PyDoc_STRVAR(UInt32_tp_doc,
422 "An unsigned 32-bit integer between 0 and 0xFFFF FFFF, represented as a\n"
423 "subtype of `long`.\n"
424 "\n"
425 "Note that this may be changed in future to be a subtype of `int` on\n"
426 "64-bit platforms; applications should not rely on either behaviour.\n"
427 "\n"
428 ":SupportedUsage:\n"
429 " ``from dbus import UInt32`` or ``from dbus.types import UInt32``\n"
430 "\n"
431 ":Constructor:\n"
432 " UInt32(value: long[, variant_level: int]) -> UInt32\n"
433 " value must be within the allowed range, or OverflowError will be\n"
434 " raised.\n"
435 " variant_level must be non-negative; the default is 0.\n"
436 "\n"
437 ":IVariables:\n"
438 " `variant_level` : int\n"
439 " Indicates how many nested Variant containers this object\n"
440 " is contained in: if a message's wire format has a variant containing a\n"
441 " variant containing a uint32, this is represented in Python by a\n"
442 " UInt32 with variant_level==2.\n"
445 static dbus_uint32_t
446 uint32_range_check(PyObject *obj)
448 unsigned long i;
449 PyObject *long_obj = PyNumber_Long(obj);
451 if (!long_obj) return (dbus_uint32_t)(-1);
452 i = PyLong_AsUnsignedLong(long_obj);
453 if (i == (unsigned long)(-1) && PyErr_Occurred()) {
454 Py_DECREF(long_obj);
455 return (dbus_uint32_t)(-1);
457 if (i > UINT32_MAX) {
458 PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt32",
459 (int)i);
460 Py_DECREF(long_obj);
461 return (dbus_uint32_t)(-1);
463 Py_DECREF(long_obj);
464 return i;
467 static PyObject *
468 UInt32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
470 PyObject *self = (DBusPythonLongType.tp_new)(cls, args, kwargs);
471 if (self && uint32_range_check(self) == (dbus_uint32_t)(-1)
472 && PyErr_Occurred()) {
473 Py_DECREF(self);
474 return NULL;
476 return self;
479 static PyTypeObject UInt32Type = {
480 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
482 "dbus.UInt32",
485 0, /* tp_dealloc */
486 0, /* tp_print */
487 0, /* tp_getattr */
488 0, /* tp_setattr */
489 0, /* tp_compare */
490 0, /* tp_repr */
491 0, /* tp_as_number */
492 0, /* tp_as_sequence */
493 0, /* tp_as_mapping */
494 0, /* tp_hash */
495 0, /* tp_call */
496 0, /* tp_str */
497 0, /* tp_getattro */
498 0, /* tp_setattro */
499 0, /* tp_as_buffer */
500 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
501 UInt32_tp_doc, /* tp_doc */
502 0, /* tp_traverse */
503 0, /* tp_clear */
504 0, /* tp_richcompare */
505 0, /* tp_weaklistoffset */
506 0, /* tp_iter */
507 0, /* tp_iternext */
508 0, /* tp_methods */
509 0, /* tp_members */
510 0, /* tp_getset */
511 DEFERRED_ADDRESS(&DBusPythonLongType), /* tp_base */
512 0, /* tp_dict */
513 0, /* tp_descr_get */
514 0, /* tp_descr_set */
515 0, /* tp_dictoffset */
516 0, /* tp_init */
517 0, /* tp_alloc */
518 UInt32_tp_new, /* tp_new */
521 /* Int64 =========================================================== */
523 #if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
524 # define DBUS_PYTHON_64_BIT_WORKS 1
525 #else
526 # undef DBUS_PYTHON_64_BIT_WORKS
527 #endif /* defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG) */
529 static PyTypeObject Int64Type;
531 DEFINE_CHECK(Int64)
533 PyDoc_STRVAR(Int64_tp_doc,
534 "A signed 64-bit integer between -0x8000 0000 0000 0000 and\n"
535 "+0x7FFF FFFF FFFF FFFF, represented as a subtype of `long`.\n"
536 "\n"
537 "Note that this may be changed in future to be a subtype of `int` on\n"
538 "64-bit platforms; applications should not rely on either behaviour.\n"
539 "\n"
540 "This type only works on platforms where the C compiler has suitable\n"
541 "64-bit types, such as C99 ``long long``.\n"
542 #ifdef DBUS_PYTHON_64_BIT_WORKS
543 "This is the case on your current platform.\n"
544 #else /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
545 "This is not the case on your current platform, so this type's\n"
546 "constructor will always raise NotImplementedError. Try a better\n"
547 "compiler, if one is available.\n"
548 #endif /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
549 "\n"
550 ":SupportedUsage:\n"
551 " ``from dbus import Int64`` or ``from dbus.types import Int64``\n"
552 "\n"
553 ":Constructor:\n"
554 " Int64(value: long[, variant_level: int]) -> Int64\n"
555 " value must be within the allowed range, or OverflowError will be\n"
556 " raised.\n"
557 " variant_level must be non-negative; the default is 0.\n"
558 "\n"
559 ":IVariables:\n"
560 " `variant_level` : int\n"
561 " Indicates how many nested Variant containers this object\n"
562 " is contained in: if a message's wire format has a variant containing a\n"
563 " variant containing an int64, this is represented in Python by an\n"
564 " Int64 with variant_level==2.\n"
567 #ifdef DBUS_PYTHON_64_BIT_WORKS
568 static dbus_int64_t
569 int64_range_check(PyObject *obj)
571 PY_LONG_LONG i;
572 PyObject *long_obj = PyNumber_Long(obj);
574 if (!long_obj) return -1;
575 i = PyLong_AsLongLong(long_obj);
576 if (i == -1 && PyErr_Occurred()) {
577 Py_DECREF(long_obj);
578 return -1;
580 if (i < INT64_MIN || i > INT64_MAX) {
581 PyErr_SetString(PyExc_OverflowError, "Value out of range for Int64");
582 Py_DECREF(long_obj);
583 return -1;
585 Py_DECREF(long_obj);
586 return i;
588 #endif
590 static PyObject *
591 Int64_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
593 #ifdef DBUS_PYTHON_64_BIT_WORKS
594 PyObject *self = (DBusPythonLongType.tp_new)(cls, args, kwargs);
595 if (self && int64_range_check(self) == -1 && PyErr_Occurred()) {
596 Py_DECREF(self);
597 return NULL;
599 return self;
600 #else
601 PyErr_SetString(PyExc_NotImplementedError,
602 "64-bit types are not available on this platform");
603 return NULL;
604 #endif
607 static PyTypeObject Int64Type = {
608 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
610 "dbus.Int64",
613 0, /* tp_dealloc */
614 0, /* tp_print */
615 0, /* tp_getattr */
616 0, /* tp_setattr */
617 0, /* tp_compare */
618 0, /* tp_repr */
619 0, /* tp_as_number */
620 0, /* tp_as_sequence */
621 0, /* tp_as_mapping */
622 0, /* tp_hash */
623 0, /* tp_call */
624 0, /* tp_str */
625 0, /* tp_getattro */
626 0, /* tp_setattro */
627 0, /* tp_as_buffer */
628 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
629 Int64_tp_doc, /* tp_doc */
630 0, /* tp_traverse */
631 0, /* tp_clear */
632 0, /* tp_richcompare */
633 0, /* tp_weaklistoffset */
634 0, /* tp_iter */
635 0, /* tp_iternext */
636 0, /* tp_methods */
637 0, /* tp_members */
638 0, /* tp_getset */
639 DEFERRED_ADDRESS(&DBusPythonLongType), /* tp_base */
640 0, /* tp_dict */
641 0, /* tp_descr_get */
642 0, /* tp_descr_set */
643 0, /* tp_dictoffset */
644 0, /* tp_init */
645 0, /* tp_alloc */
646 Int64_tp_new, /* tp_new */
649 /* UInt64 =========================================================== */
651 static PyTypeObject UInt64Type;
653 DEFINE_CHECK(UInt64)
655 PyDoc_STRVAR(UInt64_tp_doc,
656 "An unsigned 64-bit integer between 0 and 0xFFFF FFFF FFFF FFFF,\n"
657 "represented as a subtype of `long`.\n"
658 "\n"
659 "This type only exists on platforms where the C compiler has suitable\n"
660 "64-bit types, such as C99 ``unsigned long long``.\n"
661 #ifdef DBUS_PYTHON_64_BIT_WORKS
662 "This is the case on your current platform.\n"
663 #else /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
664 "This is not the case on your current platform, so this type's\n"
665 "constructor will always raise NotImplementedError. Try a better\n"
666 "compiler, if one is available.\n"
667 #endif /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
668 "\n"
669 ":Constructor:\n"
670 " UInt64(value: long[, variant_level: int]) -> UInt64\n"
671 " value must be within the allowed range, or OverflowError will be\n"
672 " raised.\n"
673 " variant_level must be non-negative; the default is 0.\n"
674 "\n"
675 ":IVariables:\n"
676 " `variant_level` : int\n"
677 " Indicates how many nested Variant containers this object\n"
678 " is contained in: if a message's wire format has a variant containing a\n"
679 " variant containing a uint64, this is represented in Python by a\n"
680 " UInt64 with variant_level==2.\n"
683 static dbus_uint64_t
684 uint64_range_check(PyObject *obj)
686 unsigned PY_LONG_LONG i;
687 PyObject *long_obj = PyNumber_Long(obj);
689 if (!long_obj) return (dbus_uint64_t)(-1);
690 i = PyLong_AsUnsignedLongLong(long_obj);
691 if (i == (unsigned PY_LONG_LONG)(-1) && PyErr_Occurred()) {
692 Py_DECREF(long_obj);
693 return (dbus_uint64_t)(-1);
695 if (i > UINT64_MAX) {
696 PyErr_SetString(PyExc_OverflowError, "Value out of range for UInt64");
697 Py_DECREF(long_obj);
698 return (dbus_uint64_t)(-1);
700 Py_DECREF(long_obj);
701 return i;
704 static PyObject *
705 UInt64_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
707 #ifdef DBUS_PYTHON_64_BIT_WORKS
708 PyObject *self = (DBusPythonLongType.tp_new)(cls, args, kwargs);
709 if (self && uint64_range_check(self) == (dbus_uint64_t)(-1)
710 && PyErr_Occurred()) {
711 Py_DECREF(self);
712 return NULL;
714 return self;
715 #else
716 PyErr_SetString(PyExc_NotImplementedError,
717 "64-bit integer types are not supported on this platform");
718 return NULL;
719 #endif
722 static PyTypeObject UInt64Type = {
723 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
725 "dbus.UInt64",
728 0, /* tp_dealloc */
729 0, /* tp_print */
730 0, /* tp_getattr */
731 0, /* tp_setattr */
732 0, /* tp_compare */
733 0, /* tp_repr */
734 0, /* tp_as_number */
735 0, /* tp_as_sequence */
736 0, /* tp_as_mapping */
737 0, /* tp_hash */
738 0, /* tp_call */
739 0, /* tp_str */
740 0, /* tp_getattro */
741 0, /* tp_setattro */
742 0, /* tp_as_buffer */
743 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
744 UInt64_tp_doc, /* tp_doc */
745 0, /* tp_traverse */
746 0, /* tp_clear */
747 0, /* tp_richcompare */
748 0, /* tp_weaklistoffset */
749 0, /* tp_iter */
750 0, /* tp_iternext */
751 0, /* tp_methods */
752 0, /* tp_members */
753 0, /* tp_getset */
754 DEFERRED_ADDRESS(&DBusPythonLongType), /* tp_base */
755 0, /* tp_dict */
756 0, /* tp_descr_get */
757 0, /* tp_descr_set */
758 0, /* tp_dictoffset */
759 0, /* tp_init */
760 0, /* tp_alloc */
761 UInt64_tp_new, /* tp_new */
764 /* UTF-8 string representation ====================================== */
766 static PyTypeObject UTF8StringType;
768 DEFINE_CHECK(UTF8String)
770 PyDoc_STRVAR(UTF8String_tp_doc,
771 "A string represented using UTF-8 - a subtype of `str`.\n"
772 "\n"
773 ":Constructor:\n"
774 " UTF8String(value: str or unicode[, variant_level: int]) -> UTF8String\n"
775 " If value is a str object it must be valid UTF-8.\n"
776 "\n"
777 " variant_level must be non-negative; the default is 0.\n"
778 "\n"
779 ":IVariables:\n"
780 " `variant_level` : int\n"
781 " Indicates how many nested Variant containers this object\n"
782 " is contained in: if a message's wire format has a variant containing a\n"
783 " variant containing a string, this is represented in Python by a\n"
784 " String or UTF8String with variant_level==2.\n"
785 ":Since: 0.80 (in older versions, use dbus.String)\n"
788 static PyObject *
789 UTF8String_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
791 const char *str = NULL;
792 long variantness = 0;
793 static char *argnames[] = {"value", "variant_level", NULL};
794 PyObject *unicode;
796 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|l:__new__", argnames,
797 &str, &variantness)) return NULL;
798 unicode = PyUnicode_DecodeUTF8(str, strlen(str), NULL);
799 if (!unicode) return NULL;
800 Py_DECREF(unicode);
801 return (DBusPythonStringType.tp_new)(cls, args, kwargs);
804 static PyTypeObject UTF8StringType = {
805 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
807 "dbus.UTF8String",
810 0, /* tp_dealloc */
811 0, /* tp_print */
812 0, /* tp_getattr */
813 0, /* tp_setattr */
814 0, /* tp_compare */
815 0, /* tp_repr */
816 0, /* tp_as_number */
817 0, /* tp_as_sequence */
818 0, /* tp_as_mapping */
819 0, /* tp_hash */
820 0, /* tp_call */
821 0, /* tp_str */
822 0, /* tp_getattro */
823 0, /* tp_setattro */
824 0, /* tp_as_buffer */
825 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
826 UTF8String_tp_doc, /* tp_doc */
827 0, /* tp_traverse */
828 0, /* tp_clear */
829 0, /* tp_richcompare */
830 0, /* tp_weaklistoffset */
831 0, /* tp_iter */
832 0, /* tp_iternext */
833 0, /* tp_methods */
834 0, /* tp_members */
835 0, /* tp_getset */
836 DEFERRED_ADDRESS(&DBusPythonStringType), /* tp_base */
837 0, /* tp_dict */
838 0, /* tp_descr_get */
839 0, /* tp_descr_set */
840 0, /* tp_dictoffset */
841 0, /* tp_init */
842 0, /* tp_alloc */
843 UTF8String_tp_new, /* tp_new */
846 /* Object path ====================================================== */
848 static PyTypeObject ObjectPathType;
850 DEFINE_CHECK(ObjectPath)
852 PyDoc_STRVAR(ObjectPath_tp_doc,
853 "A D-Bus object path, such as '/com/example/MyApp/Documents/abc'.\n"
854 "\n"
855 "ObjectPath is a subtype of str, and object-paths behave like strings.\n"
856 "\n"
857 ":Constructor:\n"
858 " ObjectPath(path: str[, variant_level: int]) -> ObjectPath\n"
859 " path must be an ASCII string following the syntax of object paths.\n"
860 " variant_level must be non-negative; the default is 0.\n"
861 "\n"
862 ":IVariables:\n"
863 " `variant_level` : int\n"
864 " Indicates how many nested Variant containers this object\n"
865 " is contained in: if a message's wire format has a variant containing a\n"
866 " variant containing an object path, this is represented in Python by an\n"
867 " ObjectPath with variant_level==2.\n"
870 static PyObject *
871 ObjectPath_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
873 const char *str = NULL;
874 long variantness = 0;
875 static char *argnames[] = {"object_path", "variant_level", NULL};
877 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|l:__new__", argnames,
878 &str, &variantness)) return NULL;
879 if (!dbus_py_validate_object_path(str)) {
880 return NULL;
882 return (DBusPythonStringType.tp_new)(cls, args, kwargs);
885 static PyTypeObject ObjectPathType = {
886 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
888 "dbus.ObjectPath",
891 0, /* tp_dealloc */
892 0, /* tp_print */
893 0, /* tp_getattr */
894 0, /* tp_setattr */
895 0, /* tp_compare */
896 0, /* tp_repr */
897 0, /* tp_as_number */
898 0, /* tp_as_sequence */
899 0, /* tp_as_mapping */
900 0, /* tp_hash */
901 0, /* tp_call */
902 0, /* tp_str */
903 0, /* tp_getattro */
904 0, /* tp_setattro */
905 0, /* tp_as_buffer */
906 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
907 ObjectPath_tp_doc, /* tp_doc */
908 0, /* tp_traverse */
909 0, /* tp_clear */
910 0, /* tp_richcompare */
911 0, /* tp_weaklistoffset */
912 0, /* tp_iter */
913 0, /* tp_iternext */
914 0, /* tp_methods */
915 0, /* tp_members */
916 0, /* tp_getset */
917 DEFERRED_ADDRESS(&DBusPythonStringType), /* tp_base */
918 0, /* tp_dict */
919 0, /* tp_descr_get */
920 0, /* tp_descr_set */
921 0, /* tp_dictoffset */
922 0, /* tp_init */
923 0, /* tp_alloc */
924 ObjectPath_tp_new, /* tp_new */
927 /* Unicode string representation ==================================== */
929 static PyTypeObject StringType;
930 DEFINE_CHECK(String)
932 PyDoc_STRVAR(String_tp_doc,
933 "A string represented using Unicode - a subtype of `unicode`.\n"
934 "\n"
935 ":Constructor:\n"
936 " String(value: str or unicode[, variant_level: int]) -> String\n"
937 "\n"
938 " variant_level must be non-negative; the default is 0.\n"
939 "\n"
940 ":IVariables:\n"
941 " `variant_level` : int\n"
942 " Indicates how many nested Variant containers this object\n"
943 " is contained in: if a message's wire format has a variant containing a\n"
944 " variant containing a string, this is represented in Python by a\n"
945 " String or UTF8String with variant_level==2.\n"
948 static PyObject *
949 String_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
951 PyObject *self;
952 PyObject *variantness = NULL;
953 static char *argnames[] = {"variant_level", NULL};
955 if (PyTuple_Size(args) > 1) {
956 PyErr_SetString(PyExc_TypeError,
957 "__new__ takes at most one positional parameter");
958 return NULL;
960 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
961 "|O!:__new__", argnames,
962 &PyInt_Type, &variantness)) return NULL;
963 if (!variantness) {
964 variantness = PyInt_FromLong(0);
965 if (!variantness) return NULL;
967 if (PyInt_AS_LONG(variantness) < 0) {
968 PyErr_SetString(PyExc_ValueError,
969 "variant_level must be non-negative");
970 return NULL;
973 self = (PyUnicode_Type.tp_new)(cls, args, NULL);
974 if (self) {
975 PyObject_GenericSetAttr(self, variant_level_const, variantness);
977 return self;
980 static PyObject *
981 String_tp_repr(PyObject *self)
983 PyObject *parent_repr = (PyUnicode_Type.tp_repr)(self);
984 PyObject *vl_obj;
985 PyObject *my_repr;
986 long variant_level;
988 if (!parent_repr) return NULL;
989 vl_obj = PyObject_GetAttr(self, variant_level_const);
990 if (!vl_obj) return NULL;
991 variant_level = PyInt_AsLong(vl_obj);
992 if (variant_level > 0) {
993 my_repr = PyString_FromFormat("%s(%s, variant_level=%ld)",
994 self->ob_type->tp_name,
995 PyString_AS_STRING(parent_repr),
996 variant_level);
998 else {
999 my_repr = PyString_FromFormat("%s(%s)", self->ob_type->tp_name,
1000 PyString_AS_STRING(parent_repr));
1002 /* whether my_repr is NULL or not: */
1003 Py_DECREF(parent_repr);
1004 return my_repr;
1007 static PyTypeObject StringType = {
1008 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
1010 "dbus.String",
1011 INT_MAX, /* placeholder */
1013 0, /* tp_dealloc */
1014 0, /* tp_print */
1015 0, /* tp_getattr */
1016 0, /* tp_setattr */
1017 0, /* tp_compare */
1018 String_tp_repr, /* tp_repr */
1019 0, /* tp_as_number */
1020 0, /* tp_as_sequence */
1021 0, /* tp_as_mapping */
1022 0, /* tp_hash */
1023 0, /* tp_call */
1024 0, /* tp_str */
1025 PyObject_GenericGetAttr, /* tp_getattro */
1026 Glue_immutable_setattro, /* tp_setattro */
1027 0, /* tp_as_buffer */
1028 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1029 String_tp_doc, /* tp_doc */
1030 0, /* tp_traverse */
1031 0, /* tp_clear */
1032 0, /* tp_richcompare */
1033 0, /* tp_weaklistoffset */
1034 0, /* tp_iter */
1035 0, /* tp_iternext */
1036 0, /* tp_methods */
1037 0, /* tp_members */
1038 0, /* tp_getset */
1039 DEFERRED_ADDRESS(&PyUnicode_Type), /* tp_base */
1040 0, /* tp_dict */
1041 0, /* tp_descr_get */
1042 0, /* tp_descr_set */
1043 -sizeof(void *), /* tp_dictoffset */
1044 0, /* tp_init */
1045 0, /* tp_alloc */
1046 String_tp_new, /* tp_new */
1049 static inline int
1050 init_types(void)
1052 Int16Type.tp_base = &DBusPythonIntType;
1053 if (PyType_Ready(&Int16Type) < 0) return 0;
1054 /* disable the tp_print copied from PyInt_Type, so tp_repr gets called as
1055 desired */
1056 Int16Type.tp_print = NULL;
1058 UInt16Type.tp_base = &DBusPythonIntType;
1059 if (PyType_Ready(&UInt16Type) < 0) return 0;
1060 UInt16Type.tp_print = NULL;
1062 Int32Type.tp_base = &DBusPythonIntType;
1063 if (PyType_Ready(&Int32Type) < 0) return 0;
1064 Int32Type.tp_print = NULL;
1066 UInt32Type.tp_base = &DBusPythonLongType;
1067 if (PyType_Ready(&UInt32Type) < 0) return 0;
1068 UInt32Type.tp_print = NULL;
1070 #if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
1071 Int64Type.tp_base = &DBusPythonLongType;
1072 if (PyType_Ready(&Int64Type) < 0) return 0;
1073 Int64Type.tp_print = NULL;
1075 UInt64Type.tp_base = &DBusPythonLongType;
1076 if (PyType_Ready(&UInt64Type) < 0) return 0;
1077 UInt64Type.tp_print = NULL;
1078 #endif
1080 StringType.tp_basicsize = PyUnicode_Type.tp_basicsize
1081 + 2*sizeof(PyObject *) - 1;
1082 StringType.tp_basicsize /= sizeof(PyObject *);
1083 StringType.tp_basicsize *= sizeof(PyObject *);
1084 StringType.tp_base = &PyUnicode_Type;
1085 if (PyType_Ready(&StringType) < 0) return 0;
1086 StringType.tp_print = NULL;
1088 UTF8StringType.tp_basicsize = PyUnicode_Type.tp_basicsize
1089 + 2*sizeof(PyObject *) - 1;
1090 UTF8StringType.tp_basicsize /= sizeof(PyObject *);
1091 UTF8StringType.tp_basicsize *= sizeof(PyObject *);
1092 UTF8StringType.tp_base = &DBusPythonStringType;
1093 if (PyType_Ready(&UTF8StringType) < 0) return 0;
1094 UTF8StringType.tp_print = NULL;
1096 ObjectPathType.tp_base = &DBusPythonStringType;
1097 if (PyType_Ready(&ObjectPathType) < 0) return 0;
1098 ObjectPathType.tp_print = NULL;
1100 BooleanType.tp_base = &DBusPythonIntType;
1101 if (PyType_Ready(&BooleanType) < 0) return 0;
1102 BooleanType.tp_print = NULL;
1104 return 1;
1107 static inline int
1108 insert_types(PyObject *this_module)
1110 Py_INCREF(&Int16Type);
1111 Py_INCREF(&UInt16Type);
1112 Py_INCREF(&Int32Type);
1113 Py_INCREF(&UInt32Type);
1114 Py_INCREF(&Int64Type);
1115 Py_INCREF(&UInt64Type);
1116 Py_INCREF(&BooleanType);
1117 if (PyModule_AddObject(this_module, "Int16",
1118 (PyObject *)&Int16Type) < 0) return 0;
1119 if (PyModule_AddObject(this_module, "UInt16",
1120 (PyObject *)&UInt16Type) < 0) return 0;
1121 if (PyModule_AddObject(this_module, "Int32",
1122 (PyObject *)&Int32Type) < 0) return 0;
1123 if (PyModule_AddObject(this_module, "UInt32",
1124 (PyObject *)&UInt32Type) < 0) return 0;
1125 if (PyModule_AddObject(this_module, "Int64",
1126 (PyObject *)&Int64Type) < 0) return 0;
1127 if (PyModule_AddObject(this_module, "UInt64",
1128 (PyObject *)&UInt64Type) < 0) return 0;
1129 if (PyModule_AddObject(this_module, "Boolean",
1130 (PyObject *)&BooleanType) < 0) return 0;
1132 Py_INCREF(&ObjectPathType);
1133 Py_INCREF(&UTF8StringType);
1134 Py_INCREF(&StringType);
1135 if (PyModule_AddObject(this_module, "ObjectPath",
1136 (PyObject *)&ObjectPathType) < 0) return 0;
1137 if (PyModule_AddObject(this_module, "UTF8String",
1138 (PyObject *)&UTF8StringType) < 0) return 0;
1139 if (PyModule_AddObject(this_module, "String",
1140 (PyObject *)&StringType) < 0) return 0;
1142 return 1;
1145 /* vim:set ft=c cino< sw=4 sts=4 et: */