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

Reply via email to