[pygobject] [gi] switch to using sequences/tuples when marshalling cairo_rectangle_int_t



commit 1c537bc67107948c92b51ba6ba749747e84263e2
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon Nov 22 15:04:00 2010 -0500

    [gi] switch to using sequences/tuples when marshalling cairo_rectangle_int_t
    
    * Upstream pycairo didn't want to add a new wrapper for cairo_rectangle_int_t
    * this works around that issue by using 4 element squences instead which
      should be accepted by pycairo for any API that takes a rect

 gi/pygi-foreign-cairo.c |   85 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 64 insertions(+), 21 deletions(-)
---
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 6326397..ada59bf 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -112,7 +112,36 @@ cairo_surface_release (GIBaseInfo *base_info,
     Py_RETURN_NONE;
 }
 
-#ifdef PycairoRectangleInt_FromRectangleInt
+#define _PY_TUPLE_GET_INT(t, pos, i)    \
+{                                       \
+    PyObject *item;                     \
+    long l;                             \
+    item = PyTuple_GET_ITEM(t, pos);    \
+    if (!item)                          \
+        goto err;                       \
+    l = PYGLIB_PyLong_AsLong(item);     \
+    if (PyErr_Occurred()) {             \
+        Py_DECREF(item);                \
+        goto err;                       \
+    }                                   \
+    if (l > INT_MAX || l < INT_MIN) {   \
+        Py_DECREF(item);                \
+        PyErr_Format(PyExc_ValueError, "integer %l is out of range", l); \
+        goto err;                       \
+    }                                   \
+    i = (int)l;                         \
+    Py_DECREF(item);                    \
+}
+
+#define _PY_TUPLE_SET_INT(t, pos, i)    \
+{                                       \
+    PyObject *item;                     \
+    item = PYGLIB_PyLong_FromLong(i);   \
+    if (!item)                          \
+        goto err;                       \
+    PyTuple_SET_ITEM(t, pos, item);     \
+}
+
 PyObject *
 cairo_rectangle_int_to_arg (PyObject       *value,
                             GITypeInfo     *type_info,
@@ -120,40 +149,55 @@ cairo_rectangle_int_to_arg (PyObject       *value,
                             GIArgument      *arg)
 {
     cairo_rectangle_int_t *rect;
+    Py_ssize_t seq_len;
 
-    rect = ( (PycairoRectangleInt *) value)->rectangle_int;
-    if (!rect) {
-        PyErr_SetString (PyExc_ValueError, "RectangleInt instance wrapping a NULL pointer");
-        return NULL;
+    seq_len = PySequence_Size(value);
+    if (!PySequence_Check(value) || (seq_len != 4)) {
+        PyErr_Format(PyExc_TypeError, "expected a sequence of length 4");
+        goto err;
     }
 
-    if (transfer == GI_TRANSFER_EVERYTHING) {
-        unsigned int size = sizeof(cairo_rectangle_int_t);
-        cairo_rectangle_int_t *transfer = malloc(size);
-        if (!transfer) {
-            PyErr_NoMemory();
-            return NULL;
-        }
+    rect = g_malloc(sizeof(cairo_rectangle_int_t));
+    if (!rect)
+        return PyErr_NoMemory();
 
-        memcpy(transfer, rect, size);
-        rect = transfer;
-    }
+    _PY_TUPLE_GET_INT(value, 0, rect->x);
+    _PY_TUPLE_GET_INT(value, 1, rect->y);
+    _PY_TUPLE_GET_INT(value, 2, rect->width);
+    _PY_TUPLE_GET_INT(value, 3, rect->height);
 
     arg->v_pointer = rect;
     Py_RETURN_NONE;
+err:
+    return NULL;
 }
 
 PyObject *
 cairo_rectangle_int_from_arg (GITypeInfo *type_info, GIArgument  *arg)
 {
+    PyObject *result;
     cairo_rectangle_int_t *rect = (cairo_rectangle_int_t*) arg;
 
-    if (rect)
-      return PycairoRectangleInt_FromRectangleInt (rect);
-    else {
-      cairo_rectangle_int_t temp = {};
-      return PycairoRectangleInt_FromRectangleInt (&temp);
+    result = PyTuple_New(4);
+    if (!result)
+        return NULL;
+
+    if (rect) {
+        _PY_TUPLE_SET_INT(result, 0, rect->x);
+        _PY_TUPLE_SET_INT(result, 1, rect->y);
+        _PY_TUPLE_SET_INT(result, 2, rect->width);
+        _PY_TUPLE_SET_INT(result, 3, rect->height);
+    } else {
+        _PY_TUPLE_SET_INT(result, 0, 0);
+        _PY_TUPLE_SET_INT(result, 1, 0);
+        _PY_TUPLE_SET_INT(result, 2, 0);
+        _PY_TUPLE_SET_INT(result, 3, 0);
     }
+
+    return result;
+err:
+    Py_DECREF(result);
+    return NULL;
 }
 
 PyObject *
@@ -163,7 +207,6 @@ cairo_rectangle_int_release (GIBaseInfo *base_info,
     g_free (struct_);
     Py_RETURN_NONE;
 }
-#endif
 
 static PyMethodDef _gi_cairo_functions[] = {};
 PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo")



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]