| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a47abdb commit 2e15785
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1563,6 +1563,15 @@ object. | |||
| 1563 | 1563 | On success, return ``0``. | |
| 1564 | 1564 | On error, set an exception, leave the writer unchanged, and return ``-1``. | |
| 1565 | 1565 | ||
| 1566 | + .. c:function:: int PyUnicodeWriter_WriteUCS4(PyUnicodeWriter *writer, Py_UCS4 *str, Py_ssize_t size) | ||
| 1567 | + | ||
| 1568 | + Writer the UCS4 string *str* into *writer*. | ||
| 1569 | + | ||
| 1570 | + *size* is a number of UCS4 characters. | ||
| 1571 | + | ||
| 1572 | + On success, return ``0``. | ||
| 1573 | + On error, set an exception, leave the writer unchanged, and return ``-1``. | ||
| 1574 | + | ||
| 1566 | 1575 | .. c:function:: int PyUnicodeWriter_WriteStr(PyUnicodeWriter *writer, PyObject *obj) | |
| 1567 | 1576 | ||
| 1568 | 1577 | Call :c:func:`PyObject_Str` on *obj* and write the output into *writer*. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -314,6 +314,7 @@ New Features | |||
| 314 | 314 | * :c:func:`PyUnicodeWriter_Finish`. | |
| 315 | 315 | * :c:func:`PyUnicodeWriter_WriteChar`. | |
| 316 | 316 | * :c:func:`PyUnicodeWriter_WriteUTF8`. | |
| 317 | + * :c:func:`PyUnicodeWriter_WriteUCS4`. | ||
| 317 | 318 | * :c:func:`PyUnicodeWriter_WriteWideChar`. | |
| 318 | 319 | * :c:func:`PyUnicodeWriter_WriteStr`. | |
| 319 | 320 | * :c:func:`PyUnicodeWriter_WriteRepr`. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -463,6 +463,10 @@ PyAPI_FUNC(int) PyUnicodeWriter_WriteWideChar( | |||
| 463 | 463 | PyUnicodeWriter *writer, | |
| 464 | 464 | const wchar_t *str, | |
| 465 | 465 | Py_ssize_t size); | |
| 466 | + PyAPI_FUNC(int) PyUnicodeWriter_WriteUCS4( | ||
| 467 | + PyUnicodeWriter *writer, | ||
| 468 | + Py_UCS4 *str, | ||
| 469 | + Py_ssize_t size); | ||
| 466 | 470 | ||
| 467 | 471 | PyAPI_FUNC(int) PyUnicodeWriter_WriteStr( | |
| 468 | 472 | PyUnicodeWriter *writer, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1826,8 +1826,42 @@ def test_widechar(self): | |||
| 1826 | 1826 | writer.write_widechar("latin1=\xE9") | |
| 1827 | 1827 | writer.write_widechar("-") | |
| 1828 | 1828 | writer.write_widechar("euro=\u20AC") | |
| 1829 | + writer.write_char("-") | ||
| 1830 | + writer.write_widechar("max=\U0010ffff") | ||
| 1829 | 1831 | writer.write_char('.') | |
| 1830 | - self.assertEqual(writer.finish(), "latin1=\xE9-euro=\u20AC.") | ||
| 1832 | + self.assertEqual(writer.finish(), | ||
| 1833 | + "latin1=\xE9-euro=\u20AC-max=\U0010ffff.") | ||
| 1834 | + | ||
| 1835 | + def test_ucs4(self): | ||
| 1836 | + writer = self.create_writer(0) | ||
| 1837 | + writer.write_ucs4("ascii IGNORED", 5) | ||
| 1838 | + writer.write_char("-") | ||
| 1839 | + writer.write_ucs4("latin1=\xe9", 8) | ||
| 1840 | + writer.write_char("-") | ||
| 1841 | + writer.write_ucs4("euro=\u20ac", 6) | ||
| 1842 | + writer.write_char("-") | ||
| 1843 | + writer.write_ucs4("max=\U0010ffff", 5) | ||
| 1844 | + writer.write_char(".") | ||
| 1845 | + self.assertEqual(writer.finish(), | ||
| 1846 | + "ascii-latin1=\xE9-euro=\u20AC-max=\U0010ffff.") | ||
| 1847 | + | ||
| 1848 | + # Test some special characters | ||
| 1849 | + writer = self.create_writer(0) | ||
| 1850 | + # Lone surrogate character | ||
| 1851 | + writer.write_ucs4("lone\uDC80", 5) | ||
| 1852 | + writer.write_char("-") | ||
| 1853 | + # Surrogate pair | ||
| 1854 | + writer.write_ucs4("pair\uDBFF\uDFFF", 5) | ||
| 1855 | + writer.write_char("-") | ||
| 1856 | + writer.write_ucs4("null[\0]", 7) | ||
| 1857 | + self.assertEqual(writer.finish(), | ||
| 1858 | + "lone\udc80-pair\udbff-null[\0]") | ||
| 1859 | + | ||
| 1860 | + # invalid size | ||
| 1861 | + writer = self.create_writer(0) | ||
| 1862 | + with self.assertRaises(ValueError): | ||
| 1863 | + writer.write_ucs4("text", -1) | ||
| 1864 | + | ||
| 1831 | 1865 | ||
| 1832 | 1866 | ||
| 1833 | 1867 | @unittest.skipIf(ctypes is None, 'need ctypes') | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,9 +5,12 @@ Add a new :c:type:`PyUnicodeWriter` API to create a Python :class:`str` object: | |||
| 5 | 5 | * :c:func:`PyUnicodeWriter_Finish`. | |
| 6 | 6 | * :c:func:`PyUnicodeWriter_WriteChar`. | |
| 7 | 7 | * :c:func:`PyUnicodeWriter_WriteUTF8`. | |
| 8 | + * :c:func:`PyUnicodeWriter_WriteUCS4`. | ||
| 9 | + * :c:func:`PyUnicodeWriter_WriteWideChar`. | ||
| 8 | 10 | * :c:func:`PyUnicodeWriter_WriteStr`. | |
| 9 | 11 | * :c:func:`PyUnicodeWriter_WriteRepr`. | |
| 10 | 12 | * :c:func:`PyUnicodeWriter_WriteSubstring`. | |
| 11 | 13 | * :c:func:`PyUnicodeWriter_Format`. | |
| 14 | + * :c:func:`PyUnicodeWriter_DecodeUTF8Stateful`. | ||
| 12 | 15 | ||
| 13 | 16 | Patch by Victor Stinner. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -360,6 +360,36 @@ writer_write_widechar(PyObject *self_raw, PyObject *args) | |||
| 360 | 360 | } | |
| 361 | 361 | ||
| 362 | 362 | ||
| 363 | + static PyObject* | ||
| 364 | + writer_write_ucs4(PyObject *self_raw, PyObject *args) | ||
| 365 | + { | ||
| 366 | + WriterObject *self = (WriterObject *)self_raw; | ||
| 367 | + if (writer_check(self) < 0) { | ||
| 368 | + return NULL; | ||
| 369 | + } | ||
| 370 | + | ||
| 371 | + PyObject *str; | ||
| 372 | + Py_ssize_t size; | ||
| 373 | + if (!PyArg_ParseTuple(args, "Un", &str, &size)) { | ||
| 374 | + return NULL; | ||
| 375 | + } | ||
| 376 | + Py_ssize_t len = PyUnicode_GET_LENGTH(str); | ||
| 377 | + size = Py_MIN(size, len); | ||
| 378 | + | ||
| 379 | + Py_UCS4 *ucs4 = PyUnicode_AsUCS4Copy(str); | ||
| 380 | + if (ucs4 == NULL) { | ||
| 381 | + return NULL; | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + int res = PyUnicodeWriter_WriteUCS4(self->writer, ucs4, size); | ||
| 385 | + PyMem_Free(ucs4); | ||
| 386 | + if (res < 0) { | ||
| 387 | + return NULL; | ||
| 388 | + } | ||
| 389 | + Py_RETURN_NONE; | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + | ||
| 363 | 393 | static PyObject* | |
| 364 | 394 | writer_write_str(PyObject *self_raw, PyObject *args) | |
| 365 | 395 | { | |
@@ -484,6 +514,7 @@ static PyMethodDef writer_methods[] = { | |||
| 484 | 514 | {"write_char", _PyCFunction_CAST(writer_write_char), METH_VARARGS}, | |
| 485 | 515 | {"write_utf8", _PyCFunction_CAST(writer_write_utf8), METH_VARARGS}, | |
| 486 | 516 | {"write_widechar", _PyCFunction_CAST(writer_write_widechar), METH_VARARGS}, | |
| 517 | + {"write_ucs4", _PyCFunction_CAST(writer_write_ucs4), METH_VARARGS}, | ||
| 487 | 518 | {"write_str", _PyCFunction_CAST(writer_write_str), METH_VARARGS}, | |
| 488 | 519 | {"write_repr", _PyCFunction_CAST(writer_write_repr), METH_VARARGS}, | |
| 489 | 520 | {"write_substring", _PyCFunction_CAST(writer_write_substring), METH_VARARGS}, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2035,11 +2035,9 @@ PyUnicodeWriter_WriteWideChar(PyUnicodeWriter *pub_writer, | |||
| 2035 | 2035 | if (!converted) { | |
| 2036 | 2036 | return -1; | |
| 2037 | 2037 | } | |
| 2038 | - PyObject *unicode = _PyUnicode_FromUCS4(converted, size); | ||
| 2039 | - PyMem_Free(converted); | ||
| 2040 | 2038 | ||
| 2041 | - int res = _PyUnicodeWriter_WriteStr(writer, unicode); | ||
| 2042 | - Py_DECREF(unicode); | ||
| 2039 | + int res = PyUnicodeWriter_WriteUCS4(pub_writer, converted, size); | ||
| 2040 | + PyMem_Free(converted); | ||
| 2043 | 2041 | return res; | |
| 2044 | 2042 | } | |
| 2045 | 2043 | #endif | |
@@ -2289,6 +2287,51 @@ _PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size) | |||
| 2289 | 2287 | return res; | |
| 2290 | 2288 | } | |
| 2291 | 2289 | ||
| 2290 | + | ||
| 2291 | + int | ||
| 2292 | + PyUnicodeWriter_WriteUCS4(PyUnicodeWriter *pub_writer, | ||
| 2293 | + Py_UCS4 *str, | ||
| 2294 | + Py_ssize_t size) | ||
| 2295 | + { | ||
| 2296 | + _PyUnicodeWriter *writer = (_PyUnicodeWriter*)pub_writer; | ||
| 2297 | + | ||
| 2298 | + if (size < 0) { | ||
| 2299 | + PyErr_SetString(PyExc_ValueError, | ||
| 2300 | + "size must be positive"); | ||
| 2301 | + return -1; | ||
| 2302 | + } | ||
| 2303 | + | ||
| 2304 | + if (size == 0) { | ||
| 2305 | + return 0; | ||
| 2306 | + } | ||
| 2307 | + | ||
| 2308 | + Py_UCS4 max_char = ucs4lib_find_max_char(str, str + size); | ||
| 2309 | + | ||
| 2310 | + if (_PyUnicodeWriter_Prepare(writer, size, max_char) < 0) { | ||
| 2311 | + return -1; | ||
| 2312 | + } | ||
| 2313 | + | ||
| 2314 | + int kind = writer->kind; | ||
| 2315 | + void *data = (Py_UCS1*)writer->data + writer->pos * kind; | ||
| 2316 | + if (kind == PyUnicode_1BYTE_KIND) { | ||
| 2317 | + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, | ||
| 2318 | + str, str + size, | ||
| 2319 | + data); | ||
| 2320 | + } | ||
| 2321 | + else if (kind == PyUnicode_2BYTE_KIND) { | ||
| 2322 | + _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, | ||
| 2323 | + str, str + size, | ||
| 2324 | + data); | ||
| 2325 | + } | ||
| 2326 | + else { | ||
| 2327 | + memcpy(data, str, size * sizeof(Py_UCS4)); | ||
| 2328 | + } | ||
| 2329 | + writer->pos += size; | ||
| 2330 | + | ||
| 2331 | + return 0; | ||
| 2332 | + } | ||
| 2333 | + | ||
| 2334 | + | ||
| 2292 | 2335 | PyObject* | |
| 2293 | 2336 | PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size) | |
| 2294 | 2337 | { | |
@@ -13357,7 +13400,7 @@ PyUnicodeWriter* | |||
| 13357 | 13400 | PyUnicodeWriter_Create(Py_ssize_t length) | |
| 13358 | 13401 | { | |
| 13359 | 13402 | if (length < 0) { | |
| 13360 | - PyErr_SetString(PyExc_TypeError, | ||
| 13403 | + PyErr_SetString(PyExc_ValueError, | ||
| 13361 | 13404 | "length must be positive"); | |
| 13362 | 13405 | return NULL; | |
| 13363 | 13406 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments