11/*
2- * wchar_t helpers
2+ * CPython 3.3 added support for sys.maxunicode == 0x10FFFF on all
3+ * platforms, even ones with wchar_t limited to 2 bytes. As such,
4+ * this code here works from the outside like wchar_helper.h in the
5+ * case Py_UNICODE_SIZE == 4, but the implementation is very different.
36 */
47
58typedef uint16_t cffi_char16_t ;
69typedef uint32_t cffi_char32_t ;
710
811
9- #if Py_UNICODE_SIZE == 2
10-
11- /* Before Python 2.7, PyUnicode_FromWideChar is not able to convert
12- wchar_t values greater than 65535 into two-unicode-characters surrogates.
13- But even the Python 2.7 version doesn't detect wchar_t values that are
14- out of range(1114112), and just returns nonsense.
15-
16- From cffi 1.11 we can't use it anyway, because we need a version
17- with char32_t input types.
18- */
19- static PyObject *
20- _my_PyUnicode_FromChar32 (const cffi_char32_t * w , Py_ssize_t size )
21- {
22- PyObject * unicode ;
23- register Py_ssize_t i ;
24- Py_ssize_t alloc ;
25- const cffi_char32_t * orig_w ;
26-
27- alloc = size ;
28- orig_w = w ;
29- for (i = size ; i > 0 ; i -- ) {
30- if (* w > 0xFFFF )
31- alloc ++ ;
32- w ++ ;
33- }
34- w = orig_w ;
35- unicode = PyUnicode_FromUnicode (NULL , alloc );
36- if (!unicode )
37- return NULL ;
38-
39- /* Copy the wchar_t data into the new object */
40- {
41- register Py_UNICODE * u ;
42- u = PyUnicode_AS_UNICODE (unicode );
43- for (i = size ; i > 0 ; i -- ) {
44- if (* w > 0xFFFF ) {
45- cffi_char32_t ordinal ;
46- if (* w > 0x10FFFF ) {
47- PyErr_Format (PyExc_ValueError ,
48- "char32_t out of range for "
49- "conversion to unicode: 0x%x" , (int )* w );
50- Py_DECREF (unicode );
51- return NULL ;
52- }
53- ordinal = * w ++ ;
54- ordinal -= 0x10000 ;
55- * u ++ = 0xD800 | (ordinal >> 10 );
56- * u ++ = 0xDC00 | (ordinal & 0x3FF );
57- }
58- else
59- * u ++ = * w ++ ;
60- }
61- }
62- return unicode ;
63- }
64-
65- static PyObject *
66- _my_PyUnicode_FromChar16 (const cffi_char16_t * w , Py_ssize_t size )
67- {
68- return PyUnicode_FromUnicode ((const Py_UNICODE * )w , size );
69- }
70-
71- #else /* Py_UNICODE_SIZE == 4 */
72-
7312static PyObject *
7413_my_PyUnicode_FromChar32 (const cffi_char32_t * w , Py_ssize_t size )
7514{
76- return PyUnicode_FromUnicode (( const Py_UNICODE * ) w , size );
15+ return PyUnicode_FromKindAndData ( PyUnicode_4BYTE_KIND , w , size );
7716}
7817
7918static PyObject *
8019_my_PyUnicode_FromChar16 (const cffi_char16_t * w , Py_ssize_t size )
8120{
82- /* 'size' is the length of the 'w' array */
83- PyObject * result = PyUnicode_FromUnicode (NULL , size );
84-
85- if (result != NULL ) {
86- Py_UNICODE * u_base = PyUnicode_AS_UNICODE (result );
87- Py_UNICODE * u = u_base ;
88-
89- if (size == 1 ) { /* performance only */
90- * u = (cffi_char32_t )* w ;
91- }
92- else {
93- while (size > 0 ) {
94- cffi_char32_t ch = * w ++ ;
95- size -- ;
96- if (0xD800 <= ch && ch <= 0xDBFF && size > 0 ) {
97- cffi_char32_t ch2 = * w ;
98- if (0xDC00 <= ch2 && ch2 <= 0xDFFF ) {
99- ch = (((ch & 0x3FF )<<10 ) | (ch2 & 0x3FF )) + 0x10000 ;
100- w ++ ;
101- size -- ;
102- }
21+ /* are there any surrogate pairs, and if so, how many? */
22+ Py_ssize_t i , count_surrogates = 0 ;
23+ for (i = 0 ; i < size - 1 ; i ++ ) {
24+ if (0xD800 <= w [i ] && w [i ] <= 0xDBFF &&
25+ 0xDC00 <= w [i + 1 ] && w [i + 1 ] <= 0xDFFF )
26+ count_surrogates ++ ;
27+ }
28+ if (count_surrogates == 0 ) {
29+ /* no, fast path */
30+ return PyUnicode_FromKindAndData (PyUnicode_2BYTE_KIND , w , size );
31+ }
32+ else
33+ {
34+ PyObject * result = PyUnicode_New (size - count_surrogates , 0x10FFFF );
35+ Py_UCS4 * data ;
36+ assert (PyUnicode_KIND (result ) == PyUnicode_4BYTE_KIND );
37+ data = PyUnicode_4BYTE_DATA (result );
38+
39+ for (i = 0 ; i < size ; i ++ )
40+ {
41+ cffi_char32_t ch = w [i ];
42+ if (0xD800 <= ch && ch <= 0xDBFF && i < size - 1 ) {
43+ cffi_char32_t ch2 = w [i + 1 ];
44+ if (0xDC00 <= ch2 && ch2 <= 0xDFFF ) {
45+ ch = (((ch & 0x3FF )<<10 ) | (ch2 & 0x3FF )) + 0x10000 ;
46+ i ++ ;
10347 }
104- * u ++ = ch ;
105- }
106- if (PyUnicode_Resize (& result , u - u_base ) < 0 ) {
107- Py_DECREF (result );
108- return NULL ;
10948 }
49+ * data ++ = ch ;
11050 }
51+ return result ;
11152 }
112- return result ;
11353}
11454
115- #endif
116-
117-
118- #define IS_SURROGATE (u ) (0xD800 <= (u)[0] && (u)[0] <= 0xDBFF && \
119- 0xDC00 <= (u)[1] && (u)[1] <= 0xDFFF)
120- #define AS_SURROGATE (u ) (0x10000 + (((u)[0] - 0xD800) << 10) + \
121- ((u)[1] - 0xDC00))
122-
12355static int
12456_my_PyUnicode_AsSingleChar16 (PyObject * unicode , cffi_char16_t * result ,
12557 char * err_got )
12658{
127- Py_UNICODE * u = PyUnicode_AS_UNICODE ( unicode ) ;
128- if (PyUnicode_GET_SIZE (unicode ) != 1 ) {
59+ cffi_char32_t ch ;
60+ if (PyUnicode_GET_LENGTH (unicode ) != 1 ) {
12961 sprintf (err_got , "unicode string of length %zd" ,
130- PyUnicode_GET_SIZE (unicode ));
62+ PyUnicode_GET_LENGTH (unicode ));
13163 return -1 ;
13264 }
133- #if Py_UNICODE_SIZE == 4
134- if (((unsigned int )u [0 ]) > 0xFFFF )
65+ ch = PyUnicode_READ_CHAR (unicode , 0 );
66+
67+ if (ch > 0xFFFF )
13568 {
13669 sprintf (err_got , "larger-than-0xFFFF character" );
13770 return -1 ;
13871 }
139- #endif
140- * result = (cffi_char16_t )u [0 ];
72+ * result = (cffi_char16_t )ch ;
14173 return 0 ;
14274}
14375
14476static int
14577_my_PyUnicode_AsSingleChar32 (PyObject * unicode , cffi_char32_t * result ,
14678 char * err_got )
14779{
148- Py_UNICODE * u = PyUnicode_AS_UNICODE (unicode );
149- if (PyUnicode_GET_SIZE (unicode ) == 1 ) {
150- * result = (cffi_char32_t )u [0 ];
151- return 0 ;
152- }
153- #if Py_UNICODE_SIZE == 2
154- if (PyUnicode_GET_SIZE (unicode ) == 2 && IS_SURROGATE (u )) {
155- * result = AS_SURROGATE (u );
156- return 0 ;
80+ if (PyUnicode_GET_LENGTH (unicode ) != 1 ) {
81+ sprintf (err_got , "unicode string of length %zd" ,
82+ PyUnicode_GET_LENGTH (unicode ));
83+ return -1 ;
15784 }
158- #endif
159- sprintf (err_got , "unicode string of length %zd" ,
160- PyUnicode_GET_SIZE (unicode ));
161- return -1 ;
85+ * result = PyUnicode_READ_CHAR (unicode , 0 );
86+ return 0 ;
16287}
16388
16489static Py_ssize_t _my_PyUnicode_SizeAsChar16 (PyObject * unicode )
16590{
166- Py_ssize_t length = PyUnicode_GET_SIZE (unicode );
91+ Py_ssize_t length = PyUnicode_GET_LENGTH (unicode );
16792 Py_ssize_t result = length ;
93+ unsigned int kind = PyUnicode_KIND (unicode );
16894
169- #if Py_UNICODE_SIZE == 4
170- Py_UNICODE * u = PyUnicode_AS_UNICODE (unicode );
171- Py_ssize_t i ;
172-
173- for (i = 0 ; i < length ; i ++ ) {
174- if (u [i ] > 0xFFFF )
175- result ++ ;
95+ if (kind == PyUnicode_4BYTE_KIND )
96+ {
97+ Py_UCS4 * data = PyUnicode_4BYTE_DATA (unicode );
98+ Py_ssize_t i ;
99+ for (i = 0 ; i < length ; i ++ ) {
100+ if (data [i ] > 0xFFFF )
101+ result ++ ;
102+ }
176103 }
177- #endif
178104 return result ;
179105}
180106
181107static Py_ssize_t _my_PyUnicode_SizeAsChar32 (PyObject * unicode )
182108{
183- Py_ssize_t length = PyUnicode_GET_SIZE (unicode );
184- Py_ssize_t result = length ;
185-
186- #if Py_UNICODE_SIZE == 2
187- Py_UNICODE * u = PyUnicode_AS_UNICODE (unicode );
188- Py_ssize_t i ;
189-
190- for (i = 0 ; i < length - 1 ; i ++ ) {
191- if (IS_SURROGATE (u + i ))
192- result -- ;
193- }
194- #endif
195- return result ;
109+ return PyUnicode_GET_LENGTH (unicode );
196110}
197111
198112static int _my_PyUnicode_AsChar16 (PyObject * unicode ,
199113 cffi_char16_t * result ,
200114 Py_ssize_t resultlen )
201115{
202- Py_ssize_t len = PyUnicode_GET_SIZE (unicode );
203- Py_UNICODE * u = PyUnicode_AS_UNICODE (unicode );
116+ Py_ssize_t len = PyUnicode_GET_LENGTH (unicode );
117+ unsigned int kind = PyUnicode_KIND (unicode );
118+ void * data = PyUnicode_DATA (unicode );
204119 Py_ssize_t i ;
205- for (i = 0 ; i < len ; i ++ ) {
206- #if Py_UNICODE_SIZE == 2
207- cffi_char16_t ordinal = u [i ];
208- #else
209- cffi_char32_t ordinal = u [i ];
120+
121+ for (i = 0 ; i < len ; i ++ ) {
122+ cffi_char32_t ordinal = PyUnicode_READ (kind , data , i );
210123 if (ordinal > 0xFFFF ) {
211124 if (ordinal > 0x10FFFF ) {
212125 PyErr_Format (PyExc_ValueError ,
@@ -217,10 +130,9 @@ static int _my_PyUnicode_AsChar16(PyObject *unicode,
217130 ordinal -= 0x10000 ;
218131 * result ++ = 0xD800 | (ordinal >> 10 );
219132 * result ++ = 0xDC00 | (ordinal & 0x3FF );
220- continue ;
221133 }
222- #endif
223- * result ++ = ordinal ;
134+ else
135+ * result ++ = ordinal ;
224136 }
225137 return 0 ;
226138}
@@ -229,18 +141,7 @@ static int _my_PyUnicode_AsChar32(PyObject *unicode,
229141 cffi_char32_t * result ,
230142 Py_ssize_t resultlen )
231143{
232- Py_UNICODE * u = PyUnicode_AS_UNICODE (unicode );
233- Py_ssize_t i ;
234- for (i = 0 ; i < resultlen ; i ++ ) {
235- cffi_char32_t ordinal = * u ;
236- #if Py_UNICODE_SIZE == 2
237- if (IS_SURROGATE (u )) {
238- ordinal = AS_SURROGATE (u );
239- u ++ ;
240- }
241- #endif
242- result [i ] = ordinal ;
243- u ++ ;
244- }
144+ if (PyUnicode_AsUCS4 (unicode , (Py_UCS4 * )result , resultlen , 0 ) == NULL )
145+ return -1 ;
245146 return 0 ;
246147}
0 commit comments