1 #include <stddef.h> // ptrdiff_t
2
3 #include "parts.h"
4 #include "util.h"
5
6 /* Test PyUnicode_New() */
7 static PyObject *
unicode_new(PyObject * self,PyObject * args)8 unicode_new(PyObject *self, PyObject *args)
9 {
10 Py_ssize_t size;
11 unsigned int maxchar;
12 PyObject *result;
13
14 if (!PyArg_ParseTuple(args, "nI", &size, &maxchar)) {
15 return NULL;
16 }
17
18 result = PyUnicode_New(size, (Py_UCS4)maxchar);
19 if (!result) {
20 return NULL;
21 }
22 if (size > 0 && maxchar <= 0x10ffff &&
23 PyUnicode_Fill(result, 0, size, (Py_UCS4)maxchar) < 0)
24 {
25 Py_DECREF(result);
26 return NULL;
27 }
28 return result;
29 }
30
31
32 static PyObject *
unicode_copy(PyObject * unicode)33 unicode_copy(PyObject *unicode)
34 {
35 PyObject *copy;
36
37 if (!unicode) {
38 return NULL;
39 }
40 if (!PyUnicode_Check(unicode)) {
41 Py_INCREF(unicode);
42 return unicode;
43 }
44
45 copy = PyUnicode_New(PyUnicode_GET_LENGTH(unicode),
46 PyUnicode_MAX_CHAR_VALUE(unicode));
47 if (!copy) {
48 return NULL;
49 }
50 if (PyUnicode_CopyCharacters(copy, 0, unicode,
51 0, PyUnicode_GET_LENGTH(unicode)) < 0)
52 {
53 Py_DECREF(copy);
54 return NULL;
55 }
56 return copy;
57 }
58
59
60 /* Test PyUnicode_Fill() */
61 static PyObject *
unicode_fill(PyObject * self,PyObject * args)62 unicode_fill(PyObject *self, PyObject *args)
63 {
64 PyObject *to, *to_copy;
65 Py_ssize_t start, length, filled;
66 unsigned int fill_char;
67
68 if (!PyArg_ParseTuple(args, "OnnI", &to, &start, &length, &fill_char)) {
69 return NULL;
70 }
71
72 NULLABLE(to);
73 if (!(to_copy = unicode_copy(to)) && to) {
74 return NULL;
75 }
76
77 filled = PyUnicode_Fill(to_copy, start, length, (Py_UCS4)fill_char);
78 if (filled == -1 && PyErr_Occurred()) {
79 Py_DECREF(to_copy);
80 return NULL;
81 }
82 return Py_BuildValue("(Nn)", to_copy, filled);
83 }
84
85
86 /* Test PyUnicode_FromKindAndData() */
87 static PyObject *
unicode_fromkindanddata(PyObject * self,PyObject * args)88 unicode_fromkindanddata(PyObject *self, PyObject *args)
89 {
90 int kind;
91 void *buffer;
92 Py_ssize_t bsize;
93 Py_ssize_t size = -100;
94
95 if (!PyArg_ParseTuple(args, "iz#|n", &kind, &buffer, &bsize, &size)) {
96 return NULL;
97 }
98
99 if (size == -100) {
100 size = bsize;
101 }
102 if (kind && size % kind) {
103 PyErr_SetString(PyExc_AssertionError,
104 "invalid size in unicode_fromkindanddata()");
105 return NULL;
106 }
107 return PyUnicode_FromKindAndData(kind, buffer, kind ? size / kind : 0);
108 }
109
110
111 // Test PyUnicode_AsUCS4().
112 // Part of the limited C API, but the test needs PyUnicode_FromKindAndData().
113 static PyObject *
unicode_asucs4(PyObject * self,PyObject * args)114 unicode_asucs4(PyObject *self, PyObject *args)
115 {
116 PyObject *unicode, *result;
117 Py_UCS4 *buffer;
118 int copy_null;
119 Py_ssize_t str_len, buf_len;
120
121 if (!PyArg_ParseTuple(args, "Onp:unicode_asucs4", &unicode, &str_len, ©_null)) {
122 return NULL;
123 }
124
125 NULLABLE(unicode);
126 buf_len = str_len + 1;
127 buffer = PyMem_NEW(Py_UCS4, buf_len);
128 if (buffer == NULL) {
129 return PyErr_NoMemory();
130 }
131 memset(buffer, 0, sizeof(Py_UCS4)*buf_len);
132 buffer[str_len] = 0xffffU;
133
134 if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) {
135 PyMem_Free(buffer);
136 return NULL;
137 }
138
139 result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len);
140 PyMem_Free(buffer);
141 return result;
142 }
143
144
145 // Test PyUnicode_AsUCS4Copy().
146 // Part of the limited C API, but the test needs PyUnicode_FromKindAndData().
147 static PyObject *
unicode_asucs4copy(PyObject * self,PyObject * args)148 unicode_asucs4copy(PyObject *self, PyObject *args)
149 {
150 PyObject *unicode;
151 Py_UCS4 *buffer;
152 PyObject *result;
153
154 if (!PyArg_ParseTuple(args, "O", &unicode)) {
155 return NULL;
156 }
157
158 NULLABLE(unicode);
159 buffer = PyUnicode_AsUCS4Copy(unicode);
160 if (buffer == NULL) {
161 return NULL;
162 }
163 result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
164 buffer,
165 PyUnicode_GET_LENGTH(unicode) + 1);
166 PyMem_FREE(buffer);
167 return result;
168 }
169
170
171 /* Test PyUnicode_AsUTF8() */
172 static PyObject *
unicode_asutf8(PyObject * self,PyObject * args)173 unicode_asutf8(PyObject *self, PyObject *args)
174 {
175 PyObject *unicode;
176 Py_ssize_t buflen;
177 const char *s;
178
179 if (!PyArg_ParseTuple(args, "On", &unicode, &buflen))
180 return NULL;
181
182 NULLABLE(unicode);
183 s = PyUnicode_AsUTF8(unicode);
184 if (s == NULL)
185 return NULL;
186
187 return PyBytes_FromStringAndSize(s, buflen);
188 }
189
190
191 /* Test PyUnicode_CopyCharacters() */
192 static PyObject *
unicode_copycharacters(PyObject * self,PyObject * args)193 unicode_copycharacters(PyObject *self, PyObject *args)
194 {
195 PyObject *from, *to, *to_copy;
196 Py_ssize_t from_start, to_start, how_many, copied;
197
198 if (!PyArg_ParseTuple(args, "UnOnn", &to, &to_start,
199 &from, &from_start, &how_many)) {
200 return NULL;
201 }
202
203 NULLABLE(from);
204 if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to),
205 PyUnicode_MAX_CHAR_VALUE(to)))) {
206 return NULL;
207 }
208 if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) {
209 Py_DECREF(to_copy);
210 return NULL;
211 }
212
213 copied = PyUnicode_CopyCharacters(to_copy, to_start, from,
214 from_start, how_many);
215 if (copied == -1 && PyErr_Occurred()) {
216 Py_DECREF(to_copy);
217 return NULL;
218 }
219
220 return Py_BuildValue("(Nn)", to_copy, copied);
221 }
222
223
224 static PyMethodDef TestMethods[] = {
225 {"unicode_new", unicode_new, METH_VARARGS},
226 {"unicode_fill", unicode_fill, METH_VARARGS},
227 {"unicode_fromkindanddata", unicode_fromkindanddata, METH_VARARGS},
228 {"unicode_asucs4", unicode_asucs4, METH_VARARGS},
229 {"unicode_asucs4copy", unicode_asucs4copy, METH_VARARGS},
230 {"unicode_asutf8", unicode_asutf8, METH_VARARGS},
231 {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS},
232 {NULL},
233 };
234
235 int
_PyTestCapi_Init_Unicode(PyObject * m)236 _PyTestCapi_Init_Unicode(PyObject *m) {
237 if (PyModule_AddFunctions(m, TestMethods) < 0) {
238 return -1;
239 }
240 return 0;
241 }
242