Author: Armin Rigo <[email protected]>
Branch: py3.6
Changeset: r97049:3ec1002a818c
Date: 2019-08-02 14:28 +0200
http://bitbucket.org/pypy/pypy/changeset/3ec1002a818c/
Log: PyUnicode_AsUCS4, PyUnicode_AsUCS4Copy
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -1008,3 +1008,32 @@
_PyUnicode_Ready(space, py_str)
assert get_kind(py_str) == 4
assert get_ascii(py_str) == 0
+
+ def test_as_ucs4(self, space):
+ w_x = space.wrap(u"ab\u0660")
+ count1 = space.int_w(space.len(w_x))
+ x_chunk = PyUnicode_AsUCS4Copy(space, w_x)
+ assert x_chunk[0] == ord('a')
+ assert x_chunk[1] == ord('b')
+ assert x_chunk[2] == 0x0660
+ assert x_chunk[3] == 0
+ Py_UCS4 = lltype.typeOf(x_chunk).TO.OF
+ lltype.free(x_chunk, flavor='raw', track_allocation=False)
+
+ target_chunk = lltype.malloc(rffi.CArray(Py_UCS4), 4, flavor='raw')
+ target_chunk[3] = rffi.cast(Py_UCS4, 99999)
+ x_chunk = PyUnicode_AsUCS4(space, w_x, target_chunk, 3, 0)
+ assert x_chunk == target_chunk
+ assert x_chunk[0] == ord('a')
+ assert x_chunk[1] == ord('b')
+ assert x_chunk[2] == 0x0660
+ assert x_chunk[3] == 99999
+
+ x_chunk[2] = rffi.cast(Py_UCS4, 77777)
+ x_chunk = PyUnicode_AsUCS4(space, w_x, target_chunk, 4, 1)
+ assert x_chunk == target_chunk
+ assert x_chunk[0] == ord('a')
+ assert x_chunk[1] == ord('b')
+ assert x_chunk[2] == 0x0660
+ assert x_chunk[3] == 0
+ lltype.free(target_chunk, flavor='raw')
diff --git a/pypy/module/cpyext/unicodeobject.py
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -29,6 +29,7 @@
cts.parse_header(parse_dir / 'cpyext_unicodeobject.h')
PyUnicodeObject = cts.gettype('PyUnicodeObject*')
Py_UNICODE = cts.gettype('Py_UNICODE')
+Py_UCS4 = cts.gettype('Py_UCS4')
INT_realP = lltype.Ptr(lltype.Array(rffi.INT_real, hints={'nolength': True}))
@bootstrap_function
@@ -1081,3 +1082,28 @@
return space.call_method(w_str, '__getitem__',
space.newslice(space.newint(start), space.newint(end),
space.newint(1)))
+
[email protected]("Py_UCS4 *PyUnicode_AsUCS4(PyObject *u, Py_UCS4 *buffer, Py_ssize_t
buflen, int copy_null)")
+def PyUnicode_AsUCS4(space, ref, pbuffer, buflen, copy_null):
+ c_buffer = PyUnicode_AsUnicode(space, ref)
+ c_length = get_wsize(ref)
+
+ size = c_length
+ if copy_null:
+ size += 1
+ if not pbuffer: # internal, for PyUnicode_AsUCS4Copy()
+ pbuffer = lltype.malloc(rffi.CArray(Py_UCS4), size,
+ flavor='raw', track_allocation=False)
+ elif buflen < size:
+ raise oefmt(space.w_SystemError, "PyUnicode_AsUCS4: buflen too short")
+
+ i = 0
+ while i < size:
+ pbuffer[i] = rffi.cast(Py_UCS4, c_buffer[i])
+ i += 1
+ return pbuffer
+
[email protected]("Py_UCS4 *PyUnicode_AsUCS4Copy(PyObject *u)")
+def PyUnicode_AsUCS4Copy(space, ref):
+ return PyUnicode_AsUCS4(space, ref, cts.cast('Py_UCS4*', 0), 0,
+ rffi.cast(rffi.INT_real, 1))
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit