[pypy-commit] pypy default: also support automatic conversion of unicode to unichar_p

antocuni noreply at buildbot.pypy.org
Wed Jul 27 18:42:59 CEST 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: 
Changeset: r46022:fe819dcd9aa2
Date: 2011-07-27 18:42 +0200
http://bitbucket.org/pypy/pypy/changeset/fe819dcd9aa2/

Log:	also support automatic conversion of unicode to unichar_p

diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -77,6 +77,10 @@
     def is_char_p(self):
         return self is app_types.char_p
 
+    def is_unichar_p(self):
+        return self is app_types.unichar_p
+
+
 W_FFIType.typedef = TypeDef(
     'FFIType',
     __repr__ = interp2app(W_FFIType.repr),
@@ -120,7 +124,9 @@
         ]
     d = dict([(t.name, t) for t in types])
     w_char = d['char']
+    w_unichar = d['unichar']
     d['char_p'] = W_FFIType('char_p', libffi.types.pointer, w_pointer_to = w_char)
+    d['unichar_p'] = W_FFIType('unichar_p', libffi.types.pointer, w_pointer_to = w_unichar)
     return d
 
 class app_types:
@@ -133,6 +139,8 @@
     except KeyError:
         if w_pointer_to is app_types.char:
             w_result = app_types.char_p
+        elif w_pointer_to is app_types.unichar:
+            w_result = app_types.unichar_p
         else:
             w_pointer_to = space.interp_w(W_FFIType, w_pointer_to)
             name = '(pointer to %s)' % w_pointer_to.name
@@ -239,6 +247,14 @@
             addr = rffi.cast(rffi.ULONG, buf)
             argchain.arg(addr)
             return True
+        elif w_argtype.is_unichar_p() and (w_type is space.w_str or
+                                           w_type is space.w_unicode):
+            unicodeval = space.unicode_w(w_arg)
+            buf = rffi.unicode2wcharp(unicodeval)
+            to_free.append(buf)
+            addr = rffi.cast(rffi.ULONG, buf)
+            argchain.arg(addr)
+            return True
         return False
 
     def convert_pointer_arg_maybe(self, space, w_arg, w_argtype):
diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test__ffi.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test__ffi.py
@@ -188,7 +188,7 @@
         assert get_dummy() == 123
         set_val_to_ptr(ptr2, 0)
 
-    def test_convert_strings_to_char_str_p(self):
+    def test_convert_strings_to_char_p(self):
         """
             long mystrlen(char* s)
             {
@@ -211,6 +211,31 @@
         assert mystrlen(mystr.buffer) == 6
         mystr.free()
 
+    def test_convert_unicode_to_unichar_p(self):
+        """
+            #include <wchar.h>
+            long mystrlen_u(wchar_t* s)
+            {
+                long len = 0;
+                while(*s++)
+                    len++;
+                return len;
+            }
+        """
+        from _ffi import CDLL, types
+        import _rawffi
+        libfoo = CDLL(self.libfoo_name)
+        mystrlen = libfoo.getfunc('mystrlen_u', [types.unichar_p], types.slong)
+        #
+        # first, try automatic conversion from strings and unicode
+        assert mystrlen('foobar') == 6
+        assert mystrlen(u'foobar') == 6
+        # then, try to pass an explicit pointer
+        UniCharArray = _rawffi.Array('u')
+        mystr = UniCharArray(7, u'foobar')
+        assert mystrlen(mystr.buffer) == 6
+        mystr.free()
+
     def test_typed_pointer(self):
         from _ffi import types
         intptr = types.Pointer(types.sint) # create a typed pointer to sint
@@ -231,6 +256,8 @@
         from _ffi import types
         x = types.Pointer(types.char)
         assert x is types.char_p
+        x = types.Pointer(types.unichar)
+        assert x is types.unichar_p
 
     def test_typed_pointer_args(self):
         """


More information about the pypy-commit mailing list