Add assertion macros and supporting functions
[dbus-python-phuang.git] / _dbus_bindings / int.c
blob7c945ed99cf7a5623022e0d8af0ddd0dc7feab20
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 "types-internal.h"
27 /* Specific types =================================================== */
29 /* Boolean, a subclass of DBusPythonInt ============================= */
31 PyDoc_STRVAR(Boolean_tp_doc,
32 "A boolean, represented as a subtype of `int` (not `bool`, because `bool`\n"
33 "cannot be subclassed).\n"
34 "\n"
35 ":SupportedUsage:\n"
36 " ``from dbus import Boolean`` or ``from dbus.types import Boolean``\n"
37 "\n"
38 ":Constructor:\n"
39 " Boolean(value: int[, variant_level: int]) -> Boolean\n"
40 "\n"
41 " value is converted to 0 or 1.\n"
42 "\n"
43 " variant_level must be non-negative; the default is 0.\n"
44 "\n"
45 ":IVariables:\n"
46 " `variant_level` : int\n"
47 " Indicates how many nested Variant containers this object\n"
48 " is contained in: if a message's wire format has a variant containing a\n"
49 " variant containing a boolean, this is represented in Python by a\n"
50 " Boolean with variant_level==2.\n"
53 static PyObject *
54 Boolean_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
56 PyObject *tuple, *self, *value = Py_None;
57 long variantness = 0;
58 static char *argnames[] = {"_", "variant_level", NULL};
60 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ol:__new__", argnames,
61 &value, &variantness)) return NULL;
62 if (variantness < 0) {
63 PyErr_SetString(PyExc_ValueError,
64 "variant_level must be non-negative");
65 return NULL;
67 tuple = Py_BuildValue("(i)", PyObject_IsTrue(value) ? 1 : 0);
68 if (!tuple) return NULL;
69 self = (DBusPyIntBase_Type.tp_new)(cls, tuple, kwargs);
70 Py_DECREF(tuple);
71 return self;
74 static PyObject *
75 Boolean_tp_repr (PyObject *self)
77 long variant_level = ((DBusPyIntBase *)self)->variant_level;
78 if (variant_level > 0) {
79 return PyString_FromFormat("%s(%s, variant_level=%ld)",
80 self->ob_type->tp_name,
81 PyInt_AsLong(self) ? "True" : "False",
82 variant_level);
84 return PyString_FromFormat("%s(%s)",
85 self->ob_type->tp_name,
86 PyInt_AsLong(self) ? "True" : "False");
89 PyTypeObject DBusPyBoolean_Type = {
90 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
92 "dbus.Boolean",
95 0, /* tp_dealloc */
96 0, /* tp_print */
97 0, /* tp_getattr */
98 0, /* tp_setattr */
99 0, /* tp_compare */
100 Boolean_tp_repr, /* tp_repr */
101 0, /* tp_as_number */
102 0, /* tp_as_sequence */
103 0, /* tp_as_mapping */
104 0, /* tp_hash */
105 0, /* tp_call */
106 0, /* tp_str */
107 0, /* tp_getattro */
108 0, /* tp_setattro */
109 0, /* tp_as_buffer */
110 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
111 Boolean_tp_doc, /* tp_doc */
112 0, /* tp_traverse */
113 0, /* tp_clear */
114 0, /* tp_richcompare */
115 0, /* tp_weaklistoffset */
116 0, /* tp_iter */
117 0, /* tp_iternext */
118 0, /* tp_methods */
119 0, /* tp_members */
120 0, /* tp_getset */
121 DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
122 0, /* tp_dict */
123 0, /* tp_descr_get */
124 0, /* tp_descr_set */
125 0, /* tp_dictoffset */
126 0, /* tp_init */
127 0, /* tp_alloc */
128 Boolean_tp_new, /* tp_new */
131 /* Int16 ============================================================ */
133 PyDoc_STRVAR(Int16_tp_doc,
134 "A signed 16-bit integer between -0x8000 and +0x7FFF, represented as\n"
135 "a subtype of `int`.\n"
136 "\n"
137 ":SupportedUsage:\n"
138 " ``from dbus import Int16`` or ``from dbus.types import Int16``\n"
139 "\n"
140 ":Constructor:\n"
141 " Int16(value: int[, variant_level: int]) -> Int16\n"
142 " value must be within the allowed range, or OverflowError will be\n"
143 " raised.\n"
144 " variant_level must be non-negative; the default is 0.\n"
145 "\n"
146 ":IVariables:\n"
147 " `variant_level` : int\n"
148 " Indicates how many nested Variant containers this object\n"
149 " is contained in: if a message's wire format has a variant containing a\n"
150 " variant containing an int16, this is represented in Python by an\n"
151 " Int16 with variant_level==2.\n"
154 dbus_int16_t
155 dbus_py_int16_range_check(PyObject *obj)
157 long i = PyInt_AsLong (obj);
158 if (i == -1 && PyErr_Occurred ()) return -1;
159 if (i < -0x8000 || i > 0x7fff) {
160 PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int16",
161 (int)i);
162 return -1;
164 return i;
167 static PyObject *
168 Int16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
170 PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
171 if (self && dbus_py_int16_range_check(self) == -1 && PyErr_Occurred()) {
172 Py_DECREF(self);
173 return NULL;
175 return self;
178 PyTypeObject DBusPyInt16_Type = {
179 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
181 "dbus.Int16",
184 0, /* tp_dealloc */
185 0, /* tp_print */
186 0, /* tp_getattr */
187 0, /* tp_setattr */
188 0, /* tp_compare */
189 0, /* tp_repr */
190 0, /* tp_as_number */
191 0, /* tp_as_sequence */
192 0, /* tp_as_mapping */
193 0, /* tp_hash */
194 0, /* tp_call */
195 0, /* tp_str */
196 0, /* tp_getattro */
197 0, /* tp_setattro */
198 0, /* tp_as_buffer */
199 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
200 Int16_tp_doc, /* tp_doc */
201 0, /* tp_traverse */
202 0, /* tp_clear */
203 0, /* tp_richcompare */
204 0, /* tp_weaklistoffset */
205 0, /* tp_iter */
206 0, /* tp_iternext */
207 0, /* tp_methods */
208 0, /* tp_members */
209 0, /* tp_getset */
210 DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
211 0, /* tp_dict */
212 0, /* tp_descr_get */
213 0, /* tp_descr_set */
214 0, /* tp_dictoffset */
215 0, /* tp_init */
216 0, /* tp_alloc */
217 Int16_tp_new, /* tp_new */
220 /* UInt16 =========================================================== */
222 PyDoc_STRVAR(UInt16_tp_doc,
223 "An unsigned 16-bit integer between 0 and 0xFFFF, represented as\n"
224 "a subtype of `int`.\n"
225 "\n"
226 ":SupportedUsage:\n"
227 " ``from dbus import UInt16`` or ``from dbus.types import UInt16``\n"
228 "\n"
229 ":Constructor:\n"
230 " UInt16(value: int[, variant_level: int]) -> UInt16\n"
231 " value must be within the allowed range, or OverflowError will be\n"
232 " raised.\n"
233 " variant_level must be non-negative; the default is 0.\n"
234 "\n"
235 ":IVariables:\n"
236 " `variant_level` : int\n"
237 " Indicates how many nested Variant containers this object\n"
238 " is contained in: if a message's wire format has a variant containing a\n"
239 " variant containing a uint16, this is represented in Python by a\n"
240 " UInt16 with variant_level==2.\n"
243 dbus_uint16_t
244 dbus_py_uint16_range_check(PyObject *obj)
246 long i = PyInt_AsLong(obj);
247 if (i == -1 && PyErr_Occurred()) return (dbus_uint16_t)(-1);
248 if (i < 0 || i > 0xffff) {
249 PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt16",
250 (int)i);
251 return (dbus_uint16_t)(-1);
253 return i;
256 static PyObject *
257 UInt16_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
259 PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
260 if (self && dbus_py_uint16_range_check(self) == (dbus_uint16_t)(-1)
261 && PyErr_Occurred()) {
262 Py_DECREF (self);
263 return NULL;
265 return self;
268 PyTypeObject DBusPyUInt16_Type = {
269 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
271 "dbus.UInt16",
274 0, /* tp_dealloc */
275 0, /* tp_print */
276 0, /* tp_getattr */
277 0, /* tp_setattr */
278 0, /* tp_compare */
279 0, /* tp_repr */
280 0, /* tp_as_number */
281 0, /* tp_as_sequence */
282 0, /* tp_as_mapping */
283 0, /* tp_hash */
284 0, /* tp_call */
285 0, /* tp_str */
286 0, /* tp_getattro */
287 0, /* tp_setattro */
288 0, /* tp_as_buffer */
289 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
290 UInt16_tp_doc, /* tp_doc */
291 0, /* tp_traverse */
292 0, /* tp_clear */
293 0, /* tp_richcompare */
294 0, /* tp_weaklistoffset */
295 0, /* tp_iter */
296 0, /* tp_iternext */
297 0, /* tp_methods */
298 0, /* tp_members */
299 0, /* tp_getset */
300 DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
301 0, /* tp_dict */
302 0, /* tp_descr_get */
303 0, /* tp_descr_set */
304 0, /* tp_dictoffset */
305 0, /* tp_init */
306 0, /* tp_alloc */
307 UInt16_tp_new, /* tp_new */
310 /* Int32 ============================================================ */
312 PyDoc_STRVAR(Int32_tp_doc,
313 "A signed 32-bit integer between -0x8000 0000 and +0x7FFF FFFF, represented as\n"
314 "a subtype of `int`.\n"
315 "\n"
316 ":SupportedUsage:\n"
317 " ``from dbus import Int32`` or ``from dbus.types import Int32``\n"
318 "\n"
319 ":Constructor:\n"
320 " Int32(value: int[, variant_level: int]) -> Int32\n"
321 " value must be within the allowed range, or OverflowError will be\n"
322 " raised.\n"
323 " variant_level must be non-negative; the default is 0.\n"
324 "\n"
325 ":IVariables:\n"
326 " `variant_level` : int\n"
327 " Indicates how many nested Variant containers this object\n"
328 " is contained in: if a message's wire format has a variant containing a\n"
329 " variant containing an int32, this is represented in Python by an\n"
330 " Int32 with variant_level==2.\n"
333 dbus_int32_t
334 dbus_py_int32_range_check(PyObject *obj)
336 long i = PyInt_AsLong(obj);
337 if (i == -1 && PyErr_Occurred()) return -1;
338 if (i < INT32_MIN || i > INT32_MAX) {
339 PyErr_Format(PyExc_OverflowError, "Value %d out of range for Int32",
340 (int)i);
341 return -1;
343 return i;
346 static PyObject *
347 Int32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
349 PyObject *self = (DBusPyIntBase_Type.tp_new)(cls, args, kwargs);
350 if (self && dbus_py_int32_range_check(self) == -1 && PyErr_Occurred()) {
351 Py_DECREF(self);
352 return NULL;
354 return self;
357 PyTypeObject DBusPyInt32_Type = {
358 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
360 "dbus.Int32",
363 0, /* tp_dealloc */
364 0, /* tp_print */
365 0, /* tp_getattr */
366 0, /* tp_setattr */
367 0, /* tp_compare */
368 0, /* tp_repr */
369 0, /* tp_as_number */
370 0, /* tp_as_sequence */
371 0, /* tp_as_mapping */
372 0, /* tp_hash */
373 0, /* tp_call */
374 0, /* tp_str */
375 0, /* tp_getattro */
376 0, /* tp_setattro */
377 0, /* tp_as_buffer */
378 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
379 Int32_tp_doc, /* tp_doc */
380 0, /* tp_traverse */
381 0, /* tp_clear */
382 0, /* tp_richcompare */
383 0, /* tp_weaklistoffset */
384 0, /* tp_iter */
385 0, /* tp_iternext */
386 0, /* tp_methods */
387 0, /* tp_members */
388 0, /* tp_getset */
389 DEFERRED_ADDRESS(&DBusPyIntBase_Type), /* tp_base */
390 0, /* tp_dict */
391 0, /* tp_descr_get */
392 0, /* tp_descr_set */
393 0, /* tp_dictoffset */
394 0, /* tp_init */
395 0, /* tp_alloc */
396 Int32_tp_new, /* tp_new */
399 /* UInt32 =========================================================== */
401 PyDoc_STRVAR(UInt32_tp_doc,
402 "An unsigned 32-bit integer between 0 and 0xFFFF FFFF, represented as a\n"
403 "subtype of `long`.\n"
404 "\n"
405 "Note that this may be changed in future to be a subtype of `int` on\n"
406 "64-bit platforms; applications should not rely on either behaviour.\n"
407 "\n"
408 ":SupportedUsage:\n"
409 " ``from dbus import UInt32`` or ``from dbus.types import UInt32``\n"
410 "\n"
411 ":Constructor:\n"
412 " UInt32(value: long[, variant_level: int]) -> UInt32\n"
413 " value must be within the allowed range, or OverflowError will be\n"
414 " raised.\n"
415 " variant_level must be non-negative; the default is 0.\n"
416 "\n"
417 ":IVariables:\n"
418 " `variant_level` : int\n"
419 " Indicates how many nested Variant containers this object\n"
420 " is contained in: if a message's wire format has a variant containing a\n"
421 " variant containing a uint32, this is represented in Python by a\n"
422 " UInt32 with variant_level==2.\n"
425 dbus_uint32_t
426 dbus_py_uint32_range_check(PyObject *obj)
428 unsigned long i;
429 PyObject *long_obj = PyNumber_Long(obj);
431 if (!long_obj) return (dbus_uint32_t)(-1);
432 i = PyLong_AsUnsignedLong(long_obj);
433 if (i == (unsigned long)(-1) && PyErr_Occurred()) {
434 Py_DECREF(long_obj);
435 return (dbus_uint32_t)(-1);
437 if (i > UINT32_MAX) {
438 PyErr_Format(PyExc_OverflowError, "Value %d out of range for UInt32",
439 (int)i);
440 Py_DECREF(long_obj);
441 return (dbus_uint32_t)(-1);
443 Py_DECREF(long_obj);
444 return i;
447 static PyObject *
448 UInt32_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
450 PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
451 if (self && dbus_py_uint32_range_check(self) == (dbus_uint32_t)(-1)
452 && PyErr_Occurred()) {
453 Py_DECREF(self);
454 return NULL;
456 return self;
459 PyTypeObject DBusPyUInt32_Type = {
460 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
462 "dbus.UInt32",
465 0, /* tp_dealloc */
466 0, /* tp_print */
467 0, /* tp_getattr */
468 0, /* tp_setattr */
469 0, /* tp_compare */
470 0, /* tp_repr */
471 0, /* tp_as_number */
472 0, /* tp_as_sequence */
473 0, /* tp_as_mapping */
474 0, /* tp_hash */
475 0, /* tp_call */
476 0, /* tp_str */
477 0, /* tp_getattro */
478 0, /* tp_setattro */
479 0, /* tp_as_buffer */
480 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
481 UInt32_tp_doc, /* tp_doc */
482 0, /* tp_traverse */
483 0, /* tp_clear */
484 0, /* tp_richcompare */
485 0, /* tp_weaklistoffset */
486 0, /* tp_iter */
487 0, /* tp_iternext */
488 0, /* tp_methods */
489 0, /* tp_members */
490 0, /* tp_getset */
491 DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
492 0, /* tp_dict */
493 0, /* tp_descr_get */
494 0, /* tp_descr_set */
495 0, /* tp_dictoffset */
496 0, /* tp_init */
497 0, /* tp_alloc */
498 UInt32_tp_new, /* tp_new */
501 /* Int64 =========================================================== */
503 PyDoc_STRVAR(Int64_tp_doc,
504 "A signed 64-bit integer between -0x8000 0000 0000 0000 and\n"
505 "+0x7FFF FFFF FFFF FFFF, represented as a subtype of `long`.\n"
506 "\n"
507 "Note that this may be changed in future to be a subtype of `int` on\n"
508 "64-bit platforms; applications should not rely on either behaviour.\n"
509 "\n"
510 "This type only works on platforms where the C compiler has suitable\n"
511 "64-bit types, such as C99 ``long long``.\n"
512 #ifdef DBUS_PYTHON_64_BIT_WORKS
513 "This is the case on your current platform.\n"
514 #else /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
515 "This is not the case on your current platform, so this type's\n"
516 "constructor will always raise NotImplementedError. Try a better\n"
517 "compiler, if one is available.\n"
518 #endif /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
519 "\n"
520 ":SupportedUsage:\n"
521 " ``from dbus import Int64`` or ``from dbus.types import Int64``\n"
522 "\n"
523 ":Constructor:\n"
524 " Int64(value: long[, variant_level: int]) -> Int64\n"
525 " value must be within the allowed range, or OverflowError will be\n"
526 " raised.\n"
527 " variant_level must be non-negative; the default is 0.\n"
528 "\n"
529 ":IVariables:\n"
530 " `variant_level` : int\n"
531 " Indicates how many nested Variant containers this object\n"
532 " is contained in: if a message's wire format has a variant containing a\n"
533 " variant containing an int64, this is represented in Python by an\n"
534 " Int64 with variant_level==2.\n"
537 #ifdef DBUS_PYTHON_64_BIT_WORKS
538 dbus_int64_t
539 dbus_py_int64_range_check(PyObject *obj)
541 PY_LONG_LONG i;
542 PyObject *long_obj = PyNumber_Long(obj);
544 if (!long_obj) return -1;
545 i = PyLong_AsLongLong(long_obj);
546 if (i == -1 && PyErr_Occurred()) {
547 Py_DECREF(long_obj);
548 return -1;
550 if (i < INT64_MIN || i > INT64_MAX) {
551 PyErr_SetString(PyExc_OverflowError, "Value out of range for Int64");
552 Py_DECREF(long_obj);
553 return -1;
555 Py_DECREF(long_obj);
556 return i;
558 #endif
560 static PyObject *
561 Int64_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
563 #ifdef DBUS_PYTHON_64_BIT_WORKS
564 PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
565 if (self && dbus_py_int64_range_check(self) == -1 && PyErr_Occurred()) {
566 Py_DECREF(self);
567 return NULL;
569 return self;
570 #else
571 PyErr_SetString(PyExc_NotImplementedError,
572 "64-bit types are not available on this platform");
573 return NULL;
574 #endif
577 PyTypeObject DBusPyInt64_Type = {
578 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
580 "dbus.Int64",
583 0, /* tp_dealloc */
584 0, /* tp_print */
585 0, /* tp_getattr */
586 0, /* tp_setattr */
587 0, /* tp_compare */
588 0, /* tp_repr */
589 0, /* tp_as_number */
590 0, /* tp_as_sequence */
591 0, /* tp_as_mapping */
592 0, /* tp_hash */
593 0, /* tp_call */
594 0, /* tp_str */
595 0, /* tp_getattro */
596 0, /* tp_setattro */
597 0, /* tp_as_buffer */
598 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
599 Int64_tp_doc, /* tp_doc */
600 0, /* tp_traverse */
601 0, /* tp_clear */
602 0, /* tp_richcompare */
603 0, /* tp_weaklistoffset */
604 0, /* tp_iter */
605 0, /* tp_iternext */
606 0, /* tp_methods */
607 0, /* tp_members */
608 0, /* tp_getset */
609 DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
610 0, /* tp_dict */
611 0, /* tp_descr_get */
612 0, /* tp_descr_set */
613 0, /* tp_dictoffset */
614 0, /* tp_init */
615 0, /* tp_alloc */
616 Int64_tp_new, /* tp_new */
619 /* UInt64 =========================================================== */
621 PyDoc_STRVAR(UInt64_tp_doc,
622 "An unsigned 64-bit integer between 0 and 0xFFFF FFFF FFFF FFFF,\n"
623 "represented as a subtype of `long`.\n"
624 "\n"
625 "This type only exists on platforms where the C compiler has suitable\n"
626 "64-bit types, such as C99 ``unsigned long long``.\n"
627 #ifdef DBUS_PYTHON_64_BIT_WORKS
628 "This is the case on your current platform.\n"
629 #else /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
630 "This is not the case on your current platform, so this type's\n"
631 "constructor will always raise NotImplementedError. Try a better\n"
632 "compiler, if one is available.\n"
633 #endif /* !defined(DBUS_PYTHON_64_BIT_WORKS) */
634 "\n"
635 ":Constructor:\n"
636 " UInt64(value: long[, variant_level: int]) -> UInt64\n"
637 " value must be within the allowed range, or OverflowError will be\n"
638 " raised.\n"
639 " variant_level must be non-negative; the default is 0.\n"
640 "\n"
641 ":IVariables:\n"
642 " `variant_level` : int\n"
643 " Indicates how many nested Variant containers this object\n"
644 " is contained in: if a message's wire format has a variant containing a\n"
645 " variant containing a uint64, this is represented in Python by a\n"
646 " UInt64 with variant_level==2.\n"
649 dbus_uint64_t
650 dbus_py_uint64_range_check(PyObject *obj)
652 unsigned PY_LONG_LONG i;
653 PyObject *long_obj = PyNumber_Long(obj);
655 if (!long_obj) return (dbus_uint64_t)(-1);
656 i = PyLong_AsUnsignedLongLong(long_obj);
657 if (i == (unsigned PY_LONG_LONG)(-1) && PyErr_Occurred()) {
658 Py_DECREF(long_obj);
659 return (dbus_uint64_t)(-1);
661 if (i > UINT64_MAX) {
662 PyErr_SetString(PyExc_OverflowError, "Value out of range for UInt64");
663 Py_DECREF(long_obj);
664 return (dbus_uint64_t)(-1);
666 Py_DECREF(long_obj);
667 return i;
670 static PyObject *
671 UInt64_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
673 #ifdef DBUS_PYTHON_64_BIT_WORKS
674 PyObject *self = (DBusPyLongBase_Type.tp_new)(cls, args, kwargs);
675 if (self && dbus_py_uint64_range_check(self) == (dbus_uint64_t)(-1)
676 && PyErr_Occurred()) {
677 Py_DECREF(self);
678 return NULL;
680 return self;
681 #else
682 PyErr_SetString(PyExc_NotImplementedError,
683 "64-bit integer types are not supported on this platform");
684 return NULL;
685 #endif
688 PyTypeObject DBusPyUInt64_Type = {
689 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
691 "dbus.UInt64",
694 0, /* tp_dealloc */
695 0, /* tp_print */
696 0, /* tp_getattr */
697 0, /* tp_setattr */
698 0, /* tp_compare */
699 0, /* tp_repr */
700 0, /* tp_as_number */
701 0, /* tp_as_sequence */
702 0, /* tp_as_mapping */
703 0, /* tp_hash */
704 0, /* tp_call */
705 0, /* tp_str */
706 0, /* tp_getattro */
707 0, /* tp_setattro */
708 0, /* tp_as_buffer */
709 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
710 UInt64_tp_doc, /* tp_doc */
711 0, /* tp_traverse */
712 0, /* tp_clear */
713 0, /* tp_richcompare */
714 0, /* tp_weaklistoffset */
715 0, /* tp_iter */
716 0, /* tp_iternext */
717 0, /* tp_methods */
718 0, /* tp_members */
719 0, /* tp_getset */
720 DEFERRED_ADDRESS(&DBusPyLongBase_Type), /* tp_base */
721 0, /* tp_dict */
722 0, /* tp_descr_get */
723 0, /* tp_descr_set */
724 0, /* tp_dictoffset */
725 0, /* tp_init */
726 0, /* tp_alloc */
727 UInt64_tp_new, /* tp_new */
730 dbus_bool_t
731 dbus_py_init_int_types(void)
733 DBusPyInt16_Type.tp_base = &DBusPyIntBase_Type;
734 if (PyType_Ready(&DBusPyInt16_Type) < 0) return 0;
735 /* disable the tp_print copied from PyInt_Type, so tp_repr gets called as
736 desired */
737 DBusPyInt16_Type.tp_print = NULL;
739 DBusPyUInt16_Type.tp_base = &DBusPyIntBase_Type;
740 if (PyType_Ready(&DBusPyUInt16_Type) < 0) return 0;
741 DBusPyUInt16_Type.tp_print = NULL;
743 DBusPyInt32_Type.tp_base = &DBusPyIntBase_Type;
744 if (PyType_Ready(&DBusPyInt32_Type) < 0) return 0;
745 DBusPyInt32_Type.tp_print = NULL;
747 DBusPyUInt32_Type.tp_base = &DBusPyLongBase_Type;
748 if (PyType_Ready(&DBusPyUInt32_Type) < 0) return 0;
749 DBusPyUInt32_Type.tp_print = NULL;
751 #if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG)
752 DBusPyInt64_Type.tp_base = &DBusPyLongBase_Type;
753 if (PyType_Ready(&DBusPyInt64_Type) < 0) return 0;
754 DBusPyInt64_Type.tp_print = NULL;
756 DBusPyUInt64_Type.tp_base = &DBusPyLongBase_Type;
757 if (PyType_Ready(&DBusPyUInt64_Type) < 0) return 0;
758 DBusPyUInt64_Type.tp_print = NULL;
759 #endif
760 return 1;
763 dbus_bool_t
764 dbus_py_insert_int_types(PyObject *this_module)
766 Py_INCREF(&DBusPyInt16_Type);
767 Py_INCREF(&DBusPyUInt16_Type);
768 Py_INCREF(&DBusPyInt32_Type);
769 Py_INCREF(&DBusPyUInt32_Type);
770 Py_INCREF(&DBusPyInt64_Type);
771 Py_INCREF(&DBusPyUInt64_Type);
772 Py_INCREF(&DBusPyBoolean_Type);
773 if (PyModule_AddObject(this_module, "Int16",
774 (PyObject *)&DBusPyInt16_Type) < 0) return 0;
775 if (PyModule_AddObject(this_module, "UInt16",
776 (PyObject *)&DBusPyUInt16_Type) < 0) return 0;
777 if (PyModule_AddObject(this_module, "Int32",
778 (PyObject *)&DBusPyInt32_Type) < 0) return 0;
779 if (PyModule_AddObject(this_module, "UInt32",
780 (PyObject *)&DBusPyUInt32_Type) < 0) return 0;
781 if (PyModule_AddObject(this_module, "Int64",
782 (PyObject *)&DBusPyInt64_Type) < 0) return 0;
783 if (PyModule_AddObject(this_module, "UInt64",
784 (PyObject *)&DBusPyUInt64_Type) < 0) return 0;
785 if (PyModule_AddObject(this_module, "Boolean",
786 (PyObject *)&DBusPyBoolean_Type) < 0) return 0;
788 return 1;
791 /* vim:set ft=c cino< sw=4 sts=4 et: */