Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r77246:2ce86180028c
Date: 2015-05-09 12:46 +0200
http://bitbucket.org/pypy/pypy/changeset/2ce86180028c/
Log: ffi.from_buffer()
diff --git a/pypy/module/_cffi_backend/ffi_obj.py
b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -7,7 +7,8 @@
from pypy.module._cffi_backend import parse_c_type, realize_c_type
from pypy.module._cffi_backend import newtype, cerrno, ccallback, ctypearray
-from pypy.module._cffi_backend import ctypestruct, ctypeptr, handle, cbuffer
+from pypy.module._cffi_backend import ctypestruct, ctypeptr, handle
+from pypy.module._cffi_backend import cbuffer, func
from pypy.module._cffi_backend.ctypeobj import W_CType
from pypy.module._cffi_backend.cdataobj import W_CData
@@ -219,6 +220,19 @@
return w_ctype.cast(w_ob)
+ def descr_from_buffer(self, w_python_buffer):
+ """\
+Return a <cdata 'char[]'> that points to the data of the given Python
+object, which must support the buffer interface. Note that this is
+not meant to be used on the built-in types str, unicode, or bytearray
+(you can build 'char[]' arrays explicitly) but only on objects
+containing large quantities of raw data in some other format, like
+'array.array' or numpy arrays."""
+ #
+ w_ctchara = newtype._new_chara_type(self.space)
+ return func.from_buffer(self.space, w_ctchara, w_python_buffer)
+
+
@unwrap_spec(w_arg=W_CData)
def descr_from_handle(self, w_arg):
"""\
@@ -399,7 +413,7 @@
buffer = interp2app(W_FFIObject.descr_buffer),
callback = interp2app(W_FFIObject.descr_callback),
cast = interp2app(W_FFIObject.descr_cast),
- #from_buffer = interp2app(W_FFIObject.descr_from_buffer),
+ from_buffer = interp2app(W_FFIObject.descr_from_buffer),
from_handle = interp2app(W_FFIObject.descr_from_handle),
#gc = interp2app(W_FFIObject.descr_gc),
getctype = interp2app(W_FFIObject.descr_getctype),
diff --git a/pypy/module/_cffi_backend/newtype.py
b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -25,6 +25,7 @@
def __init__(self, space):
self.ctvoid = None # There can be only one
self.ctvoidp = None # Cache for self.pointers[self.ctvoid]
+ self.ctchara = None # Cache for self.arrays[charp, -1]
self.primitives = {} # Keys: name
self.pointers = {} # Keys: base_ctype
self.arrays = {} # Keys: (ptr_ctype, length_or_-1)
@@ -46,7 +47,9 @@
def _clean_cache(space):
"NOT_RPYTHON"
+ from pypy.module._cffi_backend.realize_c_type import RealizeCache
space.fromcache(UniqueCache).__init__(space)
+ space.fromcache(RealizeCache).__init__(space)
# ____________________________________________________________
@@ -548,6 +551,16 @@
unique_cache.ctvoidp = new_pointer_type(space, new_void_type(space))
return unique_cache.ctvoidp
[email protected]
+def _new_chara_type(space):
+ unique_cache = space.fromcache(UniqueCache)
+ if unique_cache.ctchara is None:
+ ctchar = new_primitive_type(space, "char")
+ ctcharp = new_pointer_type(space, ctchar)
+ ctchara = _new_array_type(space, ctcharp, length=-1)
+ unique_cache.ctchara = ctchara
+ return unique_cache.ctchara
+
# ____________________________________________________________
@unwrap_spec(name=str, w_basectype=ctypeobj.W_CType)
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py
b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -1,7 +1,7 @@
from pypy.module._cffi_backend.newtype import _clean_cache
class AppTestFFIObj:
- spaceconfig = dict(usemodules=('_cffi_backend', ))
+ spaceconfig = dict(usemodules=('_cffi_backend', 'array'))
def teardown_method(self, meth):
_clean_cache(self.space)
@@ -187,3 +187,13 @@
ffi = _cffi1_backend.FFI()
a = ffi.new("signed char[]", [5, 6, 7])
assert ffi.buffer(a)[:] == '\x05\x06\x07'
+
+ def test_ffi_from_buffer(self):
+ import _cffi_backend as _cffi1_backend
+ import array
+ ffi = _cffi1_backend.FFI()
+ a = array.array('H', [10000, 20000, 30000])
+ c = ffi.from_buffer(a)
+ assert ffi.typeof(c) is ffi.typeof("char[]")
+ ffi.cast("unsigned short *", c)[1] += 500
+ assert list(a) == [10000, 20500, 30000]
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit