Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r183:0290e34a02b3
Date: 2014-12-05 21:45 +0100
http://bitbucket.org/cffi/creflect/changeset/0290e34a02b3/

Log:    cdata iteration (copied from _cffi_backend)

diff --git a/zeffir/cdata.c b/zeffir/cdata.c
--- a/zeffir/cdata.c
+++ b/zeffir/cdata.c
@@ -1559,6 +1559,7 @@
     return PyObject_GenericSetAttr((PyObject *)cd, attr, value);
 }
 
+static PyObject *cdata_iter(CDataObject *);
 
 static PyNumberMethods CData_as_number = {
     (binaryfunc)cdata_add,      /*nb_add*/
@@ -1626,7 +1627,7 @@
     0,                                          /* tp_clear */
     cdata_richcompare,                          /* tp_richcompare */
     offsetof(CDataObject, c_weakreflist),       /* tp_weaklistoffset */
-    0,//(getiterfunc)cdata_iter,                    /* tp_iter */
+    (getiterfunc)cdata_iter,                    /* tp_iter */
     0,                                          /* tp_iternext */
 };
 
diff --git a/zeffir/citer.c b/zeffir/citer.c
new file mode 100644
--- /dev/null
+++ b/zeffir/citer.c
@@ -0,0 +1,79 @@
+
+typedef struct {
+    PyObject_HEAD
+    char *di_next, *di_stop;
+    CDataObject *di_object;
+    CTypeDescrObject *di_itemtype;
+} CDataIterObject;
+
+static PyObject *
+cdataiter_next(CDataIterObject *it)
+{
+    char *result = it->di_next;
+    if (result != it->di_stop) {
+        it->di_next = result + it->di_itemtype->ct_size;
+        return convert_to_object(result, it->di_itemtype);
+    }
+    return NULL;
+}
+
+static void
+cdataiter_dealloc(CDataIterObject *it)
+{
+    Py_DECREF(it->di_object);
+    PyObject_Del(it);
+}
+
+static PyTypeObject CDataIter_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_cffi_backend.CDataIter",              /* tp_name */
+    sizeof(CDataIterObject),                /* tp_basicsize */
+    0,                                      /* tp_itemsize */
+    /* methods */
+    (destructor)cdataiter_dealloc,          /* tp_dealloc */
+    0,                                      /* tp_print */
+    0,                                      /* tp_getattr */
+    0,                                      /* tp_setattr */
+    0,                                      /* tp_compare */
+    0,                                      /* tp_repr */
+    0,                                      /* tp_as_number */
+    0,                                      /* tp_as_sequence */
+    0,                                      /* tp_as_mapping */
+    0,                                      /* tp_hash */
+    0,                                      /* tp_call */
+    0,                                      /* tp_str */
+    PyObject_GenericGetAttr,                /* tp_getattro */
+    0,                                      /* tp_setattro */
+    0,                                      /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
+    0,                                      /* tp_doc */
+    0,                                      /* tp_traverse */
+    0,                                      /* tp_clear */
+    0,                                      /* tp_richcompare */
+    0,                                      /* tp_weaklistoffset */
+    PyObject_SelfIter,                      /* tp_iter */
+    (iternextfunc)cdataiter_next,           /* tp_iternext */
+};
+
+static PyObject *
+cdata_iter(CDataObject *cd)
+{
+    CDataIterObject *it;
+
+    if (!(cd->c_type->ct_flags & CT_ARRAY)) {
+        PyErr_Format(PyExc_TypeError, "cdata '%s' does not support iteration",
+                     cd->c_type->ct_name);
+        return NULL;
+    }
+
+    it = PyObject_New(CDataIterObject, &CDataIter_Type);
+    if (it == NULL)
+        return NULL;
+
+    Py_INCREF(cd);
+    it->di_object = cd;
+    it->di_itemtype = cd->c_type->ct_itemdescr;
+    it->di_next = cd->c_data;
+    it->di_stop = cd->c_data + get_array_length(cd) * it->di_itemtype->ct_size;
+    return (PyObject *)it;
+}
diff --git a/zeffir/test/test_cdata.py b/zeffir/test/test_cdata.py
--- a/zeffir/test/test_cdata.py
+++ b/zeffir/test/test_cdata.py
@@ -38,3 +38,9 @@
     assert long(ffi.cast("short", 40000)) == 40000 - 65536
     x = float(ffi.cast("float", 1.222))
     assert 1E-15 < abs(x - 1.222) < 1E-8    # must get rounding errors
+
+def test_cdata_iter():
+    ffi = support.new_ffi()
+    p = ffi.new("int[]", [10, 20, 30])
+    it = iter(p)
+    assert list(it) == [10, 20, 30]
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -13,6 +13,7 @@
 #include "zeffir.h"
 #include "ctype.c"
 #include "cdata.c"
+#include "citer.c"
 #include "cglob.c"
 #include "lib_obj.c"
 #include "cfunc.c"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to