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 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "types-internal.h"
25 /* Specific types =================================================== */
27 /* Boolean, a subclass of DBusPythonInt ============================= */
29 PyDoc_STRVAR(Boolean_tp_doc
,
30 "A boolean, represented as a subtype of `int` (not `bool`, because `bool`\n"
31 "cannot be subclassed).\n"
35 " dbus.Boolean(value[, variant_level]) -> Boolean\n"
37 "``value`` is converted to 0 or 1 as if by ``int(bool(value))``.\n"
39 "``variant_level`` must be non-negative; the default is 0.\n"
42 " `variant_level` : int\n"
43 " Indicates how many nested Variant containers this object\n"
44 " is contained in: if a message's wire format has a variant containing a\n"
45 " variant containing a boolean, this is represented in Python by a\n"
46 " Boolean with variant_level==2.\n"
50 Boolean_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
52 PyObject
*tuple
, *self
, *value
= Py_None
;
54 static char *argnames
[] = {"_", "variant_level", NULL
};
56 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|Ol:__new__", argnames
,
57 &value
, &variantness
)) return NULL
;
58 if (variantness
< 0) {
59 PyErr_SetString(PyExc_ValueError
,
60 "variant_level must be non-negative");
63 tuple
= Py_BuildValue("(i)", PyObject_IsTrue(value
) ? 1 : 0);
64 if (!tuple
) return NULL
;
65 self
= (DBusPyIntBase_Type
.tp_new
)(cls
, tuple
, kwargs
);
71 Boolean_tp_repr (PyObject
*self
)
73 long variant_level
= ((DBusPyIntBase
*)self
)->variant_level
;
74 if (variant_level
> 0) {
75 return PyString_FromFormat("%s(%s, variant_level=%ld)",
76 self
->ob_type
->tp_name
,
77 PyInt_AsLong(self
) ? "True" : "False",
80 return PyString_FromFormat("%s(%s)",
81 self
->ob_type
->tp_name
,
82 PyInt_AsLong(self
) ? "True" : "False");
85 PyTypeObject DBusPyBoolean_Type
= {
86 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
96 Boolean_tp_repr
, /* tp_repr */
98 0, /* tp_as_sequence */
99 0, /* tp_as_mapping */
105 0, /* tp_as_buffer */
106 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
107 Boolean_tp_doc
, /* tp_doc */
110 0, /* tp_richcompare */
111 0, /* tp_weaklistoffset */
117 DEFERRED_ADDRESS(&DBusPyIntBase_Type
), /* tp_base */
119 0, /* tp_descr_get */
120 0, /* tp_descr_set */
121 0, /* tp_dictoffset */
124 Boolean_tp_new
, /* tp_new */
127 /* Int16 ============================================================ */
129 PyDoc_STRVAR(Int16_tp_doc
,
130 "A signed 16-bit integer between -0x8000 and +0x7FFF, represented as\n"
131 "a subtype of `int`.\n"
135 " dbus.Int16(value: int[, variant_level: int]) -> Int16\n"
137 "value must be within the allowed range, or OverflowError will be\n"
140 " variant_level must be non-negative; the default is 0.\n"
143 " `variant_level` : int\n"
144 " Indicates how many nested Variant containers this object\n"
145 " is contained in: if a message's wire format has a variant containing a\n"
146 " variant containing an int16, this is represented in Python by an\n"
147 " Int16 with variant_level==2.\n"
151 dbus_py_int16_range_check(PyObject
*obj
)
153 long i
= PyInt_AsLong (obj
);
154 if (i
== -1 && PyErr_Occurred ()) return -1;
155 if (i
< -0x8000 || i
> 0x7fff) {
156 PyErr_Format(PyExc_OverflowError
, "Value %d out of range for Int16",
164 Int16_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
166 PyObject
*self
= (DBusPyIntBase_Type
.tp_new
)(cls
, args
, kwargs
);
167 if (self
&& dbus_py_int16_range_check(self
) == -1 && PyErr_Occurred()) {
174 PyTypeObject DBusPyInt16_Type
= {
175 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
186 0, /* tp_as_number */
187 0, /* tp_as_sequence */
188 0, /* tp_as_mapping */
194 0, /* tp_as_buffer */
195 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
196 Int16_tp_doc
, /* tp_doc */
199 0, /* tp_richcompare */
200 0, /* tp_weaklistoffset */
206 DEFERRED_ADDRESS(&DBusPyIntBase_Type
), /* tp_base */
208 0, /* tp_descr_get */
209 0, /* tp_descr_set */
210 0, /* tp_dictoffset */
213 Int16_tp_new
, /* tp_new */
216 /* UInt16 =========================================================== */
218 PyDoc_STRVAR(UInt16_tp_doc
,
219 "An unsigned 16-bit integer between 0 and 0xFFFF, represented as\n"
220 "a subtype of `int`.\n"
224 " dbus.UInt16(value: int[, variant_level: int]) -> UInt16\n"
226 "``value`` must be within the allowed range, or `OverflowError` will be\n"
229 "``variant_level`` must be non-negative; the default is 0.\n"
232 " `variant_level` : int\n"
233 " Indicates how many nested Variant containers this object\n"
234 " is contained in: if a message's wire format has a variant containing a\n"
235 " variant containing a uint16, this is represented in Python by a\n"
236 " UInt16 with variant_level==2.\n"
240 dbus_py_uint16_range_check(PyObject
*obj
)
242 long i
= PyInt_AsLong(obj
);
243 if (i
== -1 && PyErr_Occurred()) return (dbus_uint16_t
)(-1);
244 if (i
< 0 || i
> 0xffff) {
245 PyErr_Format(PyExc_OverflowError
, "Value %d out of range for UInt16",
247 return (dbus_uint16_t
)(-1);
253 UInt16_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
255 PyObject
*self
= (DBusPyIntBase_Type
.tp_new
)(cls
, args
, kwargs
);
256 if (self
&& dbus_py_uint16_range_check(self
) == (dbus_uint16_t
)(-1)
257 && PyErr_Occurred()) {
264 PyTypeObject DBusPyUInt16_Type
= {
265 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
276 0, /* tp_as_number */
277 0, /* tp_as_sequence */
278 0, /* tp_as_mapping */
284 0, /* tp_as_buffer */
285 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
286 UInt16_tp_doc
, /* tp_doc */
289 0, /* tp_richcompare */
290 0, /* tp_weaklistoffset */
296 DEFERRED_ADDRESS(&DBusPyIntBase_Type
), /* tp_base */
298 0, /* tp_descr_get */
299 0, /* tp_descr_set */
300 0, /* tp_dictoffset */
303 UInt16_tp_new
, /* tp_new */
306 /* Int32 ============================================================ */
308 PyDoc_STRVAR(Int32_tp_doc
,
309 "A signed 32-bit integer between -0x8000 0000 and +0x7FFF FFFF, represented as\n"
310 "a subtype of `int`.\n"
314 " dbus.Int32(value: int[, variant_level: int]) -> Int32\n"
316 "``value`` must be within the allowed range, or `OverflowError` will be\n"
319 "``variant_level`` must be non-negative; the default is 0.\n"
322 " `variant_level` : int\n"
323 " Indicates how many nested Variant containers this object\n"
324 " is contained in: if a message's wire format has a variant containing a\n"
325 " variant containing an int32, this is represented in Python by an\n"
326 " Int32 with variant_level==2.\n"
330 dbus_py_int32_range_check(PyObject
*obj
)
332 long i
= PyInt_AsLong(obj
);
333 if (i
== -1 && PyErr_Occurred()) return -1;
334 if (i
< INT32_MIN
|| i
> INT32_MAX
) {
335 PyErr_Format(PyExc_OverflowError
, "Value %d out of range for Int32",
343 Int32_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
345 PyObject
*self
= (DBusPyIntBase_Type
.tp_new
)(cls
, args
, kwargs
);
346 if (self
&& dbus_py_int32_range_check(self
) == -1 && PyErr_Occurred()) {
353 PyTypeObject DBusPyInt32_Type
= {
354 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
365 0, /* tp_as_number */
366 0, /* tp_as_sequence */
367 0, /* tp_as_mapping */
373 0, /* tp_as_buffer */
374 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
375 Int32_tp_doc
, /* tp_doc */
378 0, /* tp_richcompare */
379 0, /* tp_weaklistoffset */
385 DEFERRED_ADDRESS(&DBusPyIntBase_Type
), /* tp_base */
387 0, /* tp_descr_get */
388 0, /* tp_descr_set */
389 0, /* tp_dictoffset */
392 Int32_tp_new
, /* tp_new */
395 /* UInt32 =========================================================== */
397 PyDoc_STRVAR(UInt32_tp_doc
,
398 "An unsigned 32-bit integer between 0 and 0xFFFF FFFF, represented as a\n"
399 "subtype of `long`.\n"
401 "Note that this may be changed in future to be a subtype of `int` on\n"
402 "64-bit platforms; applications should not rely on either behaviour.\n"
406 " dbus.UInt32(value: long[, variant_level: int]) -> UInt32\n"
408 "``value`` must be within the allowed range, or `OverflowError` will be\n"
411 "``variant_level`` must be non-negative; the default is 0.\n"
414 " `variant_level` : int\n"
415 " Indicates how many nested Variant containers this object\n"
416 " is contained in: if a message's wire format has a variant containing a\n"
417 " variant containing a uint32, this is represented in Python by a\n"
418 " UInt32 with variant_level==2.\n"
422 dbus_py_uint32_range_check(PyObject
*obj
)
425 PyObject
*long_obj
= PyNumber_Long(obj
);
427 if (!long_obj
) return (dbus_uint32_t
)(-1);
428 i
= PyLong_AsUnsignedLong(long_obj
);
429 if (i
== (unsigned long)(-1) && PyErr_Occurred()) {
431 return (dbus_uint32_t
)(-1);
433 if (i
> UINT32_MAX
) {
434 PyErr_Format(PyExc_OverflowError
, "Value %d out of range for UInt32",
437 return (dbus_uint32_t
)(-1);
444 UInt32_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
446 PyObject
*self
= (DBusPyLongBase_Type
.tp_new
)(cls
, args
, kwargs
);
447 if (self
&& dbus_py_uint32_range_check(self
) == (dbus_uint32_t
)(-1)
448 && PyErr_Occurred()) {
455 PyTypeObject DBusPyUInt32_Type
= {
456 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
467 0, /* tp_as_number */
468 0, /* tp_as_sequence */
469 0, /* tp_as_mapping */
475 0, /* tp_as_buffer */
476 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
477 UInt32_tp_doc
, /* tp_doc */
480 0, /* tp_richcompare */
481 0, /* tp_weaklistoffset */
487 DEFERRED_ADDRESS(&DBusPyLongBase_Type
), /* tp_base */
489 0, /* tp_descr_get */
490 0, /* tp_descr_set */
491 0, /* tp_dictoffset */
494 UInt32_tp_new
, /* tp_new */
497 /* Int64 =========================================================== */
499 PyDoc_STRVAR(Int64_tp_doc
,
500 "A signed 64-bit integer between -0x8000 0000 0000 0000 and\n"
501 "+0x7FFF FFFF FFFF FFFF, represented as a subtype of `long`.\n"
503 "Note that this may be changed in future to be a subtype of `int` on\n"
504 "64-bit platforms; applications should not rely on either behaviour.\n"
506 "This type only works on platforms where the C compiler has suitable\n"
507 "64-bit types, such as C99 ``long long``.\n"
511 " dbus.Int64(value: long[, variant_level: int]) -> Int64\n"
513 "``value`` must be within the allowed range, or `OverflowError` will be\n"
516 "``variant_level`` must be non-negative; the default is 0.\n"
519 " `variant_level` : int\n"
520 " Indicates how many nested Variant containers this object\n"
521 " is contained in: if a message's wire format has a variant containing a\n"
522 " variant containing an int64, this is represented in Python by an\n"
523 " Int64 with variant_level==2.\n"
526 #ifdef DBUS_PYTHON_64_BIT_WORKS
528 dbus_py_int64_range_check(PyObject
*obj
)
531 PyObject
*long_obj
= PyNumber_Long(obj
);
533 if (!long_obj
) return -1;
534 i
= PyLong_AsLongLong(long_obj
);
535 if (i
== -1 && PyErr_Occurred()) {
539 if (i
< INT64_MIN
|| i
> INT64_MAX
) {
540 PyErr_SetString(PyExc_OverflowError
, "Value out of range for Int64");
550 Int64_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
552 #ifdef DBUS_PYTHON_64_BIT_WORKS
553 PyObject
*self
= (DBusPyLongBase_Type
.tp_new
)(cls
, args
, kwargs
);
554 if (self
&& dbus_py_int64_range_check(self
) == -1 && PyErr_Occurred()) {
560 PyErr_SetString(PyExc_NotImplementedError
,
561 "64-bit types are not available on this platform");
566 PyTypeObject DBusPyInt64_Type
= {
567 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
578 0, /* tp_as_number */
579 0, /* tp_as_sequence */
580 0, /* tp_as_mapping */
586 0, /* tp_as_buffer */
587 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
588 Int64_tp_doc
, /* tp_doc */
591 0, /* tp_richcompare */
592 0, /* tp_weaklistoffset */
598 DEFERRED_ADDRESS(&DBusPyLongBase_Type
), /* tp_base */
600 0, /* tp_descr_get */
601 0, /* tp_descr_set */
602 0, /* tp_dictoffset */
605 Int64_tp_new
, /* tp_new */
608 /* UInt64 =========================================================== */
610 PyDoc_STRVAR(UInt64_tp_doc
,
611 "An unsigned 64-bit integer between 0 and 0xFFFF FFFF FFFF FFFF,\n"
612 "represented as a subtype of `long`.\n"
614 "This type only exists on platforms where the C compiler has suitable\n"
615 "64-bit types, such as C99 ``unsigned long long``.\n"
619 " dbus.UInt64(value: long[, variant_level: int]) -> UInt64\n"
621 "``value`` must be within the allowed range, or `OverflowError` will be\n"
624 "``variant_level`` must be non-negative; the default is 0.\n"
627 " `variant_level` : int\n"
628 " Indicates how many nested Variant containers this object\n"
629 " is contained in: if a message's wire format has a variant containing a\n"
630 " variant containing a uint64, this is represented in Python by a\n"
631 " UInt64 with variant_level==2.\n"
635 dbus_py_uint64_range_check(PyObject
*obj
)
637 unsigned PY_LONG_LONG i
;
638 PyObject
*long_obj
= PyNumber_Long(obj
);
640 if (!long_obj
) return (dbus_uint64_t
)(-1);
641 i
= PyLong_AsUnsignedLongLong(long_obj
);
642 if (i
== (unsigned PY_LONG_LONG
)(-1) && PyErr_Occurred()) {
644 return (dbus_uint64_t
)(-1);
646 if (i
> UINT64_MAX
) {
647 PyErr_SetString(PyExc_OverflowError
, "Value out of range for UInt64");
649 return (dbus_uint64_t
)(-1);
656 UInt64_tp_new (PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
658 #ifdef DBUS_PYTHON_64_BIT_WORKS
659 PyObject
*self
= (DBusPyLongBase_Type
.tp_new
)(cls
, args
, kwargs
);
660 if (self
&& dbus_py_uint64_range_check(self
) == (dbus_uint64_t
)(-1)
661 && PyErr_Occurred()) {
667 PyErr_SetString(PyExc_NotImplementedError
,
668 "64-bit integer types are not supported on this platform");
673 PyTypeObject DBusPyUInt64_Type
= {
674 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
685 0, /* tp_as_number */
686 0, /* tp_as_sequence */
687 0, /* tp_as_mapping */
693 0, /* tp_as_buffer */
694 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
695 UInt64_tp_doc
, /* tp_doc */
698 0, /* tp_richcompare */
699 0, /* tp_weaklistoffset */
705 DEFERRED_ADDRESS(&DBusPyLongBase_Type
), /* tp_base */
707 0, /* tp_descr_get */
708 0, /* tp_descr_set */
709 0, /* tp_dictoffset */
712 UInt64_tp_new
, /* tp_new */
716 dbus_py_init_int_types(void)
718 DBusPyInt16_Type
.tp_base
= &DBusPyIntBase_Type
;
719 if (PyType_Ready(&DBusPyInt16_Type
) < 0) return 0;
720 /* disable the tp_print copied from PyInt_Type, so tp_repr gets called as
722 DBusPyInt16_Type
.tp_print
= NULL
;
724 DBusPyUInt16_Type
.tp_base
= &DBusPyIntBase_Type
;
725 if (PyType_Ready(&DBusPyUInt16_Type
) < 0) return 0;
726 DBusPyUInt16_Type
.tp_print
= NULL
;
728 DBusPyInt32_Type
.tp_base
= &DBusPyIntBase_Type
;
729 if (PyType_Ready(&DBusPyInt32_Type
) < 0) return 0;
730 DBusPyInt32_Type
.tp_print
= NULL
;
732 DBusPyUInt32_Type
.tp_base
= &DBusPyLongBase_Type
;
733 if (PyType_Ready(&DBusPyUInt32_Type
) < 0) return 0;
734 DBusPyUInt32_Type
.tp_print
= NULL
;
736 #if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
737 DBusPyInt64_Type
.tp_base
= &DBusPyLongBase_Type
;
738 if (PyType_Ready(&DBusPyInt64_Type
) < 0) return 0;
739 DBusPyInt64_Type
.tp_print
= NULL
;
741 DBusPyUInt64_Type
.tp_base
= &DBusPyLongBase_Type
;
742 if (PyType_Ready(&DBusPyUInt64_Type
) < 0) return 0;
743 DBusPyUInt64_Type
.tp_print
= NULL
;
749 dbus_py_insert_int_types(PyObject
*this_module
)
751 Py_INCREF(&DBusPyInt16_Type
);
752 Py_INCREF(&DBusPyUInt16_Type
);
753 Py_INCREF(&DBusPyInt32_Type
);
754 Py_INCREF(&DBusPyUInt32_Type
);
755 Py_INCREF(&DBusPyInt64_Type
);
756 Py_INCREF(&DBusPyUInt64_Type
);
757 Py_INCREF(&DBusPyBoolean_Type
);
758 if (PyModule_AddObject(this_module
, "Int16",
759 (PyObject
*)&DBusPyInt16_Type
) < 0) return 0;
760 if (PyModule_AddObject(this_module
, "UInt16",
761 (PyObject
*)&DBusPyUInt16_Type
) < 0) return 0;
762 if (PyModule_AddObject(this_module
, "Int32",
763 (PyObject
*)&DBusPyInt32_Type
) < 0) return 0;
764 if (PyModule_AddObject(this_module
, "UInt32",
765 (PyObject
*)&DBusPyUInt32_Type
) < 0) return 0;
766 if (PyModule_AddObject(this_module
, "Int64",
767 (PyObject
*)&DBusPyInt64_Type
) < 0) return 0;
768 if (PyModule_AddObject(this_module
, "UInt64",
769 (PyObject
*)&DBusPyUInt64_Type
) < 0) return 0;
770 if (PyModule_AddObject(this_module
, "Boolean",
771 (PyObject
*)&DBusPyBoolean_Type
) < 0) return 0;
776 /* vim:set ft=c cino< sw=4 sts=4 et: */