[pygobject] [gi] when encountering guint8 arrays treat them as byte arrays
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] [gi] when encountering guint8 arrays treat them as byte arrays
- Date: Mon, 22 Nov 2010 22:17:24 +0000 (UTC)
commit 3fd51bb903724b752f72f49c7cb35652b819791d
Author: John (J5) Palmieri <johnp redhat com>
Date: Fri Nov 19 16:44:32 2010 -0500
[gi] when encountering guint8 arrays treat them as byte arrays
* In Python 2 this means returning a PyString object
* In Python 3 we return a PyBytes object
https://bugzilla.gnome.org/show_bug.cgi?id=627367
gi/pygi-argument.c | 65 ++++++++++++++++++++++++++++++++++++++++++---------
tests/test_gi.py | 6 +++-
2 files changed, 57 insertions(+), 14 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index ddd933b..8eaf8ba 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -271,8 +271,18 @@ _pygi_g_type_info_check_object (GITypeInfo *type_info,
case GI_TYPE_TAG_BOOLEAN:
/* No check; every Python object has a truth value. */
break;
- case GI_TYPE_TAG_INT8:
case GI_TYPE_TAG_UINT8:
+ /* UINT8 types can be characters */
+ if (PYGLIB_PyBytes_Check(object)) {
+ if (PYGLIB_PyBytes_Size(object) != 1) {
+ PyErr_Format (PyExc_TypeError, "Must be a single character");
+ retval = 0;
+ break;
+ }
+
+ break;
+ }
+ case GI_TYPE_TAG_INT8:
case GI_TYPE_TAG_INT16:
case GI_TYPE_TAG_UINT16:
case GI_TYPE_TAG_INT32:
@@ -407,6 +417,10 @@ check_number_release:
item_type_info = g_type_info_get_param_type (type_info, 0);
g_assert (item_type_info != NULL);
+ /* FIXME: This is insain. We really should only check the first
+ * object and perhaps have a debugging mode. Large arrays
+ * will cause apps to slow to a crawl.
+ */
for (i = 0; i < length; i++) {
PyObject *item;
@@ -640,8 +654,13 @@ _pygi_argument_from_object (PyObject *object,
arg.v_boolean = PyObject_IsTrue (object);
break;
}
- case GI_TYPE_TAG_INT8:
case GI_TYPE_TAG_UINT8:
+ if (PYGLIB_PyBytes_Check(object)) {
+ arg.v_long = (long)(PYGLIB_PyBytes_AsString(object)[0]);
+ break;
+ }
+
+ case GI_TYPE_TAG_INT8:
case GI_TYPE_TAG_INT16:
case GI_TYPE_TAG_UINT16:
case GI_TYPE_TAG_INT32:
@@ -840,6 +859,14 @@ _pygi_argument_from_object (PyObject *object,
break;
}
+ if (g_type_info_get_tag (item_type_info) == GI_TYPE_TAG_UINT8 &&
+ PYGLIB_PyBytes_Check(object)) {
+
+ memcpy(array->data, PYGLIB_PyBytes_AsString(object), length);
+ goto array_success;
+ }
+
+
item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
for (i = 0; i < length; i++) {
@@ -872,6 +899,7 @@ array_item_error:
break;
}
+array_success:
arg.v_pointer = array;
g_base_info_unref ( (GIBaseInfo *) item_type_info);
@@ -1292,23 +1320,36 @@ _pygi_argument_to_object (GIArgument *arg,
GITransfer item_transfer;
gsize i, item_size;
- if (arg->v_pointer == NULL) {
- object = PyList_New (0);
- break;
- }
-
array = arg->v_pointer;
- object = PyList_New (array->len);
- if (object == NULL) {
- break;
- }
-
item_type_info = g_type_info_get_param_type (type_info, 0);
g_assert (item_type_info != NULL);
item_type_tag = g_type_info_get_tag (item_type_info);
item_transfer = transfer == GI_TRANSFER_CONTAINER ? GI_TRANSFER_NOTHING : transfer;
+
+ if (item_type_tag == GI_TYPE_TAG_UINT8) {
+ /* Return as a byte array */
+ if (arg->v_pointer == NULL) {
+ object = PYGLIB_PyBytes_FromString ("");
+ break;
+ }
+
+ object = PYGLIB_PyBytes_FromStringAndSize(array->data, array->len);
+ break;
+
+ } else {
+ if (arg->v_pointer == NULL) {
+ object = PyList_New (0);
+ break;
+ }
+
+ object = PyList_New (array->len);
+ if (object == NULL) {
+ break;
+ }
+
+ }
item_size = g_array_get_element_size (array);
for (i = 0; i < array->len; i++) {
diff --git a/tests/test_gi.py b/tests/test_gi.py
index bff5bc7..c8b1b16 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -14,9 +14,11 @@ from gi.repository import GIMarshallingTests
if sys.version_info < (3, 0):
CONSTANT_UTF8 = "const \xe2\x99\xa5 utf8"
- PY2_UNICODE_UTF8 = u"const â?¥ utf8"
+ PY2_UNICODE_UTF8 = unicode(CONSTANT_UTF8, 'UTF-8')
+ CHAR_255='\xff'
else:
CONSTANT_UTF8 = "const â?¥ utf8"
+ CHAR_255=bytes([255])
CONSTANT_NUMBER = 42
@@ -121,9 +123,9 @@ class TestUInt8(unittest.TestCase):
number = Number(self.MAX)
GIMarshallingTests.uint8_in(number)
+ GIMarshallingTests.uint8_in(CHAR_255)
number.value += 1
-
self.assertRaises(ValueError, GIMarshallingTests.uint8_in, number)
self.assertRaises(ValueError, GIMarshallingTests.uint8_in, Number(-1))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]