summaryrefslogtreecommitdiff
path: root/_dbus_bindings/bytes-impl.h
diff options
context:
space:
mode:
Diffstat (limited to '_dbus_bindings/bytes-impl.h')
-rw-r--r--_dbus_bindings/bytes-impl.h154
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;