[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