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