1
/* Simple D-Bus types: integers of various sizes, and ObjectPath.
3
* Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
5
* Permission is hereby granted, free of charge, to any person
6
* obtaining a copy of this software and associated documentation
7
* files (the "Software"), to deal in the Software without
8
* restriction, including without limitation the rights to use, copy,
9
* modify, merge, publish, distribute, sublicense, and/or sell copies
10
* of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be
14
* included in all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
* DEALINGS IN THE SOFTWARE.
26
#include "types-internal.h"
28
/* Specific types =================================================== */
30
/* Boolean, a subclass of DBusPythonInt ============================= */
32
PyDoc_STRVAR(Boolean_tp_doc,
33
"A boolean, represented as a subtype of `int` (not `bool`, because `bool`\n"
34
"cannot be subclassed).\n"
38
" dbus.Boolean(value[, variant_level]) -> Boolean\n"
40
"``value`` is converted to 0 or 1 as if by ``int(bool(value))``.\n"
42
"``variant_level`` must be non-negative; the default is 0.\n"
45
" `variant_level` : int\n"
46
" Indicates how many nested Variant containers this object\n"
47
" is contained in: if a message's wire format has a variant containing a\n"
48
" variant containing a boolean, this is represented in Python by a\n"
49
" Boolean with variant_level==2.\n"
53
Boolean_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
55
PyObject *tuple, *self, *value = Py_None;
57
static char *argnames[] = {"_", "variant_level", NULL};
59
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ol:__new__", argnames,
60
&value, &variantness)) return NULL;
61
if (variantness < 0) {
62
PyErr_SetString(PyExc_ValueError,
63
"variant_level must be non-negative");
66
tuple = Py_BuildValue("(i)", PyObject_IsTrue(value) ? 1 : 0);
67
if (!tuple) return NULL;
68
self = (DBusPyIntBase_Type.tp_new)(cls, tuple, kwargs);
74
Boolean_tp_repr (PyObject *self)
76
long variant_level = ((DBusPyIntBase *)self)->variant_level;
77
if (variant_level > 0) {
78
return PyString_FromFormat("%s(%s, variant_level=%ld)",
79
self->ob_type->tp_name,
80
PyInt_AsLong(self) ? "True" : "False",
83
return PyString_FromFormat("%s(%s)",
84
self->ob_type->tp_name,
85
PyInt_AsLong(self) ? "True" : "False");
88
PyTypeObject DBusPyBoolean_Type = {
89
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
99
Boolean_tp_repr, /* tp_repr */
100
0, /* tp_as_number */
101
0, /* tp_as_sequence */
102
0, /* tp_as_mapping */
108
0, /* tp_as_buffer */
109
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
110
Boolean_tp_doc, /* tp_doc */
113
0, /* tp_richcompare */
114
0, /* tp_weaklistoffset */
120
DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
122
0, /* tp_descr_get */
123
0, /* tp_descr_set */
124
0, /* tp_dictoffset */
127
Boolean_tp_new, /* tp_new */
130
/* Int16 ============================================================ */
132
PyDoc_STRVAR(Int16_tp_doc,
133
"A signed 16-bit integer between -0x8000 and +0x7FFF, represented as\n"
134
"a subtype of `int`.\n"
138
" dbus.Int16(value: int[, variant_level: int]) -> Int16\n"
140
"value must be within the allowed range, or OverflowError will be\n"
143
" variant_level must be non-negative; the default is 0.\n"
146
" `variant_level` : int\n"
147
" Indicates how many nested Variant containers this object\n"
148
" is contained in: if a message's wire format has a variant containing a\n"
149
" variant containing an int16, this is represented in Python by an\n"
150
" Int16 with variant_level==2.\n"
154
dbus_py_int16_range_check(PyObject *obj)
156
long i = PyInt_AsLong (obj);
157
if (i == -1 && PyErr_Occurred ()) return -1;
158
if (i < -0x8000 || i > 0x7fff) {
159
PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int16",
167
Int16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
169
PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
170
if (self && dbus_py_int16_range_check(self) == -1 && PyErr_Occurred()) {
177
PyTypeObject DBusPyInt16_Type = {
178
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
189
0, /* tp_as_number */
190
0, /* tp_as_sequence */
191
0, /* tp_as_mapping */
197
0, /* tp_as_buffer */
198
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
199
Int16_tp_doc, /* tp_doc */
202
0, /* tp_richcompare */
203
0, /* tp_weaklistoffset */
209
DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
211
0, /* tp_descr_get */
212
0, /* tp_descr_set */
213
0, /* tp_dictoffset */
216
Int16_tp_new, /* tp_new */
219
/* UInt16 =========================================================== */
221
PyDoc_STRVAR(UInt16_tp_doc,
222
"An unsigned 16-bit integer between 0 and 0xFFFF, represented as\n"
223
"a subtype of `int`.\n"
227
" dbus.UInt16(value: int[, variant_level: int]) -> UInt16\n"
229
"``value`` must be within the allowed range, or `OverflowError` will be\n"
232
"``variant_level`` must be non-negative; the default is 0.\n"
235
" `variant_level` : int\n"
236
" Indicates how many nested Variant containers this object\n"
237
" is contained in: if a message's wire format has a variant containing a\n"
238
" variant containing a uint16, this is represented in Python by a\n"
239
" UInt16 with variant_level==2.\n"
243
dbus_py_uint16_range_check(PyObject *obj)
245
long i = PyInt_AsLong(obj);
246
if (i == -1 && PyErr_Occurred()) return (dbus_uint16_t)(-1);
247
if (i < 0 || i > 0xffff) {
248
PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt16",
250
return (dbus_uint16_t)(-1);
256
UInt16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
258
PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
259
if (self && dbus_py_uint16_range_check(self) == (dbus_uint16_t)(-1)
260
&& PyErr_Occurred()) {
267
PyTypeObject DBusPyUInt16_Type = {
268
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
279
0, /* tp_as_number */
280
0, /* tp_as_sequence */
281
0, /* tp_as_mapping */
287
0, /* tp_as_buffer */
288
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
289
UInt16_tp_doc, /* tp_doc */
292
0, /* tp_richcompare */
293
0, /* tp_weaklistoffset */
299
DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
301
0, /* tp_descr_get */
302
0, /* tp_descr_set */
303
0, /* tp_dictoffset */
306
UInt16_tp_new, /* tp_new */
309
/* Int32 ============================================================ */
311
PyDoc_STRVAR(Int32_tp_doc,
312
"A signed 32-bit integer between -0x8000 0000 and +0x7FFF FFFF, represented as\n"
313
"a subtype of `int`.\n"
317
" dbus.Int32(value: int[, variant_level: int]) -> Int32\n"
319
"``value`` must be within the allowed range, or `OverflowError` will be\n"
322
"``variant_level`` must be non-negative; the default is 0.\n"
325
" `variant_level` : int\n"
326
" Indicates how many nested Variant containers this object\n"
327
" is contained in: if a message's wire format has a variant containing a\n"
328
" variant containing an int32, this is represented in Python by an\n"
329
" Int32 with variant_level==2.\n"
333
dbus_py_int32_range_check(PyObject *obj)
335
long i = PyInt_AsLong(obj);
336
if (i == -1 && PyErr_Occurred()) return -1;
337
if (i < INT32_MIN || i > INT32_MAX) {
338
PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int32",
346
Int32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
348
PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
349
if (self && dbus_py_int32_range_check(self) == -1 && PyErr_Occurred()) {
356
PyTypeObject DBusPyInt32_Type = {
357
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
368
0, /* tp_as_number */
369
0, /* tp_as_sequence */
370
0, /* tp_as_mapping */
376
0, /* tp_as_buffer */
377
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
378
Int32_tp_doc, /* tp_doc */
381
0, /* tp_richcompare */
382
0, /* tp_weaklistoffset */
388
DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
390
0, /* tp_descr_get */
391
0, /* tp_descr_set */
392
0, /* tp_dictoffset */
395
Int32_tp_new, /* tp_new */
398
/* UInt32 =========================================================== */
400
PyDoc_STRVAR(UInt32_tp_doc,
401
"An unsigned 32-bit integer between 0 and 0xFFFF FFFF, represented as a\n"
402
"subtype of `long`.\n"
404
"Note that this may be changed in future to be a subtype of `int` on\n"
405
"64-bit platforms; applications should not rely on either behaviour.\n"
409
" dbus.UInt32(value: long[, variant_level: int]) -> UInt32\n"
411
"``value`` must be within the allowed range, or `OverflowError` will be\n"
414
"``variant_level`` must be non-negative; the default is 0.\n"
417
" `variant_level` : int\n"
418
" Indicates how many nested Variant containers this object\n"
419
" is contained in: if a message's wire format has a variant containing a\n"
420
" variant containing a uint32, this is represented in Python by a\n"
421
" UInt32 with variant_level==2.\n"
425
dbus_py_uint32_range_check(PyObject *obj)
428
PyObject *long_obj = PyNumber_Long(obj);
430
if (!long_obj) return (dbus_uint32_t)(-1);
431
i = PyLong_AsUnsignedLong(long_obj);
432
if (i == (unsigned long)(-1) && PyErr_Occurred()) {
434
return (dbus_uint32_t)(-1);
436
if (i > UINT32_MAX) {
437
PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt32",
440
return (dbus_uint32_t)(-1);
447
UInt32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
449
PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
450
if (self && dbus_py_uint32_range_check(self) == (dbus_uint32_t)(-1)
451
&& PyErr_Occurred()) {
458
PyTypeObject DBusPyUInt32_Type = {
459
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
470
0, /* tp_as_number */
471
0, /* tp_as_sequence */
472
0, /* tp_as_mapping */
478
0, /* tp_as_buffer */
479
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
480
UInt32_tp_doc, /* tp_doc */
483
0, /* tp_richcompare */
484
0, /* tp_weaklistoffset */
490
DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
492
0, /* tp_descr_get */
493
0, /* tp_descr_set */
494
0, /* tp_dictoffset */
497
UInt32_tp_new, /* tp_new */
500
/* Int64 =========================================================== */
502
PyDoc_STRVAR(Int64_tp_doc,
503
"A signed 64-bit integer between -0x8000 0000 0000 0000 and\n"
504
"+0x7FFF FFFF FFFF FFFF, represented as a subtype of `long`.\n"
506
"Note that this may be changed in future to be a subtype of `int` on\n"
507
"64-bit platforms; applications should not rely on either behaviour.\n"
509
"This type only works on platforms where the C compiler has suitable\n"
510
"64-bit types, such as C99 ``long long``.\n"
514
" dbus.Int64(value: long[, variant_level: int]) -> Int64\n"
516
"``value`` must be within the allowed range, or `OverflowError` will be\n"
519
"``variant_level`` must be non-negative; the default is 0.\n"
522
" `variant_level` : int\n"
523
" Indicates how many nested Variant containers this object\n"
524
" is contained in: if a message's wire format has a variant containing a\n"
525
" variant containing an int64, this is represented in Python by an\n"
526
" Int64 with variant_level==2.\n"
529
#ifdef DBUS_PYTHON_64_BIT_WORKS
531
dbus_py_int64_range_check(PyObject *obj)
534
PyObject *long_obj = PyNumber_Long(obj);
536
if (!long_obj) return -1;
537
i = PyLong_AsLongLong(long_obj);
538
if (i == -1 && PyErr_Occurred()) {
542
if (i < INT64_MIN || i > INT64_MAX) {
543
PyErr_SetString(PyExc_OverflowError, "Value out of range for Int64");
553
Int64_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
555
#ifdef DBUS_PYTHON_64_BIT_WORKS
556
PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
557
if (self && dbus_py_int64_range_check(self) == -1 && PyErr_Occurred()) {
563
PyErr_SetString(PyExc_NotImplementedError,
564
"64-bit types are not available on this platform");
569
PyTypeObject DBusPyInt64_Type = {
570
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
581
0, /* tp_as_number */
582
0, /* tp_as_sequence */
583
0, /* tp_as_mapping */
589
0, /* tp_as_buffer */
590
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
591
Int64_tp_doc, /* tp_doc */
594
0, /* tp_richcompare */
595
0, /* tp_weaklistoffset */
601
DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
603
0, /* tp_descr_get */
604
0, /* tp_descr_set */
605
0, /* tp_dictoffset */
608
Int64_tp_new, /* tp_new */
611
/* UInt64 =========================================================== */
613
PyDoc_STRVAR(UInt64_tp_doc,
614
"An unsigned 64-bit integer between 0 and 0xFFFF FFFF FFFF FFFF,\n"
615
"represented as a subtype of `long`.\n"
617
"This type only exists on platforms where the C compiler has suitable\n"
618
"64-bit types, such as C99 ``unsigned long long``.\n"
622
" dbus.UInt64(value: long[, variant_level: int]) -> UInt64\n"
624
"``value`` must be within the allowed range, or `OverflowError` will be\n"
627
"``variant_level`` must be non-negative; the default is 0.\n"
630
" `variant_level` : int\n"
631
" Indicates how many nested Variant containers this object\n"
632
" is contained in: if a message's wire format has a variant containing a\n"
633
" variant containing a uint64, this is represented in Python by a\n"
634
" UInt64 with variant_level==2.\n"
638
dbus_py_uint64_range_check(PyObject *obj)
640
unsigned PY_LONG_LONG i;
641
PyObject *long_obj = PyNumber_Long(obj);
643
if (!long_obj) return (dbus_uint64_t)(-1);
644
i = PyLong_AsUnsignedLongLong(long_obj);
645
if (i == (unsigned PY_LONG_LONG)(-1) && PyErr_Occurred()) {
647
return (dbus_uint64_t)(-1);
649
if (i > UINT64_MAX) {
650
PyErr_SetString(PyExc_OverflowError, "Value out of range for UInt64");
652
return (dbus_uint64_t)(-1);
659
UInt64_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
661
#ifdef DBUS_PYTHON_64_BIT_WORKS
662
PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
663
if (self && dbus_py_uint64_range_check(self) == (dbus_uint64_t)(-1)
664
&& PyErr_Occurred()) {
670
PyErr_SetString(PyExc_NotImplementedError,
671
"64-bit integer types are not supported on this platform");
676
PyTypeObject DBusPyUInt64_Type = {
677
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
688
0, /* tp_as_number */
689
0, /* tp_as_sequence */
690
0, /* tp_as_mapping */
696
0, /* tp_as_buffer */
697
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
698
UInt64_tp_doc, /* tp_doc */
701
0, /* tp_richcompare */
702
0, /* tp_weaklistoffset */
708
DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
710
0, /* tp_descr_get */
711
0, /* tp_descr_set */
712
0, /* tp_dictoffset */
715
UInt64_tp_new, /* tp_new */
719
dbus_py_init_int_types(void)
721
DBusPyInt16_Type.tp_base = &DBusPyIntBase_Type;
722
if (PyType_Ready(&DBusPyInt16_Type) < 0) return 0;
723
/* disable the tp_print copied from PyInt_Type, so tp_repr gets called as
725
DBusPyInt16_Type.tp_print = NULL;
727
DBusPyUInt16_Type.tp_base = &DBusPyIntBase_Type;
728
if (PyType_Ready(&DBusPyUInt16_Type) < 0) return 0;
729
DBusPyUInt16_Type.tp_print = NULL;
731
DBusPyInt32_Type.tp_base = &DBusPyIntBase_Type;
732
if (PyType_Ready(&DBusPyInt32_Type) < 0) return 0;
733
DBusPyInt32_Type.tp_print = NULL;
735
DBusPyUInt32_Type.tp_base = &DBusPyLongBase_Type;
736
if (PyType_Ready(&DBusPyUInt32_Type) < 0) return 0;
737
DBusPyUInt32_Type.tp_print = NULL;
739
#if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
740
DBusPyInt64_Type.tp_base = &DBusPyLongBase_Type;
741
if (PyType_Ready(&DBusPyInt64_Type) < 0) return 0;
742
DBusPyInt64_Type.tp_print = NULL;
744
DBusPyUInt64_Type.tp_base = &DBusPyLongBase_Type;
745
if (PyType_Ready(&DBusPyUInt64_Type) < 0) return 0;
746
DBusPyUInt64_Type.tp_print = NULL;
752
dbus_py_insert_int_types(PyObject *this_module)
754
/* PyModule_AddObject steals a ref */
755
Py_INCREF(&DBusPyInt16_Type);
756
Py_INCREF(&DBusPyUInt16_Type);
757
Py_INCREF(&DBusPyInt32_Type);
758
Py_INCREF(&DBusPyUInt32_Type);
759
Py_INCREF(&DBusPyInt64_Type);
760
Py_INCREF(&DBusPyUInt64_Type);
761
Py_INCREF(&DBusPyBoolean_Type);
762
if (PyModule_AddObject(this_module, "Int16",
763
(PyObject *)&DBusPyInt16_Type) < 0) return 0;
764
if (PyModule_AddObject(this_module, "UInt16",
765
(PyObject *)&DBusPyUInt16_Type) < 0) return 0;
766
if (PyModule_AddObject(this_module, "Int32",
767
(PyObject *)&DBusPyInt32_Type) < 0) return 0;
768
if (PyModule_AddObject(this_module, "UInt32",
769
(PyObject *)&DBusPyUInt32_Type) < 0) return 0;
770
if (PyModule_AddObject(this_module, "Int64",
771
(PyObject *)&DBusPyInt64_Type) < 0) return 0;
772
if (PyModule_AddObject(this_module, "UInt64",
773
(PyObject *)&DBusPyUInt64_Type) < 0) return 0;
774
if (PyModule_AddObject(this_module, "Boolean",
775
(PyObject *)&DBusPyBoolean_Type) < 0) return 0;
780
/* vim:set ft=c cino< sw=4 sts=4 et: */