Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r75552:d03ab3fafd19
Date: 2015-01-27 20:01 +0100
http://bitbucket.org/pypy/pypy/changeset/d03ab3fafd19/

Log:    from_buffer_copy().

diff --git a/lib-python/2.7/ctypes/test/test_frombuffer.py 
b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -2,7 +2,6 @@
 import array
 import gc
 import unittest
-from ctypes.test import xfail
 
 class X(Structure):
     _fields_ = [("c_int", c_int)]
@@ -44,7 +43,6 @@
         self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, 
sizeof(c_int)))
         self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * 
sizeof(c_int)))
 
-    @xfail
     def test_from_buffer_copy(self):
         a = array.array("i", range(16))
         x = (c_int * 16).from_buffer_copy(a)
@@ -69,7 +67,6 @@
         x = (c_char * 16).from_buffer_copy("a" * 16)
         self.assertEqual(x[:], "a" * 16)
 
-    @xfail
     def test_fom_buffer_copy_with_offset(self):
         a = array.array("i", range(16))
         x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
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
@@ -84,17 +84,36 @@
         return self.from_address(dll._handle.getaddressindll(name))
 
     def from_buffer(self, obj, offset=0):
-        # XXX missing size checks
-        buf = buffer(obj, offset)
-        if len(buf) < self._sizeofinstances():
+        size = self._sizeofinstances()
+        buf = buffer(obj, offset, size)
+        if len(buf) < size:
             raise ValueError(
                 "Buffer size too small (%d instead of at least %d bytes)"
-                % (len(buffer(obj)), self._sizeofinstances() + offset))
+                % (len(buf) + offset, size + offset))
         raw_addr = buf._pypy_raw_address()
         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:
+            raise ValueError(
+                "Buffer size too small (%d instead of at least %d bytes)"
+                % (len(buf) + offset, size + offset))
+        result = self()
+        dest = result._buffer.buffer
+        try:
+            raw_addr = buf._pypy_raw_address()
+        except ValueError:
+            _rawffi.rawstring2charp(dest, buf)
+        else:
+            from ctypes import memmove
+            memmove(dest, raw_addr, size)
+        return result
+
+
 class CArgObject(object):
     """ simple wrapper around buffer, just for the case of freeing
     it afterwards
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to