[pypy-svn] r73916 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test

afa at codespeak.net afa at codespeak.net
Tue Apr 20 18:58:44 CEST 2010


Author: afa
Date: Tue Apr 20 18:58:42 2010
New Revision: 73916

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
Log:
implement PyUnicode_FromWideChar and PyUnicode_AsWideChar.
unlike other functions, PyUnicode_AsWideChar takes a PyUnicodeObject as first argument.


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py	Tue Apr 20 18:58:42 2010
@@ -56,8 +56,12 @@
     _compilation_info_ = CConfig._compilation_info_
 
 VA_LIST_P = rffi.VOIDP # rffi.COpaquePtr('va_list')
-CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True}))
+CONST_STRING = lltype.Ptr(lltype.Array(lltype.Char,
+                                       hints={'nolength': True}))
+CONST_WSTRING = lltype.Ptr(lltype.Array(lltype.UniChar,
+                                        hints={'nolength': True}))
 assert CONST_STRING is not rffi.CCHARP
+assert CONST_WSTRING is not rffi.CWCHARP
 
 constant_names = """
 Py_TPFLAGS_READY Py_TPFLAGS_READYING
@@ -586,6 +590,8 @@
         for i, argtype in enumerate(func.argtypes):
             if argtype is CONST_STRING:
                 arg = 'const char *@'
+            elif argtype is CONST_WSTRING:
+                arg = 'const wchar_t *@'
             else:
                 arg = db.gettype(argtype)
             arg = arg.replace('@', 'arg%d' % (i,)).strip()

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py	Tue Apr 20 18:58:42 2010
@@ -5626,30 +5626,6 @@
     throughout the interpreter whenever coercion to Unicode is needed."""
     raise NotImplementedError
 
- at cpython_api([{const wchar_t*}, Py_ssize_t], PyObject)
-def PyUnicode_FromWideChar(space, w, size):
-    """Create a Unicode object from the wchar_t buffer w of the given size.
-    Return NULL on failure.
-    
-    This function used an int type for size. This might require
-    changes in your code for properly supporting 64-bit systems."""
-    raise NotImplementedError
-
- at cpython_api([{PyUnicodeObject*}, {wchar_t*}, Py_ssize_t], Py_ssize_t)
-def PyUnicode_AsWideChar(space, unicode, w, size):
-    """Copy the Unicode object contents into the wchar_t buffer w.  At most
-    size wchar_t characters are copied (excluding a possibly trailing
-    0-termination character).  Return the number of wchar_t characters
-    copied or -1 in case of an error.  Note that the resulting wchar_t
-    string may or may not be 0-terminated.  It is the responsibility of the caller
-    to make sure that the wchar_t string is 0-terminated in case this is
-    required by the application.
-    
-    This function returned an int type and used an int
-    type for size. This might require changes in your code for properly
-    supporting 64-bit systems."""
-    raise NotImplementedError
-
 @cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject)
 def PyUnicode_Decode(space, s, size, encoding, errors):
     """Create a Unicode object by decoding size bytes of the encoded string s.

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_unicodeobject.py	Tue Apr 20 18:58:42 2010
@@ -49,6 +49,13 @@
                space.wrap(''), None, None)
         rffi.free_charp(utf_8)
 
+        buf = rffi.unicode2wcharp(u"12345")
+        api.PyUnicode_AsWideChar(space.wrap(u'longword'), buf, 5)
+        assert rffi.wcharp2unicode(buf) == 'longw'
+        api.PyUnicode_AsWideChar(space.wrap(u'a'), buf, 5)
+        assert rffi.wcharp2unicode(buf) == 'a'
+        lltype.free(buf, flavor='raw')
+
     def test_IS(self, space, api):
         for char in [0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f,
                      0x20, 0x85, 0xa0, 0x1680, 0x2000, 0x2001, 0x2002,

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/unicodeobject.py	Tue Apr 20 18:58:42 2010
@@ -4,7 +4,7 @@
 from pypy.module.cpyext.api import (
     CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api,
     bootstrap_function, generic_cpy_call, PyObjectFields,
-    cpython_struct, CONST_STRING)
+    cpython_struct, CONST_STRING, CONST_WSTRING)
 from pypy.module.cpyext.pyerrors import PyErr_BadArgument
 from pypy.module.cpyext.pyobject import PyObject, from_ref, make_ref, Py_DecRef, make_typedescr
 from pypy.module.cpyext.stringobject import PyString_Check
@@ -142,6 +142,37 @@
                              space.wrap("expected unicode object"))
     return PyUnicode_AS_UNICODE(space, ref)
 
+ at cpython_api([PyUnicodeObject, rffi.CWCHARP, Py_ssize_t], Py_ssize_t, error=-1)
+def PyUnicode_AsWideChar(space, ref, buf, size):
+    """Copy the Unicode object contents into the wchar_t buffer w.  At most
+    size wchar_t characters are copied (excluding a possibly trailing
+    0-termination character).  Return the number of wchar_t characters
+    copied or -1 in case of an error.  Note that the resulting wchar_t
+    string may or may not be 0-terminated.  It is the responsibility of the caller
+    to make sure that the wchar_t string is 0-terminated in case this is
+    required by the application."""
+    if not PyUnicode_Check(space, ref):
+        raise OperationError(space.w_TypeError,
+                             space.wrap("expected unicode object"))
+
+    c_buffer = PyUnicode_AS_UNICODE(space, ref)
+    c_size = rffi.cast(PyUnicodeObject, ref).c_size
+
+    # If possible, try to copy the 0-termination as well
+    if size > c_size:
+        size = c_size + 1
+
+
+    i = 0
+    while i < size:
+        buf[i] = c_buffer[i]
+        i += 1
+
+    if size > c_size:
+        return c_size
+    else:
+        return size
+
 @cpython_api([], rffi.CCHARP, error=CANNOT_FAIL)
 def PyUnicode_GetDefaultEncoding(space):
     """Returns the currently active default encoding."""
@@ -179,7 +210,7 @@
         w_errors = rffi.charp2str(encoding)
     return unicodetype.encode_object(space, w_unicode, w_encoding, w_errors)
 
- at cpython_api([rffi.CWCHARP, Py_ssize_t], PyObject)
+ at cpython_api([CONST_WSTRING, Py_ssize_t], PyObject)
 def PyUnicode_FromUnicode(space, wchar_p, length):
     """Create a Unicode Object from the Py_UNICODE buffer u of the given size. u
     may be NULL which causes the contents to be undefined. It is the user's
@@ -193,6 +224,13 @@
     ptr = make_ref(space, space.wrap(s))
     return ptr
 
+ at cpython_api([CONST_WSTRING, Py_ssize_t], PyObject)
+def PyUnicode_FromWideChar(space, wchar_p, length):
+    """Create a Unicode object from the wchar_t buffer w of the given size.
+    Return NULL on failure."""
+    # PyPy supposes Py_UNICODE == wchar_t
+    return PyUnicode_FromUnicode(space, wchar_p, length)
+
 @cpython_api([PyObject, CONST_STRING], PyObject)
 def _PyUnicode_AsDefaultEncodedString(space, w_unicode, errors):
     return PyUnicode_AsEncodedString(space, w_unicode, lltype.nullptr(rffi.CCHARP.TO), errors)



More information about the Pypy-commit mailing list