[pypy-commit] pypy py3.5: fix ctypes from_buffer() and from_buffer_copy(), only partially tested

arigo pypy.commits at gmail.com
Wed Dec 7 10:44:39 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r88951:c46dd5995acc
Date: 2016-12-07 16:41 +0100
http://bitbucket.org/pypy/pypy/changeset/c46dd5995acc/

Log:	fix ctypes from_buffer() and from_buffer_copy(), only partially
	tested

diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -85,29 +85,29 @@
 
     def from_buffer(self, obj, offset=0):
         size = self._sizeofinstances()
-        buf = buffer(obj, offset, size)
-        if len(buf) < size:
+        buf = memoryview(obj)
+        if buf.nbytes < offset + size:
             raise ValueError(
                 "Buffer size too small (%d instead of at least %d bytes)"
-                % (len(buf) + offset, size + offset))
-        raw_addr = buf._pypy_raw_address()
+                % (buf.nbytes, offset + size))
+        raw_addr = buf._pypy_raw_address() + offset
         result = self.from_address(raw_addr)
         result._ensure_objects()['ffffffff'] = obj
         return result
 
     def from_buffer_copy(self, obj, offset=0):
         size = self._sizeofinstances()
-        buf = buffer(obj, offset, size)
-        if len(buf) < size:
+        buf = memoryview(obj)
+        if buf.nbytes < offset + size:
             raise ValueError(
                 "Buffer size too small (%d instead of at least %d bytes)"
-                % (len(buf) + offset, size + offset))
+                % (buf.nbytes, offset + size))
         result = self()
         dest = result._buffer.buffer
         try:
-            raw_addr = buf._pypy_raw_address()
+            raw_addr = buf._pypy_raw_address() + offset
         except ValueError:
-            _rawffi.rawstring2charp(dest, buf)
+            _rawffi.rawstring2charp(dest, buf, offset, size)
         else:
             from ctypes import memmove
             memmove(dest, raw_addr, size)
diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -606,12 +606,14 @@
     s = rffi.wcharpsize2unicode(rffi.cast(rffi.CWCHARP, address), maxlength)
     return space.wrap(s)
 
- at unwrap_spec(address=r_uint, newcontent='bufferstr')
-def rawstring2charp(space, address, newcontent):
+ at unwrap_spec(address=r_uint, newcontent='bufferstr', offset=int, size=int)
+def rawstring2charp(space, address, newcontent, offset=0, size=-1):
     from rpython.rtyper.annlowlevel import llstr
     from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw
     array = rffi.cast(rffi.CCHARP, address)
-    copy_string_to_raw(llstr(newcontent), array, 0, len(newcontent))
+    if size < 0:
+        size = len(newcontent) - offset
+    copy_string_to_raw(llstr(newcontent), array, offset, size)
 
 if _MS_WINDOWS:
     @unwrap_spec(code=int)
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -365,6 +365,10 @@
         assert b''.join([a[i] for i in range(10)]) == b"foobarxxxx"
         _rawffi.rawstring2charp(a.buffer, memoryview(b"baz"))
         assert b''.join([a[i] for i in range(10)]) == b"bazbarxxxx"
+        _rawffi.rawstring2charp(a.buffer, memoryview(b"ABCDEF"), 2)
+        assert b''.join([a[i] for i in range(10)]) == b"CDEFarxxxx"
+        _rawffi.rawstring2charp(a.buffer, memoryview(b"ZYXWVU"), 2, 3)
+        assert b''.join([a[i] for i in range(10)]) == b"XWVFarxxxx"
         a.free()
 
     def test_raw_callable(self):


More information about the pypy-commit mailing list