[pypy-commit] pypy ffi-backend: wchar_t: in-progress
arigo
noreply at buildbot.pypy.org
Thu Jul 26 21:57:23 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56482:41e915635f62
Date: 2012-07-26 21:34 +0200
http://bitbucket.org/pypy/pypy/changeset/41e915635f62/
Log: wchar_t: in-progress
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -74,6 +74,9 @@
def str(self):
return self.ctype.str(self)
+ def unicode(self):
+ return self.ctype.unicode(self)
+
def _make_comparison(name):
op = getattr(operator, name)
requires_ordering = name not in ('eq', 'ne')
@@ -316,7 +319,7 @@
__float__ = interp2app(W_CData.float),
__len__ = interp2app(W_CData.len),
__str__ = interp2app(W_CData.str),
- #XXX WCHAR __unicode__ =
+ __unicode__ = interp2app(W_CData.unicode),
__lt__ = interp2app(W_CData.lt),
__le__ = interp2app(W_CData.le),
__eq__ = interp2app(W_CData.eq),
diff --git a/pypy/module/_cffi_backend/ctypearray.py b/pypy/module/_cffi_backend/ctypearray.py
--- a/pypy/module/_cffi_backend/ctypearray.py
+++ b/pypy/module/_cffi_backend/ctypearray.py
@@ -12,6 +12,7 @@
from pypy.module._cffi_backend.ctypeobj import W_CType
from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar
+from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar
from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray
from pypy.module._cffi_backend import cdataobj
@@ -31,6 +32,14 @@
return self.space.wrap(s)
return W_CTypePtrOrArray.str(self, cdataobj)
+ def unicode(self, cdataobj):
+ if isinstance(self.ctitem, W_CTypePrimitiveUniChar):
+ XXX
+ s = rffi.charp2strn(cdataobj._cdata, cdataobj.get_array_length())
+ keepalive_until_here(cdataobj)
+ return self.space.wrap(s)
+ return W_CTypePtrOrArray.unicode(self, cdataobj)
+
def _alignof(self):
return self.ctitem.alignof()
@@ -42,7 +51,7 @@
if (space.isinstance_w(w_init, space.w_list) or
space.isinstance_w(w_init, space.w_tuple)):
length = space.int_w(space.len(w_init))
- elif space.isinstance_w(w_init, space.w_str):
+ elif space.isinstance_w(w_init, space.w_basestring):
# from a string, we add the null terminator
length = space.int_w(space.len(w_init)) + 1
else:
@@ -109,7 +118,24 @@
cdata[i] = s[i]
if n != self.length:
cdata[n] = '\x00'
- #XXX WCHAR
+ elif isinstance(self.ctitem, W_CTypePrimitiveUniChar):
+ try:
+ s = space.unicode_w(w_ob)
+ except OperationError, e:
+ if not e.match(space, space.w_TypeError):
+ raise
+ raise self._convert_error("unicode or list or tuple", w_ob)
+ n = len(s)
+ if self.length >= 0 and n > self.length:
+ raise operationerrfmt(space.w_IndexError,
+ "initializer unicode string is too long for '%s'"
+ " (got %d characters)",
+ self.name, n)
+ unichardata = rffi.cast(rffi.CWCHARP, cdata)
+ for i in range(n):
+ unichardata[i] = s[i]
+ if n != self.length:
+ unichardata[n] = u'\x00'
else:
raise self._convert_error("list or tuple", w_ob)
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -296,7 +296,7 @@
elif size == 4: return _settype(ctype, clibffi.ffi_type_sint32)
elif size == 8: return _settype(ctype, clibffi.ffi_type_sint64)
- elif (isinstance(ctype, ctypeprim.W_CTypePrimitiveChar) or
+ elif (isinstance(ctype, ctypeprim.W_CTypePrimitiveCharOrWChar) or
isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned)):
if size == 1: return _settype(ctype, clibffi.ffi_type_uint8)
elif size == 2: return _settype(ctype, clibffi.ffi_type_uint16)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -13,6 +13,7 @@
#_immutable_ = True XXX newtype.complete_struct_or_union()?
cast_anything = False
is_char_ptr_or_array = False
+ is_unichar_ptr_or_array = False
def __init__(self, space, size, name, name_position):
self.space = space
@@ -85,6 +86,9 @@
def str(self, cdataobj):
return cdataobj.repr()
+ def unicode(self, cdataobj):
+ XXX
+
def add(self, cdata, i):
space = self.space
raise operationerrfmt(space.w_TypeError,
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
@@ -58,9 +58,12 @@
"integer %s does not fit '%s'", s, self.name)
-class W_CTypePrimitiveChar(W_CTypePrimitive):
+class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
+ pass
+
+
+class W_CTypePrimitiveChar(W_CTypePrimitiveCharOrUniChar):
cast_anything = True
- #XXX WCHAR class PrimitiveUniChar
def int(self, cdata):
return self.space.wrap(ord(cdata[0]))
@@ -90,6 +93,38 @@
cdata[0] = value
+class W_CTypePrimitiveUniChar(W_CTypePrimitiveCharOrUniChar):
+
+ def int(self, cdata):
+ XXX
+
+ def convert_to_object(self, cdata):
+ unichardata = rffi.cast(rffi.CWCHARP, cdata)
+ s = rffi.wcharpsize2unicode(unichardata, 1)
+ return self.space.wrap(s)
+
+ def unicode(self, cdataobj):
+ w_res = self.convert_to_object(cdataobj._cdata)
+ keepalive_until_here(cdataobj)
+ return w_res
+
+ def _convert_to_unichar(self, w_ob):
+ space = self.space
+ if space.isinstance_w(w_ob, space.w_unicode):
+ s = space.unicode_w(w_ob)
+ if len(s) == 1:
+ return s[0]
+ ob = space.interpclass_w(w_ob)
+ if (isinstance(ob, cdataobj.W_CData) and
+ isinstance(ob.ctype, W_CTypePrimitiveUniChar)):
+ return rffi.cast(rffi.CWCHARP, ob._cdata)[0]
+ raise self._convert_error("unicode string of length 1", w_ob)
+
+ def convert_from_object(self, cdata, w_ob):
+ value = self._convert_to_unichar(w_ob)
+ rffi.cast(rffi.CWCHARP, cdata)[0] = value
+
+
class W_CTypePrimitiveSigned(W_CTypePrimitive):
def __init__(self, *args):
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -15,6 +15,7 @@
def __init__(self, space, size, extra, extra_position, ctitem,
could_cast_anything=True):
from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveChar
+ from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitiveUniChar
from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion
name, name_position = ctitem.insert_name(extra, extra_position)
W_CType.__init__(self, space, size, name, name_position)
@@ -25,6 +26,7 @@
self.ctitem = ctitem
self.can_cast_anything = could_cast_anything and ctitem.cast_anything
self.is_char_ptr_or_array = isinstance(ctitem, W_CTypePrimitiveChar)
+ self.is_unichar_ptr_or_array=isinstance(ctitem,W_CTypePrimitiveUniChar)
self.is_struct_ptr = isinstance(ctitem, W_CTypeStructOrUnion)
def cast(self, w_ob):
@@ -98,6 +100,9 @@
return self.space.wrap(s)
return W_CTypePtrOrArray.str(self, cdataobj)
+ def unicode(self, cdataobj):
+ XXX
+
def newp(self, w_init):
from pypy.module._cffi_backend import ctypeprim
space = self.space
@@ -116,7 +121,7 @@
cdatastruct._cdata,
self, cdatastruct)
else:
- if self.is_char_ptr_or_array:
+ if self.is_char_ptr_or_array or self.is_unichar_ptr_or_array:
datasize *= 2 # forcefully add a null character
cdata = cdataobj.W_CDataNewOwning(space, datasize, self)
#
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -183,7 +183,7 @@
#
if isinstance(ctype, ctypeprim.W_CTypePrimitiveUnsigned):
value_fits_long = ctype.value_fits_long
- elif isinstance(ctype, ctypeprim.W_CTypePrimitiveChar):
+ elif isinstance(ctype, ctypeprim.W_CTypePrimitiveCharOrUniChar):
value_fits_long = True
else:
raise NotImplementedError
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -24,6 +24,7 @@
PRIMITIVE_TYPES[name] = ctypecls, rffi.sizeof(TYPE), alignment(TYPE)
eptype("char", lltype.Char, ctypeprim.W_CTypePrimitiveChar)
+eptype("wchar_t", lltype.UniChar, ctypeprim.W_CTypePrimitiveUniChar)
eptype("signed char", rffi.SIGNEDCHAR, ctypeprim.W_CTypePrimitiveSigned)
eptype("short", rffi.SHORT, ctypeprim.W_CTypePrimitiveSigned)
eptype("int", rffi.INT, ctypeprim.W_CTypePrimitiveSigned)
@@ -36,7 +37,6 @@
eptype("unsigned long long", rffi.LONGLONG, ctypeprim.W_CTypePrimitiveUnsigned)
eptype("float", rffi.FLOAT, ctypeprim.W_CTypePrimitiveFloat)
eptype("double", rffi.DOUBLE, ctypeprim.W_CTypePrimitiveFloat)
-#XXX WCHAR
@unwrap_spec(name=str)
def new_primitive_type(space, name):
@@ -148,8 +148,9 @@
custom_field_pos |= (offset != foffset)
offset = foffset
#
- if fbitsize < 0 or (fbitsize == 8 * ftype.size and not
- isinstance(ftype, ctypeprim.W_CTypePrimitiveChar)):
+ if fbitsize < 0 or (
+ fbitsize == 8 * ftype.size and not
+ isinstance(ftype, ctypeprim.W_CTypePrimitiveCharOrUniChar)):
fbitsize = -1
bitshift = -1
prev_bit_position = 0
@@ -159,7 +160,6 @@
isinstance(ftype, ctypeprim.W_CTypePrimitiveChar)) or
fbitsize == 0 or
fbitsize > 8 * ftype.size):
- #XXX WCHAR: reach here if ftype is PrimitiveUniChar
raise operationerrfmt(space.w_TypeError,
"invalid bit field '%s'", fname)
if prev_bit_position > 0:
More information about the pypy-commit
mailing list