[pygobject/gsoc2009: 43/160] Add pygi_py_object_get_buffer



commit 5144e5bf6a2179905be5f882e8185a0470784d2e
Author: Simon van der Linden <svdlinden src gnome org>
Date:   Mon Jul 20 15:10:01 2009 +0200

    Add pygi_py_object_get_buffer
    
    Add pygi_py_object_get_buffer to get a pointer to an object's __buffer__
    attribute.
    Use that function in _wrap_g_field_info_(get|set)_value.

 gi/gimodule.c     |   30 ++++++++++++++++++++++++++++
 gi/pygargument.c  |   56 ++++++++++++++++++++--------------------------------
 gi/pygi-private.h |    2 +
 gi/pygiinfo.c     |   38 +++++------------------------------
 4 files changed, 60 insertions(+), 66 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index d73e70a..86e369e 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -54,6 +54,36 @@ pygi_py_type_find_by_name(const char *namespace_, const char *name)
     return py_module;
 }
 
+gpointer
+pygi_py_object_get_buffer(PyObject *object, gsize *size)
+{
+    PyBufferProcs *py_buffer_procs;
+    PyObject *py_buffer;
+    gpointer buffer;
+
+    py_buffer = PyObject_GetAttrString(object, "__buffer__");
+    if (py_buffer == NULL) {
+        return NULL;
+    }
+
+    if(!PyBuffer_Check(py_buffer)) {
+        PyErr_Format(PyExc_TypeError, "Must be buffer, not %s",
+                object->ob_type->tp_name);
+    }
+
+    /* We don't need to keep a reference. */
+    Py_DECREF(py_buffer);
+
+    py_buffer_procs = py_buffer->ob_type->tp_as_buffer;
+
+    *size = (*py_buffer_procs->bf_getreadbuffer)(py_buffer, 0, &buffer);
+    if (*size < 0) {
+        return NULL;
+    }
+
+    return buffer;
+}
+
 static PyObject *
 _wrap_set_object_has_new_constructor(PyObject *self, PyObject *args)
 {
diff --git a/gi/pygargument.c b/gi/pygargument.c
index 51f1e01..b8175d7 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -170,7 +170,6 @@ pygi_gi_type_info_check_py_object(GITypeInfo *type_info, PyObject *object)
     gint retval;
 
     GITypeTag type_tag;
-    const gchar *type_name_expected;
 
     type_tag = g_type_info_get_tag(type_info);
 
@@ -205,8 +204,10 @@ pygi_gi_type_info_check_py_object(GITypeInfo *type_info, PyObject *object)
             PyObject *lower, *upper;
 
             if (!PyNumber_Check(object)) {
-                type_name_expected = "int or long";
-                goto gi_type_info_check_py_object_check_type_error;
+                PyErr_Format(PyExc_TypeError, "Must be int or long, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
+                break;
             }
 
             pygi_gi_type_tag_get_py_bounds(type_tag, &lower, &upper);
@@ -250,8 +251,9 @@ gi_type_info_check_py_object_check_number_clean:
         }
         case GI_TYPE_TAG_UTF8:
             if (!PyString_Check(object)) {
-                type_name_expected = "string";
-                goto gi_type_info_check_py_object_check_type_error;
+                PyErr_Format(PyExc_TypeError, "Must be string, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
             }
             break;
         case GI_TYPE_TAG_ARRAY:
@@ -262,8 +264,10 @@ gi_type_info_check_py_object_check_number_clean:
             gsize i;
 
             if (!PyTuple_Check(object)) {
-                type_name_expected = "tuple";
-                goto gi_type_info_check_py_object_check_type_error;
+                PyErr_Format(PyExc_TypeError, "Must be tuple, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
+                break;
             }
 
             object_size = PyTuple_Size(object);
@@ -320,8 +324,9 @@ gi_type_info_check_py_object_check_number_clean:
                     (void) PyInt_AsLong(object);
                     if (PyErr_Occurred()) {
                         PyErr_Clear();
-                        type_name_expected = "int";
-                        goto gi_type_info_check_py_object_check_type_error;
+                        PyErr_Format(PyExc_TypeError, "Must be int, not %s",
+                                object->ob_type->tp_name);
+                        retval = 0;
                     }
                     /* XXX: What if the value doesn't correspond to any enum field? */
                     break;
@@ -337,9 +342,9 @@ gi_type_info_check_py_object_check_number_clean:
                         break;
                     } else if (g_type_is_a(type, G_TYPE_CLOSURE)) {
                         if (!PyCallable_Check(object)) {
-                            g_base_info_unref(info);
-                            type_name_expected = "callable";
-                            goto gi_type_info_check_py_object_check_type_error;
+                            PyErr_Format(PyExc_TypeError, "Must be callable, not %s",
+                                    object->ob_type->tp_name);
+                            retval = 0;
                         }
                         break;
                     }
@@ -362,14 +367,15 @@ gi_type_info_check_py_object_check_number_clean:
 
             is_instance = PyObject_IsInstance(object, (PyObject *)&PyGTypeWrapper_Type);
             if (is_instance < 0) {
-                return -1;
+                retval = -1;
+                break;
             }
 
             if (!is_instance && (!PyType_Check(object) || pyg_type_from_object(object) == 0)) {
-                type_name_expected = "GType";
-                goto gi_type_info_check_py_object_check_type_error;
+                PyErr_Format(PyExc_TypeError, "Must be gobject.GType, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
             }
-
             break;
         }
         case GI_TYPE_TAG_TIME_T:
@@ -384,24 +390,6 @@ gi_type_info_check_py_object_check_number_clean:
     }
 
     return retval;
-
-gi_type_info_check_py_object_check_type_error:
-    {
-        PyTypeObject *type;
-
-        type = (PyTypeObject *)PyObject_Type(object);
-        if (type == NULL) {
-            return -1;
-        }
-
-        g_assert(type_name_expected != NULL);
-        PyErr_Format(PyExc_TypeError, "Must be %s, not %s", 
-            type_name_expected, type->tp_name);
-
-        Py_DECREF((PyObject *)type);
-
-        return 0;
-    }
 }
 
 GArgument
diff --git a/gi/pygi-private.h b/gi/pygi-private.h
index 22bead0..af32488 100644
--- a/gi/pygi-private.h
+++ b/gi/pygi-private.h
@@ -61,4 +61,6 @@ PyObject * pygi_py_type_find_by_name(const char *namespace_,
 #define pygi_py_type_find_by_gi_info(info) \
     pygi_py_type_find_by_name(g_base_info_get_namespace(info), g_base_info_get_name(info))
 
+gpointer pygi_py_object_get_buffer(PyObject *object, gsize *size);
+
 #endif /* __PYGI_PRIVATE_H__ */
diff --git a/gi/pygiinfo.c b/gi/pygiinfo.c
index 5878d89..0decf5c 100644
--- a/gi/pygiinfo.c
+++ b/gi/pygiinfo.c
@@ -1470,24 +1470,11 @@ _wrap_g_field_info_get_value(PyGIBaseInfo *self, PyObject *args)
 
     if (container_info_type == GI_INFO_TYPE_STRUCT
             || container_info_type == GI_INFO_TYPE_BOXED) {
-        PyBufferProcs *py_buffer_procs;
-        PyObject *py_buffer;
-
-        py_buffer = PyObject_GetAttrString(object, "__buffer__");
-        if (py_buffer == NULL) {
-            goto field_info_get_value_return;
-        }
-
-        /* We don't need to keep a reference. */
-        Py_DECREF(py_buffer);
-
-        py_buffer_procs = py_buffer->ob_type->tp_as_buffer;
-        if (py_buffer_procs == NULL || py_buffer_procs->bf_getreadbuffer == NULL) {
-            PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+        gsize size;
+        buffer = pygi_py_object_get_buffer(object, &size);
+        if (buffer == NULL) {
             goto field_info_get_value_return;
         }
-
-        (*py_buffer_procs->bf_getreadbuffer)(py_buffer, 0, &buffer);
     } else {
         buffer = pygobject_get(object);
     }
@@ -1582,24 +1569,11 @@ _wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
 
     if (container_info_type == GI_INFO_TYPE_STRUCT
             || container_info_type == GI_INFO_TYPE_BOXED) {
-        PyObject *py_buffer;
-        PyBufferProcs *py_buffer_procs;
-
-        py_buffer = PyObject_GetAttrString(object, "__buffer__");
-        if (py_buffer == NULL) {
-            goto field_info_set_value_return;
-        }
-
-        /* We don't need to keep a reference. */
-        Py_DECREF(py_buffer);
-
-        py_buffer_procs = py_buffer->ob_type->tp_as_buffer;
-        if (py_buffer_procs == NULL || py_buffer_procs->bf_getreadbuffer == 0) {
-            PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+        gsize size;
+        buffer = pygi_py_object_get_buffer(object, &size);
+        if (buffer == NULL) {
             goto field_info_set_value_return;
         }
-
-        (*py_buffer_procs->bf_getreadbuffer)(py_buffer, 0, &buffer);
     } else {
         buffer = pygobject_get(object);
     }



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