[pypy-commit] pypy ffistruct: add support for getting/setting signed values other than long

antocuni noreply at buildbot.pypy.org
Wed Nov 9 13:51:11 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: ffistruct
Changeset: r49000:175c37225dc8
Date: 2011-11-08 18:49 +0100
http://bitbucket.org/pypy/pypy/changeset/175c37225dc8/

Log:	add support for getting/setting signed values other than long

diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -129,18 +129,15 @@
     @unwrap_spec(name=str)
     def getfield(self, space, name):
         w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(name)
-        assert w_ffitype is app_types.slong # XXX: handle all cases
-        FIELD_TYPE  = rffi.LONG
-        #
         value = libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, offset)
         return space.wrap(value)
 
     @unwrap_spec(name=str)
     def setfield(self, space, name, w_value):
         w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(name)
-        assert w_ffitype is app_types.slong # XXX: handle all cases
-        FIELD_TYPE  = rffi.LONG
-        value = space.int_w(w_value)
+        # XXX: add support for long long
+        if w_ffitype.is_signed() or w_ffitype.is_unsigned():
+            value = rffi.cast(rffi.LONG, space.uint_w(w_value))
         #
         libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, offset, value)
 
diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py
--- a/pypy/module/_ffi/test/test_struct.py
+++ b/pypy/module/_ffi/test/test_struct.py
@@ -75,7 +75,6 @@
         assert fields[0].offset == 0
         assert fields[1].offset == longsize # aligned to WORD
 
-
     def test_getfield_setfield(self):
         from _ffi import _StructDescr, Field, types
         longsize = types.slong.sizeof()
@@ -104,6 +103,40 @@
         raises(AttributeError, "struct.getfield('missing')")
         raises(AttributeError, "struct.setfield('missing', 42)")
 
+    def test_getfield_setfield(self):
+        from _ffi import _StructDescr, Field, types
+        longsize = types.slong.sizeof()
+        fields = [
+            Field('x', types.slong),
+            Field('y', types.slong),
+            ]
+        descr = _StructDescr('foo', fields)
+        struct = descr.allocate()
+        struct.setfield('x', 42)
+        struct.setfield('y', 43)
+        assert struct.getfield('x') == 42
+        assert struct.getfield('y') == 43
+        mem = self.read_raw_mem(struct.getaddr(), 'c_long', 2)
+        assert mem == [42, 43]
+
+    def test_getfield_setfield_signed_types(self):
+        import sys
+        from _ffi import _StructDescr, Field, types
+        longsize = types.slong.sizeof()
+        fields = [
+            Field('sbyte', types.sbyte),
+            Field('sint', types.sint),
+            Field('slong', types.slong),
+            ]
+        descr = _StructDescr('foo', fields)
+        struct = descr.allocate()
+        struct.setfield('sbyte', 42)
+        struct.setfield('sint', 43)
+        struct.setfield('slong', 44)
+        assert struct.getfield('sbyte') == 42
+        assert struct.getfield('sint') == 43
+        assert struct.getfield('slong') == 44
+
     def test_compute_shape(self):
         from _ffi import Structure, Field, types
         class Point(Structure):


More information about the pypy-commit mailing list