• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &copy_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