[pybank] Add field support to objects



commit 4df4fa25a9fd4700890c084c8b007feb47b5bd2d
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date:   Tue May 12 15:42:35 2009 +0200

    Add field support to objects
---
 bank/bank-info.c |  193 +++++++++++++++++++++++++++++-------------------------
 bank/btypes.py   |   30 +++++++--
 2 files changed, 128 insertions(+), 95 deletions(-)

diff --git a/bank/bank-info.c b/bank/bank-info.c
index 389ace2..e3075ac 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -713,98 +713,10 @@ _wrap_g_struct_info_new_buffer(PyGIBaseInfo *self)
     return buffer;
 }
 
-static PyObject *
-_wrap_g_struct_info_get_value(PyGIBaseInfo *self, PyObject *args)
-{
-    PyObject *pybuffer;
-    PyBufferProcs *buffer_procs;
-    void *buffer;
-    char *field_name;
-    GArgument value;
-    GIFieldInfo *field_info;
-    int i;
-    int n_fields;
-    PyObject *retval;
-
-    if (!PyArg_ParseTuple(args, "Os:TypeInfo.getValue", &pybuffer, &field_name))
-        return NULL;
-
-    buffer_procs = pybuffer->ob_type->tp_as_buffer;
-    (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
-
-    field_info = NULL;
-    n_fields = g_struct_info_get_n_fields ((GIStructInfo*) self->info);
-    for( i = 0; i < n_fields; i++ ) {
-        GIFieldInfo *temp = g_struct_info_get_field((GIStructInfo*) self->info, i);
-        if( !strcmp( g_base_info_get_name((GIBaseInfo *) temp), field_name ) ) {
-            field_info = temp;
-            break;
-        }
-    }
-
-    if( field_info == NULL ) {
-        return NULL;
-    }
-
-    if (!g_field_info_get_field (field_info, buffer, &value)) {
-        return NULL;
-    }
-
-    retval = pyg_argument_to_pyobject(&value, g_field_info_get_type (field_info));
-
-    Py_INCREF(retval);
-    return retval;
-}
-
-static PyObject *
-_wrap_g_struct_info_set_value(PyGIBaseInfo *self, PyObject *args)
-{
-    PyObject *pybuffer;
-    PyBufferProcs *buffer_procs;
-    void *buffer;
-    char *field_name;
-    GArgument arg;
-    GIFieldInfo *field_info;
-    int i;
-    int n_fields;
-    PyObject *value;
-
-    if (!PyArg_ParseTuple(args, "OsO:TypeInfo.setValue", &pybuffer, &field_name, &value))
-        return NULL;
-
-    buffer_procs = pybuffer->ob_type->tp_as_buffer;
-    (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
-
-    field_info = NULL;
-    n_fields = g_struct_info_get_n_fields ((GIStructInfo*) self->info);
-    for( i = 0; i < n_fields; i++ ) {
-        GIFieldInfo *temp = g_struct_info_get_field((GIStructInfo*) self->info, i);
-        if( !strcmp( g_base_info_get_name((GIBaseInfo *) temp), field_name ) ) {
-            field_info = temp;
-            break;
-        }
-    }
-
-    if( field_info == NULL ) {
-        return NULL;
-    }
-
-    arg = pyg_argument_from_pyobject(value, g_field_info_get_type (field_info));
-
-    if (!g_field_info_set_field (field_info, buffer, &arg)) {
-        return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
 static PyMethodDef _PyGIStructInfo_methods[] = {
     { "getFields", (PyCFunction)_wrap_g_struct_info_get_fields, METH_NOARGS },
     { "getMethods", (PyCFunction)_wrap_g_struct_info_get_methods, METH_NOARGS },
     { "newBuffer", (PyCFunction)_wrap_g_struct_info_new_buffer, METH_NOARGS },
-    { "getValue", (PyCFunction)_wrap_g_struct_info_get_value, METH_VARARGS },
-    { "setValue", (PyCFunction)_wrap_g_struct_info_set_value, METH_VARARGS },
     { NULL, NULL, 0 }
 };
 
@@ -903,10 +815,32 @@ _wrap_g_object_info_get_methods(PyGIBaseInfo *self)
     return retval;
 }
 
+static PyObject *
+_wrap_g_object_info_get_fields(PyGIBaseInfo *self)
+{
+    int i, length;
+    PyObject *retval;
+
+    g_base_info_ref(self->info);
+    length = g_object_info_get_n_fields((GIObjectInfo*)self->info);
+    retval = PyTuple_New(length);
+
+    for (i = 0; i < length; i++) {
+        GIFieldInfo *field;
+        field = g_object_info_get_field((GIObjectInfo*)self->info, i);
+        PyTuple_SetItem(retval, i, pyg_info_new(field));
+        g_base_info_unref((GIBaseInfo*)field);
+    }
+    g_base_info_unref(self->info);
+
+    return retval;
+}
+
 static PyMethodDef _PyGIObjectInfo_methods[] = {
     { "getParent", (PyCFunction)_wrap_g_object_info_get_parent, METH_NOARGS },
     { "getTypeName", (PyCFunction)_wrap_g_object_info_get_type_name, METH_NOARGS },
     { "getMethods", (PyCFunction)_wrap_g_object_info_get_methods, METH_NOARGS },
+    { "getFields", (PyCFunction)_wrap_g_object_info_get_fields, METH_NOARGS },
     { NULL, NULL, 0 }
 };
 
@@ -997,7 +931,90 @@ static PyMethodDef _PyGIPropertyInfo_methods[] = {
 /* GIFieldInfo */
 NEW_CLASS("FieldInfo", GIFieldInfo);
 
+static PyObject *
+_wrap_g_field_info_get_value(PyGIBaseInfo *self, PyObject *args)
+{
+    PyObject *obj;
+    void *buffer;
+    GArgument value;
+    GIFieldInfo *field_info;
+    PyObject *retval;
+
+    field_info = (GIFieldInfo *)self->info;
+
+    if (!PyArg_ParseTuple(args, "O:TypeInfo.getValue", &obj))
+        return NULL;
+
+    GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
+    GIInfoType container_type = g_base_info_get_type(container);
+
+    if (container_type == GI_INFO_TYPE_STRUCT || container_type == GI_INFO_TYPE_BOXED) {
+        PyObject *pybuffer = PyObject_GetAttrString(obj, "__buffer__");
+        PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+        if (buffer_procs == NULL || buffer_procs->bf_getreadbuffer == 0) {
+            PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+            return NULL;
+        }
+        (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
+    } else {
+        buffer = ((PyGObject *) obj)->obj;
+        printf("obj: %p\n", buffer);
+    }
+
+    if (!g_field_info_get_field (field_info, buffer, &value)) {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to get value for field");
+        return NULL;
+    }
+
+    retval = pyg_argument_to_pyobject (&value, g_field_info_get_type (field_info));
+
+    Py_INCREF(retval);
+    return retval;
+}
+
+static PyObject *
+_wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
+{
+    PyObject *obj;
+    void *buffer;
+    GArgument arg;
+    GIFieldInfo *field_info;
+    PyObject *value;
+
+    field_info = (GIFieldInfo *)self->info;
+
+    if (!PyArg_ParseTuple(args, "OO:TypeInfo.setValue", &obj, &value))
+        return NULL;
+
+    GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) self->info);
+    GIInfoType container_type = g_base_info_get_type(container);
+
+    if (container_type == GI_INFO_TYPE_STRUCT || container_type == GI_INFO_TYPE_BOXED) {
+        PyObject *pybuffer = PyObject_GetAttrString(obj, "__buffer__");
+        PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+        if (buffer_procs == NULL || buffer_procs->bf_getreadbuffer == 0) {
+            PyErr_SetString(PyExc_RuntimeError, "Failed to get buffer for struct");
+            return NULL;
+        }
+        (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &buffer);
+    } else {
+        buffer = ((PyGObject *) obj)->obj;
+    }
+
+    arg = pyg_argument_from_pyobject(value, g_field_info_get_type (field_info));
+
+    if (!g_field_info_set_field (field_info, buffer, &arg)) {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to set value for field");
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 static PyMethodDef _PyGIFieldInfo_methods[] = {
+    { "getValue", (PyCFunction)_wrap_g_field_info_get_value, METH_VARARGS },
+    { "setValue", (PyCFunction)_wrap_g_field_info_set_value, METH_VARARGS },
     { NULL, NULL, 0 }
 };
 
diff --git a/bank/btypes.py b/bank/btypes.py
index 6ee24f9..d889920 100644
--- a/bank/btypes.py
+++ b/bank/btypes.py
@@ -82,6 +82,9 @@ class Callable(object):
         elif tag == repo.TYPE_TAG_ERROR:
             # TODO
             pass
+        elif tag == repo.TYPE_TAG_VOID:
+            # TODO
+            pass
         else:
             raise NotImplementedError('type checking for tag %d' % tag)
 
@@ -163,6 +166,16 @@ class Method(Callable):
             self.__module__,
             self.className)
 
+class FieldDescriptor(object):
+    def __init__(self, info):
+        self._info = info
+
+    def __get__(self, obj, klass=None):
+        return self._info.getValue(obj)
+
+    def __set__(self, obj, value):
+        return self._info.setValue(obj, value)
+
 class PyBankMeta(gobject.GObjectMeta):
     def __init__(cls, name, bases, dict_):
         gobject.GObjectMeta.__init__(cls, name, bases, dict_)
@@ -170,6 +183,9 @@ class PyBankMeta(gobject.GObjectMeta):
         needs_constructor = not '__init__' in dict_
         cls._setup_methods(needs_constructor)
 
+        if hasattr(cls.__info__, 'getFields'):
+            cls._setup_fields()
+
     def _setup_methods(cls, needs_constructor):
         info = cls.__info__
         constructors = []
@@ -208,6 +224,12 @@ class PyBankMeta(gobject.GObjectMeta):
             func = Method(static_method, cls.__name__, call_type=Method.STATIC_METHOD)
             setattr(cls, static_method.getName(), staticmethod(func))
 
+    def _setup_fields(cls):
+        info = cls.__info__
+        for field in info.getFields():
+            name = field.getName().replace('-', '_')
+            setattr(cls, name, FieldDescriptor(field))
+
 _classDict = {}
 
 def getClass(info):
@@ -244,13 +266,7 @@ class BaseBlob(object):
     def __init__(self, buf=None):
         if buf is None:
             buf = self.__info__.newBuffer()
-        self.__dict__['__buffer__'] = buf
-
-    def __getattr__(self, name):
-        return self.__info__.getValue(self.__dict__['__buffer__'], name)
-
-    def __setattr__(self, name, value):
-        self.__info__.setValue(self.__dict__['__buffer__'], name, value)
+        self.__buffer__ = buf
 
     def __eq__(self, other):
         for field in self.__info__.getFields():



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