Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r67552:41853fcb0f1b
Date: 2013-10-24 10:11 +0200
http://bitbucket.org/pypy/pypy/changeset/41853fcb0f1b/

Log:    Unpacking lists of smaller integer types

diff --git a/pypy/module/_cffi_backend/ctypeprim.py 
b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -203,13 +203,17 @@
         w_cdata.write_raw_signed_data(value)
 
     def unpack_list_of_int_items(self, w_cdata):
-        if self.size == rffi.sizeof(rffi.LONG): # XXX
+        if self.size == rffi.sizeof(rffi.LONG):
             from rpython.rlib.rarray import populate_list_from_raw_array
             res = []
             buf = rffi.cast(rffi.LONGP, w_cdata._cdata)
             length = w_cdata.get_array_length()
             populate_list_from_raw_array(res, buf, length)
             return res
+        elif self.value_fits_long:
+            res = [0] * w_cdata.get_array_length()
+            misc.unpack_list_from_raw_array(res, w_cdata._cdata, self.size)
+            return res
         return None
 
     def pack_list_of_items(self, cdata, w_ob):
@@ -284,6 +288,13 @@
     def write_raw_integer_data(self, w_cdata, value):
         w_cdata.write_raw_unsigned_data(value)
 
+    def unpack_list_of_int_items(self, w_cdata):
+        if self.value_fits_long:
+            res = [0] * w_cdata.get_array_length()
+            misc.unpack_list_from_raw_array(res, w_cdata._cdata, self.size)
+            return res
+        return None
+
     def pack_list_of_items(self, cdata, w_ob):
         int_list = self.space.listview_int(w_ob)
         if int_list is not None:
diff --git a/pypy/module/_cffi_backend/misc.py 
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -336,3 +336,12 @@
     for i in range(len(float_list)):
         x = float_list[i]
         target[i] = rffi.cast(TP, x)
+
+def unpack_list_from_raw_array(int_list, source, size):
+    for TP, TPP in _prim_signed_types:
+        if size == rffi.sizeof(TP):
+            ptr = rffi.cast(TPP, source)
+            for i in range(len(int_list)):
+                int_list[i] = rffi.cast(lltype.Signed, ptr[i])
+            return
+    raise NotImplementedError("bad integer size")
diff --git a/pypy/module/_cffi_backend/test/test_fastpath.py 
b/pypy/module/_cffi_backend/test/test_fastpath.py
--- a/pypy/module/_cffi_backend/test/test_fastpath.py
+++ b/pypy/module/_cffi_backend/test/test_fastpath.py
@@ -138,12 +138,20 @@
         self._original = original
         rarray.populate_list_from_raw_array = populate_list_from_raw_array
         #
+        original2 = misc.unpack_list_from_raw_array
+        def unpack_list_from_raw_array(*args):
+            self.count += 1
+            return original2(*args)
+        self._original2 = original2
+        misc.unpack_list_from_raw_array = unpack_list_from_raw_array
+        #
         self.w_runappdirect = self.space.wrap(self.runappdirect)
 
 
     def teardown_method(self, meth):
         from rpython.rlib import rarray
         rarray.populate_list_from_raw_array = self._original
+        misc.unpack_list_from_raw_array = self._original2
 
     def test_list_int(self):
         import _cffi_backend
@@ -190,3 +198,31 @@
         assert lst == [1.1, 2.2, 3.3]
         if not self.runappdirect:
             assert self.get_count() == 1
+
+    def test_list_short(self):
+        import _cffi_backend
+        SHORT = _cffi_backend.new_primitive_type('short')
+        P_SHORT = _cffi_backend.new_pointer_type(SHORT)
+        SHORT_ARRAY = _cffi_backend.new_array_type(P_SHORT, 3)
+        buf = _cffi_backend.newp(SHORT_ARRAY)
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 3
+        lst = list(buf)
+        assert lst == [1, 2, 3]
+        if not self.runappdirect:
+            assert self.get_count() == 1
+
+    def test_list_ushort(self):
+        import _cffi_backend
+        USHORT = _cffi_backend.new_primitive_type('unsigned short')
+        P_USHORT = _cffi_backend.new_pointer_type(USHORT)
+        USHORT_ARRAY = _cffi_backend.new_array_type(P_USHORT, 3)
+        buf = _cffi_backend.newp(USHORT_ARRAY)
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 3
+        lst = list(buf)
+        assert lst == [1, 2, 3]
+        if not self.runappdirect:
+            assert self.get_count() == 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to