[pypy-svn] r50572 - pypy/branch/applevel-ctypes2/pypy/lib/_ctypes
fijal at codespeak.net
fijal at codespeak.net
Sun Jan 13 23:26:41 CET 2008
Author: fijal
Date: Sun Jan 13 23:26:40 2008
New Revision: 50572
Modified:
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py
Log:
(arigo, fijal) ARGH.
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/array.py Sun Jan 13 23:26:40 2008
@@ -1,9 +1,9 @@
import _ffi
-from _ctypes.basics import _CData, cdata_from_address
+from _ctypes.basics import _CData, cdata_from_address, _CDataMeta
-class ArrayMeta(type):
+class ArrayMeta(_CDataMeta):
def __new__(self, name, cls, typedict):
res = type.__new__(self, name, cls, typedict)
res._ffiletter = 'P'
@@ -19,14 +19,23 @@
i += 1
return "".join(res)
def setvalue(self, val):
- for i in range(min(len(val), self._length_)):
+ # we don't want to have buffers here
+ import ctypes
+ if len(val) > self._length_:
+ raise ValueError("%s too long" % (val,))
+ for i in range(len(val)):
self[i] = val[i]
- self[len(val)] = '\x00'
+ if len(val) < self._length_:
+ self[len(val)] = '\x00'
res.value = property(getvalue, setvalue)
def getraw(self):
return "".join([self[i] for i in range(self._length_)])
- res.raw = property(getraw)
+
+ def setraw(self, buffer):
+ for i in range(len(buffer)):
+ self[i] = buffer[i]
+ res.raw = property(getraw, setraw)
else:
res._ffiarray = None
return res
@@ -65,12 +74,11 @@
return "".join([self[i] for i in range(start, stop)])
def __setitem__(self, item, value):
+ from ctypes import _SimpleCData
if isinstance(item, slice):
self._slice_setitem(item, value)
- # XXX
- from ctypes import _SimpleCData
- if isinstance(value, _SimpleCData):
- value = value.value
+ return
+ value = self._type_.from_param(value).value
item = self._fix_item(item)
if self._type_._ffiletter == 'c' and len(value) > 1:
raise TypeError("Expected strings of length 1")
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/basics.py Sun Jan 13 23:26:40 2008
@@ -1,20 +1,28 @@
import _ffi
+class _CDataMeta(type):
+ def from_param(self, value):
+ if isinstance(value, self):
+ return value
+ raise TypeError("Wrong type")
+
class _CData(object):
""" The most basic object for all ctypes types
"""
+ __metaclass__ = _CDataMeta
+
def __ctypes_from_outparam__(self):
return self
-class CArgObject(object):
- def __init__(self, letter, raw_value, _type):
- self.ffiletter = letter
- self.raw_value = raw_value
- self._type = _type
+#class CArgObject(object):
+# def __init__(self, letter, raw_value, _type):
+# self.ffiletter = letter
+# self._array = raw_value
+# self._type = _type
- def __repr__(self):
- return "<cparam '%s' %r>" % (self.ffiletter, self.raw_value)
+# def __repr__(self):
+# return "<cparam '%s' %r>" % (self.ffiletter, self._array[0])
TP_TO_FFITP = { # XXX this should die; interp_ffi should just accept them
@@ -22,7 +30,6 @@
'z': 's',
}
-
def sizeof(tp):
ffitp = tp._type_
return _ffi.sizeof(TP_TO_FFITP.get(ffitp, ffitp))
@@ -35,7 +42,7 @@
from ctypes import pointer, _SimpleCData
if not isinstance(cdata, _SimpleCData):
raise TypeError("expected CData instance")
- return pointer(cdata)._as_ffi()
+ return pointer(cdata)
def cdata_from_address(self, address):
instance = self.__new__(self)
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/function.py Sun Jan 13 23:26:40 2008
@@ -1,68 +1,59 @@
import _ffi
-from _ctypes.basics import CArgObject
-class CFuncPtrType(type):
+from _ctypes.basics import _CData, _CDataMeta
+
+class CFuncPtrType(_CDataMeta):
# XXX write down here defaults and such things
pass
-class CFuncPtr(object):
+class CFuncPtr(_CData):
__metaclass__ = CFuncPtrType
- argtypes = None
- _argtypes = None
- restype = None
- _restype = None
- def __init__(self, stuff):
- if isinstance(stuff, tuple):
- name, dll = stuff
- self.name = name
- self.dll = dll
- self._funcptr = None
+
+ _argtypes_ = None
+ _restype_ = None
+
+ def _getargtypes(self):
+ return self._argtypes_
+ def _setargtypes(self, argtypes):
+ self._argtypes_ = argtypes
+ argtypes = property(_getargtypes, _setargtypes)
+
+ def _getrestype(self):
+ return self._restype_
+ def _setrestype(self, restype):
+ self._restype_ = restype
+ restype = property(_getrestype, _setrestype)
+
+ def __init__(self, address_or_name_and_dll):
+ if isinstance(address_or_name_and_dll, tuple):
+ self.name, self.dll = address_or_name_and_dll
else:
self.name = None
- self.dll = None
def __call__(self, *args):
- import ctypes
- if self.restype is None:
- # XXX point to default instead
- self.restype = ctypes.c_int
- if self.argtypes is not None:
- if len(args) != len(self.argtypes):
- raise TypeError("%s takes %s arguments, given %s" %
- (self.name, len(self.argtypes), len(args)))
- funcptr = self._getfuncptr(args)
- argvalues = [tp.from_param(arg).raw_value for tp, arg in zip(self._argtypes, args)]
- res = funcptr(*argvalues)
- if issubclass(self.restype, ctypes._SimpleCData):
- return res
- else:
- # XXX pointers
- return self.restype(res)
+ if self.name is None:
+ raise NotImplementedError("Creation of function pointer to pure addresses is not implemented")
+ argtypes = self._argtypes_
+ if argtypes is None:
+ argtypes = self._guess_argtypes(args)
+ restype = self._restype_
+ funcptr = self._getfuncptr(argtypes, restype)
+ res = funcptr(*self._wrap_args(argtypes, args))
+ if restype is not None:
+ return restype(res).__ctypes_from_outparam__()
- def _getfuncptr(self, args):
- if self._funcptr is not None:
- if (self.argtypes is self._argtypes
- and self.restype is self._restype):
- return self._funcptr
- if self.argtypes is None:
- argtypes = self._guess_magic_args(args)
- else:
- argtypes = self.argtypes
- argtps = [argtype._ffiletter for argtype in argtypes]
- restp = self.restype._ffiletter
- self._funcptr = funcptr = self.dll._handle.ptr(self.name, argtps, restp)
- self._argtypes = argtypes
- self._restype = self.restype
- return funcptr
+ def _getfuncptr(self, argtypes, restype):
+ argletters = [arg._ffiletter for arg in argtypes]
+ return self.dll._handle.ptr(self.name, argletters, restype._ffiletter)
- def _guess_magic_args(self, args):
- import _ctypes
+ def _guess_argtypes(self, args):
+ from _ctypes import _CData
res = []
for arg in args:
- if isinstance(arg, _ctypes._CData):
- res.append(type(arg))
- elif isinstance(arg, CArgObject):
- res.append(arg._type)
- else:
- raise TypeError("Cannot convert %s" % arg)
+ assert isinstance(arg, _CData)
+ res.append(type(arg))
return res
+
+ def _wrap_args(self, argtypes, args):
+ return [argtype.from_param(arg)._array[0] for argtype, arg in
+ zip(argtypes, args)]
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/pointer.py Sun Jan 13 23:26:40 2008
@@ -1,10 +1,10 @@
import _ffi
-from _ctypes.basics import _CData, CArgObject, cdata_from_address
+from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
DEFAULT_VALUE = object()
-class PointerType(type):
+class PointerType(_CDataMeta):
def __new__(self, name, cls, typedict):
d = dict(
size = _ffi.sizeof('P'),
@@ -31,13 +31,6 @@
from_address = cdata_from_address
- def from_param(self, param):
- # XXX think deeper about that
- if isinstance(param, CArgObject):
- return param
- else:
- return self.from_address(param._array.buffer)._as_ffi()
-
class _Pointer(_CData):
__metaclass__ = PointerType
@@ -55,10 +48,6 @@
else:
self._array[0] = value._array
- def _as_ffi(self):
- # XXX performance
- return CArgObject('P', self._type_.from_address(self._array[0])._array, type(self))
-
def __getitem__(self, item):
assert item == 0
return self._type_.from_address(self._array[0]).__ctypes_from_outparam__()
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/primitive.py Sun Jan 13 23:26:40 2008
@@ -2,7 +2,7 @@
SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv"
-from _ctypes.basics import _CData, CArgObject, cdata_from_address, TP_TO_FFITP
+from _ctypes.basics import _CData, _CDataMeta, cdata_from_address, TP_TO_FFITP
from _ctypes.array import create_array_type
class NULL(object):
@@ -31,7 +31,7 @@
DEFAULT_VALUE = object()
-class SimpleType(type):
+class SimpleType(_CDataMeta):
def __new__(self, name, bases, dct):
tp = dct['_type_']
if (not isinstance(tp, str) or
@@ -52,16 +52,15 @@
return create_array_type(self, other)
def from_param(self, value):
- return self(value)._as_ffi()
+ if not isinstance(value, _CData):
+ return self(value)
+ return super(SimpleType, self).from_param(value)
class _SimpleCData(_CData):
__metaclass__ = SimpleType
_type_ = 'i'
def __init__(self, value=DEFAULT_VALUE):
- #if address is not DEFAULT_VALUE:
- # self._array = ffiarray.fromaddress(address, 1)
- #else:
self._array = self._ffiarray(1)
if value is not DEFAULT_VALUE:
self._array[0] = value
@@ -70,14 +69,15 @@
return self._array[0]
def _setvalue(self, value):
- self._array[0] = value
+ # XXX
+ if isinstance(value, _SimpleCData):
+ self._array[0] = value.value
+ else:
+ self._array[0] = value
value = property(_getvalue, _setvalue)
def __ctypes_from_outparam__(self):
return self._array[0]
- def _as_ffi(self):
- return CArgObject(self._type_, self.value, type(self))
-
def __repr__(self):
return "%s(%s)" % (type(self).__name__, self.value)
Modified: pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py
==============================================================================
--- pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py (original)
+++ pypy/branch/applevel-ctypes2/pypy/lib/_ctypes/structure.py Sun Jan 13 23:26:40 2008
@@ -1,7 +1,7 @@
-from _ctypes.basics import _CData
+from _ctypes.basics import _CData, _CDataMeta
-class StructureMeta(type):
+class StructureMeta(_CDataMeta):
def __new__(self, name, cls, typedict):
return type.__new__(self, name, cls, typedict)
More information about the Pypy-commit
mailing list