diff options
Diffstat (limited to '_dbus_bindings/bytes-impl.h')
-rw-r--r-- | _dbus_bindings/bytes-impl.h | 154 |
1 files changed, 37 insertions, 117 deletions
diff --git a/_dbus_bindings/bytes-impl.h b/_dbus_bindings/bytes-impl.h index c9753a3..2983554 100644 --- a/_dbus_bindings/bytes-impl.h +++ b/_dbus_bindings/bytes-impl.h @@ -39,19 +39,15 @@ static inline int ByteArray_Check(PyObject *o) PyDoc_STRVAR(Byte_tp_doc, "Byte(integer or str of length 1)\n" "\n" -"Byte is a subtype of str, restricted to length exactly 1.\n" +"Byte is a subtype of int, with range restricted to [0, 255].\n" "\n" -"A Byte b also supports the following operations:\n" -"\n" -"* int(b) == long(b) == float(b) == ord(b)\n" -"\n" -"* oct(b), hex(b)\n" +"A Byte b may be converted to a str of length 1 via str(b) == chr(b).\n" ); static inline unsigned char Byte_as_uchar(PyObject *self) { - return (unsigned char) (PyString_AS_STRING (self)[0]); + return (unsigned char) (PyInt_AsLong (self)); } PyObject *allocated_bytes[256] = {NULL}; @@ -62,13 +58,12 @@ Byte_from_uchar(unsigned char data) PyObject *ret; ret = allocated_bytes[data]; if (!ret) { - char c[] = { (char)data, '\0' }; - PyObject *tuple = Py_BuildValue("(s#)", c, 1); + PyObject *tuple = Py_BuildValue("(i)", data); DBG("Allocating a new Byte of value \\x%02x", data); if (!tuple) return NULL; - ret = PyString_Type.tp_new(&ByteType, tuple, NULL); + ret = PyInt_Type.tp_new(&ByteType, tuple, NULL); Py_DECREF(tuple); tuple = NULL; @@ -88,8 +83,7 @@ Byte_from_uchar(unsigned char data) static PyObject * Byte_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs) { - PyObject *arg; - PyObject *string; + PyObject *obj; PyObject *tuple; if (PyTuple_Size(args) != 1 || (kwargs && PyDict_Size(kwargs) != 0)) { @@ -98,36 +92,31 @@ Byte_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs) return NULL; } - /* arg is only a borrowed ref for the moment */ - arg = PyTuple_GetItem(args, 0); + /* obj is only a borrowed ref for the moment */ + obj = PyTuple_GetItem(args, 0); - if (PyString_Check(arg)) { + if (PyString_Check(obj)) { /* string of length 1, we hope */ - if (PyString_GET_SIZE(arg) != 1) { + if (PyString_GET_SIZE(obj) != 1) { goto bad_arg; } - if (arg->ob_type == &ByteType) { - Py_INCREF(arg); - return arg; - } + /* here arg goes from a borrowed to owned reference */ + obj = Byte_from_uchar((unsigned char)(PyString_AS_STRING(obj)[0])); if (cls == &ByteType) { - /* we know that the Byte type is the same as a string - * internally, so fast-track it */ - return Byte_from_uchar((unsigned char)(PyString_AS_STRING(arg)[0])); + /* we know that the Byte type is the same as an int internally */ + return obj; } - /* only a borrowed reference so far, take ownership */ - Py_INCREF(arg); } - else if (PyInt_Check(arg)) { - long i = PyInt_AS_LONG(arg); + else if (PyInt_Check(obj)) { + long i = PyInt_AS_LONG(obj); + if (obj->ob_type == cls) { + Py_INCREF(obj); + return obj; + } if (i < 0 || i > 255) goto bad_range; - /* make a byte object, which is a length-1 string - now it's a new - reference */ - arg = Byte_from_uchar((unsigned char)i); - if (!arg) return NULL; - /* if that's the type we wanted, there's nothing more to do */ - if (cls == &ByteType) return arg; + /* else make it a new reference */ + Py_INCREF(obj); } else { goto bad_arg; @@ -136,17 +125,17 @@ Byte_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs) /* so here's the complicated case: we're trying to instantiate a subclass so we can't just allocate a Byte and go "it'll all be fine". - By now, we do have a string-of-length-1 to use as an argument to the c'tor + By now, we do have an int (or Byte) to use as an argument to the c'tor. */ - tuple = Py_BuildValue("(O)", arg); + tuple = Py_BuildValue("(O)", obj); if (!tuple) return NULL; - Py_DECREF(arg); - arg = NULL; + Py_DECREF(obj); + obj = NULL; - string = PyString_Type.tp_new(cls, tuple, NULL); + obj = PyInt_Type.tp_new(cls, tuple, NULL); Py_DECREF(tuple); tuple = NULL; - return string; + return obj; bad_arg: PyErr_SetString(PyExc_TypeError, "Expected a string of length 1, " @@ -157,80 +146,13 @@ bad_range: return NULL; } -static PyObject *Byte_nb_int (PyObject *self) -{ - return PyInt_FromLong(Byte_as_uchar(self)); -} - -static PyObject *Byte_nb_float (PyObject *self) -{ - return PyFloat_FromDouble(Byte_as_uchar(self)); -} - -static PyObject *Byte_nb_long (PyObject *self) -{ - return PyLong_FromLong(Byte_as_uchar(self)); -} - -static PyObject *Byte_nb_oct (PyObject *self) -{ - PyObject *i = PyInt_FromLong(Byte_as_uchar(self)); - if (!i) return NULL; - PyObject *s = (i->ob_type->tp_as_number->nb_oct) (i); - Py_XDECREF (i); - return s; -} - -static PyObject *Byte_nb_hex (PyObject *self) +static PyObject * +Byte_tp_str(PyObject *self) { - PyObject *i = PyInt_FromLong(Byte_as_uchar(self)); - if (!i) return NULL; - PyObject *s = (i->ob_type->tp_as_number->nb_hex) (i); - Py_XDECREF (i); - return s; + char str[] = { (char)Byte_as_uchar(self), 0 }; + return PyString_FromStringAndSize(str, 1); } -static PyNumberMethods Byte_tp_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_divide */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_nonzero */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - 0, /* nb_and */ - 0, /* nb_xor */ - 0, /* nb_or */ - 0, /* nb_coerce */ - (unaryfunc)Byte_nb_int, /* nb_int */ - (unaryfunc)Byte_nb_long, /* nb_long */ - (unaryfunc)Byte_nb_float, /* nb_float */ - (unaryfunc)Byte_nb_oct, /* nb_oct */ - (unaryfunc)Byte_nb_hex, /* nb_hex */ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 0, /* nb_inplace_divide */ - 0, /* nb_inplace_remainder */ - 0, /* nb_inplace_power */ - 0, /* nb_inplace_lshift */ - 0, /* nb_inplace_rshift */ - 0, /* nb_inplace_and */ - 0, /* nb_inplace_xor */ - 0, /* nb_inplace_or */ - 0, /* nb_floor_divide */ - 0, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ -}; - static PyTypeObject ByteType = { PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type)) 0, @@ -242,13 +164,13 @@ static PyTypeObject ByteType = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - str_subclass_tp_repr, /* tp_repr */ - &Byte_tp_as_number, + int_subclass_tp_repr, /* tp_repr */ + 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + Byte_tp_str, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ @@ -263,7 +185,7 @@ static PyTypeObject ByteType = { 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ - DEFERRED_ADDRESS(&PyString_Type), /* tp_base */ + DEFERRED_ADDRESS(&PyInt_Type), /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ @@ -391,10 +313,8 @@ static PyTypeObject ByteArrayType = { static inline int init_byte_types(void) { - ByteType.tp_base = &PyString_Type; + ByteType.tp_base = &PyInt_Type; if (PyType_Ready(&ByteType) < 0) return 0; - /* disable the tp_print copied from PyString_Type, so tp_repr gets called as - desired */ ByteType.tp_print = NULL; ByteArrayType.tp_base = &PyString_Type; |