[pypy-svn] r50962 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes
fijal at codespeak.net
fijal at codespeak.net
Thu Jan 24 14:20:36 CET 2008
Author: fijal
Date: Thu Jan 24 14:20:36 2008
New Revision: 50962
Added:
pypy/dist/pypy/lib/app_test/ctypes/test_array_in_pointer.py (contents, props changed)
Modified:
pypy/dist/pypy/lib/_ctypes/array.py
pypy/dist/pypy/lib/_ctypes/pointer.py
pypy/dist/pypy/lib/_ctypes/structure.py
pypy/dist/pypy/lib/app_test/ctypes/test_memfunctions.py
Log:
A bit of special-logic and 3 more tests pass.
Modified: pypy/dist/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/array.py (original)
+++ pypy/dist/pypy/lib/_ctypes/array.py Thu Jan 24 14:20:36 2008
@@ -53,6 +53,25 @@
return self(*value)
return _CDataMeta.from_param(self, value)
+def array_get_slice_params(self, index):
+ if index.step is not None:
+ raise TypeError("3 arg slices not supported (for no reason)")
+ start = index.start or 0
+ stop = index.stop or self._length_
+ return start, stop
+
+def array_slice_setitem(self, index, value):
+ start, stop = self._get_slice_params(index)
+ for i in range(start, stop):
+ self[i] = value[i - start]
+
+def array_slice_getitem(self, index):
+ start, stop = self._get_slice_params(index)
+ l = [self[i] for i in range(start, stop)]
+ if getattr(self._type_, '_type_', None) == 'c':
+ return "".join(l)
+ return l
+
class Array(_CData):
__metaclass__ = ArrayMeta
_ffiletter = 'P'
@@ -70,24 +89,9 @@
else:
raise IndexError
- def _get_slice_params(self, index):
- if index.step is not None:
- raise TypeError("3 arg slices not supported (for no reason)")
- start = index.start or 0
- stop = index.stop or self._length_
- return start, stop
-
- def _slice_setitem(self, index, value):
- start, stop = self._get_slice_params(index)
- for i in range(start, stop):
- self[i] = value[i - start]
-
- def _slice_getitem(self, index):
- start, stop = self._get_slice_params(index)
- l = [self[i] for i in range(start, stop)]
- if getattr(self._type_, '_type_', None) == 'c':
- return "".join(l)
- return l
+ _get_slice_params = array_get_slice_params
+ _slice_getitem = array_slice_getitem
+ _slice_setitem = array_slice_setitem
def _subarray(self, index):
"""Return a _rawffi array of length 1 whose address is the same as
Modified: pypy/dist/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/pointer.py (original)
+++ pypy/dist/pypy/lib/_ctypes/pointer.py Thu Jan 24 14:20:36 2008
@@ -2,7 +2,8 @@
import _rawffi
from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
from _ctypes.basics import sizeof, byref
-from _ctypes.array import Array
+from _ctypes.array import Array, array_get_slice_params, array_slice_getitem,\
+ array_slice_setitem
DEFAULT_VALUE = object()
@@ -78,14 +79,19 @@
value = value._buffer
self._buffer[0] = value
+ _get_slice_params = array_get_slice_params
+ _slice_getitem = array_slice_getitem
+
def _subarray(self, index=0):
"""Return a _rawffi array of length 1 whose address is the same as
the index'th item to which self is pointing."""
address = self._buffer[0]
address += index * sizeof(self._type_)
- return self._type_._ffiarray.fromaddress(address, 1)
+ return self._type_.from_address(address)._buffer
def __getitem__(self, index):
+ if isinstance(index, slice):
+ return self._slice_getitem(index)
return self._type_._CData_output(self._subarray(index))
def __setitem__(self, index, value):
@@ -100,12 +106,17 @@
def _cast_addr(obj, _, tp):
- if not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
- raise TypeError("cast() argument 1 must be a pointer, not %s"
- % (type(obj),))
if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
raise TypeError("cast() argument 2 must be a pointer type, not %s"
% (tp,))
+ if isinstance(obj, Array):
+ ptr = tp.__new__(tp)
+ ptr._buffer = tp._ffiarray(1)
+ ptr._buffer[0] = obj._buffer
+ return ptr
+ if not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
+ raise TypeError("cast() argument 1 must be a pointer, not %s"
+ % (type(obj),))
result = tp()
result._buffer[0] = obj._buffer[0]
return result
Modified: pypy/dist/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/structure.py (original)
+++ pypy/dist/pypy/lib/_ctypes/structure.py Thu Jan 24 14:20:36 2008
@@ -117,7 +117,6 @@
return self._ffistruct.alignment
def _CData_output(self, resarray):
- assert isinstance(resarray, _rawffi.ArrayInstance)
res = self.__new__(self)
ffistruct = self._ffistruct.fromaddress(resarray.buffer)
res.__dict__['_buffer'] = ffistruct
Added: pypy/dist/pypy/lib/app_test/ctypes/test_array_in_pointer.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_array_in_pointer.py Thu Jan 24 14:20:36 2008
@@ -0,0 +1,63 @@
+from ctypes import *
+from binascii import hexlify
+import re
+import _rawffi
+
+def dump(obj):
+ # helper function to dump memory contents in hex, with a hyphen
+ # between the bytes.
+ # cast it to the raw buffer
+ size = sizeof(obj)
+ a = _rawffi.Array('c').fromaddress(obj._buffer.buffer, size)
+ h = hexlify([a[i] for i in range(len(a))])
+ return re.sub(r"(..)", r"\1-", h)[:-1]
+
+class Value(Structure):
+ _fields_ = [("val", c_byte)]
+
+class Container(Structure):
+ _fields_ = [("pvalues", POINTER(Value))]
+
+class TestOne:
+ def test(self):
+ # create an array of 4 values
+ val_array = (Value * 4)()
+
+ # create a container, which holds a pointer to the pvalues array.
+ c = Container()
+ c.pvalues = val_array
+
+ # memory contains 4 NUL bytes now, that's correct
+ assert "00-00-00-00" == dump(val_array)
+
+ # set the values of the array through the pointer:
+ for i in range(4):
+ c.pvalues[i].val = i + 1
+
+ values = [c.pvalues[i].val for i in range(4)]
+
+ # These are the expected results: here s the bug!
+ assert (
+ (values, dump(val_array))) == (
+ ([1, 2, 3, 4], "01-02-03-04")
+ )
+
+ def test_2(self):
+
+ val_array = (Value * 4)()
+
+ # memory contains 4 NUL bytes now, that's correct
+ assert "00-00-00-00" == dump(val_array)
+
+ ptr = cast(val_array, POINTER(Value))
+ # set the values of the array through the pointer:
+ for i in range(4):
+ ptr[i].val = i + 1
+
+ values = [ptr[i].val for i in range(4)]
+
+ # These are the expected results: here s the bug!
+ assert (
+ (values, dump(val_array))) == (
+ ([1, 2, 3, 4], "01-02-03-04")
+ )
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_memfunctions.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_memfunctions.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_memfunctions.py Thu Jan 24 14:20:36 2008
@@ -27,7 +27,6 @@
assert string_at(a, 20) == "xxxxxxxxxxxxxxxx\0\0\0\0"
def test_cast(self):
- py.test.skip("I'm not sure I understood")
a = (c_ubyte * 32)(*map(ord, "abcdef"))
assert cast(a, c_char_p).value == "abcdef"
assert cast(a, POINTER(c_byte))[:7] == (
More information about the Pypy-commit
mailing list