Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1840:923f1d3495c9
Date: 2015-04-26 11:23 +0200
http://bitbucket.org/cffi/cffi/changeset/923f1d3495c9/
Log: ffi.from_buffer()
diff --git a/_cffi1/ffi_obj.c b/_cffi1/ffi_obj.c
--- a/_cffi1/ffi_obj.c
+++ b/_cffi1/ffi_obj.c
@@ -533,6 +533,19 @@
return x;
}
+PyDoc_STRVAR(ffi_from_buffer_doc,
+"Return a <cdata 'char[]'> that points to the data of the given Python\n"
+"object, which must support the buffer interface. Note that this is\n"
+"not meant to be used on the built-in types str, unicode, or bytearray\n"
+"(you can build 'char[]' arrays explicitly) but only on objects\n"
+"containing large quantities of raw data in some other format, like\n"
+"'array.array' or numpy arrays.");
+
+static PyObject *ffi_from_buffer(PyObject *self, PyObject *arg)
+{
+ return direct_from_buffer(g_ct_chararray, arg);
+}
+
#if 0
static PyObject *ffi_gc(ZefFFIObject *self, PyObject *args)
{
@@ -716,9 +729,7 @@
{"callback", (PyCFunction)ffi_callback, METH_VARARGS |
METH_KEYWORDS,ffi_callback_doc},
{"cast", (PyCFunction)ffi_cast, METH_VARARGS, ffi_cast_doc},
-#if 0
{"from_buffer",(PyCFunction)ffi_from_buffer,METH_O,
ffi_from_buffer_doc},
-#endif
{"from_handle",(PyCFunction)ffi_from_handle,METH_O,
ffi_from_handle_doc},
#if 0
{"gc", (PyCFunction)ffi_gc, METH_VARARGS},
diff --git a/_cffi1/realize_c_type.c b/_cffi1/realize_c_type.c
--- a/_cffi1/realize_c_type.c
+++ b/_cffi1/realize_c_type.c
@@ -8,7 +8,7 @@
static PyObject *all_primitives[_CFFI__NUM_PRIM];
static PyObject *global_types_dict;
-static CTypeDescrObject *g_ct_voidp;
+static CTypeDescrObject *g_ct_voidp, *g_ct_chararray;
static PyObject *build_primitive_type(int num); /* forward */
@@ -16,33 +16,49 @@
(all_primitives[num] != NULL ? all_primitives[num] \
: build_primitive_type(num))
+static int _add_to_global_types_dict(PyObject *ct)
+{
+ if (ct == NULL)
+ return -1;
+ return PyDict_SetItemString(global_types_dict,
+ ((CTypeDescrObject *)ct)->ct_name, ct);
+}
+
static int init_global_types_dict(PyObject *ffi_type_dict)
{
int err;
- PyObject *ct, *ct2, *pnull;
+ PyObject *ct_void, *ct_char, *ct2, *pnull;
+ /* XXX some leaks in case these functions fail, but well,
+ MemoryErrors during importing an extension module are kind
+ of bad anyway */
global_types_dict = PyDict_New();
if (global_types_dict == NULL)
return -1;
- ct = get_primitive_type(_CFFI_PRIM_VOID); // 'void'
- if (ct == NULL)
+ ct_void = get_primitive_type(_CFFI_PRIM_VOID); // 'void'
+ if (_add_to_global_types_dict(ct_void) < 0)
return -1;
- if (PyDict_SetItemString(global_types_dict,
- ((CTypeDescrObject *)ct)->ct_name, ct) < 0) {
+
+ ct2 = new_pointer_type((CTypeDescrObject *)ct_void); // 'void *'
+ if (_add_to_global_types_dict(ct2) < 0)
return -1;
- }
- ct2 = new_pointer_type((CTypeDescrObject *)ct); // 'void *'
- if (ct2 == NULL)
- return -1;
- if (PyDict_SetItemString(global_types_dict,
- ((CTypeDescrObject *)ct2)->ct_name, ct2) < 0) {
- Py_DECREF(ct2);
- return -1;
- }
g_ct_voidp = (CTypeDescrObject *)ct2;
- pnull = new_simple_cdata(NULL, (CTypeDescrObject *)ct2);
+ ct_char = get_primitive_type(_CFFI_PRIM_CHAR); // 'char'
+ if (_add_to_global_types_dict(ct_char) < 0)
+ return -1;
+
+ ct2 = new_pointer_type((CTypeDescrObject *)ct_char); // 'char *'
+ if (_add_to_global_types_dict(ct2) < 0)
+ return -1;
+
+ ct2 = new_array_type((CTypeDescrObject *)ct2, -1); // 'char[]'
+ if (_add_to_global_types_dict(ct2) < 0)
+ return -1;
+ g_ct_chararray = (CTypeDescrObject *)ct2;
+
+ pnull = new_simple_cdata(NULL, g_ct_voidp);
if (pnull == NULL)
return -1;
err = PyDict_SetItemString(ffi_type_dict, "NULL", pnull);
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -5359,21 +5359,11 @@
return 0;
}
-static PyObject *b_from_buffer(PyObject *self, PyObject *args)
-{
- CTypeDescrObject *ct;
+static PyObject *direct_from_buffer(CTypeDescrObject *ct, PyObject *x)
+{
CDataObject *cd;
- PyObject *x;
Py_buffer *view;
- if (!PyArg_ParseTuple(args, "O!O", &CTypeDescr_Type, &ct, &x))
- return NULL;
-
- if (!(ct->ct_flags & CT_IS_UNSIZED_CHAR_A)) {
- PyErr_Format(PyExc_TypeError, "needs 'char[]', got '%s'", ct->ct_name);
- return NULL;
- }
-
if (invalid_input_buffer_type(x)) {
PyErr_SetString(PyExc_TypeError,
"from_buffer() cannot return the address of the "
@@ -5407,6 +5397,21 @@
return NULL;
}
+static PyObject *b_from_buffer(PyObject *self, PyObject *args)
+{
+ CTypeDescrObject *ct;
+ PyObject *x;
+
+ if (!PyArg_ParseTuple(args, "O!O", &CTypeDescr_Type, &ct, &x))
+ return NULL;
+
+ if (!(ct->ct_flags & CT_IS_UNSIZED_CHAR_A)) {
+ PyErr_Format(PyExc_TypeError, "needs 'char[]', got '%s'", ct->ct_name);
+ return NULL;
+ }
+ return direct_from_buffer(ct, x);
+}
+
static PyObject *b__get_types(PyObject *self, PyObject *noarg)
{
return PyTuple_Pack(2, (PyObject *)&CData_Type,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit