[3.5] bpo-30708: Add private C API function _PyUnicode_AsWideCharStri… · python/cpython@94b169f (original) (raw)

10 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -1054,6 +1054,12 @@ PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString(
1054 1054 );
1055 1055
1056 1056 #ifndef Py_LIMITED_API
1057 +/* Similar to PyUnicode_AsWideCharString(unicode, NULL), but check if
1058 + the string contains null characters. */
1059 +PyAPI_FUNC(wchar_t*) _PyUnicode_AsWideCharString(
1060 + PyObject *unicode /* Unicode object */
1061 + );
1062 +
1057 1063 PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind);
1058 1064 #endif
1059 1065
Original file line number Diff line number Diff line change
@@ -134,7 +134,7 @@ def test_wchar_ptr(self):
134 134 dll.my_wcsdup.restype = POINTER(c_wchar)
135 135 dll.my_wcsdup.argtypes = POINTER(c_wchar),
136 136 dll.my_free.restype = None
137 -res = dll.my_wcsdup(s)
137 +res = dll.my_wcsdup(s[:-1])
138 138 self.assertEqual(res[:len(s)], s)
139 139 self.assertEqual(res[:len(s):], s)
140 140 self.assertEqual(res[len(s)-1:-1:-1], s[::-1])
@@ -153,7 +153,7 @@ def test_wchar_ptr(self):
153 153 dll.my_wcsdup.restype = POINTER(c_long)
154 154 else:
155 155 self.skipTest('Pointers to c_wchar are not supported')
156 -res = dll.my_wcsdup(s)
156 +res = dll.my_wcsdup(s[:-1])
157 157 tmpl = list(range(ord("a"), ord("z")+1))
158 158 self.assertEqual(res[:len(s)-1], tmpl)
159 159 self.assertEqual(res[:len(s)-1:], tmpl)
Original file line number Diff line number Diff line change
@@ -672,7 +672,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
672 672 #ifdef CTYPES_UNICODE
673 673 if (PyUnicode_Check(obj)) {
674 674 pa->ffi_type = &ffi_type_pointer;
675 -pa->value.p = PyUnicode_AsWideCharString(obj, NULL);
675 +pa->value.p = _PyUnicode_AsWideCharString(obj);
676 676 if (pa->value.p == NULL)
677 677 return -1;
678 678 pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
Original file line number Diff line number Diff line change
@@ -1386,7 +1386,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
1386 1386
1387 1387 /* We must create a wchar_t* buffer from the unicode object,
1388 1388 and keep it alive */
1389 -buffer = PyUnicode_AsWideCharString(value, NULL);
1389 +buffer = _PyUnicode_AsWideCharString(value);
1390 1390 if (!buffer)
1391 1391 return NULL;
1392 1392 keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
Original file line number Diff line number Diff line change
@@ -345,7 +345,7 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
345 345 if (PyUnicode_Check(obj)) {
346 346 #ifdef HAVE_NCURSESW
347 347 assert (wstr != NULL);
348 -*wstr = PyUnicode_AsWideCharString(obj, NULL);
348 +*wstr = _PyUnicode_AsWideCharString(obj);
349 349 if (*wstr == NULL)
350 350 return 0;
351 351 return 2;
Original file line number Diff line number Diff line change
@@ -215,10 +215,10 @@ PyLocale_strcoll(PyObject* self, PyObject* args)
215 215 if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2))
216 216 return NULL;
217 217 /* Convert the unicode strings to wchar[]. */
218 -ws1 = PyUnicode_AsWideCharString(os1, NULL);
218 +ws1 = _PyUnicode_AsWideCharString(os1);
219 219 if (ws1 == NULL)
220 220 goto done;
221 -ws2 = PyUnicode_AsWideCharString(os2, NULL);
221 +ws2 = _PyUnicode_AsWideCharString(os2);
222 222 if (ws2 == NULL)
223 223 goto done;
224 224 /* Collate the strings. */
Original file line number Diff line number Diff line change
@@ -3620,7 +3620,7 @@ PyInit__tkinter(void)
3620 3620 return NULL;
3621 3621 }
3622 3622 if (str_path != NULL) {
3623 -wcs_path = PyUnicode_AsWideCharString(str_path, NULL);
3623 +wcs_path = _PyUnicode_AsWideCharString(str_path);
3624 3624 if (wcs_path == NULL) {
3625 3625 return NULL;
3626 3626 }
Original file line number Diff line number Diff line change
@@ -1151,7 +1151,7 @@ ConnectPipe(OverlappedObject *self, PyObject *args)
1151 1151 if (!PyArg_ParseTuple(args, "U", &AddressObj))
1152 1152 return NULL;
1153 1153
1154 -Address = PyUnicode_AsWideCharString(AddressObj, NULL);
1154 +Address = _PyUnicode_AsWideCharString(AddressObj);
1155 1155 if (Address == NULL)
1156 1156 return NULL;
1157 1157
Original file line number Diff line number Diff line change
@@ -596,7 +596,7 @@ time_strftime(PyObject *self, PyObject *args)
596 596 buf.tm_isdst = 1;
597 597
598 598 #ifdef HAVE_WCSFTIME
599 -format = PyUnicode_AsWideCharString(format_arg, NULL);
599 +format = _PyUnicode_AsWideCharString(format_arg);
600 600 if (format == NULL)
601 601 return NULL;
602 602 fmt = format;
Original file line number Diff line number Diff line change
@@ -2839,6 +2839,37 @@ PyUnicode_AsWideCharString(PyObject *unicode,
2839 2839 return buffer;
2840 2840 }
2841 2841
2842 +wchar_t*
2843 +_PyUnicode_AsWideCharString(PyObject *unicode)
2844 +{
2845 +const wchar_t *wstr;
2846 +wchar_t *buffer;
2847 +Py_ssize_t buflen;
2848 +
2849 +if (unicode == NULL) {
2850 +PyErr_BadInternalCall();
2851 +return NULL;
2852 + }
2853 +
2854 +wstr = PyUnicode_AsUnicodeAndSize(unicode, &buflen);
2855 +if (wstr == NULL) {
2856 +return NULL;
2857 + }
2858 +if (wcslen(wstr) != (size_t)buflen) {
2859 +PyErr_SetString(PyExc_ValueError,
2860 +"embedded null character");
2861 +return NULL;
2862 + }
2863 +
2864 +buffer = PyMem_NEW(wchar_t, buflen + 1);
2865 +if (buffer == NULL) {
2866 +PyErr_NoMemory();
2867 +return NULL;
2868 + }
2869 +memcpy(buffer, wstr, (buflen + 1) * sizeof(wchar_t));
2870 +return buffer;
2871 +}
2872 +
2842 2873 #endif /* HAVE_WCHAR_H */
2843 2874
2844 2875 PyObject *