/src/cpython/Objects/clinic/bytesobject.c.h
Line | Count | Source |
1 | | /*[clinic input] |
2 | | preserve |
3 | | [clinic start generated code]*/ |
4 | | |
5 | | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
6 | | # include "pycore_gc.h" // PyGC_Head |
7 | | # include "pycore_runtime.h" // _Py_ID() |
8 | | #endif |
9 | | #include "pycore_abstract.h" // _PyNumber_Index() |
10 | | #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() |
11 | | |
12 | | PyDoc_STRVAR(bytes___bytes____doc__, |
13 | | "__bytes__($self, /)\n" |
14 | | "--\n" |
15 | | "\n" |
16 | | "Convert this value to exact type bytes."); |
17 | | |
18 | | #define BYTES___BYTES___METHODDEF \ |
19 | | {"__bytes__", (PyCFunction)bytes___bytes__, METH_NOARGS, bytes___bytes____doc__}, |
20 | | |
21 | | static PyObject * |
22 | | bytes___bytes___impl(PyBytesObject *self); |
23 | | |
24 | | static PyObject * |
25 | | bytes___bytes__(PyObject *self, PyObject *Py_UNUSED(ignored)) |
26 | 53.1k | { |
27 | 53.1k | return bytes___bytes___impl((PyBytesObject *)self); |
28 | 53.1k | } |
29 | | |
30 | | PyDoc_STRVAR(bytes_split__doc__, |
31 | | "split($self, /, sep=None, maxsplit=-1)\n" |
32 | | "--\n" |
33 | | "\n" |
34 | | "Return a list of the sections in the bytes, using sep as the delimiter.\n" |
35 | | "\n" |
36 | | " sep\n" |
37 | | " The delimiter according which to split the bytes.\n" |
38 | | " None (the default value) means split on ASCII whitespace\n" |
39 | | " characters (space, tab, return, newline, formfeed, vertical tab).\n" |
40 | | " maxsplit\n" |
41 | | " Maximum number of splits to do.\n" |
42 | | " -1 (the default value) means no limit."); |
43 | | |
44 | | #define BYTES_SPLIT_METHODDEF \ |
45 | | {"split", _PyCFunction_CAST(bytes_split), METH_FASTCALL|METH_KEYWORDS, bytes_split__doc__}, |
46 | | |
47 | | static PyObject * |
48 | | bytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); |
49 | | |
50 | | static PyObject * |
51 | | bytes_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
52 | 3.01M | { |
53 | 3.01M | PyObject *return_value = NULL; |
54 | 3.01M | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
55 | | |
56 | 3.01M | #define NUM_KEYWORDS 2 |
57 | 3.01M | static struct { |
58 | 3.01M | PyGC_Head _this_is_not_used; |
59 | 3.01M | PyObject_VAR_HEAD |
60 | 3.01M | Py_hash_t ob_hash; |
61 | 3.01M | PyObject *ob_item[NUM_KEYWORDS]; |
62 | 3.01M | } _kwtuple = { |
63 | 3.01M | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
64 | 3.01M | .ob_hash = -1, |
65 | 3.01M | .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, |
66 | 3.01M | }; |
67 | 3.01M | #undef NUM_KEYWORDS |
68 | 3.01M | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
69 | | |
70 | | #else // !Py_BUILD_CORE |
71 | | # define KWTUPLE NULL |
72 | | #endif // !Py_BUILD_CORE |
73 | | |
74 | 3.01M | static const char * const _keywords[] = {"sep", "maxsplit", NULL}; |
75 | 3.01M | static _PyArg_Parser _parser = { |
76 | 3.01M | .keywords = _keywords, |
77 | 3.01M | .fname = "split", |
78 | 3.01M | .kwtuple = KWTUPLE, |
79 | 3.01M | }; |
80 | 3.01M | #undef KWTUPLE |
81 | 3.01M | PyObject *argsbuf[2]; |
82 | 3.01M | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; |
83 | 3.01M | PyObject *sep = Py_None; |
84 | 3.01M | Py_ssize_t maxsplit = -1; |
85 | | |
86 | 3.01M | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
87 | 3.01M | /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
88 | 3.01M | if (!args) { |
89 | 0 | goto exit; |
90 | 0 | } |
91 | 3.01M | if (!noptargs) { |
92 | 0 | goto skip_optional_pos; |
93 | 0 | } |
94 | 3.01M | if (args[0]) { |
95 | 3.01M | sep = args[0]; |
96 | 3.01M | if (!--noptargs) { |
97 | 3.01M | goto skip_optional_pos; |
98 | 3.01M | } |
99 | 3.01M | } |
100 | 0 | { |
101 | 0 | Py_ssize_t ival = -1; |
102 | 0 | PyObject *iobj = _PyNumber_Index(args[1]); |
103 | 0 | if (iobj != NULL) { |
104 | 0 | ival = PyLong_AsSsize_t(iobj); |
105 | 0 | Py_DECREF(iobj); |
106 | 0 | } |
107 | 0 | if (ival == -1 && PyErr_Occurred()) { |
108 | 0 | goto exit; |
109 | 0 | } |
110 | 0 | maxsplit = ival; |
111 | 0 | } |
112 | 3.01M | skip_optional_pos: |
113 | 3.01M | return_value = bytes_split_impl((PyBytesObject *)self, sep, maxsplit); |
114 | | |
115 | 3.01M | exit: |
116 | 3.01M | return return_value; |
117 | 3.01M | } |
118 | | |
119 | | PyDoc_STRVAR(bytes_partition__doc__, |
120 | | "partition($self, sep, /)\n" |
121 | | "--\n" |
122 | | "\n" |
123 | | "Partition the bytes into three parts using the given separator.\n" |
124 | | "\n" |
125 | | "This will search for the separator sep in the bytes. If the\n" |
126 | | "separator is found, returns a 3-tuple containing the part before the\n" |
127 | | "separator, the separator itself, and the part after it.\n" |
128 | | "\n" |
129 | | "If the separator is not found, returns a 3-tuple containing the\n" |
130 | | "original bytes object and two empty bytes objects."); |
131 | | |
132 | | #define BYTES_PARTITION_METHODDEF \ |
133 | | {"partition", (PyCFunction)bytes_partition, METH_O, bytes_partition__doc__}, |
134 | | |
135 | | static PyObject * |
136 | | bytes_partition_impl(PyBytesObject *self, Py_buffer *sep); |
137 | | |
138 | | static PyObject * |
139 | | bytes_partition(PyObject *self, PyObject *arg) |
140 | 380k | { |
141 | 380k | PyObject *return_value = NULL; |
142 | 380k | Py_buffer sep = {NULL, NULL}; |
143 | | |
144 | 380k | if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { |
145 | 0 | goto exit; |
146 | 0 | } |
147 | 380k | return_value = bytes_partition_impl((PyBytesObject *)self, &sep); |
148 | | |
149 | 380k | exit: |
150 | | /* Cleanup for sep */ |
151 | 380k | if (sep.obj) { |
152 | 380k | PyBuffer_Release(&sep); |
153 | 380k | } |
154 | | |
155 | 380k | return return_value; |
156 | 380k | } |
157 | | |
158 | | PyDoc_STRVAR(bytes_rpartition__doc__, |
159 | | "rpartition($self, sep, /)\n" |
160 | | "--\n" |
161 | | "\n" |
162 | | "Partition the bytes into three parts using the given separator.\n" |
163 | | "\n" |
164 | | "This will search for the separator sep in the bytes, starting at the\n" |
165 | | "end. If the separator is found, returns a 3-tuple containing the\n" |
166 | | "part before the separator, the separator itself, and the part after\n" |
167 | | "it.\n" |
168 | | "\n" |
169 | | "If the separator is not found, returns a 3-tuple containing two\n" |
170 | | "empty bytes objects and the original bytes object."); |
171 | | |
172 | | #define BYTES_RPARTITION_METHODDEF \ |
173 | | {"rpartition", (PyCFunction)bytes_rpartition, METH_O, bytes_rpartition__doc__}, |
174 | | |
175 | | static PyObject * |
176 | | bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep); |
177 | | |
178 | | static PyObject * |
179 | | bytes_rpartition(PyObject *self, PyObject *arg) |
180 | 0 | { |
181 | 0 | PyObject *return_value = NULL; |
182 | 0 | Py_buffer sep = {NULL, NULL}; |
183 | |
|
184 | 0 | if (PyObject_GetBuffer(arg, &sep, PyBUF_SIMPLE) != 0) { |
185 | 0 | goto exit; |
186 | 0 | } |
187 | 0 | return_value = bytes_rpartition_impl((PyBytesObject *)self, &sep); |
188 | |
|
189 | 0 | exit: |
190 | | /* Cleanup for sep */ |
191 | 0 | if (sep.obj) { |
192 | 0 | PyBuffer_Release(&sep); |
193 | 0 | } |
194 | |
|
195 | 0 | return return_value; |
196 | 0 | } |
197 | | |
198 | | PyDoc_STRVAR(bytes_rsplit__doc__, |
199 | | "rsplit($self, /, sep=None, maxsplit=-1)\n" |
200 | | "--\n" |
201 | | "\n" |
202 | | "Return a list of the sections in the bytes, using sep as the delimiter.\n" |
203 | | "\n" |
204 | | " sep\n" |
205 | | " The delimiter according which to split the bytes.\n" |
206 | | " None (the default value) means split on ASCII whitespace\n" |
207 | | " characters (space, tab, return, newline, formfeed, vertical tab).\n" |
208 | | " maxsplit\n" |
209 | | " Maximum number of splits to do.\n" |
210 | | " -1 (the default value) means no limit.\n" |
211 | | "\n" |
212 | | "Splitting is done starting at the end of the bytes and working to\n" |
213 | | "the front."); |
214 | | |
215 | | #define BYTES_RSPLIT_METHODDEF \ |
216 | | {"rsplit", _PyCFunction_CAST(bytes_rsplit), METH_FASTCALL|METH_KEYWORDS, bytes_rsplit__doc__}, |
217 | | |
218 | | static PyObject * |
219 | | bytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit); |
220 | | |
221 | | static PyObject * |
222 | | bytes_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
223 | 0 | { |
224 | 0 | PyObject *return_value = NULL; |
225 | 0 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
226 | |
|
227 | 0 | #define NUM_KEYWORDS 2 |
228 | 0 | static struct { |
229 | 0 | PyGC_Head _this_is_not_used; |
230 | 0 | PyObject_VAR_HEAD |
231 | 0 | Py_hash_t ob_hash; |
232 | 0 | PyObject *ob_item[NUM_KEYWORDS]; |
233 | 0 | } _kwtuple = { |
234 | 0 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
235 | 0 | .ob_hash = -1, |
236 | 0 | .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, |
237 | 0 | }; |
238 | 0 | #undef NUM_KEYWORDS |
239 | 0 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
240 | |
|
241 | | #else // !Py_BUILD_CORE |
242 | | # define KWTUPLE NULL |
243 | | #endif // !Py_BUILD_CORE |
244 | |
|
245 | 0 | static const char * const _keywords[] = {"sep", "maxsplit", NULL}; |
246 | 0 | static _PyArg_Parser _parser = { |
247 | 0 | .keywords = _keywords, |
248 | 0 | .fname = "rsplit", |
249 | 0 | .kwtuple = KWTUPLE, |
250 | 0 | }; |
251 | 0 | #undef KWTUPLE |
252 | 0 | PyObject *argsbuf[2]; |
253 | 0 | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; |
254 | 0 | PyObject *sep = Py_None; |
255 | 0 | Py_ssize_t maxsplit = -1; |
256 | |
|
257 | 0 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
258 | 0 | /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
259 | 0 | if (!args) { |
260 | 0 | goto exit; |
261 | 0 | } |
262 | 0 | if (!noptargs) { |
263 | 0 | goto skip_optional_pos; |
264 | 0 | } |
265 | 0 | if (args[0]) { |
266 | 0 | sep = args[0]; |
267 | 0 | if (!--noptargs) { |
268 | 0 | goto skip_optional_pos; |
269 | 0 | } |
270 | 0 | } |
271 | 0 | { |
272 | 0 | Py_ssize_t ival = -1; |
273 | 0 | PyObject *iobj = _PyNumber_Index(args[1]); |
274 | 0 | if (iobj != NULL) { |
275 | 0 | ival = PyLong_AsSsize_t(iobj); |
276 | 0 | Py_DECREF(iobj); |
277 | 0 | } |
278 | 0 | if (ival == -1 && PyErr_Occurred()) { |
279 | 0 | goto exit; |
280 | 0 | } |
281 | 0 | maxsplit = ival; |
282 | 0 | } |
283 | 0 | skip_optional_pos: |
284 | 0 | return_value = bytes_rsplit_impl((PyBytesObject *)self, sep, maxsplit); |
285 | |
|
286 | 0 | exit: |
287 | 0 | return return_value; |
288 | 0 | } |
289 | | |
290 | | PyDoc_STRVAR(bytes_join__doc__, |
291 | | "join($self, iterable_of_bytes, /)\n" |
292 | | "--\n" |
293 | | "\n" |
294 | | "Concatenate any number of bytes objects.\n" |
295 | | "\n" |
296 | | "The bytes whose method is called is inserted in between each pair.\n" |
297 | | "\n" |
298 | | "The result is returned as a new bytes object.\n" |
299 | | "\n" |
300 | | "Example: b\'.\'.join([b\'ab\', b\'pq\', b\'rs\']) -> b\'ab.pq.rs\'."); |
301 | | |
302 | | #define BYTES_JOIN_METHODDEF \ |
303 | | {"join", (PyCFunction)bytes_join, METH_O, bytes_join__doc__}, |
304 | | |
305 | | static PyObject * |
306 | | bytes_join_impl(PyBytesObject *self, PyObject *iterable_of_bytes); |
307 | | |
308 | | static PyObject * |
309 | | bytes_join(PyObject *self, PyObject *iterable_of_bytes) |
310 | 260k | { |
311 | 260k | PyObject *return_value = NULL; |
312 | | |
313 | 260k | return_value = bytes_join_impl((PyBytesObject *)self, iterable_of_bytes); |
314 | | |
315 | 260k | return return_value; |
316 | 260k | } |
317 | | |
318 | | PyDoc_STRVAR(bytes_find__doc__, |
319 | | "find($self, sub[, start[, end]], /)\n" |
320 | | "--\n" |
321 | | "\n" |
322 | | "Return the lowest index in B where subsection \'sub\' is found, such that \'sub\' is contained within B[start,end].\n" |
323 | | "\n" |
324 | | " start\n" |
325 | | " Optional start position. Default: start of the bytes.\n" |
326 | | " end\n" |
327 | | " Optional stop position. Default: end of the bytes.\n" |
328 | | "\n" |
329 | | "Return -1 on failure."); |
330 | | |
331 | | #define BYTES_FIND_METHODDEF \ |
332 | | {"find", _PyCFunction_CAST(bytes_find), METH_FASTCALL, bytes_find__doc__}, |
333 | | |
334 | | static PyObject * |
335 | | bytes_find_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start, |
336 | | Py_ssize_t end); |
337 | | |
338 | | static PyObject * |
339 | | bytes_find(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
340 | 13.4M | { |
341 | 13.4M | PyObject *return_value = NULL; |
342 | 13.4M | PyObject *sub; |
343 | 13.4M | Py_ssize_t start = 0; |
344 | 13.4M | Py_ssize_t end = PY_SSIZE_T_MAX; |
345 | | |
346 | 13.4M | if (!_PyArg_CheckPositional("find", nargs, 1, 3)) { |
347 | 0 | goto exit; |
348 | 0 | } |
349 | 13.4M | sub = args[0]; |
350 | 13.4M | if (nargs < 2) { |
351 | 13.4M | goto skip_optional; |
352 | 13.4M | } |
353 | 32.1k | if (!_PyEval_SliceIndex(args[1], &start)) { |
354 | 0 | goto exit; |
355 | 0 | } |
356 | 32.1k | if (nargs < 3) { |
357 | 32.1k | goto skip_optional; |
358 | 32.1k | } |
359 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
360 | 0 | goto exit; |
361 | 0 | } |
362 | 13.4M | skip_optional: |
363 | 13.4M | return_value = bytes_find_impl((PyBytesObject *)self, sub, start, end); |
364 | | |
365 | 13.4M | exit: |
366 | 13.4M | return return_value; |
367 | 13.4M | } |
368 | | |
369 | | PyDoc_STRVAR(bytes_index__doc__, |
370 | | "index($self, sub[, start[, end]], /)\n" |
371 | | "--\n" |
372 | | "\n" |
373 | | "Return the lowest index in B where subsection \'sub\' is found, such that \'sub\' is contained within B[start,end].\n" |
374 | | "\n" |
375 | | " start\n" |
376 | | " Optional start position. Default: start of the bytes.\n" |
377 | | " end\n" |
378 | | " Optional stop position. Default: end of the bytes.\n" |
379 | | "\n" |
380 | | "Raise ValueError if the subsection is not found."); |
381 | | |
382 | | #define BYTES_INDEX_METHODDEF \ |
383 | | {"index", _PyCFunction_CAST(bytes_index), METH_FASTCALL, bytes_index__doc__}, |
384 | | |
385 | | static PyObject * |
386 | | bytes_index_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start, |
387 | | Py_ssize_t end); |
388 | | |
389 | | static PyObject * |
390 | | bytes_index(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
391 | 0 | { |
392 | 0 | PyObject *return_value = NULL; |
393 | 0 | PyObject *sub; |
394 | 0 | Py_ssize_t start = 0; |
395 | 0 | Py_ssize_t end = PY_SSIZE_T_MAX; |
396 | |
|
397 | 0 | if (!_PyArg_CheckPositional("index", nargs, 1, 3)) { |
398 | 0 | goto exit; |
399 | 0 | } |
400 | 0 | sub = args[0]; |
401 | 0 | if (nargs < 2) { |
402 | 0 | goto skip_optional; |
403 | 0 | } |
404 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
405 | 0 | goto exit; |
406 | 0 | } |
407 | 0 | if (nargs < 3) { |
408 | 0 | goto skip_optional; |
409 | 0 | } |
410 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
411 | 0 | goto exit; |
412 | 0 | } |
413 | 0 | skip_optional: |
414 | 0 | return_value = bytes_index_impl((PyBytesObject *)self, sub, start, end); |
415 | |
|
416 | 0 | exit: |
417 | 0 | return return_value; |
418 | 0 | } |
419 | | |
420 | | PyDoc_STRVAR(bytes_rfind__doc__, |
421 | | "rfind($self, sub[, start[, end]], /)\n" |
422 | | "--\n" |
423 | | "\n" |
424 | | "Return the highest index in B where subsection \'sub\' is found, such that \'sub\' is contained within B[start,end].\n" |
425 | | "\n" |
426 | | " start\n" |
427 | | " Optional start position. Default: start of the bytes.\n" |
428 | | " end\n" |
429 | | " Optional stop position. Default: end of the bytes.\n" |
430 | | "\n" |
431 | | "Return -1 on failure."); |
432 | | |
433 | | #define BYTES_RFIND_METHODDEF \ |
434 | | {"rfind", _PyCFunction_CAST(bytes_rfind), METH_FASTCALL, bytes_rfind__doc__}, |
435 | | |
436 | | static PyObject * |
437 | | bytes_rfind_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start, |
438 | | Py_ssize_t end); |
439 | | |
440 | | static PyObject * |
441 | | bytes_rfind(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
442 | 278k | { |
443 | 278k | PyObject *return_value = NULL; |
444 | 278k | PyObject *sub; |
445 | 278k | Py_ssize_t start = 0; |
446 | 278k | Py_ssize_t end = PY_SSIZE_T_MAX; |
447 | | |
448 | 278k | if (!_PyArg_CheckPositional("rfind", nargs, 1, 3)) { |
449 | 0 | goto exit; |
450 | 0 | } |
451 | 278k | sub = args[0]; |
452 | 278k | if (nargs < 2) { |
453 | 278k | goto skip_optional; |
454 | 278k | } |
455 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
456 | 0 | goto exit; |
457 | 0 | } |
458 | 0 | if (nargs < 3) { |
459 | 0 | goto skip_optional; |
460 | 0 | } |
461 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
462 | 0 | goto exit; |
463 | 0 | } |
464 | 278k | skip_optional: |
465 | 278k | return_value = bytes_rfind_impl((PyBytesObject *)self, sub, start, end); |
466 | | |
467 | 278k | exit: |
468 | 278k | return return_value; |
469 | 278k | } |
470 | | |
471 | | PyDoc_STRVAR(bytes_rindex__doc__, |
472 | | "rindex($self, sub[, start[, end]], /)\n" |
473 | | "--\n" |
474 | | "\n" |
475 | | "Return the highest index in B where subsection \'sub\' is found, such that \'sub\' is contained within B[start,end].\n" |
476 | | "\n" |
477 | | " start\n" |
478 | | " Optional start position. Default: start of the bytes.\n" |
479 | | " end\n" |
480 | | " Optional stop position. Default: end of the bytes.\n" |
481 | | "\n" |
482 | | "Raise ValueError if the subsection is not found."); |
483 | | |
484 | | #define BYTES_RINDEX_METHODDEF \ |
485 | | {"rindex", _PyCFunction_CAST(bytes_rindex), METH_FASTCALL, bytes_rindex__doc__}, |
486 | | |
487 | | static PyObject * |
488 | | bytes_rindex_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start, |
489 | | Py_ssize_t end); |
490 | | |
491 | | static PyObject * |
492 | | bytes_rindex(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
493 | 0 | { |
494 | 0 | PyObject *return_value = NULL; |
495 | 0 | PyObject *sub; |
496 | 0 | Py_ssize_t start = 0; |
497 | 0 | Py_ssize_t end = PY_SSIZE_T_MAX; |
498 | |
|
499 | 0 | if (!_PyArg_CheckPositional("rindex", nargs, 1, 3)) { |
500 | 0 | goto exit; |
501 | 0 | } |
502 | 0 | sub = args[0]; |
503 | 0 | if (nargs < 2) { |
504 | 0 | goto skip_optional; |
505 | 0 | } |
506 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
507 | 0 | goto exit; |
508 | 0 | } |
509 | 0 | if (nargs < 3) { |
510 | 0 | goto skip_optional; |
511 | 0 | } |
512 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
513 | 0 | goto exit; |
514 | 0 | } |
515 | 0 | skip_optional: |
516 | 0 | return_value = bytes_rindex_impl((PyBytesObject *)self, sub, start, end); |
517 | |
|
518 | 0 | exit: |
519 | 0 | return return_value; |
520 | 0 | } |
521 | | |
522 | | PyDoc_STRVAR(bytes_strip__doc__, |
523 | | "strip($self, bytes=None, /)\n" |
524 | | "--\n" |
525 | | "\n" |
526 | | "Strip leading and trailing bytes contained in the argument.\n" |
527 | | "\n" |
528 | | "If the argument is omitted or None, strip leading and trailing ASCII\n" |
529 | | "whitespace."); |
530 | | |
531 | | #define BYTES_STRIP_METHODDEF \ |
532 | | {"strip", _PyCFunction_CAST(bytes_strip), METH_FASTCALL, bytes_strip__doc__}, |
533 | | |
534 | | static PyObject * |
535 | | bytes_strip_impl(PyBytesObject *self, PyObject *bytes); |
536 | | |
537 | | static PyObject * |
538 | | bytes_strip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
539 | 0 | { |
540 | 0 | PyObject *return_value = NULL; |
541 | 0 | PyObject *bytes = Py_None; |
542 | |
|
543 | 0 | if (!_PyArg_CheckPositional("strip", nargs, 0, 1)) { |
544 | 0 | goto exit; |
545 | 0 | } |
546 | 0 | if (nargs < 1) { |
547 | 0 | goto skip_optional; |
548 | 0 | } |
549 | 0 | bytes = args[0]; |
550 | 0 | skip_optional: |
551 | 0 | return_value = bytes_strip_impl((PyBytesObject *)self, bytes); |
552 | |
|
553 | 0 | exit: |
554 | 0 | return return_value; |
555 | 0 | } |
556 | | |
557 | | PyDoc_STRVAR(bytes_lstrip__doc__, |
558 | | "lstrip($self, bytes=None, /)\n" |
559 | | "--\n" |
560 | | "\n" |
561 | | "Strip leading bytes contained in the argument.\n" |
562 | | "\n" |
563 | | "If the argument is omitted or None, strip leading ASCII whitespace."); |
564 | | |
565 | | #define BYTES_LSTRIP_METHODDEF \ |
566 | | {"lstrip", _PyCFunction_CAST(bytes_lstrip), METH_FASTCALL, bytes_lstrip__doc__}, |
567 | | |
568 | | static PyObject * |
569 | | bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); |
570 | | |
571 | | static PyObject * |
572 | | bytes_lstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
573 | 0 | { |
574 | 0 | PyObject *return_value = NULL; |
575 | 0 | PyObject *bytes = Py_None; |
576 | |
|
577 | 0 | if (!_PyArg_CheckPositional("lstrip", nargs, 0, 1)) { |
578 | 0 | goto exit; |
579 | 0 | } |
580 | 0 | if (nargs < 1) { |
581 | 0 | goto skip_optional; |
582 | 0 | } |
583 | 0 | bytes = args[0]; |
584 | 0 | skip_optional: |
585 | 0 | return_value = bytes_lstrip_impl((PyBytesObject *)self, bytes); |
586 | |
|
587 | 0 | exit: |
588 | 0 | return return_value; |
589 | 0 | } |
590 | | |
591 | | PyDoc_STRVAR(bytes_rstrip__doc__, |
592 | | "rstrip($self, bytes=None, /)\n" |
593 | | "--\n" |
594 | | "\n" |
595 | | "Strip trailing bytes contained in the argument.\n" |
596 | | "\n" |
597 | | "If the argument is omitted or None, strip trailing ASCII whitespace."); |
598 | | |
599 | | #define BYTES_RSTRIP_METHODDEF \ |
600 | | {"rstrip", _PyCFunction_CAST(bytes_rstrip), METH_FASTCALL, bytes_rstrip__doc__}, |
601 | | |
602 | | static PyObject * |
603 | | bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); |
604 | | |
605 | | static PyObject * |
606 | | bytes_rstrip(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
607 | 294 | { |
608 | 294 | PyObject *return_value = NULL; |
609 | 294 | PyObject *bytes = Py_None; |
610 | | |
611 | 294 | if (!_PyArg_CheckPositional("rstrip", nargs, 0, 1)) { |
612 | 0 | goto exit; |
613 | 0 | } |
614 | 294 | if (nargs < 1) { |
615 | 0 | goto skip_optional; |
616 | 0 | } |
617 | 294 | bytes = args[0]; |
618 | 294 | skip_optional: |
619 | 294 | return_value = bytes_rstrip_impl((PyBytesObject *)self, bytes); |
620 | | |
621 | 294 | exit: |
622 | 294 | return return_value; |
623 | 294 | } |
624 | | |
625 | | PyDoc_STRVAR(bytes_count__doc__, |
626 | | "count($self, sub[, start[, end]], /)\n" |
627 | | "--\n" |
628 | | "\n" |
629 | | "Return the number of non-overlapping occurrences of subsection \'sub\' in bytes B[start:end].\n" |
630 | | "\n" |
631 | | " start\n" |
632 | | " Optional start position. Default: start of the bytes.\n" |
633 | | " end\n" |
634 | | " Optional stop position. Default: end of the bytes."); |
635 | | |
636 | | #define BYTES_COUNT_METHODDEF \ |
637 | | {"count", _PyCFunction_CAST(bytes_count), METH_FASTCALL, bytes_count__doc__}, |
638 | | |
639 | | static PyObject * |
640 | | bytes_count_impl(PyBytesObject *self, PyObject *sub, Py_ssize_t start, |
641 | | Py_ssize_t end); |
642 | | |
643 | | static PyObject * |
644 | | bytes_count(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
645 | 5.70M | { |
646 | 5.70M | PyObject *return_value = NULL; |
647 | 5.70M | PyObject *sub; |
648 | 5.70M | Py_ssize_t start = 0; |
649 | 5.70M | Py_ssize_t end = PY_SSIZE_T_MAX; |
650 | | |
651 | 5.70M | if (!_PyArg_CheckPositional("count", nargs, 1, 3)) { |
652 | 0 | goto exit; |
653 | 0 | } |
654 | 5.70M | sub = args[0]; |
655 | 5.70M | if (nargs < 2) { |
656 | 5.70M | goto skip_optional; |
657 | 5.70M | } |
658 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
659 | 0 | goto exit; |
660 | 0 | } |
661 | 0 | if (nargs < 3) { |
662 | 0 | goto skip_optional; |
663 | 0 | } |
664 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
665 | 0 | goto exit; |
666 | 0 | } |
667 | 5.70M | skip_optional: |
668 | 5.70M | return_value = bytes_count_impl((PyBytesObject *)self, sub, start, end); |
669 | | |
670 | 5.70M | exit: |
671 | 5.70M | return return_value; |
672 | 5.70M | } |
673 | | |
674 | | PyDoc_STRVAR(bytes_translate__doc__, |
675 | | "translate($self, table, /, delete=b\'\')\n" |
676 | | "--\n" |
677 | | "\n" |
678 | | "Return a copy with each character mapped by the given translation table.\n" |
679 | | "\n" |
680 | | " table\n" |
681 | | " Translation table, which must be a bytes object of length 256.\n" |
682 | | "\n" |
683 | | "All characters occurring in the optional argument delete are\n" |
684 | | "removed. The remaining characters are mapped through the given\n" |
685 | | "translation table."); |
686 | | |
687 | | #define BYTES_TRANSLATE_METHODDEF \ |
688 | | {"translate", _PyCFunction_CAST(bytes_translate), METH_FASTCALL|METH_KEYWORDS, bytes_translate__doc__}, |
689 | | |
690 | | static PyObject * |
691 | | bytes_translate_impl(PyBytesObject *self, PyObject *table, |
692 | | PyObject *deletechars); |
693 | | |
694 | | static PyObject * |
695 | | bytes_translate(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
696 | 0 | { |
697 | 0 | PyObject *return_value = NULL; |
698 | 0 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
699 | |
|
700 | 0 | #define NUM_KEYWORDS 1 |
701 | 0 | static struct { |
702 | 0 | PyGC_Head _this_is_not_used; |
703 | 0 | PyObject_VAR_HEAD |
704 | 0 | Py_hash_t ob_hash; |
705 | 0 | PyObject *ob_item[NUM_KEYWORDS]; |
706 | 0 | } _kwtuple = { |
707 | 0 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
708 | 0 | .ob_hash = -1, |
709 | 0 | .ob_item = { &_Py_ID(delete), }, |
710 | 0 | }; |
711 | 0 | #undef NUM_KEYWORDS |
712 | 0 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
713 | |
|
714 | | #else // !Py_BUILD_CORE |
715 | | # define KWTUPLE NULL |
716 | | #endif // !Py_BUILD_CORE |
717 | |
|
718 | 0 | static const char * const _keywords[] = {"", "delete", NULL}; |
719 | 0 | static _PyArg_Parser _parser = { |
720 | 0 | .keywords = _keywords, |
721 | 0 | .fname = "translate", |
722 | 0 | .kwtuple = KWTUPLE, |
723 | 0 | }; |
724 | 0 | #undef KWTUPLE |
725 | 0 | PyObject *argsbuf[2]; |
726 | 0 | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; |
727 | 0 | PyObject *table; |
728 | 0 | PyObject *deletechars = NULL; |
729 | |
|
730 | 0 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
731 | 0 | /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
732 | 0 | if (!args) { |
733 | 0 | goto exit; |
734 | 0 | } |
735 | 0 | table = args[0]; |
736 | 0 | if (!noptargs) { |
737 | 0 | goto skip_optional_pos; |
738 | 0 | } |
739 | 0 | deletechars = args[1]; |
740 | 0 | skip_optional_pos: |
741 | 0 | return_value = bytes_translate_impl((PyBytesObject *)self, table, deletechars); |
742 | |
|
743 | 0 | exit: |
744 | 0 | return return_value; |
745 | 0 | } |
746 | | |
747 | | PyDoc_STRVAR(bytes_maketrans__doc__, |
748 | | "maketrans(frm, to, /)\n" |
749 | | "--\n" |
750 | | "\n" |
751 | | "Return a translation table usable for the bytes or bytearray translate method.\n" |
752 | | "\n" |
753 | | "The returned table will be one where each byte in frm is mapped to\n" |
754 | | "the byte at the same position in to.\n" |
755 | | "\n" |
756 | | "The bytes objects frm and to must be of the same length."); |
757 | | |
758 | | #define BYTES_MAKETRANS_METHODDEF \ |
759 | | {"maketrans", _PyCFunction_CAST(bytes_maketrans), METH_FASTCALL|METH_STATIC, bytes_maketrans__doc__}, |
760 | | |
761 | | static PyObject * |
762 | | bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); |
763 | | |
764 | | static PyObject * |
765 | | bytes_maketrans(PyObject *null, PyObject *const *args, Py_ssize_t nargs) |
766 | 9 | { |
767 | 9 | PyObject *return_value = NULL; |
768 | 9 | Py_buffer frm = {NULL, NULL}; |
769 | 9 | Py_buffer to = {NULL, NULL}; |
770 | | |
771 | 9 | if (!_PyArg_CheckPositional("maketrans", nargs, 2, 2)) { |
772 | 0 | goto exit; |
773 | 0 | } |
774 | 9 | if (PyObject_GetBuffer(args[0], &frm, PyBUF_SIMPLE) != 0) { |
775 | 0 | goto exit; |
776 | 0 | } |
777 | 9 | if (PyObject_GetBuffer(args[1], &to, PyBUF_SIMPLE) != 0) { |
778 | 0 | goto exit; |
779 | 0 | } |
780 | 9 | return_value = bytes_maketrans_impl(&frm, &to); |
781 | | |
782 | 9 | exit: |
783 | | /* Cleanup for frm */ |
784 | 9 | if (frm.obj) { |
785 | 9 | PyBuffer_Release(&frm); |
786 | 9 | } |
787 | | /* Cleanup for to */ |
788 | 9 | if (to.obj) { |
789 | 9 | PyBuffer_Release(&to); |
790 | 9 | } |
791 | | |
792 | 9 | return return_value; |
793 | 9 | } |
794 | | |
795 | | PyDoc_STRVAR(bytes_replace__doc__, |
796 | | "replace($self, old, new, /, count=-1)\n" |
797 | | "--\n" |
798 | | "\n" |
799 | | "Return a copy with all occurrences of substring old replaced by new.\n" |
800 | | "\n" |
801 | | " count\n" |
802 | | " Maximum number of occurrences to replace.\n" |
803 | | " -1 (the default value) means replace all occurrences.\n" |
804 | | "\n" |
805 | | "If count is given, only the first count occurrences are replaced.\n" |
806 | | "If count is not specified or -1, then all occurrences are replaced."); |
807 | | |
808 | | #define BYTES_REPLACE_METHODDEF \ |
809 | | {"replace", _PyCFunction_CAST(bytes_replace), METH_FASTCALL|METH_KEYWORDS, bytes_replace__doc__}, |
810 | | |
811 | | static PyObject * |
812 | | bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new, |
813 | | Py_ssize_t count); |
814 | | |
815 | | static PyObject * |
816 | | bytes_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
817 | 35.7k | { |
818 | 35.7k | PyObject *return_value = NULL; |
819 | 35.7k | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
820 | | |
821 | 35.7k | #define NUM_KEYWORDS 1 |
822 | 35.7k | static struct { |
823 | 35.7k | PyGC_Head _this_is_not_used; |
824 | 35.7k | PyObject_VAR_HEAD |
825 | 35.7k | Py_hash_t ob_hash; |
826 | 35.7k | PyObject *ob_item[NUM_KEYWORDS]; |
827 | 35.7k | } _kwtuple = { |
828 | 35.7k | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
829 | 35.7k | .ob_hash = -1, |
830 | 35.7k | .ob_item = { &_Py_ID(count), }, |
831 | 35.7k | }; |
832 | 35.7k | #undef NUM_KEYWORDS |
833 | 35.7k | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
834 | | |
835 | | #else // !Py_BUILD_CORE |
836 | | # define KWTUPLE NULL |
837 | | #endif // !Py_BUILD_CORE |
838 | | |
839 | 35.7k | static const char * const _keywords[] = {"", "", "count", NULL}; |
840 | 35.7k | static _PyArg_Parser _parser = { |
841 | 35.7k | .keywords = _keywords, |
842 | 35.7k | .fname = "replace", |
843 | 35.7k | .kwtuple = KWTUPLE, |
844 | 35.7k | }; |
845 | 35.7k | #undef KWTUPLE |
846 | 35.7k | PyObject *argsbuf[3]; |
847 | 35.7k | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; |
848 | 35.7k | Py_buffer old = {NULL, NULL}; |
849 | 35.7k | Py_buffer new = {NULL, NULL}; |
850 | 35.7k | Py_ssize_t count = -1; |
851 | | |
852 | 35.7k | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
853 | 35.7k | /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
854 | 35.7k | if (!args) { |
855 | 0 | goto exit; |
856 | 0 | } |
857 | 35.7k | if (PyObject_GetBuffer(args[0], &old, PyBUF_SIMPLE) != 0) { |
858 | 0 | goto exit; |
859 | 0 | } |
860 | 35.7k | if (PyObject_GetBuffer(args[1], &new, PyBUF_SIMPLE) != 0) { |
861 | 0 | goto exit; |
862 | 0 | } |
863 | 35.7k | if (!noptargs) { |
864 | 35.7k | goto skip_optional_pos; |
865 | 35.7k | } |
866 | 0 | { |
867 | 0 | Py_ssize_t ival = -1; |
868 | 0 | PyObject *iobj = _PyNumber_Index(args[2]); |
869 | 0 | if (iobj != NULL) { |
870 | 0 | ival = PyLong_AsSsize_t(iobj); |
871 | 0 | Py_DECREF(iobj); |
872 | 0 | } |
873 | 0 | if (ival == -1 && PyErr_Occurred()) { |
874 | 0 | goto exit; |
875 | 0 | } |
876 | 0 | count = ival; |
877 | 0 | } |
878 | 35.7k | skip_optional_pos: |
879 | 35.7k | return_value = bytes_replace_impl((PyBytesObject *)self, &old, &new, count); |
880 | | |
881 | 35.7k | exit: |
882 | | /* Cleanup for old */ |
883 | 35.7k | if (old.obj) { |
884 | 35.7k | PyBuffer_Release(&old); |
885 | 35.7k | } |
886 | | /* Cleanup for new */ |
887 | 35.7k | if (new.obj) { |
888 | 35.7k | PyBuffer_Release(&new); |
889 | 35.7k | } |
890 | | |
891 | 35.7k | return return_value; |
892 | 35.7k | } |
893 | | |
894 | | PyDoc_STRVAR(bytes_removeprefix__doc__, |
895 | | "removeprefix($self, prefix, /)\n" |
896 | | "--\n" |
897 | | "\n" |
898 | | "Return a bytes object with the given prefix string removed if present.\n" |
899 | | "\n" |
900 | | "If the bytes starts with the prefix string, return\n" |
901 | | "bytes[len(prefix):]. Otherwise, return a copy of the original\n" |
902 | | "bytes."); |
903 | | |
904 | | #define BYTES_REMOVEPREFIX_METHODDEF \ |
905 | | {"removeprefix", (PyCFunction)bytes_removeprefix, METH_O, bytes_removeprefix__doc__}, |
906 | | |
907 | | static PyObject * |
908 | | bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix); |
909 | | |
910 | | static PyObject * |
911 | | bytes_removeprefix(PyObject *self, PyObject *arg) |
912 | 0 | { |
913 | 0 | PyObject *return_value = NULL; |
914 | 0 | Py_buffer prefix = {NULL, NULL}; |
915 | |
|
916 | 0 | if (PyObject_GetBuffer(arg, &prefix, PyBUF_SIMPLE) != 0) { |
917 | 0 | goto exit; |
918 | 0 | } |
919 | 0 | return_value = bytes_removeprefix_impl((PyBytesObject *)self, &prefix); |
920 | |
|
921 | 0 | exit: |
922 | | /* Cleanup for prefix */ |
923 | 0 | if (prefix.obj) { |
924 | 0 | PyBuffer_Release(&prefix); |
925 | 0 | } |
926 | |
|
927 | 0 | return return_value; |
928 | 0 | } |
929 | | |
930 | | PyDoc_STRVAR(bytes_removesuffix__doc__, |
931 | | "removesuffix($self, suffix, /)\n" |
932 | | "--\n" |
933 | | "\n" |
934 | | "Return a bytes object with the given suffix string removed if present.\n" |
935 | | "\n" |
936 | | "If the bytes ends with the suffix string and that suffix is not\n" |
937 | | "empty, return bytes[:-len(prefix)]. Otherwise, return a copy of the\n" |
938 | | "original bytes."); |
939 | | |
940 | | #define BYTES_REMOVESUFFIX_METHODDEF \ |
941 | | {"removesuffix", (PyCFunction)bytes_removesuffix, METH_O, bytes_removesuffix__doc__}, |
942 | | |
943 | | static PyObject * |
944 | | bytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix); |
945 | | |
946 | | static PyObject * |
947 | | bytes_removesuffix(PyObject *self, PyObject *arg) |
948 | 0 | { |
949 | 0 | PyObject *return_value = NULL; |
950 | 0 | Py_buffer suffix = {NULL, NULL}; |
951 | |
|
952 | 0 | if (PyObject_GetBuffer(arg, &suffix, PyBUF_SIMPLE) != 0) { |
953 | 0 | goto exit; |
954 | 0 | } |
955 | 0 | return_value = bytes_removesuffix_impl((PyBytesObject *)self, &suffix); |
956 | |
|
957 | 0 | exit: |
958 | | /* Cleanup for suffix */ |
959 | 0 | if (suffix.obj) { |
960 | 0 | PyBuffer_Release(&suffix); |
961 | 0 | } |
962 | |
|
963 | 0 | return return_value; |
964 | 0 | } |
965 | | |
966 | | PyDoc_STRVAR(bytes_startswith__doc__, |
967 | | "startswith($self, prefix[, start[, end]], /)\n" |
968 | | "--\n" |
969 | | "\n" |
970 | | "Return True if the bytes starts with the specified prefix, False otherwise.\n" |
971 | | "\n" |
972 | | " prefix\n" |
973 | | " A bytes or a tuple of bytes to try.\n" |
974 | | " start\n" |
975 | | " Optional start position. Default: start of the bytes.\n" |
976 | | " end\n" |
977 | | " Optional stop position. Default: end of the bytes."); |
978 | | |
979 | | #define BYTES_STARTSWITH_METHODDEF \ |
980 | | {"startswith", _PyCFunction_CAST(bytes_startswith), METH_FASTCALL, bytes_startswith__doc__}, |
981 | | |
982 | | static PyObject * |
983 | | bytes_startswith_impl(PyBytesObject *self, PyObject *subobj, |
984 | | Py_ssize_t start, Py_ssize_t end); |
985 | | |
986 | | static PyObject * |
987 | | bytes_startswith(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
988 | 1.93M | { |
989 | 1.93M | PyObject *return_value = NULL; |
990 | 1.93M | PyObject *subobj; |
991 | 1.93M | Py_ssize_t start = 0; |
992 | 1.93M | Py_ssize_t end = PY_SSIZE_T_MAX; |
993 | | |
994 | 1.93M | if (!_PyArg_CheckPositional("startswith", nargs, 1, 3)) { |
995 | 0 | goto exit; |
996 | 0 | } |
997 | 1.93M | subobj = args[0]; |
998 | 1.93M | if (nargs < 2) { |
999 | 1.93M | goto skip_optional; |
1000 | 1.93M | } |
1001 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
1002 | 0 | goto exit; |
1003 | 0 | } |
1004 | 0 | if (nargs < 3) { |
1005 | 0 | goto skip_optional; |
1006 | 0 | } |
1007 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
1008 | 0 | goto exit; |
1009 | 0 | } |
1010 | 1.93M | skip_optional: |
1011 | 1.93M | return_value = bytes_startswith_impl((PyBytesObject *)self, subobj, start, end); |
1012 | | |
1013 | 1.93M | exit: |
1014 | 1.93M | return return_value; |
1015 | 1.93M | } |
1016 | | |
1017 | | PyDoc_STRVAR(bytes_endswith__doc__, |
1018 | | "endswith($self, suffix[, start[, end]], /)\n" |
1019 | | "--\n" |
1020 | | "\n" |
1021 | | "Return True if the bytes ends with the specified suffix, False otherwise.\n" |
1022 | | "\n" |
1023 | | " suffix\n" |
1024 | | " A bytes or a tuple of bytes to try.\n" |
1025 | | " start\n" |
1026 | | " Optional start position. Default: start of the bytes.\n" |
1027 | | " end\n" |
1028 | | " Optional stop position. Default: end of the bytes."); |
1029 | | |
1030 | | #define BYTES_ENDSWITH_METHODDEF \ |
1031 | | {"endswith", _PyCFunction_CAST(bytes_endswith), METH_FASTCALL, bytes_endswith__doc__}, |
1032 | | |
1033 | | static PyObject * |
1034 | | bytes_endswith_impl(PyBytesObject *self, PyObject *subobj, Py_ssize_t start, |
1035 | | Py_ssize_t end); |
1036 | | |
1037 | | static PyObject * |
1038 | | bytes_endswith(PyObject *self, PyObject *const *args, Py_ssize_t nargs) |
1039 | 315 | { |
1040 | 315 | PyObject *return_value = NULL; |
1041 | 315 | PyObject *subobj; |
1042 | 315 | Py_ssize_t start = 0; |
1043 | 315 | Py_ssize_t end = PY_SSIZE_T_MAX; |
1044 | | |
1045 | 315 | if (!_PyArg_CheckPositional("endswith", nargs, 1, 3)) { |
1046 | 0 | goto exit; |
1047 | 0 | } |
1048 | 315 | subobj = args[0]; |
1049 | 315 | if (nargs < 2) { |
1050 | 315 | goto skip_optional; |
1051 | 315 | } |
1052 | 0 | if (!_PyEval_SliceIndex(args[1], &start)) { |
1053 | 0 | goto exit; |
1054 | 0 | } |
1055 | 0 | if (nargs < 3) { |
1056 | 0 | goto skip_optional; |
1057 | 0 | } |
1058 | 0 | if (!_PyEval_SliceIndex(args[2], &end)) { |
1059 | 0 | goto exit; |
1060 | 0 | } |
1061 | 315 | skip_optional: |
1062 | 315 | return_value = bytes_endswith_impl((PyBytesObject *)self, subobj, start, end); |
1063 | | |
1064 | 315 | exit: |
1065 | 315 | return return_value; |
1066 | 315 | } |
1067 | | |
1068 | | PyDoc_STRVAR(bytes_decode__doc__, |
1069 | | "decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" |
1070 | | "--\n" |
1071 | | "\n" |
1072 | | "Decode the bytes using the codec registered for encoding.\n" |
1073 | | "\n" |
1074 | | " encoding\n" |
1075 | | " The encoding with which to decode the bytes.\n" |
1076 | | " errors\n" |
1077 | | " The error handling scheme to use for the handling of decoding\n" |
1078 | | " errors. The default is \'strict\' meaning that decoding errors\n" |
1079 | | " raise a UnicodeDecodeError. Other possible values are \'ignore\'\n" |
1080 | | " and \'replace\' as well as any other name registered with\n" |
1081 | | " codecs.register_error that can handle UnicodeDecodeErrors."); |
1082 | | |
1083 | | #define BYTES_DECODE_METHODDEF \ |
1084 | | {"decode", _PyCFunction_CAST(bytes_decode), METH_FASTCALL|METH_KEYWORDS, bytes_decode__doc__}, |
1085 | | |
1086 | | static PyObject * |
1087 | | bytes_decode_impl(PyBytesObject *self, const char *encoding, |
1088 | | const char *errors); |
1089 | | |
1090 | | static PyObject * |
1091 | | bytes_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
1092 | 18.9M | { |
1093 | 18.9M | PyObject *return_value = NULL; |
1094 | 18.9M | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
1095 | | |
1096 | 18.9M | #define NUM_KEYWORDS 2 |
1097 | 18.9M | static struct { |
1098 | 18.9M | PyGC_Head _this_is_not_used; |
1099 | 18.9M | PyObject_VAR_HEAD |
1100 | 18.9M | Py_hash_t ob_hash; |
1101 | 18.9M | PyObject *ob_item[NUM_KEYWORDS]; |
1102 | 18.9M | } _kwtuple = { |
1103 | 18.9M | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
1104 | 18.9M | .ob_hash = -1, |
1105 | 18.9M | .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, |
1106 | 18.9M | }; |
1107 | 18.9M | #undef NUM_KEYWORDS |
1108 | 18.9M | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
1109 | | |
1110 | | #else // !Py_BUILD_CORE |
1111 | | # define KWTUPLE NULL |
1112 | | #endif // !Py_BUILD_CORE |
1113 | | |
1114 | 18.9M | static const char * const _keywords[] = {"encoding", "errors", NULL}; |
1115 | 18.9M | static _PyArg_Parser _parser = { |
1116 | 18.9M | .keywords = _keywords, |
1117 | 18.9M | .fname = "decode", |
1118 | 18.9M | .kwtuple = KWTUPLE, |
1119 | 18.9M | }; |
1120 | 18.9M | #undef KWTUPLE |
1121 | 18.9M | PyObject *argsbuf[2]; |
1122 | 18.9M | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; |
1123 | 18.9M | const char *encoding = NULL; |
1124 | 18.9M | const char *errors = NULL; |
1125 | | |
1126 | 18.9M | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
1127 | 18.9M | /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
1128 | 18.9M | if (!args) { |
1129 | 0 | goto exit; |
1130 | 0 | } |
1131 | 18.9M | if (!noptargs) { |
1132 | 66.1k | goto skip_optional_pos; |
1133 | 66.1k | } |
1134 | 18.9M | if (args[0]) { |
1135 | 18.9M | if (!PyUnicode_Check(args[0])) { |
1136 | 0 | _PyArg_BadArgument("decode", "argument 'encoding'", "str", args[0]); |
1137 | 0 | goto exit; |
1138 | 0 | } |
1139 | 18.9M | Py_ssize_t encoding_length; |
1140 | 18.9M | encoding = PyUnicode_AsUTF8AndSize(args[0], &encoding_length); |
1141 | 18.9M | if (encoding == NULL) { |
1142 | 0 | goto exit; |
1143 | 0 | } |
1144 | 18.9M | if (strlen(encoding) != (size_t)encoding_length) { |
1145 | 1.34k | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
1146 | 1.34k | goto exit; |
1147 | 1.34k | } |
1148 | 18.9M | if (!--noptargs) { |
1149 | 1.33M | goto skip_optional_pos; |
1150 | 1.33M | } |
1151 | 18.9M | } |
1152 | 17.5M | if (!PyUnicode_Check(args[1])) { |
1153 | 0 | _PyArg_BadArgument("decode", "argument 'errors'", "str", args[1]); |
1154 | 0 | goto exit; |
1155 | 0 | } |
1156 | 17.5M | Py_ssize_t errors_length; |
1157 | 17.5M | errors = PyUnicode_AsUTF8AndSize(args[1], &errors_length); |
1158 | 17.5M | if (errors == NULL) { |
1159 | 0 | goto exit; |
1160 | 0 | } |
1161 | 17.5M | if (strlen(errors) != (size_t)errors_length) { |
1162 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
1163 | 0 | goto exit; |
1164 | 0 | } |
1165 | 18.9M | skip_optional_pos: |
1166 | 18.9M | return_value = bytes_decode_impl((PyBytesObject *)self, encoding, errors); |
1167 | | |
1168 | 18.9M | exit: |
1169 | 18.9M | return return_value; |
1170 | 18.9M | } |
1171 | | |
1172 | | PyDoc_STRVAR(bytes_splitlines__doc__, |
1173 | | "splitlines($self, /, keepends=False)\n" |
1174 | | "--\n" |
1175 | | "\n" |
1176 | | "Return a list of the lines in the bytes, breaking at line boundaries.\n" |
1177 | | "\n" |
1178 | | "Line breaks are not included in the resulting list unless keepends\n" |
1179 | | "is given and true."); |
1180 | | |
1181 | | #define BYTES_SPLITLINES_METHODDEF \ |
1182 | | {"splitlines", _PyCFunction_CAST(bytes_splitlines), METH_FASTCALL|METH_KEYWORDS, bytes_splitlines__doc__}, |
1183 | | |
1184 | | static PyObject * |
1185 | | bytes_splitlines_impl(PyBytesObject *self, int keepends); |
1186 | | |
1187 | | static PyObject * |
1188 | | bytes_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
1189 | 0 | { |
1190 | 0 | PyObject *return_value = NULL; |
1191 | 0 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
1192 | |
|
1193 | 0 | #define NUM_KEYWORDS 1 |
1194 | 0 | static struct { |
1195 | 0 | PyGC_Head _this_is_not_used; |
1196 | 0 | PyObject_VAR_HEAD |
1197 | 0 | Py_hash_t ob_hash; |
1198 | 0 | PyObject *ob_item[NUM_KEYWORDS]; |
1199 | 0 | } _kwtuple = { |
1200 | 0 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
1201 | 0 | .ob_hash = -1, |
1202 | 0 | .ob_item = { &_Py_ID(keepends), }, |
1203 | 0 | }; |
1204 | 0 | #undef NUM_KEYWORDS |
1205 | 0 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
1206 | |
|
1207 | | #else // !Py_BUILD_CORE |
1208 | | # define KWTUPLE NULL |
1209 | | #endif // !Py_BUILD_CORE |
1210 | |
|
1211 | 0 | static const char * const _keywords[] = {"keepends", NULL}; |
1212 | 0 | static _PyArg_Parser _parser = { |
1213 | 0 | .keywords = _keywords, |
1214 | 0 | .fname = "splitlines", |
1215 | 0 | .kwtuple = KWTUPLE, |
1216 | 0 | }; |
1217 | 0 | #undef KWTUPLE |
1218 | 0 | PyObject *argsbuf[1]; |
1219 | 0 | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; |
1220 | 0 | int keepends = 0; |
1221 | |
|
1222 | 0 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
1223 | 0 | /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
1224 | 0 | if (!args) { |
1225 | 0 | goto exit; |
1226 | 0 | } |
1227 | 0 | if (!noptargs) { |
1228 | 0 | goto skip_optional_pos; |
1229 | 0 | } |
1230 | 0 | keepends = PyObject_IsTrue(args[0]); |
1231 | 0 | if (keepends < 0) { |
1232 | 0 | goto exit; |
1233 | 0 | } |
1234 | 0 | skip_optional_pos: |
1235 | 0 | return_value = bytes_splitlines_impl((PyBytesObject *)self, keepends); |
1236 | |
|
1237 | 0 | exit: |
1238 | 0 | return return_value; |
1239 | 0 | } |
1240 | | |
1241 | | PyDoc_STRVAR(bytes_fromhex__doc__, |
1242 | | "fromhex($type, string, /)\n" |
1243 | | "--\n" |
1244 | | "\n" |
1245 | | "Create a bytes object from a string of hexadecimal numbers.\n" |
1246 | | "\n" |
1247 | | "Spaces between two numbers are accepted.\n" |
1248 | | "Example: bytes.fromhex(\'B9 01EF\') -> b\'\\\\xb9\\\\x01\\\\xef\'."); |
1249 | | |
1250 | | #define BYTES_FROMHEX_METHODDEF \ |
1251 | | {"fromhex", (PyCFunction)bytes_fromhex, METH_O|METH_CLASS, bytes_fromhex__doc__}, |
1252 | | |
1253 | | static PyObject * |
1254 | | bytes_fromhex_impl(PyTypeObject *type, PyObject *string); |
1255 | | |
1256 | | static PyObject * |
1257 | | bytes_fromhex(PyObject *type, PyObject *string) |
1258 | 34.9k | { |
1259 | 34.9k | PyObject *return_value = NULL; |
1260 | | |
1261 | 34.9k | return_value = bytes_fromhex_impl((PyTypeObject *)type, string); |
1262 | | |
1263 | 34.9k | return return_value; |
1264 | 34.9k | } |
1265 | | |
1266 | | PyDoc_STRVAR(bytes_hex__doc__, |
1267 | | "hex($self, /, sep=<unrepresentable>, bytes_per_sep=1)\n" |
1268 | | "--\n" |
1269 | | "\n" |
1270 | | "Create a string of hexadecimal numbers from a bytes object.\n" |
1271 | | "\n" |
1272 | | " sep\n" |
1273 | | " An optional single character or byte to separate hex bytes.\n" |
1274 | | " bytes_per_sep\n" |
1275 | | " How many bytes between separators. Positive values count from\n" |
1276 | | " the right, negative values count from the left.\n" |
1277 | | "\n" |
1278 | | "Example:\n" |
1279 | | ">>> value = b\'\\xb9\\x01\\xef\'\n" |
1280 | | ">>> value.hex()\n" |
1281 | | "\'b901ef\'\n" |
1282 | | ">>> value.hex(\':\')\n" |
1283 | | "\'b9:01:ef\'\n" |
1284 | | ">>> value.hex(\':\', 2)\n" |
1285 | | "\'b9:01ef\'\n" |
1286 | | ">>> value.hex(\':\', -2)\n" |
1287 | | "\'b901:ef\'"); |
1288 | | |
1289 | | #define BYTES_HEX_METHODDEF \ |
1290 | | {"hex", _PyCFunction_CAST(bytes_hex), METH_FASTCALL|METH_KEYWORDS, bytes_hex__doc__}, |
1291 | | |
1292 | | static PyObject * |
1293 | | bytes_hex_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t bytes_per_sep); |
1294 | | |
1295 | | static PyObject * |
1296 | | bytes_hex(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) |
1297 | 0 | { |
1298 | 0 | PyObject *return_value = NULL; |
1299 | 0 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
1300 | |
|
1301 | 0 | #define NUM_KEYWORDS 2 |
1302 | 0 | static struct { |
1303 | 0 | PyGC_Head _this_is_not_used; |
1304 | 0 | PyObject_VAR_HEAD |
1305 | 0 | Py_hash_t ob_hash; |
1306 | 0 | PyObject *ob_item[NUM_KEYWORDS]; |
1307 | 0 | } _kwtuple = { |
1308 | 0 | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
1309 | 0 | .ob_hash = -1, |
1310 | 0 | .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, |
1311 | 0 | }; |
1312 | 0 | #undef NUM_KEYWORDS |
1313 | 0 | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
1314 | |
|
1315 | | #else // !Py_BUILD_CORE |
1316 | | # define KWTUPLE NULL |
1317 | | #endif // !Py_BUILD_CORE |
1318 | |
|
1319 | 0 | static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; |
1320 | 0 | static _PyArg_Parser _parser = { |
1321 | 0 | .keywords = _keywords, |
1322 | 0 | .fname = "hex", |
1323 | 0 | .kwtuple = KWTUPLE, |
1324 | 0 | }; |
1325 | 0 | #undef KWTUPLE |
1326 | 0 | PyObject *argsbuf[2]; |
1327 | 0 | Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; |
1328 | 0 | PyObject *sep = NULL; |
1329 | 0 | Py_ssize_t bytes_per_sep = 1; |
1330 | |
|
1331 | 0 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, |
1332 | 0 | /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
1333 | 0 | if (!args) { |
1334 | 0 | goto exit; |
1335 | 0 | } |
1336 | 0 | if (!noptargs) { |
1337 | 0 | goto skip_optional_pos; |
1338 | 0 | } |
1339 | 0 | if (args[0]) { |
1340 | 0 | sep = args[0]; |
1341 | 0 | if (!--noptargs) { |
1342 | 0 | goto skip_optional_pos; |
1343 | 0 | } |
1344 | 0 | } |
1345 | 0 | { |
1346 | 0 | Py_ssize_t ival = -1; |
1347 | 0 | PyObject *iobj = _PyNumber_Index(args[1]); |
1348 | 0 | if (iobj != NULL) { |
1349 | 0 | ival = PyLong_AsSsize_t(iobj); |
1350 | 0 | Py_DECREF(iobj); |
1351 | 0 | } |
1352 | 0 | if (ival == -1 && PyErr_Occurred()) { |
1353 | 0 | goto exit; |
1354 | 0 | } |
1355 | 0 | bytes_per_sep = ival; |
1356 | 0 | } |
1357 | 0 | skip_optional_pos: |
1358 | 0 | return_value = bytes_hex_impl((PyBytesObject *)self, sep, bytes_per_sep); |
1359 | |
|
1360 | 0 | exit: |
1361 | 0 | return return_value; |
1362 | 0 | } |
1363 | | |
1364 | | static PyObject * |
1365 | | bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, |
1366 | | const char *errors); |
1367 | | |
1368 | | static PyObject * |
1369 | | bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) |
1370 | 17.3M | { |
1371 | 17.3M | PyObject *return_value = NULL; |
1372 | 17.3M | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) |
1373 | | |
1374 | 17.3M | #define NUM_KEYWORDS 3 |
1375 | 17.3M | static struct { |
1376 | 17.3M | PyGC_Head _this_is_not_used; |
1377 | 17.3M | PyObject_VAR_HEAD |
1378 | 17.3M | Py_hash_t ob_hash; |
1379 | 17.3M | PyObject *ob_item[NUM_KEYWORDS]; |
1380 | 17.3M | } _kwtuple = { |
1381 | 17.3M | .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) |
1382 | 17.3M | .ob_hash = -1, |
1383 | 17.3M | .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, |
1384 | 17.3M | }; |
1385 | 17.3M | #undef NUM_KEYWORDS |
1386 | 17.3M | #define KWTUPLE (&_kwtuple.ob_base.ob_base) |
1387 | | |
1388 | | #else // !Py_BUILD_CORE |
1389 | | # define KWTUPLE NULL |
1390 | | #endif // !Py_BUILD_CORE |
1391 | | |
1392 | 17.3M | static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; |
1393 | 17.3M | static _PyArg_Parser _parser = { |
1394 | 17.3M | .keywords = _keywords, |
1395 | 17.3M | .fname = "bytes", |
1396 | 17.3M | .kwtuple = KWTUPLE, |
1397 | 17.3M | }; |
1398 | 17.3M | #undef KWTUPLE |
1399 | 17.3M | PyObject *argsbuf[3]; |
1400 | 17.3M | PyObject * const *fastargs; |
1401 | 17.3M | Py_ssize_t nargs = PyTuple_GET_SIZE(args); |
1402 | 17.3M | Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; |
1403 | 17.3M | PyObject *x = NULL; |
1404 | 17.3M | const char *encoding = NULL; |
1405 | 17.3M | const char *errors = NULL; |
1406 | | |
1407 | 17.3M | fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, |
1408 | 17.3M | /*minpos*/ 0, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); |
1409 | 17.3M | if (!fastargs) { |
1410 | 0 | goto exit; |
1411 | 0 | } |
1412 | 17.3M | if (!noptargs) { |
1413 | 0 | goto skip_optional_pos; |
1414 | 0 | } |
1415 | 17.3M | if (fastargs[0]) { |
1416 | 17.3M | x = fastargs[0]; |
1417 | 17.3M | if (!--noptargs) { |
1418 | 17.0M | goto skip_optional_pos; |
1419 | 17.0M | } |
1420 | 17.3M | } |
1421 | 330k | if (fastargs[1]) { |
1422 | 330k | if (!PyUnicode_Check(fastargs[1])) { |
1423 | 0 | _PyArg_BadArgument("bytes", "argument 'encoding'", "str", fastargs[1]); |
1424 | 0 | goto exit; |
1425 | 0 | } |
1426 | 330k | Py_ssize_t encoding_length; |
1427 | 330k | encoding = PyUnicode_AsUTF8AndSize(fastargs[1], &encoding_length); |
1428 | 330k | if (encoding == NULL) { |
1429 | 0 | goto exit; |
1430 | 0 | } |
1431 | 330k | if (strlen(encoding) != (size_t)encoding_length) { |
1432 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
1433 | 0 | goto exit; |
1434 | 0 | } |
1435 | 330k | if (!--noptargs) { |
1436 | 330k | goto skip_optional_pos; |
1437 | 330k | } |
1438 | 330k | } |
1439 | 0 | if (!PyUnicode_Check(fastargs[2])) { |
1440 | 0 | _PyArg_BadArgument("bytes", "argument 'errors'", "str", fastargs[2]); |
1441 | 0 | goto exit; |
1442 | 0 | } |
1443 | 0 | Py_ssize_t errors_length; |
1444 | 0 | errors = PyUnicode_AsUTF8AndSize(fastargs[2], &errors_length); |
1445 | 0 | if (errors == NULL) { |
1446 | 0 | goto exit; |
1447 | 0 | } |
1448 | 0 | if (strlen(errors) != (size_t)errors_length) { |
1449 | 0 | PyErr_SetString(PyExc_ValueError, "embedded null character"); |
1450 | 0 | goto exit; |
1451 | 0 | } |
1452 | 17.3M | skip_optional_pos: |
1453 | 17.3M | return_value = bytes_new_impl(type, x, encoding, errors); |
1454 | | |
1455 | 17.3M | exit: |
1456 | 17.3M | return return_value; |
1457 | 17.3M | } |
1458 | | /*[clinic end generated code: output=c20458db7a2123db input=a9049054013a1b77]*/ |