@@ -221,22 +221,36 @@ unicode_copycharacters(PyObject *self, PyObject *args)
221221}
222222
223223static PyObject *
224- unicode_case_operation (PyObject * str , Py_ssize_t (* function )(Py_UCS4 , Py_UCS4 * , Py_ssize_t ),
225- Py_UCS4 * buf , Py_ssize_t size )
224+ unicode_case_operation (PyObject * str ,
225+ Py_ssize_t (* function )(const Py_UCS4 * , Py_ssize_t , Py_UCS4 * , Py_ssize_t ),
226+ int buf_too_small )
226227{
227228 if (!PyUnicode_Check (str )) {
228229 PyErr_Format (PyExc_TypeError , "expect str type, got %T" , str );
229230 return NULL ;
230231 }
232+ Py_ssize_t len = PyUnicode_GET_LENGTH (str );
231233
232- if ( PyUnicode_GET_LENGTH ( str ) != 1 ) {
233- PyErr_SetString ( PyExc_ValueError , "expecting 1-character strings only" );
234+ Py_UCS4 * ucs4 = PyUnicode_AsUCS4Copy ( str );
235+ if ( ucs4 == NULL ) {
234236 return NULL ;
235237 }
236238
237- Py_UCS4 c = PyUnicode_READ_CHAR (str , 0 );
239+ Py_ssize_t buf_size ;
240+ if (!buf_too_small ) {
241+ buf_size = len * PyUCS4_CASE_CONVERSION_BUFFER_SIZE ;
242+ }
243+ else {
244+ buf_size = len * 1 ;
245+ }
246+ Py_UCS4 * buf = PyMem_Malloc (buf_size * sizeof (Py_UCS4 ));
247+ if (buf == NULL ) {
248+ PyMem_Free (ucs4 );
249+ return NULL ;
250+ }
238251
239- Py_ssize_t chars = function (c , buf , size );
252+ Py_ssize_t chars = function (ucs4 , len , buf , buf_size );
253+ PyMem_Free (ucs4 );
240254 if (chars < 0 ) {
241255 return NULL ;
242256 }
@@ -248,41 +262,36 @@ unicode_case_operation(PyObject *str, Py_ssize_t (*function)(Py_UCS4, Py_UCS4 *,
248262static PyObject *
249263unicode_tolower (PyObject * self , PyObject * arg )
250264{
251- Py_UCS4 buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
252- return unicode_case_operation (arg , PyUCS4_ToLower , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
265+ return unicode_case_operation (arg , PyUCS4_ToLower , 0 );
253266}
254267
255268
256269/* Test PyUCS4_ToUpper() */
257270static PyObject *
258271unicode_toupper (PyObject * self , PyObject * arg )
259272{
260- Py_UCS4 buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
261- return unicode_case_operation (arg , PyUCS4_ToUpper , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
273+ return unicode_case_operation (arg , PyUCS4_ToUpper , 0 );
262274}
263275
264276/* Test PyUCS4_ToUpper() with a small buffer */
265277static PyObject *
266278unicode_toupper_buffer_too_small (PyObject * self , PyObject * arg )
267279{
268- Py_UCS4 buf ;
269- return unicode_case_operation (arg , PyUCS4_ToUpper , & buf , 1 );
280+ return unicode_case_operation (arg , PyUCS4_ToUpper , 1 );
270281}
271282
272283/* Test PyUCS4_ToLower() */
273284static PyObject *
274285unicode_totitle (PyObject * self , PyObject * arg )
275286{
276- Py_UCS4 buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
277- return unicode_case_operation (arg , PyUCS4_ToTitle , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
287+ return unicode_case_operation (arg , PyUCS4_ToTitle , 0 );
278288}
279289
280290/* Test PyUCS4_ToLower() */
281291static PyObject *
282292unicode_tofolded (PyObject * self , PyObject * arg )
283293{
284- Py_UCS4 buf [PyUCS4_CASE_CONVERSION_BUFFER_SIZE ];
285- return unicode_case_operation (arg , PyUCS4_ToFolded , buf , PyUCS4_CASE_CONVERSION_BUFFER_SIZE );
294+ return unicode_case_operation (arg , PyUCS4_ToFolded , 0 );
286295}
287296
288297
0 commit comments