Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 137c34c

Browse files
author
Victor Stinner
committed
Issue #9979: Create function PyUnicode_AsWideCharString().
1 parent 41a64a5 commit 137c34c

4 files changed

Lines changed: 80 additions & 16 deletions

File tree

Doc/c-api/unicode.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,19 @@ wchar_t support for platforms which support it:
462462
required by the application.
463463

464464

465+
.. cfunction:: wchar_t* PyUnicode_AsWideCharString(PyUnicodeObject *unicode, Py_ssize_t *size)
466+
467+
Convert the Unicode object to a wide character string. The output string
468+
always ends with a nul character. If *size* is not *NULL*, write the number
469+
of wide characters (including the nul character) into *\*size*.
470+
471+
Returns a buffer allocated by :cfunc:`PyMem_Alloc` (use :cfunc:`PyMem_Free`
472+
to free it) on success. On error, returns *NULL*, *\*size* is undefined and
473+
raises a :exc:`MemoryError`.
474+
475+
.. versionadded:: 3.2
476+
477+
465478
.. _builtincodecs:
466479

467480
Built-in Codecs

Include/unicodeobject.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ Copyright (c) Corporation for National Research Initiatives.
9999
#endif
100100

101101
/* If the compiler provides a wchar_t type we try to support it
102-
through the interface functions PyUnicode_FromWideChar() and
103-
PyUnicode_AsWideChar(). */
102+
through the interface functions PyUnicode_FromWideChar(),
103+
PyUnicode_AsWideChar() and PyUnicode_AsWideCharString(). */
104104

105105
#ifdef HAVE_USABLE_WCHAR_T
106106
# ifndef HAVE_WCHAR_H
@@ -156,6 +156,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
156156
# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode
157157
# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString
158158
# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar
159+
# define PyUnicode_AsWideCharString PyUnicodeUCS2_AsWideCharString
159160
# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist
160161
# define PyUnicode_Compare PyUnicodeUCS2_Compare
161162
# define PyUnicode_CompareWithASCII PyUnicodeUCS2_CompareASCII
@@ -239,6 +240,7 @@ typedef PY_UNICODE_TYPE Py_UNICODE;
239240
# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode
240241
# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString
241242
# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar
243+
# define PyUnicode_AsWideCharString PyUnicodeUCS4_AsWideCharString
242244
# define PyUnicode_ClearFreeList PyUnicodeUCS4_ClearFreelist
243245
# define PyUnicode_Compare PyUnicodeUCS4_Compare
244246
# define PyUnicode_CompareWithASCII PyUnicodeUCS4_CompareWithASCII
@@ -570,6 +572,19 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar(
570572
Py_ssize_t size /* size of buffer */
571573
);
572574

575+
/* Convert the Unicode object to a wide character string. The output string
576+
always ends with a nul character. If size is not NULL, write the number of
577+
wide characters (including the nul character) into *size.
578+
579+
Returns a buffer allocated by PyMem_Alloc() (use PyMem_Free() to free it)
580+
on success. On error, returns NULL, *size is undefined and raises a
581+
MemoryError. */
582+
583+
PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString(
584+
PyUnicodeObject *unicode, /* Unicode object */
585+
Py_ssize_t *size /* number of characters of the result */
586+
);
587+
573588
#endif
574589

575590
/* --- Unicode ordinals --------------------------------------------------- */

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.2 Alpha 3?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #9979: Create function PyUnicode_AsWideCharString().
14+
1315
- Issue #7397: Mention that importlib.import_module() is probably what someone
1416
really wants to be using in __import__'s docstring.
1517

Objects/unicodeobject.c

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,9 +1153,26 @@ PyUnicode_FromFormat(const char *format, ...)
11531153
return ret;
11541154
}
11551155

1156-
Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
1157-
wchar_t *w,
1158-
Py_ssize_t size)
1156+
static void
1157+
unicode_aswidechar(PyUnicodeObject *unicode,
1158+
wchar_t *w,
1159+
Py_ssize_t size)
1160+
{
1161+
#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
1162+
memcpy(w, unicode->str, size * sizeof(wchar_t));
1163+
#else
1164+
register Py_UNICODE *u;
1165+
register Py_ssize_t i;
1166+
u = PyUnicode_AS_UNICODE(unicode);
1167+
for (i = size; i > 0; i--)
1168+
*w++ = *u++;
1169+
#endif
1170+
}
1171+
1172+
Py_ssize_t
1173+
PyUnicode_AsWideChar(PyUnicodeObject *unicode,
1174+
wchar_t *w,
1175+
Py_ssize_t size)
11591176
{
11601177
if (unicode == NULL) {
11611178
PyErr_BadInternalCall();
@@ -1166,24 +1183,41 @@ Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,
11661183
if (size > PyUnicode_GET_SIZE(unicode))
11671184
size = PyUnicode_GET_SIZE(unicode) + 1;
11681185

1169-
#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
1170-
memcpy(w, unicode->str, size * sizeof(wchar_t));
1171-
#else
1172-
{
1173-
register Py_UNICODE *u;
1174-
register Py_ssize_t i;
1175-
u = PyUnicode_AS_UNICODE(unicode);
1176-
for (i = size; i > 0; i--)
1177-
*w++ = *u++;
1178-
}
1179-
#endif
1186+
unicode_aswidechar(unicode, w, size);
11801187

11811188
if (size > PyUnicode_GET_SIZE(unicode))
11821189
return PyUnicode_GET_SIZE(unicode);
11831190
else
11841191
return size;
11851192
}
11861193

1194+
wchar_t*
1195+
PyUnicode_AsWideCharString(PyUnicodeObject *unicode,
1196+
Py_ssize_t *size)
1197+
{
1198+
wchar_t* buffer;
1199+
Py_ssize_t buflen;
1200+
1201+
if (unicode == NULL) {
1202+
PyErr_BadInternalCall();
1203+
return NULL;
1204+
}
1205+
1206+
if ((PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) < PyUnicode_GET_SIZE(unicode)) {
1207+
PyErr_NoMemory();
1208+
return NULL;
1209+
}
1210+
1211+
buflen = PyUnicode_GET_SIZE(unicode) + 1; /* copy L'\0' */
1212+
buffer = PyMem_MALLOC(buflen * sizeof(wchar_t));
1213+
if (buffer == NULL) {
1214+
PyErr_NoMemory();
1215+
return NULL;
1216+
}
1217+
unicode_aswidechar(unicode, buffer, buflen);
1218+
return buffer;
1219+
}
1220+
11871221
#endif
11881222

11891223
PyObject *PyUnicode_FromOrdinal(int ordinal)

0 commit comments

Comments
 (0)