@@ -235,24 +235,31 @@ BB_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
235
235
static PyObject *
236
236
u_getitem (arrayobject * ap , Py_ssize_t i )
237
237
{
238
- return PyUnicode_FromOrdinal (((Py_UNICODE * ) ap -> ob_item )[i ]);
238
+ return PyUnicode_FromOrdinal (((wchar_t * ) ap -> ob_item )[i ]);
239
239
}
240
240
241
241
static int
242
242
u_setitem (arrayobject * ap , Py_ssize_t i , PyObject * v )
243
243
{
244
- Py_UNICODE * p ;
245
- Py_ssize_t len ;
246
-
247
- if (!PyArg_Parse (v , "u#;array item must be unicode character" , & p , & len ))
244
+ PyObject * u ;
245
+ if (!PyArg_Parse (v , "U;array item must be unicode character" , & u )) {
248
246
return -1 ;
249
- if (len != 1 ) {
247
+ }
248
+
249
+ Py_ssize_t len = PyUnicode_AsWideChar (u , NULL , 0 );
250
+ if (len != 2 ) {
250
251
PyErr_SetString (PyExc_TypeError ,
251
252
"array item must be unicode character" );
252
253
return -1 ;
253
254
}
254
- if (i >= 0 )
255
- ((Py_UNICODE * )ap -> ob_item )[i ] = p [0 ];
255
+
256
+ wchar_t w ;
257
+ len = PyUnicode_AsWideChar (u , & w , 1 );
258
+ assert (len == 1 );
259
+
260
+ if (i >= 0 ) {
261
+ ((wchar_t * )ap -> ob_item )[i ] = w ;
262
+ }
256
263
return 0 ;
257
264
}
258
265
@@ -530,7 +537,7 @@ d_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
530
537
531
538
DEFINE_COMPAREITEMS (b , signed char )
532
539
DEFINE_COMPAREITEMS (BB , unsigned char )
533
- DEFINE_COMPAREITEMS (u , Py_UNICODE )
540
+ DEFINE_COMPAREITEMS (u , wchar_t )
534
541
DEFINE_COMPAREITEMS (h , short )
535
542
DEFINE_COMPAREITEMS (HH , unsigned short )
536
543
DEFINE_COMPAREITEMS (i , int )
@@ -548,7 +555,7 @@ DEFINE_COMPAREITEMS(QQ, unsigned long long)
548
555
static const struct arraydescr descriptors [] = {
549
556
{'b' , 1 , b_getitem , b_setitem , b_compareitems , "b" , 1 , 1 },
550
557
{'B' , 1 , BB_getitem , BB_setitem , BB_compareitems , "B" , 1 , 0 },
551
- {'u' , sizeof (Py_UNICODE ), u_getitem , u_setitem , u_compareitems , "u" , 0 , 0 },
558
+ {'u' , sizeof (wchar_t ), u_getitem , u_setitem , u_compareitems , "u" , 0 , 0 },
552
559
{'h' , sizeof (short ), h_getitem , h_setitem , h_compareitems , "h" , 1 , 1 },
553
560
{'H' , sizeof (short ), HH_getitem , HH_setitem , HH_compareitems , "H" , 1 , 0 },
554
561
{'i' , sizeof (int ), i_getitem , i_setitem , i_compareitems , "i" , 1 , 1 },
@@ -1660,7 +1667,7 @@ array_array_tobytes_impl(arrayobject *self)
1660
1667
/*[clinic input]
1661
1668
array.array.fromunicode
1662
1669
1663
- ustr: Py_UNICODE(zeroes=True)
1670
+ ustr: unicode
1664
1671
/
1665
1672
1666
1673
Extends this array with data from the unicode string ustr.
@@ -1671,25 +1678,28 @@ some other type.
1671
1678
[clinic start generated code]*/
1672
1679
1673
1680
static PyObject *
1674
- array_array_fromunicode_impl (arrayobject * self , const Py_UNICODE * ustr ,
1675
- Py_ssize_clean_t ustr_length )
1676
- /*[clinic end generated code: output=cf2f662908e2befc input=150f00566ffbca6e]*/
1681
+ array_array_fromunicode_impl (arrayobject * self , PyObject * ustr )
1682
+ /*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
1677
1683
{
1678
- char typecode ;
1679
-
1680
- typecode = self -> ob_descr -> typecode ;
1681
- if (typecode != 'u' ) {
1684
+ if (self -> ob_descr -> typecode != 'u' ) {
1682
1685
PyErr_SetString (PyExc_ValueError ,
1683
1686
"fromunicode() may only be called on "
1684
1687
"unicode type arrays" );
1685
1688
return NULL ;
1686
1689
}
1687
- if (ustr_length > 0 ) {
1690
+
1691
+ Py_ssize_t ustr_length = PyUnicode_AsWideChar (ustr , NULL , 0 );
1692
+ assert (ustr_length > 0 );
1693
+ if (ustr_length > 1 ) {
1694
+ ustr_length -- ; /* trim trailing NUL character */
1688
1695
Py_ssize_t old_size = Py_SIZE (self );
1689
- if (array_resize (self , old_size + ustr_length ) == -1 )
1696
+ if (array_resize (self , old_size + ustr_length ) == -1 ) {
1690
1697
return NULL ;
1691
- memcpy (self -> ob_item + old_size * sizeof (Py_UNICODE ),
1692
- ustr , ustr_length * sizeof (Py_UNICODE ));
1698
+ }
1699
+
1700
+ // must not fail
1701
+ PyUnicode_AsWideChar (
1702
+ ustr , ((wchar_t * )self -> ob_item ) + old_size , ustr_length );
1693
1703
}
1694
1704
1695
1705
Py_RETURN_NONE ;
@@ -1709,14 +1719,12 @@ static PyObject *
1709
1719
array_array_tounicode_impl (arrayobject * self )
1710
1720
/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
1711
1721
{
1712
- char typecode ;
1713
- typecode = self -> ob_descr -> typecode ;
1714
- if (typecode != 'u' ) {
1722
+ if (self -> ob_descr -> typecode != 'u' ) {
1715
1723
PyErr_SetString (PyExc_ValueError ,
1716
1724
"tounicode() may only be called on unicode type arrays" );
1717
1725
return NULL ;
1718
1726
}
1719
- return PyUnicode_FromWideChar ((Py_UNICODE * ) self -> ob_item , Py_SIZE (self ));
1727
+ return PyUnicode_FromWideChar ((wchar_t * ) self -> ob_item , Py_SIZE (self ));
1720
1728
}
1721
1729
1722
1730
/*[clinic input]
@@ -2675,30 +2683,20 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2675
2683
Py_DECREF (v );
2676
2684
}
2677
2685
else if (initial != NULL && PyUnicode_Check (initial )) {
2678
- Py_UNICODE * ustr ;
2679
2686
Py_ssize_t n ;
2680
-
2681
- ustr = PyUnicode_AsUnicode (initial );
2687
+ wchar_t * ustr = PyUnicode_AsWideCharString (initial , & n );
2682
2688
if (ustr == NULL ) {
2683
- PyErr_NoMemory ();
2684
2689
Py_DECREF (a );
2685
2690
return NULL ;
2686
2691
}
2687
2692
2688
- n = PyUnicode_GET_DATA_SIZE (initial );
2689
2693
if (n > 0 ) {
2690
2694
arrayobject * self = (arrayobject * )a ;
2691
- char * item = self -> ob_item ;
2692
- item = (char * )PyMem_Realloc (item , n );
2693
- if (item == NULL ) {
2694
- PyErr_NoMemory ();
2695
- Py_DECREF (a );
2696
- return NULL ;
2697
- }
2698
- self -> ob_item = item ;
2699
- Py_SET_SIZE (self , n / sizeof (Py_UNICODE ));
2700
- memcpy (item , ustr , n );
2701
- self -> allocated = Py_SIZE (self );
2695
+ // self->ob_item may be NULL but it is safe.
2696
+ PyMem_Free (self -> ob_item );
2697
+ self -> ob_item = (char * )ustr ;
2698
+ Py_SET_SIZE (self , n );
2699
+ self -> allocated = n ;
2702
2700
}
2703
2701
}
2704
2702
else if (initial != NULL && array_Check (initial ) && len > 0 ) {
0 commit comments