ยปCore Development>Code coverage>Modules/cjkcodecs/multibytecodec.c

Python code coverage for Modules/cjkcodecs/multibytecodec.c

#countcontent
1n/a/*
2n/a * multibytecodec.c: Common Multibyte Codec Implementation
3n/a *
4n/a * Written by Hye-Shik Chang <perky@FreeBSD.org>
5n/a */
6n/a
7n/a#define PY_SSIZE_T_CLEAN
8n/a#include "Python.h"
9n/a#include "structmember.h"
10n/a#include "multibytecodec.h"
11n/a#include "clinic/multibytecodec.c.h"
12n/a
13n/a/*[clinic input]
14n/amodule _multibytecodec
15n/aclass _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type"
16n/a[clinic start generated code]*/
17n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/
18n/a
19n/atypedef struct {
20n/a PyObject *inobj;
21n/a Py_ssize_t inpos, inlen;
22n/a unsigned char *outbuf, *outbuf_end;
23n/a PyObject *excobj, *outobj;
24n/a} MultibyteEncodeBuffer;
25n/a
26n/atypedef struct {
27n/a const unsigned char *inbuf, *inbuf_top, *inbuf_end;
28n/a PyObject *excobj;
29n/a _PyUnicodeWriter writer;
30n/a} MultibyteDecodeBuffer;
31n/a
32n/astatic char *incnewkwarglist[] = {"errors", NULL};
33n/astatic char *streamkwarglist[] = {"stream", "errors", NULL};
34n/a
35n/astatic PyObject *multibytecodec_encode(MultibyteCodec *,
36n/a MultibyteCodec_State *, PyObject *, Py_ssize_t *,
37n/a PyObject *, int);
38n/a
39n/a#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */
40n/a
41n/a_Py_IDENTIFIER(write);
42n/a
43n/astatic PyObject *
44n/amake_tuple(PyObject *object, Py_ssize_t len)
45n/a{
46n/a PyObject *v, *w;
47n/a
48n/a if (object == NULL)
49n/a return NULL;
50n/a
51n/a v = PyTuple_New(2);
52n/a if (v == NULL) {
53n/a Py_DECREF(object);
54n/a return NULL;
55n/a }
56n/a PyTuple_SET_ITEM(v, 0, object);
57n/a
58n/a w = PyLong_FromSsize_t(len);
59n/a if (w == NULL) {
60n/a Py_DECREF(v);
61n/a return NULL;
62n/a }
63n/a PyTuple_SET_ITEM(v, 1, w);
64n/a
65n/a return v;
66n/a}
67n/a
68n/astatic PyObject *
69n/ainternal_error_callback(const char *errors)
70n/a{
71n/a if (errors == NULL || strcmp(errors, "strict") == 0)
72n/a return ERROR_STRICT;
73n/a else if (strcmp(errors, "ignore") == 0)
74n/a return ERROR_IGNORE;
75n/a else if (strcmp(errors, "replace") == 0)
76n/a return ERROR_REPLACE;
77n/a else
78n/a return PyUnicode_FromString(errors);
79n/a}
80n/a
81n/astatic PyObject *
82n/acall_error_callback(PyObject *errors, PyObject *exc)
83n/a{
84n/a PyObject *args, *cb, *r;
85n/a const char *str;
86n/a
87n/a assert(PyUnicode_Check(errors));
88n/a str = PyUnicode_AsUTF8(errors);
89n/a if (str == NULL)
90n/a return NULL;
91n/a cb = PyCodec_LookupError(str);
92n/a if (cb == NULL)
93n/a return NULL;
94n/a
95n/a args = PyTuple_New(1);
96n/a if (args == NULL) {
97n/a Py_DECREF(cb);
98n/a return NULL;
99n/a }
100n/a
101n/a PyTuple_SET_ITEM(args, 0, exc);
102n/a Py_INCREF(exc);
103n/a
104n/a r = PyObject_CallObject(cb, args);
105n/a Py_DECREF(args);
106n/a Py_DECREF(cb);
107n/a return r;
108n/a}
109n/a
110n/astatic PyObject *
111n/acodecctx_errors_get(MultibyteStatefulCodecContext *self)
112n/a{
113n/a const char *errors;
114n/a
115n/a if (self->errors == ERROR_STRICT)
116n/a errors = "strict";
117n/a else if (self->errors == ERROR_IGNORE)
118n/a errors = "ignore";
119n/a else if (self->errors == ERROR_REPLACE)
120n/a errors = "replace";
121n/a else {
122n/a Py_INCREF(self->errors);
123n/a return self->errors;
124n/a }
125n/a
126n/a return PyUnicode_FromString(errors);
127n/a}
128n/a
129n/astatic int
130n/acodecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value,
131n/a void *closure)
132n/a{
133n/a PyObject *cb;
134n/a const char *str;
135n/a
136n/a if (!PyUnicode_Check(value)) {
137n/a PyErr_SetString(PyExc_TypeError, "errors must be a string");
138n/a return -1;
139n/a }
140n/a
141n/a str = PyUnicode_AsUTF8(value);
142n/a if (str == NULL)
143n/a return -1;
144n/a
145n/a cb = internal_error_callback(str);
146n/a if (cb == NULL)
147n/a return -1;
148n/a
149n/a ERROR_DECREF(self->errors);
150n/a self->errors = cb;
151n/a return 0;
152n/a}
153n/a
154n/a/* This getset handlers list is used by all the stateful codec objects */
155n/astatic PyGetSetDef codecctx_getsets[] = {
156n/a {"errors", (getter)codecctx_errors_get,
157n/a (setter)codecctx_errors_set,
158n/a PyDoc_STR("how to treat errors")},
159n/a {NULL,}
160n/a};
161n/a
162n/astatic int
163n/aexpand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize)
164n/a{
165n/a Py_ssize_t orgpos, orgsize, incsize;
166n/a
167n/a orgpos = (Py_ssize_t)((char *)buf->outbuf -
168n/a PyBytes_AS_STRING(buf->outobj));
169n/a orgsize = PyBytes_GET_SIZE(buf->outobj);
170n/a incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize);
171n/a
172n/a if (orgsize > PY_SSIZE_T_MAX - incsize) {
173n/a PyErr_NoMemory();
174n/a return -1;
175n/a }
176n/a
177n/a if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1)
178n/a return -1;
179n/a
180n/a buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos;
181n/a buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj)
182n/a + PyBytes_GET_SIZE(buf->outobj);
183n/a
184n/a return 0;
185n/a}
186n/a#define REQUIRE_ENCODEBUFFER(buf, s) do { \
187n/a if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf) \
188n/a if (expand_encodebuffer(buf, s) == -1) \
189n/a goto errorexit; \
190n/a} while(0)
191n/a
192n/a
193n/a/**
194n/a * MultibyteCodec object
195n/a */
196n/a
197n/astatic int
198n/amultibytecodec_encerror(MultibyteCodec *codec,
199n/a MultibyteCodec_State *state,
200n/a MultibyteEncodeBuffer *buf,
201n/a PyObject *errors, Py_ssize_t e)
202n/a{
203n/a PyObject *retobj = NULL, *retstr = NULL, *tobj;
204n/a Py_ssize_t retstrsize, newpos;
205n/a Py_ssize_t esize, start, end;
206n/a const char *reason;
207n/a
208n/a if (e > 0) {
209n/a reason = "illegal multibyte sequence";
210n/a esize = e;
211n/a }
212n/a else {
213n/a switch (e) {
214n/a case MBERR_TOOSMALL:
215n/a REQUIRE_ENCODEBUFFER(buf, -1);
216n/a return 0; /* retry it */
217n/a case MBERR_TOOFEW:
218n/a reason = "incomplete multibyte sequence";
219n/a esize = (Py_ssize_t)buf->inpos;
220n/a break;
221n/a case MBERR_INTERNAL:
222n/a PyErr_SetString(PyExc_RuntimeError,
223n/a "internal codec error");
224n/a return -1;
225n/a default:
226n/a PyErr_SetString(PyExc_RuntimeError,
227n/a "unknown runtime error");
228n/a return -1;
229n/a }
230n/a }
231n/a
232n/a if (errors == ERROR_REPLACE) {
233n/a PyObject *replchar;
234n/a Py_ssize_t r;
235n/a Py_ssize_t inpos;
236n/a int kind;
237n/a void *data;
238n/a
239n/a replchar = PyUnicode_FromOrdinal('?');
240n/a if (replchar == NULL)
241n/a goto errorexit;
242n/a kind = PyUnicode_KIND(replchar);
243n/a data = PyUnicode_DATA(replchar);
244n/a
245n/a inpos = 0;
246n/a for (;;) {
247n/a Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
248n/a
249n/a r = codec->encode(state, codec->config,
250n/a kind, data, &inpos, 1,
251n/a &buf->outbuf, outleft, 0);
252n/a if (r == MBERR_TOOSMALL) {
253n/a REQUIRE_ENCODEBUFFER(buf, -1);
254n/a continue;
255n/a }
256n/a else
257n/a break;
258n/a }
259n/a
260n/a Py_DECREF(replchar);
261n/a
262n/a if (r != 0) {
263n/a REQUIRE_ENCODEBUFFER(buf, 1);
264n/a *buf->outbuf++ = '?';
265n/a }
266n/a }
267n/a if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
268n/a buf->inpos += esize;
269n/a return 0;
270n/a }
271n/a
272n/a start = (Py_ssize_t)buf->inpos;
273n/a end = start + esize;
274n/a
275n/a /* use cached exception object if available */
276n/a if (buf->excobj == NULL) {
277n/a buf->excobj = PyObject_CallFunction(PyExc_UnicodeEncodeError,
278n/a "sOnns",
279n/a codec->encoding, buf->inobj,
280n/a start, end, reason);
281n/a if (buf->excobj == NULL)
282n/a goto errorexit;
283n/a }
284n/a else
285n/a if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 ||
286n/a PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 ||
287n/a PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0)
288n/a goto errorexit;
289n/a
290n/a if (errors == ERROR_STRICT) {
291n/a PyCodec_StrictErrors(buf->excobj);
292n/a goto errorexit;
293n/a }
294n/a
295n/a retobj = call_error_callback(errors, buf->excobj);
296n/a if (retobj == NULL)
297n/a goto errorexit;
298n/a
299n/a if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
300n/a (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) ||
301n/a !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) {
302n/a PyErr_SetString(PyExc_TypeError,
303n/a "encoding error handler must return "
304n/a "(str, int) tuple");
305n/a goto errorexit;
306n/a }
307n/a
308n/a if (PyUnicode_Check(tobj)) {
309n/a Py_ssize_t inpos;
310n/a
311n/a retstr = multibytecodec_encode(codec, state, tobj,
312n/a &inpos, ERROR_STRICT,
313n/a MBENC_FLUSH);
314n/a if (retstr == NULL)
315n/a goto errorexit;
316n/a }
317n/a else {
318n/a Py_INCREF(tobj);
319n/a retstr = tobj;
320n/a }
321n/a
322n/a assert(PyBytes_Check(retstr));
323n/a retstrsize = PyBytes_GET_SIZE(retstr);
324n/a if (retstrsize > 0) {
325n/a REQUIRE_ENCODEBUFFER(buf, retstrsize);
326n/a memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize);
327n/a buf->outbuf += retstrsize;
328n/a }
329n/a
330n/a newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
331n/a if (newpos < 0 && !PyErr_Occurred())
332n/a newpos += (Py_ssize_t)buf->inlen;
333n/a if (newpos < 0 || newpos > buf->inlen) {
334n/a PyErr_Clear();
335n/a PyErr_Format(PyExc_IndexError,
336n/a "position %zd from error handler out of bounds",
337n/a newpos);
338n/a goto errorexit;
339n/a }
340n/a buf->inpos = newpos;
341n/a
342n/a Py_DECREF(retobj);
343n/a Py_DECREF(retstr);
344n/a return 0;
345n/a
346n/aerrorexit:
347n/a Py_XDECREF(retobj);
348n/a Py_XDECREF(retstr);
349n/a return -1;
350n/a}
351n/a
352n/astatic int
353n/amultibytecodec_decerror(MultibyteCodec *codec,
354n/a MultibyteCodec_State *state,
355n/a MultibyteDecodeBuffer *buf,
356n/a PyObject *errors, Py_ssize_t e)
357n/a{
358n/a PyObject *retobj = NULL, *retuni = NULL;
359n/a Py_ssize_t newpos;
360n/a const char *reason;
361n/a Py_ssize_t esize, start, end;
362n/a
363n/a if (e > 0) {
364n/a reason = "illegal multibyte sequence";
365n/a esize = e;
366n/a }
367n/a else {
368n/a switch (e) {
369n/a case MBERR_TOOSMALL:
370n/a return 0; /* retry it */
371n/a case MBERR_TOOFEW:
372n/a reason = "incomplete multibyte sequence";
373n/a esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
374n/a break;
375n/a case MBERR_INTERNAL:
376n/a PyErr_SetString(PyExc_RuntimeError,
377n/a "internal codec error");
378n/a return -1;
379n/a case MBERR_EXCEPTION:
380n/a return -1;
381n/a default:
382n/a PyErr_SetString(PyExc_RuntimeError,
383n/a "unknown runtime error");
384n/a return -1;
385n/a }
386n/a }
387n/a
388n/a if (errors == ERROR_REPLACE) {
389n/a if (_PyUnicodeWriter_WriteChar(&buf->writer,
390n/a Py_UNICODE_REPLACEMENT_CHARACTER) < 0)
391n/a goto errorexit;
392n/a }
393n/a if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) {
394n/a buf->inbuf += esize;
395n/a return 0;
396n/a }
397n/a
398n/a start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top);
399n/a end = start + esize;
400n/a
401n/a /* use cached exception object if available */
402n/a if (buf->excobj == NULL) {
403n/a buf->excobj = PyUnicodeDecodeError_Create(codec->encoding,
404n/a (const char *)buf->inbuf_top,
405n/a (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top),
406n/a start, end, reason);
407n/a if (buf->excobj == NULL)
408n/a goto errorexit;
409n/a }
410n/a else
411n/a if (PyUnicodeDecodeError_SetStart(buf->excobj, start) ||
412n/a PyUnicodeDecodeError_SetEnd(buf->excobj, end) ||
413n/a PyUnicodeDecodeError_SetReason(buf->excobj, reason))
414n/a goto errorexit;
415n/a
416n/a if (errors == ERROR_STRICT) {
417n/a PyCodec_StrictErrors(buf->excobj);
418n/a goto errorexit;
419n/a }
420n/a
421n/a retobj = call_error_callback(errors, buf->excobj);
422n/a if (retobj == NULL)
423n/a goto errorexit;
424n/a
425n/a if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 ||
426n/a !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) ||
427n/a !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) {
428n/a PyErr_SetString(PyExc_TypeError,
429n/a "decoding error handler must return "
430n/a "(str, int) tuple");
431n/a goto errorexit;
432n/a }
433n/a
434n/a if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0)
435n/a goto errorexit;
436n/a
437n/a newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1));
438n/a if (newpos < 0 && !PyErr_Occurred())
439n/a newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top);
440n/a if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) {
441n/a PyErr_Clear();
442n/a PyErr_Format(PyExc_IndexError,
443n/a "position %zd from error handler out of bounds",
444n/a newpos);
445n/a goto errorexit;
446n/a }
447n/a buf->inbuf = buf->inbuf_top + newpos;
448n/a Py_DECREF(retobj);
449n/a return 0;
450n/a
451n/aerrorexit:
452n/a Py_XDECREF(retobj);
453n/a return -1;
454n/a}
455n/a
456n/astatic PyObject *
457n/amultibytecodec_encode(MultibyteCodec *codec,
458n/a MultibyteCodec_State *state,
459n/a PyObject *text, Py_ssize_t *inpos_t,
460n/a PyObject *errors, int flags)
461n/a{
462n/a MultibyteEncodeBuffer buf;
463n/a Py_ssize_t finalsize, r = 0;
464n/a Py_ssize_t datalen;
465n/a int kind;
466n/a void *data;
467n/a
468n/a if (PyUnicode_READY(text) < 0)
469n/a return NULL;
470n/a datalen = PyUnicode_GET_LENGTH(text);
471n/a
472n/a if (datalen == 0 && !(flags & MBENC_RESET))
473n/a return PyBytes_FromStringAndSize(NULL, 0);
474n/a
475n/a buf.excobj = NULL;
476n/a buf.outobj = NULL;
477n/a buf.inobj = text; /* borrowed reference */
478n/a buf.inpos = 0;
479n/a buf.inlen = datalen;
480n/a kind = PyUnicode_KIND(buf.inobj);
481n/a data = PyUnicode_DATA(buf.inobj);
482n/a
483n/a if (datalen > (PY_SSIZE_T_MAX - 16) / 2) {
484n/a PyErr_NoMemory();
485n/a goto errorexit;
486n/a }
487n/a
488n/a buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16);
489n/a if (buf.outobj == NULL)
490n/a goto errorexit;
491n/a buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj);
492n/a buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj);
493n/a
494n/a while (buf.inpos < buf.inlen) {
495n/a /* we don't reuse inleft and outleft here.
496n/a * error callbacks can relocate the cursor anywhere on buffer*/
497n/a Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
498n/a
499n/a r = codec->encode(state, codec->config,
500n/a kind, data,
501n/a &buf.inpos, buf.inlen,
502n/a &buf.outbuf, outleft, flags);
503n/a if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH)))
504n/a break;
505n/a else if (multibytecodec_encerror(codec, state, &buf, errors,r))
506n/a goto errorexit;
507n/a else if (r == MBERR_TOOFEW)
508n/a break;
509n/a }
510n/a
511n/a if (codec->encreset != NULL && (flags & MBENC_RESET))
512n/a for (;;) {
513n/a Py_ssize_t outleft;
514n/a
515n/a outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf);
516n/a r = codec->encreset(state, codec->config, &buf.outbuf,
517n/a outleft);
518n/a if (r == 0)
519n/a break;
520n/a else if (multibytecodec_encerror(codec, state,
521n/a &buf, errors, r))
522n/a goto errorexit;
523n/a }
524n/a
525n/a finalsize = (Py_ssize_t)((char *)buf.outbuf -
526n/a PyBytes_AS_STRING(buf.outobj));
527n/a
528n/a if (finalsize != PyBytes_GET_SIZE(buf.outobj))
529n/a if (_PyBytes_Resize(&buf.outobj, finalsize) == -1)
530n/a goto errorexit;
531n/a
532n/a if (inpos_t)
533n/a *inpos_t = buf.inpos;
534n/a Py_XDECREF(buf.excobj);
535n/a return buf.outobj;
536n/a
537n/aerrorexit:
538n/a Py_XDECREF(buf.excobj);
539n/a Py_XDECREF(buf.outobj);
540n/a return NULL;
541n/a}
542n/a
543n/a/*[clinic input]
544n/a_multibytecodec.MultibyteCodec.encode
545n/a
546n/a input: object
547n/a errors: str(accept={str, NoneType}) = NULL
548n/a
549n/aReturn an encoded string version of `input'.
550n/a
551n/a'errors' may be given to set a different error handling scheme. Default is
552n/a'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible
553n/avalues are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name
554n/aregistered with codecs.register_error that can handle UnicodeEncodeErrors.
555n/a[clinic start generated code]*/
556n/a
557n/astatic PyObject *
558n/a_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self,
559n/a PyObject *input,
560n/a const char *errors)
561n/a/*[clinic end generated code: output=7b26652045ba56a9 input=05f6ced3c8dd0582]*/
562n/a{
563n/a MultibyteCodec_State state;
564n/a PyObject *errorcb, *r, *ucvt;
565n/a Py_ssize_t datalen;
566n/a
567n/a if (PyUnicode_Check(input))
568n/a ucvt = NULL;
569n/a else {
570n/a input = ucvt = PyObject_Str(input);
571n/a if (input == NULL)
572n/a return NULL;
573n/a else if (!PyUnicode_Check(input)) {
574n/a PyErr_SetString(PyExc_TypeError,
575n/a "couldn't convert the object to unicode.");
576n/a Py_DECREF(ucvt);
577n/a return NULL;
578n/a }
579n/a }
580n/a
581n/a if (PyUnicode_READY(input) < 0) {
582n/a Py_XDECREF(ucvt);
583n/a return NULL;
584n/a }
585n/a datalen = PyUnicode_GET_LENGTH(input);
586n/a
587n/a errorcb = internal_error_callback(errors);
588n/a if (errorcb == NULL) {
589n/a Py_XDECREF(ucvt);
590n/a return NULL;
591n/a }
592n/a
593n/a if (self->codec->encinit != NULL &&
594n/a self->codec->encinit(&state, self->codec->config) != 0)
595n/a goto errorexit;
596n/a r = multibytecodec_encode(self->codec, &state,
597n/a input, NULL, errorcb,
598n/a MBENC_FLUSH | MBENC_RESET);
599n/a if (r == NULL)
600n/a goto errorexit;
601n/a
602n/a ERROR_DECREF(errorcb);
603n/a Py_XDECREF(ucvt);
604n/a return make_tuple(r, datalen);
605n/a
606n/aerrorexit:
607n/a ERROR_DECREF(errorcb);
608n/a Py_XDECREF(ucvt);
609n/a return NULL;
610n/a}
611n/a
612n/a/*[clinic input]
613n/a_multibytecodec.MultibyteCodec.decode
614n/a
615n/a input: Py_buffer
616n/a errors: str(accept={str, NoneType}) = NULL
617n/a
618n/aDecodes 'input'.
619n/a
620n/a'errors' may be given to set a different error handling scheme. Default is
621n/a'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible
622n/avalues are 'ignore' and 'replace' as well as any other name registered with
623n/acodecs.register_error that is able to handle UnicodeDecodeErrors."
624n/a[clinic start generated code]*/
625n/a
626n/astatic PyObject *
627n/a_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self,
628n/a Py_buffer *input,
629n/a const char *errors)
630n/a/*[clinic end generated code: output=ff419f65bad6cc77 input=a7d45f87f75e5e02]*/
631n/a{
632n/a MultibyteCodec_State state;
633n/a MultibyteDecodeBuffer buf;
634n/a PyObject *errorcb, *res;
635n/a const char *data;
636n/a Py_ssize_t datalen;
637n/a
638n/a data = input->buf;
639n/a datalen = input->len;
640n/a
641n/a errorcb = internal_error_callback(errors);
642n/a if (errorcb == NULL) {
643n/a return NULL;
644n/a }
645n/a
646n/a if (datalen == 0) {
647n/a ERROR_DECREF(errorcb);
648n/a return make_tuple(PyUnicode_New(0, 0), 0);
649n/a }
650n/a
651n/a _PyUnicodeWriter_Init(&buf.writer);
652n/a buf.writer.min_length = datalen;
653n/a buf.excobj = NULL;
654n/a buf.inbuf = buf.inbuf_top = (unsigned char *)data;
655n/a buf.inbuf_end = buf.inbuf_top + datalen;
656n/a
657n/a if (self->codec->decinit != NULL &&
658n/a self->codec->decinit(&state, self->codec->config) != 0)
659n/a goto errorexit;
660n/a
661n/a while (buf.inbuf < buf.inbuf_end) {
662n/a Py_ssize_t inleft, r;
663n/a
664n/a inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf);
665n/a
666n/a r = self->codec->decode(&state, self->codec->config,
667n/a &buf.inbuf, inleft, &buf.writer);
668n/a if (r == 0)
669n/a break;
670n/a else if (multibytecodec_decerror(self->codec, &state,
671n/a &buf, errorcb, r))
672n/a goto errorexit;
673n/a }
674n/a
675n/a res = _PyUnicodeWriter_Finish(&buf.writer);
676n/a if (res == NULL)
677n/a goto errorexit;
678n/a
679n/a Py_XDECREF(buf.excobj);
680n/a ERROR_DECREF(errorcb);
681n/a return make_tuple(res, datalen);
682n/a
683n/aerrorexit:
684n/a ERROR_DECREF(errorcb);
685n/a Py_XDECREF(buf.excobj);
686n/a _PyUnicodeWriter_Dealloc(&buf.writer);
687n/a
688n/a return NULL;
689n/a}
690n/a
691n/astatic struct PyMethodDef multibytecodec_methods[] = {
692n/a _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF
693n/a _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF
694n/a {NULL, NULL},
695n/a};
696n/a
697n/astatic void
698n/amultibytecodec_dealloc(MultibyteCodecObject *self)
699n/a{
700n/a PyObject_Del(self);
701n/a}
702n/a
703n/astatic PyTypeObject MultibyteCodec_Type = {
704n/a PyVarObject_HEAD_INIT(NULL, 0)
705n/a "MultibyteCodec", /* tp_name */
706n/a sizeof(MultibyteCodecObject), /* tp_basicsize */
707n/a 0, /* tp_itemsize */
708n/a /* methods */
709n/a (destructor)multibytecodec_dealloc, /* tp_dealloc */
710n/a 0, /* tp_print */
711n/a 0, /* tp_getattr */
712n/a 0, /* tp_setattr */
713n/a 0, /* tp_reserved */
714n/a 0, /* tp_repr */
715n/a 0, /* tp_as_number */
716n/a 0, /* tp_as_sequence */
717n/a 0, /* tp_as_mapping */
718n/a 0, /* tp_hash */
719n/a 0, /* tp_call */
720n/a 0, /* tp_str */
721n/a PyObject_GenericGetAttr, /* tp_getattro */
722n/a 0, /* tp_setattro */
723n/a 0, /* tp_as_buffer */
724n/a Py_TPFLAGS_DEFAULT, /* tp_flags */
725n/a 0, /* tp_doc */
726n/a 0, /* tp_traverse */
727n/a 0, /* tp_clear */
728n/a 0, /* tp_richcompare */
729n/a 0, /* tp_weaklistoffset */
730n/a 0, /* tp_iter */
731n/a 0, /* tp_iterext */
732n/a multibytecodec_methods, /* tp_methods */
733n/a};
734n/a
735n/a
736n/a/**
737n/a * Utility functions for stateful codec mechanism
738n/a */
739n/a
740n/a#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o))
741n/a#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o))
742n/a
743n/astatic PyObject *
744n/aencoder_encode_stateful(MultibyteStatefulEncoderContext *ctx,
745n/a PyObject *unistr, int final)
746n/a{
747n/a PyObject *ucvt, *r = NULL;
748n/a PyObject *inbuf = NULL;
749n/a Py_ssize_t inpos, datalen;
750n/a PyObject *origpending = NULL;
751n/a
752n/a if (PyUnicode_Check(unistr))
753n/a ucvt = NULL;
754n/a else {
755n/a unistr = ucvt = PyObject_Str(unistr);
756n/a if (unistr == NULL)
757n/a return NULL;
758n/a else if (!PyUnicode_Check(unistr)) {
759n/a PyErr_SetString(PyExc_TypeError,
760n/a "couldn't convert the object to str.");
761n/a Py_DECREF(ucvt);
762n/a return NULL;
763n/a }
764n/a }
765n/a
766n/a if (ctx->pending) {
767n/a PyObject *inbuf_tmp;
768n/a
769n/a Py_INCREF(ctx->pending);
770n/a origpending = ctx->pending;
771n/a
772n/a Py_INCREF(ctx->pending);
773n/a inbuf_tmp = ctx->pending;
774n/a PyUnicode_Append(&inbuf_tmp, unistr);
775n/a if (inbuf_tmp == NULL)
776n/a goto errorexit;
777n/a Py_CLEAR(ctx->pending);
778n/a inbuf = inbuf_tmp;
779n/a }
780n/a else {
781n/a origpending = NULL;
782n/a
783n/a Py_INCREF(unistr);
784n/a inbuf = unistr;
785n/a }
786n/a if (PyUnicode_READY(inbuf) < 0)
787n/a goto errorexit;
788n/a inpos = 0;
789n/a datalen = PyUnicode_GET_LENGTH(inbuf);
790n/a
791n/a r = multibytecodec_encode(ctx->codec, &ctx->state,
792n/a inbuf, &inpos,
793n/a ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0);
794n/a if (r == NULL) {
795n/a /* recover the original pending buffer */
796n/a Py_XSETREF(ctx->pending, origpending);
797n/a origpending = NULL;
798n/a goto errorexit;
799n/a }
800n/a Py_XDECREF(origpending);
801n/a
802n/a if (inpos < datalen) {
803n/a if (datalen - inpos > MAXENCPENDING) {
804n/a /* normal codecs can't reach here */
805n/a PyErr_SetString(PyExc_UnicodeError,
806n/a "pending buffer overflow");
807n/a goto errorexit;
808n/a }
809n/a ctx->pending = PyUnicode_Substring(inbuf, inpos, datalen);
810n/a if (ctx->pending == NULL) {
811n/a /* normal codecs can't reach here */
812n/a goto errorexit;
813n/a }
814n/a }
815n/a
816n/a Py_DECREF(inbuf);
817n/a Py_XDECREF(ucvt);
818n/a return r;
819n/a
820n/aerrorexit:
821n/a Py_XDECREF(r);
822n/a Py_XDECREF(ucvt);
823n/a Py_XDECREF(origpending);
824n/a Py_XDECREF(inbuf);
825n/a return NULL;
826n/a}
827n/a
828n/astatic int
829n/adecoder_append_pending(MultibyteStatefulDecoderContext *ctx,
830n/a MultibyteDecodeBuffer *buf)
831n/a{
832n/a Py_ssize_t npendings;
833n/a
834n/a npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
835n/a if (npendings + ctx->pendingsize > MAXDECPENDING ||
836n/a npendings > PY_SSIZE_T_MAX - ctx->pendingsize) {
837n/a PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow");
838n/a return -1;
839n/a }
840n/a memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings);
841n/a ctx->pendingsize += npendings;
842n/a return 0;
843n/a}
844n/a
845n/astatic int
846n/adecoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data,
847n/a Py_ssize_t size)
848n/a{
849n/a buf->inbuf = buf->inbuf_top = (const unsigned char *)data;
850n/a buf->inbuf_end = buf->inbuf_top + size;
851n/a buf->writer.min_length += size;
852n/a return 0;
853n/a}
854n/a
855n/astatic int
856n/adecoder_feed_buffer(MultibyteStatefulDecoderContext *ctx,
857n/a MultibyteDecodeBuffer *buf)
858n/a{
859n/a while (buf->inbuf < buf->inbuf_end) {
860n/a Py_ssize_t inleft;
861n/a Py_ssize_t r;
862n/a
863n/a inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
864n/a
865n/a r = ctx->codec->decode(&ctx->state, ctx->codec->config,
866n/a &buf->inbuf, inleft, &buf->writer);
867n/a if (r == 0 || r == MBERR_TOOFEW)
868n/a break;
869n/a else if (multibytecodec_decerror(ctx->codec, &ctx->state,
870n/a buf, ctx->errors, r))
871n/a return -1;
872n/a }
873n/a return 0;
874n/a}
875n/a
876n/a
877n/a/*[clinic input]
878n/a class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type"
879n/a[clinic start generated code]*/
880n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/
881n/a
882n/a/*[clinic input]
883n/a_multibytecodec.MultibyteIncrementalEncoder.encode
884n/a
885n/a input: object
886n/a final: int(c_default="0") = False
887n/a[clinic start generated code]*/
888n/a
889n/astatic PyObject *
890n/a_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self,
891n/a PyObject *input,
892n/a int final)
893n/a/*[clinic end generated code: output=123361b6c505e2c1 input=a345c688fa664f92]*/
894n/a{
895n/a return encoder_encode_stateful(STATEFUL_ECTX(self), input, final);
896n/a}
897n/a
898n/a/*[clinic input]
899n/a_multibytecodec.MultibyteIncrementalEncoder.reset
900n/a[clinic start generated code]*/
901n/a
902n/astatic PyObject *
903n/a_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self)
904n/a/*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/
905n/a{
906n/a /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */
907n/a unsigned char buffer[4], *outbuf;
908n/a Py_ssize_t r;
909n/a if (self->codec->encreset != NULL) {
910n/a outbuf = buffer;
911n/a r = self->codec->encreset(&self->state, self->codec->config,
912n/a &outbuf, sizeof(buffer));
913n/a if (r != 0)
914n/a return NULL;
915n/a }
916n/a Py_CLEAR(self->pending);
917n/a Py_RETURN_NONE;
918n/a}
919n/a
920n/astatic struct PyMethodDef mbiencoder_methods[] = {
921n/a _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF
922n/a _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF
923n/a {NULL, NULL},
924n/a};
925n/a
926n/astatic PyObject *
927n/ambiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
928n/a{
929n/a MultibyteIncrementalEncoderObject *self;
930n/a PyObject *codec = NULL;
931n/a char *errors = NULL;
932n/a
933n/a if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder",
934n/a incnewkwarglist, &errors))
935n/a return NULL;
936n/a
937n/a self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0);
938n/a if (self == NULL)
939n/a return NULL;
940n/a
941n/a codec = PyObject_GetAttrString((PyObject *)type, "codec");
942n/a if (codec == NULL)
943n/a goto errorexit;
944n/a if (!MultibyteCodec_Check(codec)) {
945n/a PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
946n/a goto errorexit;
947n/a }
948n/a
949n/a self->codec = ((MultibyteCodecObject *)codec)->codec;
950n/a self->pending = NULL;
951n/a self->errors = internal_error_callback(errors);
952n/a if (self->errors == NULL)
953n/a goto errorexit;
954n/a if (self->codec->encinit != NULL &&
955n/a self->codec->encinit(&self->state, self->codec->config) != 0)
956n/a goto errorexit;
957n/a
958n/a Py_DECREF(codec);
959n/a return (PyObject *)self;
960n/a
961n/aerrorexit:
962n/a Py_XDECREF(self);
963n/a Py_XDECREF(codec);
964n/a return NULL;
965n/a}
966n/a
967n/astatic int
968n/ambiencoder_init(PyObject *self, PyObject *args, PyObject *kwds)
969n/a{
970n/a return 0;
971n/a}
972n/a
973n/astatic int
974n/ambiencoder_traverse(MultibyteIncrementalEncoderObject *self,
975n/a visitproc visit, void *arg)
976n/a{
977n/a if (ERROR_ISCUSTOM(self->errors))
978n/a Py_VISIT(self->errors);
979n/a return 0;
980n/a}
981n/a
982n/astatic void
983n/ambiencoder_dealloc(MultibyteIncrementalEncoderObject *self)
984n/a{
985n/a PyObject_GC_UnTrack(self);
986n/a ERROR_DECREF(self->errors);
987n/a Py_TYPE(self)->tp_free(self);
988n/a}
989n/a
990n/astatic PyTypeObject MultibyteIncrementalEncoder_Type = {
991n/a PyVarObject_HEAD_INIT(NULL, 0)
992n/a "MultibyteIncrementalEncoder", /* tp_name */
993n/a sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */
994n/a 0, /* tp_itemsize */
995n/a /* methods */
996n/a (destructor)mbiencoder_dealloc, /* tp_dealloc */
997n/a 0, /* tp_print */
998n/a 0, /* tp_getattr */
999n/a 0, /* tp_setattr */
1000n/a 0, /* tp_reserved */
1001n/a 0, /* tp_repr */
1002n/a 0, /* tp_as_number */
1003n/a 0, /* tp_as_sequence */
1004n/a 0, /* tp_as_mapping */
1005n/a 0, /* tp_hash */
1006n/a 0, /* tp_call */
1007n/a 0, /* tp_str */
1008n/a PyObject_GenericGetAttr, /* tp_getattro */
1009n/a 0, /* tp_setattro */
1010n/a 0, /* tp_as_buffer */
1011n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
1012n/a | Py_TPFLAGS_BASETYPE, /* tp_flags */
1013n/a 0, /* tp_doc */
1014n/a (traverseproc)mbiencoder_traverse, /* tp_traverse */
1015n/a 0, /* tp_clear */
1016n/a 0, /* tp_richcompare */
1017n/a 0, /* tp_weaklistoffset */
1018n/a 0, /* tp_iter */
1019n/a 0, /* tp_iterext */
1020n/a mbiencoder_methods, /* tp_methods */
1021n/a 0, /* tp_members */
1022n/a codecctx_getsets, /* tp_getset */
1023n/a 0, /* tp_base */
1024n/a 0, /* tp_dict */
1025n/a 0, /* tp_descr_get */
1026n/a 0, /* tp_descr_set */
1027n/a 0, /* tp_dictoffset */
1028n/a mbiencoder_init, /* tp_init */
1029n/a 0, /* tp_alloc */
1030n/a mbiencoder_new, /* tp_new */
1031n/a};
1032n/a
1033n/a
1034n/a/*[clinic input]
1035n/a class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type"
1036n/a[clinic start generated code]*/
1037n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/
1038n/a
1039n/a/*[clinic input]
1040n/a_multibytecodec.MultibyteIncrementalDecoder.decode
1041n/a
1042n/a input: Py_buffer
1043n/a final: int(c_default="0") = False
1044n/a[clinic start generated code]*/
1045n/a
1046n/astatic PyObject *
1047n/a_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self,
1048n/a Py_buffer *input,
1049n/a int final)
1050n/a/*[clinic end generated code: output=b9b9090e8a9ce2ba input=576631c61906d39d]*/
1051n/a{
1052n/a MultibyteDecodeBuffer buf;
1053n/a char *data, *wdata = NULL;
1054n/a Py_ssize_t wsize, size, origpending;
1055n/a PyObject *res;
1056n/a
1057n/a data = input->buf;
1058n/a size = input->len;
1059n/a
1060n/a _PyUnicodeWriter_Init(&buf.writer);
1061n/a buf.excobj = NULL;
1062n/a origpending = self->pendingsize;
1063n/a
1064n/a if (self->pendingsize == 0) {
1065n/a wsize = size;
1066n/a wdata = data;
1067n/a }
1068n/a else {
1069n/a if (size > PY_SSIZE_T_MAX - self->pendingsize) {
1070n/a PyErr_NoMemory();
1071n/a goto errorexit;
1072n/a }
1073n/a wsize = size + self->pendingsize;
1074n/a wdata = PyMem_Malloc(wsize);
1075n/a if (wdata == NULL) {
1076n/a PyErr_NoMemory();
1077n/a goto errorexit;
1078n/a }
1079n/a memcpy(wdata, self->pending, self->pendingsize);
1080n/a memcpy(wdata + self->pendingsize, data, size);
1081n/a self->pendingsize = 0;
1082n/a }
1083n/a
1084n/a if (decoder_prepare_buffer(&buf, wdata, wsize) != 0)
1085n/a goto errorexit;
1086n/a
1087n/a if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf))
1088n/a goto errorexit;
1089n/a
1090n/a if (final && buf.inbuf < buf.inbuf_end) {
1091n/a if (multibytecodec_decerror(self->codec, &self->state,
1092n/a &buf, self->errors, MBERR_TOOFEW)) {
1093n/a /* recover the original pending buffer */
1094n/a memcpy(self->pending, wdata, origpending);
1095n/a self->pendingsize = origpending;
1096n/a goto errorexit;
1097n/a }
1098n/a }
1099n/a
1100n/a if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */
1101n/a if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0)
1102n/a goto errorexit;
1103n/a }
1104n/a
1105n/a res = _PyUnicodeWriter_Finish(&buf.writer);
1106n/a if (res == NULL)
1107n/a goto errorexit;
1108n/a
1109n/a if (wdata != data)
1110n/a PyMem_Del(wdata);
1111n/a Py_XDECREF(buf.excobj);
1112n/a return res;
1113n/a
1114n/aerrorexit:
1115n/a if (wdata != NULL && wdata != data)
1116n/a PyMem_Del(wdata);
1117n/a Py_XDECREF(buf.excobj);
1118n/a _PyUnicodeWriter_Dealloc(&buf.writer);
1119n/a return NULL;
1120n/a}
1121n/a
1122n/a/*[clinic input]
1123n/a_multibytecodec.MultibyteIncrementalDecoder.reset
1124n/a[clinic start generated code]*/
1125n/a
1126n/astatic PyObject *
1127n/a_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self)
1128n/a/*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/
1129n/a{
1130n/a if (self->codec->decreset != NULL &&
1131n/a self->codec->decreset(&self->state, self->codec->config) != 0)
1132n/a return NULL;
1133n/a self->pendingsize = 0;
1134n/a
1135n/a Py_RETURN_NONE;
1136n/a}
1137n/a
1138n/astatic struct PyMethodDef mbidecoder_methods[] = {
1139n/a _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF
1140n/a _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF
1141n/a {NULL, NULL},
1142n/a};
1143n/a
1144n/astatic PyObject *
1145n/ambidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1146n/a{
1147n/a MultibyteIncrementalDecoderObject *self;
1148n/a PyObject *codec = NULL;
1149n/a char *errors = NULL;
1150n/a
1151n/a if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder",
1152n/a incnewkwarglist, &errors))
1153n/a return NULL;
1154n/a
1155n/a self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0);
1156n/a if (self == NULL)
1157n/a return NULL;
1158n/a
1159n/a codec = PyObject_GetAttrString((PyObject *)type, "codec");
1160n/a if (codec == NULL)
1161n/a goto errorexit;
1162n/a if (!MultibyteCodec_Check(codec)) {
1163n/a PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
1164n/a goto errorexit;
1165n/a }
1166n/a
1167n/a self->codec = ((MultibyteCodecObject *)codec)->codec;
1168n/a self->pendingsize = 0;
1169n/a self->errors = internal_error_callback(errors);
1170n/a if (self->errors == NULL)
1171n/a goto errorexit;
1172n/a if (self->codec->decinit != NULL &&
1173n/a self->codec->decinit(&self->state, self->codec->config) != 0)
1174n/a goto errorexit;
1175n/a
1176n/a Py_DECREF(codec);
1177n/a return (PyObject *)self;
1178n/a
1179n/aerrorexit:
1180n/a Py_XDECREF(self);
1181n/a Py_XDECREF(codec);
1182n/a return NULL;
1183n/a}
1184n/a
1185n/astatic int
1186n/ambidecoder_init(PyObject *self, PyObject *args, PyObject *kwds)
1187n/a{
1188n/a return 0;
1189n/a}
1190n/a
1191n/astatic int
1192n/ambidecoder_traverse(MultibyteIncrementalDecoderObject *self,
1193n/a visitproc visit, void *arg)
1194n/a{
1195n/a if (ERROR_ISCUSTOM(self->errors))
1196n/a Py_VISIT(self->errors);
1197n/a return 0;
1198n/a}
1199n/a
1200n/astatic void
1201n/ambidecoder_dealloc(MultibyteIncrementalDecoderObject *self)
1202n/a{
1203n/a PyObject_GC_UnTrack(self);
1204n/a ERROR_DECREF(self->errors);
1205n/a Py_TYPE(self)->tp_free(self);
1206n/a}
1207n/a
1208n/astatic PyTypeObject MultibyteIncrementalDecoder_Type = {
1209n/a PyVarObject_HEAD_INIT(NULL, 0)
1210n/a "MultibyteIncrementalDecoder", /* tp_name */
1211n/a sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */
1212n/a 0, /* tp_itemsize */
1213n/a /* methods */
1214n/a (destructor)mbidecoder_dealloc, /* tp_dealloc */
1215n/a 0, /* tp_print */
1216n/a 0, /* tp_getattr */
1217n/a 0, /* tp_setattr */
1218n/a 0, /* tp_reserved */
1219n/a 0, /* tp_repr */
1220n/a 0, /* tp_as_number */
1221n/a 0, /* tp_as_sequence */
1222n/a 0, /* tp_as_mapping */
1223n/a 0, /* tp_hash */
1224n/a 0, /* tp_call */
1225n/a 0, /* tp_str */
1226n/a PyObject_GenericGetAttr, /* tp_getattro */
1227n/a 0, /* tp_setattro */
1228n/a 0, /* tp_as_buffer */
1229n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
1230n/a | Py_TPFLAGS_BASETYPE, /* tp_flags */
1231n/a 0, /* tp_doc */
1232n/a (traverseproc)mbidecoder_traverse, /* tp_traverse */
1233n/a 0, /* tp_clear */
1234n/a 0, /* tp_richcompare */
1235n/a 0, /* tp_weaklistoffset */
1236n/a 0, /* tp_iter */
1237n/a 0, /* tp_iterext */
1238n/a mbidecoder_methods, /* tp_methods */
1239n/a 0, /* tp_members */
1240n/a codecctx_getsets, /* tp_getset */
1241n/a 0, /* tp_base */
1242n/a 0, /* tp_dict */
1243n/a 0, /* tp_descr_get */
1244n/a 0, /* tp_descr_set */
1245n/a 0, /* tp_dictoffset */
1246n/a mbidecoder_init, /* tp_init */
1247n/a 0, /* tp_alloc */
1248n/a mbidecoder_new, /* tp_new */
1249n/a};
1250n/a
1251n/a
1252n/a/*[clinic input]
1253n/a class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type"
1254n/a[clinic start generated code]*/
1255n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/
1256n/a
1257n/astatic PyObject *
1258n/ambstreamreader_iread(MultibyteStreamReaderObject *self,
1259n/a const char *method, Py_ssize_t sizehint)
1260n/a{
1261n/a MultibyteDecodeBuffer buf;
1262n/a PyObject *cres, *res;
1263n/a Py_ssize_t rsize;
1264n/a
1265n/a if (sizehint == 0)
1266n/a return PyUnicode_New(0, 0);
1267n/a
1268n/a _PyUnicodeWriter_Init(&buf.writer);
1269n/a buf.excobj = NULL;
1270n/a cres = NULL;
1271n/a
1272n/a for (;;) {
1273n/a int endoffile;
1274n/a
1275n/a if (sizehint < 0)
1276n/a cres = PyObject_CallMethod(self->stream,
1277n/a method, NULL);
1278n/a else
1279n/a cres = PyObject_CallMethod(self->stream,
1280n/a method, "i", sizehint);
1281n/a if (cres == NULL)
1282n/a goto errorexit;
1283n/a
1284n/a if (!PyBytes_Check(cres)) {
1285n/a PyErr_Format(PyExc_TypeError,
1286n/a "stream function returned a "
1287n/a "non-bytes object (%.100s)",
1288n/a cres->ob_type->tp_name);
1289n/a goto errorexit;
1290n/a }
1291n/a
1292n/a endoffile = (PyBytes_GET_SIZE(cres) == 0);
1293n/a
1294n/a if (self->pendingsize > 0) {
1295n/a PyObject *ctr;
1296n/a char *ctrdata;
1297n/a
1298n/a if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) {
1299n/a PyErr_NoMemory();
1300n/a goto errorexit;
1301n/a }
1302n/a rsize = PyBytes_GET_SIZE(cres) + self->pendingsize;
1303n/a ctr = PyBytes_FromStringAndSize(NULL, rsize);
1304n/a if (ctr == NULL)
1305n/a goto errorexit;
1306n/a ctrdata = PyBytes_AS_STRING(ctr);
1307n/a memcpy(ctrdata, self->pending, self->pendingsize);
1308n/a memcpy(ctrdata + self->pendingsize,
1309n/a PyBytes_AS_STRING(cres),
1310n/a PyBytes_GET_SIZE(cres));
1311n/a Py_DECREF(cres);
1312n/a cres = ctr;
1313n/a self->pendingsize = 0;
1314n/a }
1315n/a
1316n/a rsize = PyBytes_GET_SIZE(cres);
1317n/a if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres),
1318n/a rsize) != 0)
1319n/a goto errorexit;
1320n/a
1321n/a if (rsize > 0 && decoder_feed_buffer(
1322n/a (MultibyteStatefulDecoderContext *)self, &buf))
1323n/a goto errorexit;
1324n/a
1325n/a if (endoffile || sizehint < 0) {
1326n/a if (buf.inbuf < buf.inbuf_end &&
1327n/a multibytecodec_decerror(self->codec, &self->state,
1328n/a &buf, self->errors, MBERR_TOOFEW))
1329n/a goto errorexit;
1330n/a }
1331n/a
1332n/a if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */
1333n/a if (decoder_append_pending(STATEFUL_DCTX(self),
1334n/a &buf) != 0)
1335n/a goto errorexit;
1336n/a }
1337n/a
1338n/a Py_DECREF(cres);
1339n/a cres = NULL;
1340n/a
1341n/a if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0)
1342n/a break;
1343n/a
1344n/a sizehint = 1; /* read 1 more byte and retry */
1345n/a }
1346n/a
1347n/a res = _PyUnicodeWriter_Finish(&buf.writer);
1348n/a if (res == NULL)
1349n/a goto errorexit;
1350n/a
1351n/a Py_XDECREF(cres);
1352n/a Py_XDECREF(buf.excobj);
1353n/a return res;
1354n/a
1355n/aerrorexit:
1356n/a Py_XDECREF(cres);
1357n/a Py_XDECREF(buf.excobj);
1358n/a _PyUnicodeWriter_Dealloc(&buf.writer);
1359n/a return NULL;
1360n/a}
1361n/a
1362n/a/*[clinic input]
1363n/a _multibytecodec.MultibyteStreamReader.read
1364n/a
1365n/a sizeobj: object = None
1366n/a /
1367n/a[clinic start generated code]*/
1368n/a
1369n/astatic PyObject *
1370n/a_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self,
1371n/a PyObject *sizeobj)
1372n/a/*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/
1373n/a{
1374n/a Py_ssize_t size;
1375n/a
1376n/a if (sizeobj == Py_None)
1377n/a size = -1;
1378n/a else if (PyLong_Check(sizeobj))
1379n/a size = PyLong_AsSsize_t(sizeobj);
1380n/a else {
1381n/a PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
1382n/a return NULL;
1383n/a }
1384n/a
1385n/a if (size == -1 && PyErr_Occurred())
1386n/a return NULL;
1387n/a
1388n/a return mbstreamreader_iread(self, "read", size);
1389n/a}
1390n/a
1391n/a/*[clinic input]
1392n/a _multibytecodec.MultibyteStreamReader.readline
1393n/a
1394n/a sizeobj: object = None
1395n/a /
1396n/a[clinic start generated code]*/
1397n/a
1398n/astatic PyObject *
1399n/a_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self,
1400n/a PyObject *sizeobj)
1401n/a/*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/
1402n/a{
1403n/a Py_ssize_t size;
1404n/a
1405n/a if (sizeobj == Py_None)
1406n/a size = -1;
1407n/a else if (PyLong_Check(sizeobj))
1408n/a size = PyLong_AsSsize_t(sizeobj);
1409n/a else {
1410n/a PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
1411n/a return NULL;
1412n/a }
1413n/a
1414n/a if (size == -1 && PyErr_Occurred())
1415n/a return NULL;
1416n/a
1417n/a return mbstreamreader_iread(self, "readline", size);
1418n/a}
1419n/a
1420n/a/*[clinic input]
1421n/a _multibytecodec.MultibyteStreamReader.readlines
1422n/a
1423n/a sizehintobj: object = None
1424n/a /
1425n/a[clinic start generated code]*/
1426n/a
1427n/astatic PyObject *
1428n/a_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self,
1429n/a PyObject *sizehintobj)
1430n/a/*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/
1431n/a{
1432n/a PyObject *r, *sr;
1433n/a Py_ssize_t sizehint;
1434n/a
1435n/a if (sizehintobj == Py_None)
1436n/a sizehint = -1;
1437n/a else if (PyLong_Check(sizehintobj))
1438n/a sizehint = PyLong_AsSsize_t(sizehintobj);
1439n/a else {
1440n/a PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer");
1441n/a return NULL;
1442n/a }
1443n/a
1444n/a if (sizehint == -1 && PyErr_Occurred())
1445n/a return NULL;
1446n/a
1447n/a r = mbstreamreader_iread(self, "read", sizehint);
1448n/a if (r == NULL)
1449n/a return NULL;
1450n/a
1451n/a sr = PyUnicode_Splitlines(r, 1);
1452n/a Py_DECREF(r);
1453n/a return sr;
1454n/a}
1455n/a
1456n/a/*[clinic input]
1457n/a _multibytecodec.MultibyteStreamReader.reset
1458n/a[clinic start generated code]*/
1459n/a
1460n/astatic PyObject *
1461n/a_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self)
1462n/a/*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/
1463n/a{
1464n/a if (self->codec->decreset != NULL &&
1465n/a self->codec->decreset(&self->state, self->codec->config) != 0)
1466n/a return NULL;
1467n/a self->pendingsize = 0;
1468n/a
1469n/a Py_RETURN_NONE;
1470n/a}
1471n/a
1472n/astatic struct PyMethodDef mbstreamreader_methods[] = {
1473n/a _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF
1474n/a _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF
1475n/a _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF
1476n/a _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF
1477n/a {NULL, NULL},
1478n/a};
1479n/a
1480n/astatic PyMemberDef mbstreamreader_members[] = {
1481n/a {"stream", T_OBJECT,
1482n/a offsetof(MultibyteStreamReaderObject, stream),
1483n/a READONLY, NULL},
1484n/a {NULL,}
1485n/a};
1486n/a
1487n/astatic PyObject *
1488n/ambstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1489n/a{
1490n/a MultibyteStreamReaderObject *self;
1491n/a PyObject *stream, *codec = NULL;
1492n/a char *errors = NULL;
1493n/a
1494n/a if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader",
1495n/a streamkwarglist, &stream, &errors))
1496n/a return NULL;
1497n/a
1498n/a self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0);
1499n/a if (self == NULL)
1500n/a return NULL;
1501n/a
1502n/a codec = PyObject_GetAttrString((PyObject *)type, "codec");
1503n/a if (codec == NULL)
1504n/a goto errorexit;
1505n/a if (!MultibyteCodec_Check(codec)) {
1506n/a PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
1507n/a goto errorexit;
1508n/a }
1509n/a
1510n/a self->codec = ((MultibyteCodecObject *)codec)->codec;
1511n/a self->stream = stream;
1512n/a Py_INCREF(stream);
1513n/a self->pendingsize = 0;
1514n/a self->errors = internal_error_callback(errors);
1515n/a if (self->errors == NULL)
1516n/a goto errorexit;
1517n/a if (self->codec->decinit != NULL &&
1518n/a self->codec->decinit(&self->state, self->codec->config) != 0)
1519n/a goto errorexit;
1520n/a
1521n/a Py_DECREF(codec);
1522n/a return (PyObject *)self;
1523n/a
1524n/aerrorexit:
1525n/a Py_XDECREF(self);
1526n/a Py_XDECREF(codec);
1527n/a return NULL;
1528n/a}
1529n/a
1530n/astatic int
1531n/ambstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds)
1532n/a{
1533n/a return 0;
1534n/a}
1535n/a
1536n/astatic int
1537n/ambstreamreader_traverse(MultibyteStreamReaderObject *self,
1538n/a visitproc visit, void *arg)
1539n/a{
1540n/a if (ERROR_ISCUSTOM(self->errors))
1541n/a Py_VISIT(self->errors);
1542n/a Py_VISIT(self->stream);
1543n/a return 0;
1544n/a}
1545n/a
1546n/astatic void
1547n/ambstreamreader_dealloc(MultibyteStreamReaderObject *self)
1548n/a{
1549n/a PyObject_GC_UnTrack(self);
1550n/a ERROR_DECREF(self->errors);
1551n/a Py_XDECREF(self->stream);
1552n/a Py_TYPE(self)->tp_free(self);
1553n/a}
1554n/a
1555n/astatic PyTypeObject MultibyteStreamReader_Type = {
1556n/a PyVarObject_HEAD_INIT(NULL, 0)
1557n/a "MultibyteStreamReader", /* tp_name */
1558n/a sizeof(MultibyteStreamReaderObject), /* tp_basicsize */
1559n/a 0, /* tp_itemsize */
1560n/a /* methods */
1561n/a (destructor)mbstreamreader_dealloc, /* tp_dealloc */
1562n/a 0, /* tp_print */
1563n/a 0, /* tp_getattr */
1564n/a 0, /* tp_setattr */
1565n/a 0, /* tp_reserved */
1566n/a 0, /* tp_repr */
1567n/a 0, /* tp_as_number */
1568n/a 0, /* tp_as_sequence */
1569n/a 0, /* tp_as_mapping */
1570n/a 0, /* tp_hash */
1571n/a 0, /* tp_call */
1572n/a 0, /* tp_str */
1573n/a PyObject_GenericGetAttr, /* tp_getattro */
1574n/a 0, /* tp_setattro */
1575n/a 0, /* tp_as_buffer */
1576n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
1577n/a | Py_TPFLAGS_BASETYPE, /* tp_flags */
1578n/a 0, /* tp_doc */
1579n/a (traverseproc)mbstreamreader_traverse, /* tp_traverse */
1580n/a 0, /* tp_clear */
1581n/a 0, /* tp_richcompare */
1582n/a 0, /* tp_weaklistoffset */
1583n/a 0, /* tp_iter */
1584n/a 0, /* tp_iterext */
1585n/a mbstreamreader_methods, /* tp_methods */
1586n/a mbstreamreader_members, /* tp_members */
1587n/a codecctx_getsets, /* tp_getset */
1588n/a 0, /* tp_base */
1589n/a 0, /* tp_dict */
1590n/a 0, /* tp_descr_get */
1591n/a 0, /* tp_descr_set */
1592n/a 0, /* tp_dictoffset */
1593n/a mbstreamreader_init, /* tp_init */
1594n/a 0, /* tp_alloc */
1595n/a mbstreamreader_new, /* tp_new */
1596n/a};
1597n/a
1598n/a
1599n/a/*[clinic input]
1600n/a class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type"
1601n/a[clinic start generated code]*/
1602n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/
1603n/a
1604n/astatic int
1605n/ambstreamwriter_iwrite(MultibyteStreamWriterObject *self,
1606n/a PyObject *unistr)
1607n/a{
1608n/a PyObject *str, *wr;
1609n/a
1610n/a str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0);
1611n/a if (str == NULL)
1612n/a return -1;
1613n/a
1614n/a wr = _PyObject_CallMethodIdObjArgs(self->stream, &PyId_write, str, NULL);
1615n/a Py_DECREF(str);
1616n/a if (wr == NULL)
1617n/a return -1;
1618n/a
1619n/a Py_DECREF(wr);
1620n/a return 0;
1621n/a}
1622n/a
1623n/a/*[clinic input]
1624n/a _multibytecodec.MultibyteStreamWriter.write
1625n/a
1626n/a strobj: object
1627n/a /
1628n/a[clinic start generated code]*/
1629n/a
1630n/astatic PyObject *
1631n/a_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self,
1632n/a PyObject *strobj)
1633n/a/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/
1634n/a{
1635n/a if (mbstreamwriter_iwrite(self, strobj))
1636n/a return NULL;
1637n/a else
1638n/a Py_RETURN_NONE;
1639n/a}
1640n/a
1641n/a/*[clinic input]
1642n/a _multibytecodec.MultibyteStreamWriter.writelines
1643n/a
1644n/a lines: object
1645n/a /
1646n/a[clinic start generated code]*/
1647n/a
1648n/astatic PyObject *
1649n/a_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self,
1650n/a PyObject *lines)
1651n/a/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/
1652n/a{
1653n/a PyObject *strobj;
1654n/a int i, r;
1655n/a
1656n/a if (!PySequence_Check(lines)) {
1657n/a PyErr_SetString(PyExc_TypeError,
1658n/a "arg must be a sequence object");
1659n/a return NULL;
1660n/a }
1661n/a
1662n/a for (i = 0; i < PySequence_Length(lines); i++) {
1663n/a /* length can be changed even within this loop */
1664n/a strobj = PySequence_GetItem(lines, i);
1665n/a if (strobj == NULL)
1666n/a return NULL;
1667n/a
1668n/a r = mbstreamwriter_iwrite(self, strobj);
1669n/a Py_DECREF(strobj);
1670n/a if (r == -1)
1671n/a return NULL;
1672n/a }
1673n/a
1674n/a Py_RETURN_NONE;
1675n/a}
1676n/a
1677n/a/*[clinic input]
1678n/a _multibytecodec.MultibyteStreamWriter.reset
1679n/a[clinic start generated code]*/
1680n/a
1681n/astatic PyObject *
1682n/a_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self)
1683n/a/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/
1684n/a{
1685n/a PyObject *pwrt;
1686n/a
1687n/a if (!self->pending)
1688n/a Py_RETURN_NONE;
1689n/a
1690n/a pwrt = multibytecodec_encode(self->codec, &self->state,
1691n/a self->pending, NULL, self->errors,
1692n/a MBENC_FLUSH | MBENC_RESET);
1693n/a /* some pending buffer can be truncated when UnicodeEncodeError is
1694n/a * raised on 'strict' mode. but, 'reset' method is designed to
1695n/a * reset the pending buffer or states so failed string sequence
1696n/a * ought to be missed */
1697n/a Py_CLEAR(self->pending);
1698n/a if (pwrt == NULL)
1699n/a return NULL;
1700n/a
1701n/a assert(PyBytes_Check(pwrt));
1702n/a if (PyBytes_Size(pwrt) > 0) {
1703n/a PyObject *wr;
1704n/a
1705n/a wr = _PyObject_CallMethodIdObjArgs(self->stream, &PyId_write, pwrt);
1706n/a if (wr == NULL) {
1707n/a Py_DECREF(pwrt);
1708n/a return NULL;
1709n/a }
1710n/a }
1711n/a Py_DECREF(pwrt);
1712n/a
1713n/a Py_RETURN_NONE;
1714n/a}
1715n/a
1716n/astatic PyObject *
1717n/ambstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1718n/a{
1719n/a MultibyteStreamWriterObject *self;
1720n/a PyObject *stream, *codec = NULL;
1721n/a char *errors = NULL;
1722n/a
1723n/a if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter",
1724n/a streamkwarglist, &stream, &errors))
1725n/a return NULL;
1726n/a
1727n/a self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0);
1728n/a if (self == NULL)
1729n/a return NULL;
1730n/a
1731n/a codec = PyObject_GetAttrString((PyObject *)type, "codec");
1732n/a if (codec == NULL)
1733n/a goto errorexit;
1734n/a if (!MultibyteCodec_Check(codec)) {
1735n/a PyErr_SetString(PyExc_TypeError, "codec is unexpected type");
1736n/a goto errorexit;
1737n/a }
1738n/a
1739n/a self->codec = ((MultibyteCodecObject *)codec)->codec;
1740n/a self->stream = stream;
1741n/a Py_INCREF(stream);
1742n/a self->pending = NULL;
1743n/a self->errors = internal_error_callback(errors);
1744n/a if (self->errors == NULL)
1745n/a goto errorexit;
1746n/a if (self->codec->encinit != NULL &&
1747n/a self->codec->encinit(&self->state, self->codec->config) != 0)
1748n/a goto errorexit;
1749n/a
1750n/a Py_DECREF(codec);
1751n/a return (PyObject *)self;
1752n/a
1753n/aerrorexit:
1754n/a Py_XDECREF(self);
1755n/a Py_XDECREF(codec);
1756n/a return NULL;
1757n/a}
1758n/a
1759n/astatic int
1760n/ambstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds)
1761n/a{
1762n/a return 0;
1763n/a}
1764n/a
1765n/astatic int
1766n/ambstreamwriter_traverse(MultibyteStreamWriterObject *self,
1767n/a visitproc visit, void *arg)
1768n/a{
1769n/a if (ERROR_ISCUSTOM(self->errors))
1770n/a Py_VISIT(self->errors);
1771n/a Py_VISIT(self->stream);
1772n/a return 0;
1773n/a}
1774n/a
1775n/astatic void
1776n/ambstreamwriter_dealloc(MultibyteStreamWriterObject *self)
1777n/a{
1778n/a PyObject_GC_UnTrack(self);
1779n/a ERROR_DECREF(self->errors);
1780n/a Py_XDECREF(self->stream);
1781n/a Py_TYPE(self)->tp_free(self);
1782n/a}
1783n/a
1784n/astatic struct PyMethodDef mbstreamwriter_methods[] = {
1785n/a _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF
1786n/a _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF
1787n/a _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF
1788n/a {NULL, NULL},
1789n/a};
1790n/a
1791n/astatic PyMemberDef mbstreamwriter_members[] = {
1792n/a {"stream", T_OBJECT,
1793n/a offsetof(MultibyteStreamWriterObject, stream),
1794n/a READONLY, NULL},
1795n/a {NULL,}
1796n/a};
1797n/a
1798n/astatic PyTypeObject MultibyteStreamWriter_Type = {
1799n/a PyVarObject_HEAD_INIT(NULL, 0)
1800n/a "MultibyteStreamWriter", /* tp_name */
1801n/a sizeof(MultibyteStreamWriterObject), /* tp_basicsize */
1802n/a 0, /* tp_itemsize */
1803n/a /* methods */
1804n/a (destructor)mbstreamwriter_dealloc, /* tp_dealloc */
1805n/a 0, /* tp_print */
1806n/a 0, /* tp_getattr */
1807n/a 0, /* tp_setattr */
1808n/a 0, /* tp_reserved */
1809n/a 0, /* tp_repr */
1810n/a 0, /* tp_as_number */
1811n/a 0, /* tp_as_sequence */
1812n/a 0, /* tp_as_mapping */
1813n/a 0, /* tp_hash */
1814n/a 0, /* tp_call */
1815n/a 0, /* tp_str */
1816n/a PyObject_GenericGetAttr, /* tp_getattro */
1817n/a 0, /* tp_setattro */
1818n/a 0, /* tp_as_buffer */
1819n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC
1820n/a | Py_TPFLAGS_BASETYPE, /* tp_flags */
1821n/a 0, /* tp_doc */
1822n/a (traverseproc)mbstreamwriter_traverse, /* tp_traverse */
1823n/a 0, /* tp_clear */
1824n/a 0, /* tp_richcompare */
1825n/a 0, /* tp_weaklistoffset */
1826n/a 0, /* tp_iter */
1827n/a 0, /* tp_iterext */
1828n/a mbstreamwriter_methods, /* tp_methods */
1829n/a mbstreamwriter_members, /* tp_members */
1830n/a codecctx_getsets, /* tp_getset */
1831n/a 0, /* tp_base */
1832n/a 0, /* tp_dict */
1833n/a 0, /* tp_descr_get */
1834n/a 0, /* tp_descr_set */
1835n/a 0, /* tp_dictoffset */
1836n/a mbstreamwriter_init, /* tp_init */
1837n/a 0, /* tp_alloc */
1838n/a mbstreamwriter_new, /* tp_new */
1839n/a};
1840n/a
1841n/a
1842n/a/*[clinic input]
1843n/a_multibytecodec.__create_codec
1844n/a
1845n/a arg: object
1846n/a /
1847n/a[clinic start generated code]*/
1848n/a
1849n/astatic PyObject *
1850n/a_multibytecodec___create_codec(PyObject *module, PyObject *arg)
1851n/a/*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/
1852n/a{
1853n/a MultibyteCodecObject *self;
1854n/a MultibyteCodec *codec;
1855n/a
1856n/a if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) {
1857n/a PyErr_SetString(PyExc_ValueError, "argument type invalid");
1858n/a return NULL;
1859n/a }
1860n/a
1861n/a codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME);
1862n/a if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0)
1863n/a return NULL;
1864n/a
1865n/a self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type);
1866n/a if (self == NULL)
1867n/a return NULL;
1868n/a self->codec = codec;
1869n/a
1870n/a return (PyObject *)self;
1871n/a}
1872n/a
1873n/astatic struct PyMethodDef __methods[] = {
1874n/a _MULTIBYTECODEC___CREATE_CODEC_METHODDEF
1875n/a {NULL, NULL},
1876n/a};
1877n/a
1878n/a
1879n/astatic struct PyModuleDef _multibytecodecmodule = {
1880n/a PyModuleDef_HEAD_INIT,
1881n/a "_multibytecodec",
1882n/a NULL,
1883n/a -1,
1884n/a __methods,
1885n/a NULL,
1886n/a NULL,
1887n/a NULL,
1888n/a NULL
1889n/a};
1890n/a
1891n/aPyMODINIT_FUNC
1892n/aPyInit__multibytecodec(void)
1893n/a{
1894n/a int i;
1895n/a PyObject *m;
1896n/a PyTypeObject *typelist[] = {
1897n/a &MultibyteIncrementalEncoder_Type,
1898n/a &MultibyteIncrementalDecoder_Type,
1899n/a &MultibyteStreamReader_Type,
1900n/a &MultibyteStreamWriter_Type,
1901n/a NULL
1902n/a };
1903n/a
1904n/a if (PyType_Ready(&MultibyteCodec_Type) < 0)
1905n/a return NULL;
1906n/a
1907n/a m = PyModule_Create(&_multibytecodecmodule);
1908n/a if (m == NULL)
1909n/a return NULL;
1910n/a
1911n/a for (i = 0; typelist[i] != NULL; i++) {
1912n/a if (PyType_Ready(typelist[i]) < 0)
1913n/a return NULL;
1914n/a Py_INCREF(typelist[i]);
1915n/a PyModule_AddObject(m, typelist[i]->tp_name,
1916n/a (PyObject *)typelist[i]);
1917n/a }
1918n/a
1919n/a if (PyErr_Occurred()) {
1920n/a Py_FatalError("can't initialize the _multibytecodec module");
1921n/a Py_DECREF(m);
1922n/a m = NULL;
1923n/a }
1924n/a return m;
1925n/a}