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

Reply via email to