| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * multibytecodec.c: Common Multibyte Codec Implementation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Written by Hye-Shik Chang <perky@FreeBSD.org> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-04 16:08:19 +00:00
										 |  |  | #define PY_SSIZE_T_CLEAN
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | #include "structmember.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | #include "multibytecodec.h"
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | #include "clinic/multibytecodec.c.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | module _multibytecodec | 
					
						
							|  |  |  | class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2015-04-03 23:53:51 +03:00
										 |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6ad689546cbb5450]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     PyObject            *inobj; | 
					
						
							|  |  |  |     Py_ssize_t          inpos, inlen; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  |     unsigned char       *outbuf, *outbuf_end; | 
					
						
							|  |  |  |     PyObject            *excobj, *outobj; | 
					
						
							|  |  |  | } MultibyteEncodeBuffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     const unsigned char *inbuf, *inbuf_top, *inbuf_end; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     PyObject            *excobj; | 
					
						
							|  |  |  |     _PyUnicodeWriter    writer; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } MultibyteDecodeBuffer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static char *incnewkwarglist[] = {"errors", NULL}; | 
					
						
							| 
									
										
										
										
											2006-02-27 17:20:04 +00:00
										 |  |  | static char *streamkwarglist[] = {"stream", "errors", NULL}; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject *multibytecodec_encode(MultibyteCodec *, | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |                 MultibyteCodec_State *, PyObject *, Py_ssize_t *, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                 PyObject *, int); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | #define MBENC_RESET     MBENC_MAX<<1 /* reset after an encoding session */
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-12 21:39:02 +01:00
										 |  |  | _Py_IDENTIFIER(write); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-03-04 16:08:19 +00:00
										 |  |  | make_tuple(PyObject *object, Py_ssize_t len) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *v, *w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (object == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     v = PyTuple_New(2); | 
					
						
							|  |  |  |     if (v == NULL) { | 
					
						
							|  |  |  |         Py_DECREF(object); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(v, 0, object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     w = PyLong_FromSsize_t(len); | 
					
						
							|  |  |  |     if (w == NULL) { | 
					
						
							|  |  |  |         Py_DECREF(v); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     PyTuple_SET_ITEM(v, 1, w); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return v; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | internal_error_callback(const char *errors) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (errors == NULL || strcmp(errors, "strict") == 0) | 
					
						
							|  |  |  |         return ERROR_STRICT; | 
					
						
							|  |  |  |     else if (strcmp(errors, "ignore") == 0) | 
					
						
							|  |  |  |         return ERROR_IGNORE; | 
					
						
							|  |  |  |     else if (strcmp(errors, "replace") == 0) | 
					
						
							|  |  |  |         return ERROR_REPLACE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return PyUnicode_FromString(errors); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | call_error_callback(PyObject *errors, PyObject *exc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-07-04 12:31:34 +02:00
										 |  |  |     PyObject *cb, *r; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     const char *str; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(PyUnicode_Check(errors)); | 
					
						
							| 
									
										
										
										
											2016-11-20 09:13:07 +02:00
										 |  |  |     str = PyUnicode_AsUTF8(errors); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (str == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     cb = PyCodec_LookupError(str); | 
					
						
							|  |  |  |     if (cb == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 17:46:57 +01:00
										 |  |  |     r = PyObject_CallOneArg(cb, exc); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_DECREF(cb); | 
					
						
							|  |  |  |     return r; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2018-11-27 19:34:35 +02:00
										 |  |  | codecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored)) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     const char *errors; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (self->errors == ERROR_STRICT) | 
					
						
							|  |  |  |         errors = "strict"; | 
					
						
							|  |  |  |     else if (self->errors == ERROR_IGNORE) | 
					
						
							|  |  |  |         errors = "ignore"; | 
					
						
							|  |  |  |     else if (self->errors == ERROR_REPLACE) | 
					
						
							|  |  |  |         errors = "replace"; | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         Py_INCREF(self->errors); | 
					
						
							|  |  |  |         return self->errors; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PyUnicode_FromString(errors); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | codecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     void *closure) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *cb; | 
					
						
							|  |  |  |     const char *str; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-17 07:52:45 -07:00
										 |  |  |     if (value == NULL) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (!PyUnicode_Check(value)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "errors must be a string"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-20 09:13:07 +02:00
										 |  |  |     str = PyUnicode_AsUTF8(value); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (str == NULL) | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2007-08-26 04:19:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     cb = internal_error_callback(str); | 
					
						
							|  |  |  |     if (cb == NULL) | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     ERROR_DECREF(self->errors); | 
					
						
							|  |  |  |     self->errors = cb; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | /* This getset handlers list is used by all the stateful codec objects */ | 
					
						
							|  |  |  | static PyGetSetDef codecctx_getsets[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"errors",          (getter)codecctx_errors_get, | 
					
						
							|  |  |  |                     (setter)codecctx_errors_set, | 
					
						
							|  |  |  |                     PyDoc_STR("how to treat errors")}, | 
					
						
							|  |  |  |     {NULL,} | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2006-03-04 16:08:19 +00:00
										 |  |  | expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t orgpos, orgsize, incsize; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     orgpos = (Py_ssize_t)((char *)buf->outbuf - | 
					
						
							|  |  |  |                             PyBytes_AS_STRING(buf->outobj)); | 
					
						
							|  |  |  |     orgsize = PyBytes_GET_SIZE(buf->outobj); | 
					
						
							|  |  |  |     incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); | 
					
						
							| 
									
										
										
										
											2008-06-18 00:47:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 01:19:58 +02:00
										 |  |  |     if (orgsize > PY_SSIZE_T_MAX - incsize) { | 
					
						
							|  |  |  |         PyErr_NoMemory(); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2015-02-21 01:19:58 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-06-18 00:47:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     buf->outbuf = (unsigned char *)PyBytes_AS_STRING(buf->outobj) +orgpos; | 
					
						
							|  |  |  |     buf->outbuf_end = (unsigned char *)PyBytes_AS_STRING(buf->outobj) | 
					
						
							|  |  |  |         + PyBytes_GET_SIZE(buf->outobj); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-21 01:19:58 +02:00
										 |  |  | #define REQUIRE_ENCODEBUFFER(buf, s) do {                               \
 | 
					
						
							|  |  |  |     if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf)             \ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (expand_encodebuffer(buf, s) == -1)                          \ | 
					
						
							|  |  |  |             goto errorexit;                                             \ | 
					
						
							| 
									
										
										
										
											2015-02-21 01:19:58 +02:00
										 |  |  | } while(0) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * MultibyteCodec object | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | multibytecodec_encerror(MultibyteCodec *codec, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         MultibyteCodec_State *state, | 
					
						
							|  |  |  |                         MultibyteEncodeBuffer *buf, | 
					
						
							|  |  |  |                         PyObject *errors, Py_ssize_t e) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *retobj = NULL, *retstr = NULL, *tobj; | 
					
						
							|  |  |  |     Py_ssize_t retstrsize, newpos; | 
					
						
							|  |  |  |     Py_ssize_t esize, start, end; | 
					
						
							|  |  |  |     const char *reason; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (e > 0) { | 
					
						
							|  |  |  |         reason = "illegal multibyte sequence"; | 
					
						
							|  |  |  |         esize = e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         switch (e) { | 
					
						
							|  |  |  |         case MBERR_TOOSMALL: | 
					
						
							|  |  |  |             REQUIRE_ENCODEBUFFER(buf, -1); | 
					
						
							|  |  |  |             return 0; /* retry it */ | 
					
						
							|  |  |  |         case MBERR_TOOFEW: | 
					
						
							|  |  |  |             reason = "incomplete multibyte sequence"; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |             esize = (Py_ssize_t)buf->inpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case MBERR_INTERNAL: | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  |                             "internal codec error"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  |                             "unknown runtime error"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (errors == ERROR_REPLACE) { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         PyObject *replchar; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         Py_ssize_t r; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_ssize_t inpos; | 
					
						
							|  |  |  |         int kind; | 
					
						
							|  |  |  |         void *data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         replchar = PyUnicode_FromOrdinal('?'); | 
					
						
							|  |  |  |         if (replchar == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         kind = PyUnicode_KIND(replchar); | 
					
						
							|  |  |  |         data = PyUnicode_DATA(replchar); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         inpos = 0; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         for (;;) { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |             Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |             r = codec->encode(state, codec->config, | 
					
						
							|  |  |  |                               kind, data, &inpos, 1, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                               &buf->outbuf, outleft, 0); | 
					
						
							|  |  |  |             if (r == MBERR_TOOSMALL) { | 
					
						
							|  |  |  |                 REQUIRE_ENCODEBUFFER(buf, -1); | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_DECREF(replchar); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (r != 0) { | 
					
						
							|  |  |  |             REQUIRE_ENCODEBUFFER(buf, 1); | 
					
						
							|  |  |  |             *buf->outbuf++ = '?'; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         buf->inpos += esize; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     start = (Py_ssize_t)buf->inpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     end = start + esize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* use cached exception object if available */ | 
					
						
							|  |  |  |     if (buf->excobj == NULL) { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         buf->excobj =  PyObject_CallFunction(PyExc_UnicodeEncodeError, | 
					
						
							|  |  |  |                                              "sOnns", | 
					
						
							|  |  |  |                                              codec->encoding, buf->inobj, | 
					
						
							|  |  |  |                                              start, end, reason); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (buf->excobj == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 || | 
					
						
							|  |  |  |             PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 || | 
					
						
							|  |  |  |             PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (errors == ERROR_STRICT) { | 
					
						
							|  |  |  |         PyCodec_StrictErrors(buf->excobj); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retobj = call_error_callback(errors, buf->excobj); | 
					
						
							|  |  |  |     if (retobj == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || | 
					
						
							| 
									
										
										
										
											2012-12-02 11:20:28 -05:00
										 |  |  |         (!PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) && !PyBytes_Check(tobj)) || | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "encoding error handler must return " | 
					
						
							| 
									
										
										
										
											2012-12-02 10:53:41 -05:00
										 |  |  |                         "(str, int) tuple"); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 11:20:28 -05:00
										 |  |  |     if (PyUnicode_Check(tobj)) { | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_ssize_t inpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         retstr = multibytecodec_encode(codec, state, tobj, | 
					
						
							|  |  |  |                         &inpos, ERROR_STRICT, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         MBENC_FLUSH); | 
					
						
							|  |  |  |         if (retstr == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-12-02 11:20:28 -05:00
										 |  |  |     else { | 
					
						
							|  |  |  |         Py_INCREF(tobj); | 
					
						
							|  |  |  |         retstr = tobj; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     assert(PyBytes_Check(retstr)); | 
					
						
							|  |  |  |     retstrsize = PyBytes_GET_SIZE(retstr); | 
					
						
							| 
									
										
										
										
											2015-02-21 01:19:58 +02:00
										 |  |  |     if (retstrsize > 0) { | 
					
						
							|  |  |  |         REQUIRE_ENCODEBUFFER(buf, retstrsize); | 
					
						
							|  |  |  |         memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); | 
					
						
							|  |  |  |         buf->outbuf += retstrsize; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); | 
					
						
							|  |  |  |     if (newpos < 0 && !PyErr_Occurred()) | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         newpos += (Py_ssize_t)buf->inlen; | 
					
						
							|  |  |  |     if (newpos < 0 || newpos > buf->inlen) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                      "position %zd from error handler out of bounds", | 
					
						
							|  |  |  |                      newpos); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     buf->inpos = newpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(retobj); | 
					
						
							|  |  |  |     Py_DECREF(retstr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(retobj); | 
					
						
							|  |  |  |     Py_XDECREF(retstr); | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | multibytecodec_decerror(MultibyteCodec *codec, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         MultibyteCodec_State *state, | 
					
						
							|  |  |  |                         MultibyteDecodeBuffer *buf, | 
					
						
							|  |  |  |                         PyObject *errors, Py_ssize_t e) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *retobj = NULL, *retuni = NULL; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     Py_ssize_t newpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     const char *reason; | 
					
						
							|  |  |  |     Py_ssize_t esize, start, end; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (e > 0) { | 
					
						
							|  |  |  |         reason = "illegal multibyte sequence"; | 
					
						
							|  |  |  |         esize = e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         switch (e) { | 
					
						
							|  |  |  |         case MBERR_TOOSMALL: | 
					
						
							|  |  |  |             return 0; /* retry it */ | 
					
						
							|  |  |  |         case MBERR_TOOFEW: | 
					
						
							|  |  |  |             reason = "incomplete multibyte sequence"; | 
					
						
							|  |  |  |             esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case MBERR_INTERNAL: | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  |                             "internal codec error"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2013-07-16 21:41:43 +02:00
										 |  |  |         case MBERR_EXCEPTION: | 
					
						
							|  |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         default: | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_RuntimeError, | 
					
						
							|  |  |  |                             "unknown runtime error"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (errors == ERROR_REPLACE) { | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |         if (_PyUnicodeWriter_WriteChar(&buf->writer, | 
					
						
							|  |  |  |                                        Py_UNICODE_REPLACEMENT_CHARACTER) < 0) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { | 
					
						
							|  |  |  |         buf->inbuf += esize; | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); | 
					
						
							|  |  |  |     end = start + esize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* use cached exception object if available */ | 
					
						
							|  |  |  |     if (buf->excobj == NULL) { | 
					
						
							|  |  |  |         buf->excobj = PyUnicodeDecodeError_Create(codec->encoding, | 
					
						
							|  |  |  |                         (const char *)buf->inbuf_top, | 
					
						
							|  |  |  |                         (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top), | 
					
						
							|  |  |  |                         start, end, reason); | 
					
						
							|  |  |  |         if (buf->excobj == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         if (PyUnicodeDecodeError_SetStart(buf->excobj, start) || | 
					
						
							|  |  |  |             PyUnicodeDecodeError_SetEnd(buf->excobj, end) || | 
					
						
							|  |  |  |             PyUnicodeDecodeError_SetReason(buf->excobj, reason)) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (errors == ERROR_STRICT) { | 
					
						
							|  |  |  |         PyCodec_StrictErrors(buf->excobj); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     retobj = call_error_callback(errors, buf->excobj); | 
					
						
							|  |  |  |     if (retobj == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || | 
					
						
							|  |  |  |         !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || | 
					
						
							|  |  |  |         !PyLong_Check(PyTuple_GET_ITEM(retobj, 1))) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "decoding error handler must return " | 
					
						
							| 
									
										
										
										
											2012-12-02 10:53:41 -05:00
										 |  |  |                         "(str, int) tuple"); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     if (_PyUnicodeWriter_WriteStr(&buf->writer, retuni) < 0) | 
					
						
							| 
									
										
										
										
											2011-11-21 03:01:27 +01:00
										 |  |  |         goto errorexit; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); | 
					
						
							|  |  |  |     if (newpos < 0 && !PyErr_Occurred()) | 
					
						
							|  |  |  |         newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); | 
					
						
							|  |  |  |     if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { | 
					
						
							|  |  |  |         PyErr_Clear(); | 
					
						
							|  |  |  |         PyErr_Format(PyExc_IndexError, | 
					
						
							|  |  |  |                      "position %zd from error handler out of bounds", | 
					
						
							|  |  |  |                      newpos); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     buf->inbuf = buf->inbuf_top + newpos; | 
					
						
							|  |  |  |     Py_DECREF(retobj); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(retobj); | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | multibytecodec_encode(MultibyteCodec *codec, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                       MultibyteCodec_State *state, | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |                       PyObject *text, Py_ssize_t *inpos_t, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                       PyObject *errors, int flags) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteEncodeBuffer buf; | 
					
						
							|  |  |  |     Py_ssize_t finalsize, r = 0; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     Py_ssize_t datalen; | 
					
						
							|  |  |  |     int kind; | 
					
						
							|  |  |  |     void *data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyUnicode_READY(text) < 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     datalen = PyUnicode_GET_LENGTH(text); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 22:17:55 +02:00
										 |  |  |     if (datalen == 0 && !(flags & MBENC_RESET)) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         return PyBytes_FromStringAndSize(NULL, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buf.excobj = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-22 20:15:44 +00:00
										 |  |  |     buf.outobj = NULL; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     buf.inobj = text;   /* borrowed reference */ | 
					
						
							|  |  |  |     buf.inpos = 0; | 
					
						
							|  |  |  |     buf.inlen = datalen; | 
					
						
							|  |  |  |     kind = PyUnicode_KIND(buf.inobj); | 
					
						
							|  |  |  |     data = PyUnicode_DATA(buf.inobj); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { | 
					
						
							|  |  |  |         PyErr_NoMemory(); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     buf.outobj = PyBytes_FromStringAndSize(NULL, datalen * 2 + 16); | 
					
						
							|  |  |  |     if (buf.outobj == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     buf.outbuf = (unsigned char *)PyBytes_AS_STRING(buf.outobj); | 
					
						
							|  |  |  |     buf.outbuf_end = buf.outbuf + PyBytes_GET_SIZE(buf.outobj); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     while (buf.inpos < buf.inlen) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         /* we don't reuse inleft and outleft here.
 | 
					
						
							|  |  |  |          * error callbacks can relocate the cursor anywhere on buffer*/ | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r = codec->encode(state, codec->config, | 
					
						
							|  |  |  |                           kind, data, | 
					
						
							|  |  |  |                           &buf.inpos, buf.inlen, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                           &buf.outbuf, outleft, flags); | 
					
						
							|  |  |  |         if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         else if (multibytecodec_encerror(codec, state, &buf, errors,r)) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         else if (r == MBERR_TOOFEW) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-24 22:17:55 +02:00
										 |  |  |     if (codec->encreset != NULL && (flags & MBENC_RESET)) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         for (;;) { | 
					
						
							|  |  |  |             Py_ssize_t outleft; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); | 
					
						
							|  |  |  |             r = codec->encreset(state, codec->config, &buf.outbuf, | 
					
						
							|  |  |  |                                 outleft); | 
					
						
							|  |  |  |             if (r == 0) | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             else if (multibytecodec_encerror(codec, state, | 
					
						
							|  |  |  |                                              &buf, errors, r)) | 
					
						
							|  |  |  |                 goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     finalsize = (Py_ssize_t)((char *)buf.outbuf - | 
					
						
							|  |  |  |                              PyBytes_AS_STRING(buf.outobj)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (finalsize != PyBytes_GET_SIZE(buf.outobj)) | 
					
						
							|  |  |  |         if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     if (inpos_t) | 
					
						
							|  |  |  |         *inpos_t = buf.inpos; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							|  |  |  |     return buf.outobj; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							|  |  |  |     Py_XDECREF(buf.outobj); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteCodec.encode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   input: object | 
					
						
							| 
									
										
										
										
											2019-09-14 12:24:05 +03:00
										 |  |  |   errors: str(accept={str, NoneType}) = None | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | Return an encoded string version of `input'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 'errors' may be given to set a different error handling scheme. Default is | 
					
						
							|  |  |  | 'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible | 
					
						
							|  |  |  | values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name | 
					
						
							|  |  |  | registered with codecs.register_error that can handle UnicodeEncodeErrors. | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, | 
					
						
							|  |  |  |                                            PyObject *input, | 
					
						
							|  |  |  |                                            const char *errors) | 
					
						
							| 
									
										
										
										
											2019-09-14 12:24:05 +03:00
										 |  |  | /*[clinic end generated code: output=7b26652045ba56a9 input=606d0e128a577bae]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteCodec_State state; | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     PyObject *errorcb, *r, *ucvt; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t datalen; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     if (PyUnicode_Check(input)) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         ucvt = NULL; | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |         input = ucvt = PyObject_Str(input); | 
					
						
							|  |  |  |         if (input == NULL) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             return NULL; | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |         else if (!PyUnicode_Check(input)) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                 "couldn't convert the object to unicode."); | 
					
						
							|  |  |  |             Py_DECREF(ucvt); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     if (PyUnicode_READY(input) < 0) { | 
					
						
							| 
									
										
										
										
											2011-11-21 02:50:14 +01:00
										 |  |  |         Py_XDECREF(ucvt); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     datalen = PyUnicode_GET_LENGTH(input); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     errorcb = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (errorcb == NULL) { | 
					
						
							|  |  |  |         Py_XDECREF(ucvt); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (self->codec->encinit != NULL && | 
					
						
							|  |  |  |         self->codec->encinit(&state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     r = multibytecodec_encode(self->codec, &state, | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |                     input, NULL, errorcb, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     MBENC_FLUSH | MBENC_RESET); | 
					
						
							|  |  |  |     if (r == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ERROR_DECREF(errorcb); | 
					
						
							|  |  |  |     Py_XDECREF(ucvt); | 
					
						
							|  |  |  |     return make_tuple(r, datalen); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     ERROR_DECREF(errorcb); | 
					
						
							|  |  |  |     Py_XDECREF(ucvt); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteCodec.decode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   input: Py_buffer | 
					
						
							| 
									
										
										
										
											2019-09-14 12:24:05 +03:00
										 |  |  |   errors: str(accept={str, NoneType}) = None | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | Decodes 'input'. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 'errors' may be given to set a different error handling scheme. Default is | 
					
						
							|  |  |  | 'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible | 
					
						
							|  |  |  | values are 'ignore' and 'replace' as well as any other name registered with | 
					
						
							|  |  |  | codecs.register_error that is able to handle UnicodeDecodeErrors." | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, | 
					
						
							|  |  |  |                                            Py_buffer *input, | 
					
						
							|  |  |  |                                            const char *errors) | 
					
						
							| 
									
										
										
										
											2019-09-14 12:24:05 +03:00
										 |  |  | /*[clinic end generated code: output=ff419f65bad6cc77 input=e0c78fc7ab190def]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteCodec_State state; | 
					
						
							|  |  |  |     MultibyteDecodeBuffer buf; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     PyObject *errorcb, *res; | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     const char *data; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     Py_ssize_t datalen; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     data = input->buf; | 
					
						
							|  |  |  |     datalen = input->len; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     errorcb = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (errorcb == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (datalen == 0) { | 
					
						
							|  |  |  |         ERROR_DECREF(errorcb); | 
					
						
							| 
									
										
										
										
											2011-12-01 03:18:59 +01:00
										 |  |  |         return make_tuple(PyUnicode_New(0, 0), 0); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:02:17 +02:00
										 |  |  |     _PyUnicodeWriter_Init(&buf.writer); | 
					
						
							|  |  |  |     buf.writer.min_length = datalen; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     buf.excobj = NULL; | 
					
						
							|  |  |  |     buf.inbuf = buf.inbuf_top = (unsigned char *)data; | 
					
						
							|  |  |  |     buf.inbuf_end = buf.inbuf_top + datalen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (self->codec->decinit != NULL && | 
					
						
							|  |  |  |         self->codec->decinit(&state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while (buf.inbuf < buf.inbuf_end) { | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |         Py_ssize_t inleft, r; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r = self->codec->decode(&state, self->codec->config, | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |                         &buf.inbuf, inleft, &buf.writer); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (r == 0) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         else if (multibytecodec_decerror(self->codec, &state, | 
					
						
							|  |  |  |                                          &buf, errorcb, r)) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     res = _PyUnicodeWriter_Finish(&buf.writer); | 
					
						
							|  |  |  |     if (res == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							|  |  |  |     ERROR_DECREF(errorcb); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     return make_tuple(res, datalen); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     ERROR_DECREF(errorcb); | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     _PyUnicodeWriter_Dealloc(&buf.writer); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef multibytecodec_methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | multibytecodec_dealloc(MultibyteCodecObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject_Del(self); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MultibyteCodec_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MultibyteCodec",                   /* tp_name */ | 
					
						
							|  |  |  |     sizeof(MultibyteCodecObject),       /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                  /* tp_itemsize */ | 
					
						
							|  |  |  |     /* methods */ | 
					
						
							|  |  |  |     (destructor)multibytecodec_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_repr */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_mapping */ | 
					
						
							|  |  |  |     0,                                  /* tp_hash */ | 
					
						
							|  |  |  |     0,                                  /* tp_call */ | 
					
						
							|  |  |  |     0,                                  /* tp_str */ | 
					
						
							|  |  |  |     PyObject_GenericGetAttr,            /* tp_getattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT,                 /* tp_flags */ | 
					
						
							|  |  |  |     0,                                  /* tp_doc */ | 
					
						
							|  |  |  |     0,                                  /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                  /* tp_clear */ | 
					
						
							|  |  |  |     0,                                  /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                  /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                  /* tp_iter */ | 
					
						
							|  |  |  |     0,                                  /* tp_iterext */ | 
					
						
							|  |  |  |     multibytecodec_methods,             /* tp_methods */ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Utility functions for stateful codec mechanism | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | #define STATEFUL_DCTX(o)        ((MultibyteStatefulDecoderContext *)(o))
 | 
					
						
							|  |  |  | #define STATEFUL_ECTX(o)        ((MultibyteStatefulEncoderContext *)(o))
 | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							|  |  |  | encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         PyObject *unistr, int final) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *ucvt, *r = NULL; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     PyObject *inbuf = NULL; | 
					
						
							|  |  |  |     Py_ssize_t inpos, datalen; | 
					
						
							|  |  |  |     PyObject *origpending = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (PyUnicode_Check(unistr)) | 
					
						
							|  |  |  |         ucvt = NULL; | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         unistr = ucvt = PyObject_Str(unistr); | 
					
						
							|  |  |  |         if (unistr == NULL) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         else if (!PyUnicode_Check(unistr)) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_TypeError, | 
					
						
							| 
									
										
										
										
											2012-12-02 10:53:41 -05:00
										 |  |  |                 "couldn't convert the object to str."); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             Py_DECREF(ucvt); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     if (ctx->pending) { | 
					
						
							|  |  |  |         PyObject *inbuf_tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_INCREF(ctx->pending); | 
					
						
							|  |  |  |         origpending = ctx->pending; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_INCREF(ctx->pending); | 
					
						
							|  |  |  |         inbuf_tmp = ctx->pending; | 
					
						
							|  |  |  |         PyUnicode_Append(&inbuf_tmp, unistr); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (inbuf_tmp == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_CLEAR(ctx->pending); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         inbuf = inbuf_tmp; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     else { | 
					
						
							|  |  |  |         origpending = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         Py_INCREF(unistr); | 
					
						
							|  |  |  |         inbuf = unistr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (PyUnicode_READY(inbuf) < 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     inpos = 0; | 
					
						
							|  |  |  |     datalen = PyUnicode_GET_LENGTH(inbuf); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     r = multibytecodec_encode(ctx->codec, &ctx->state, | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |                               inbuf, &inpos, | 
					
						
							|  |  |  |                               ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (r == NULL) { | 
					
						
							|  |  |  |         /* recover the original pending buffer */ | 
					
						
							| 
									
										
										
										
											2016-04-06 09:45:48 +03:00
										 |  |  |         Py_XSETREF(ctx->pending, origpending); | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         origpending = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-14 18:11:41 +02:00
										 |  |  |     Py_XDECREF(origpending); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     if (inpos < datalen) { | 
					
						
							|  |  |  |         if (datalen - inpos > MAXENCPENDING) { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             /* normal codecs can't reach here */ | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_UnicodeError, | 
					
						
							|  |  |  |                             "pending buffer overflow"); | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |         ctx->pending = PyUnicode_Substring(inbuf, inpos, datalen); | 
					
						
							|  |  |  |         if (ctx->pending == NULL) { | 
					
						
							|  |  |  |             /* normal codecs can't reach here */ | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-14 18:11:41 +02:00
										 |  |  |     Py_DECREF(inbuf); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(ucvt); | 
					
						
							|  |  |  |     return r; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(r); | 
					
						
							|  |  |  |     Py_XDECREF(ucvt); | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     Py_XDECREF(origpending); | 
					
						
							| 
									
										
										
										
											2013-04-14 18:11:41 +02:00
										 |  |  |     Py_XDECREF(inbuf); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | decoder_append_pending(MultibyteStatefulDecoderContext *ctx, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                        MultibyteDecodeBuffer *buf) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t npendings; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); | 
					
						
							|  |  |  |     if (npendings + ctx->pendingsize > MAXDECPENDING || | 
					
						
							|  |  |  |         npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); | 
					
						
							|  |  |  |     ctx->pendingsize += npendings; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | decoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                        Py_ssize_t size) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     buf->inbuf = buf->inbuf_top = (const unsigned char *)data; | 
					
						
							|  |  |  |     buf->inbuf_end = buf->inbuf_top + size; | 
					
						
							| 
									
										
										
										
											2013-04-17 23:02:17 +02:00
										 |  |  |     buf->writer.min_length += size; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     MultibyteDecodeBuffer *buf) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     while (buf->inbuf < buf->inbuf_end) { | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |         Py_ssize_t inleft; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         Py_ssize_t r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r = ctx->codec->decode(&ctx->state, ctx->codec->config, | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |             &buf->inbuf, inleft, &buf->writer); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (r == 0 || r == MBERR_TOOFEW) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         else if (multibytecodec_decerror(ctx->codec, &ctx->state, | 
					
						
							|  |  |  |                                          buf, ctx->errors, r)) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalEncoder.encode | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     input: object | 
					
						
							| 
									
										
										
										
											2017-03-12 10:10:47 +02:00
										 |  |  |     final: bool(accept={int}) = False | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, | 
					
						
							|  |  |  |                                                         PyObject *input, | 
					
						
							|  |  |  |                                                         int final) | 
					
						
							| 
									
										
										
										
											2017-03-12 10:10:47 +02:00
										 |  |  | /*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalEncoder.getstate | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _multibytecodec_MultibyteIncrementalEncoder_getstate_impl(MultibyteIncrementalEncoderObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=9794a5ace70d7048 input=4a2a82874ffa40bb]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* state made up of 1 byte for buffer size, up to MAXENCPENDING*4 bytes
 | 
					
						
							|  |  |  |        for UTF-8 encoded buffer (each character can use up to 4 | 
					
						
							|  |  |  |        bytes), and required bytes for MultibyteCodec_State.c. A byte | 
					
						
							|  |  |  |        array is used to avoid different compilers generating different | 
					
						
							|  |  |  |        values for the same state, e.g. as a result of struct padding. | 
					
						
							|  |  |  |     */ | 
					
						
							|  |  |  |     unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; | 
					
						
							|  |  |  |     Py_ssize_t statesize; | 
					
						
							|  |  |  |     const char *pendingbuffer = NULL; | 
					
						
							|  |  |  |     Py_ssize_t pendingsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (self->pending != NULL) { | 
					
						
							|  |  |  |         pendingbuffer = PyUnicode_AsUTF8AndSize(self->pending, &pendingsize); | 
					
						
							|  |  |  |         if (pendingbuffer == NULL) { | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (pendingsize > MAXENCPENDING*4) { | 
					
						
							|  |  |  |             PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-11-22 10:25:46 +01:00
										 |  |  |         statebytes[0] = (unsigned char)pendingsize; | 
					
						
							|  |  |  |         memcpy(statebytes + 1, pendingbuffer, pendingsize); | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |         statesize = 1 + pendingsize; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         statebytes[0] = 0; | 
					
						
							|  |  |  |         statesize = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     memcpy(statebytes+statesize, self->state.c, | 
					
						
							|  |  |  |            sizeof(self->state.c)); | 
					
						
							|  |  |  |     statesize += sizeof(self->state.c); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return (PyObject *)_PyLong_FromByteArray(statebytes, statesize, | 
					
						
							|  |  |  |                                              1 /* little-endian */ , | 
					
						
							|  |  |  |                                              0 /* unsigned */ ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalEncoder.setstate | 
					
						
							|  |  |  |     state as statelong: object(type='PyLongObject *', subclass_of='&PyLong_Type') | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEncoderObject *self, | 
					
						
							|  |  |  |                                                           PyLongObject *statelong) | 
					
						
							|  |  |  | /*[clinic end generated code: output=4e5e98ac1f4039ca input=c80fb5830d4d2f76]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *pending = NULL; | 
					
						
							|  |  |  |     unsigned char statebytes[1 + MAXENCPENDING*4 + sizeof(self->state.c)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), | 
					
						
							|  |  |  |                             1 /* little-endian */ , | 
					
						
							|  |  |  |                             0 /* unsigned */ ) < 0) { | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (statebytes[0] > MAXENCPENDING*4) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pending = PyUnicode_DecodeUTF8((const char *)statebytes+1, | 
					
						
							|  |  |  |                                    statebytes[0], "strict"); | 
					
						
							|  |  |  |     if (pending == NULL) { | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_CLEAR(self->pending); | 
					
						
							|  |  |  |     self->pending = pending; | 
					
						
							|  |  |  |     memcpy(self->state.c, statebytes+1+statebytes[0], | 
					
						
							|  |  |  |            sizeof(self->state.c)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							|  |  |  |     Py_XDECREF(pending); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalEncoder.reset | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | _multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-30 22:56:00 +02:00
										 |  |  |     /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ | 
					
						
							|  |  |  |     unsigned char buffer[4], *outbuf; | 
					
						
							|  |  |  |     Py_ssize_t r; | 
					
						
							|  |  |  |     if (self->codec->encreset != NULL) { | 
					
						
							|  |  |  |         outbuf = buffer; | 
					
						
							|  |  |  |         r = self->codec->encreset(&self->state, self->codec->config, | 
					
						
							|  |  |  |                                   &outbuf, sizeof(buffer)); | 
					
						
							|  |  |  |         if (r != 0) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     Py_CLEAR(self->pending); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static struct PyMethodDef mbiencoder_methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_GETSTATE_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_SETSTATE_METHODDEF | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteIncrementalEncoderObject *self; | 
					
						
							|  |  |  |     PyObject *codec = NULL; | 
					
						
							|  |  |  |     char *errors = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", | 
					
						
							|  |  |  |                                      incnewkwarglist, &errors)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     if (self == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     codec = PyObject_GetAttrString((PyObject *)type, "codec"); | 
					
						
							|  |  |  |     if (codec == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (!MultibyteCodec_Check(codec)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self->codec = ((MultibyteCodecObject *)codec)->codec; | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     self->pending = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     self->errors = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (self->errors == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (self->codec->encinit != NULL && | 
					
						
							|  |  |  |         self->codec->encinit(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(codec); | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(self); | 
					
						
							|  |  |  |     Py_XDECREF(codec); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbiencoder_traverse(MultibyteIncrementalEncoderObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (ERROR_ISCUSTOM(self->errors)) | 
					
						
							|  |  |  |         Py_VISIT(self->errors); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | mbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     ERROR_DECREF(self->errors); | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     Py_CLEAR(self->pending); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MultibyteIncrementalEncoder_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MultibyteIncrementalEncoder",      /* tp_name */ | 
					
						
							|  |  |  |     sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                  /* tp_itemsize */ | 
					
						
							|  |  |  |     /*  methods  */ | 
					
						
							|  |  |  |     (destructor)mbiencoder_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_repr */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_mapping */ | 
					
						
							|  |  |  |     0,                                  /* tp_hash */ | 
					
						
							|  |  |  |     0,                                  /* tp_call */ | 
					
						
							|  |  |  |     0,                                  /* tp_str */ | 
					
						
							|  |  |  |     PyObject_GenericGetAttr,            /* tp_getattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
					
						
							|  |  |  |         | Py_TPFLAGS_BASETYPE,          /* tp_flags */ | 
					
						
							|  |  |  |     0,                                  /* tp_doc */ | 
					
						
							|  |  |  |     (traverseproc)mbiencoder_traverse,          /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                  /* tp_clear */ | 
					
						
							|  |  |  |     0,                                  /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                  /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                  /* tp_iter */ | 
					
						
							|  |  |  |     0,                                  /* tp_iterext */ | 
					
						
							|  |  |  |     mbiencoder_methods,                 /* tp_methods */ | 
					
						
							|  |  |  |     0,                                  /* tp_members */ | 
					
						
							|  |  |  |     codecctx_getsets,                   /* tp_getset */ | 
					
						
							|  |  |  |     0,                                  /* tp_base */ | 
					
						
							|  |  |  |     0,                                  /* tp_dict */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                  /* tp_dictoffset */ | 
					
						
							|  |  |  |     mbiencoder_init,                    /* tp_init */ | 
					
						
							|  |  |  |     0,                                  /* tp_alloc */ | 
					
						
							|  |  |  |     mbiencoder_new,                     /* tp_new */ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalDecoder.decode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     input: Py_buffer | 
					
						
							| 
									
										
										
										
											2017-03-12 10:10:47 +02:00
										 |  |  |     final: bool(accept={int}) = False | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, | 
					
						
							|  |  |  |                                                         Py_buffer *input, | 
					
						
							|  |  |  |                                                         int final) | 
					
						
							| 
									
										
										
										
											2017-03-12 10:10:47 +02:00
										 |  |  | /*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteDecodeBuffer buf; | 
					
						
							|  |  |  |     char *data, *wdata = NULL; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     Py_ssize_t wsize, size, origpending; | 
					
						
							|  |  |  |     PyObject *res; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     data = input->buf; | 
					
						
							|  |  |  |     size = input->len; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:02:17 +02:00
										 |  |  |     _PyUnicodeWriter_Init(&buf.writer); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     buf.excobj = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     origpending = self->pendingsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (self->pendingsize == 0) { | 
					
						
							|  |  |  |         wsize = size; | 
					
						
							|  |  |  |         wdata = data; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         if (size > PY_SSIZE_T_MAX - self->pendingsize) { | 
					
						
							|  |  |  |             PyErr_NoMemory(); | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         wsize = size + self->pendingsize; | 
					
						
							|  |  |  |         wdata = PyMem_Malloc(wsize); | 
					
						
							| 
									
										
										
										
											2013-07-15 17:47:39 +02:00
										 |  |  |         if (wdata == NULL) { | 
					
						
							|  |  |  |             PyErr_NoMemory(); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             goto errorexit; | 
					
						
							| 
									
										
										
										
											2013-07-15 17:47:39 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         memcpy(wdata, self->pending, self->pendingsize); | 
					
						
							|  |  |  |         memcpy(wdata + self->pendingsize, data, size); | 
					
						
							|  |  |  |         self->pendingsize = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (decoder_prepare_buffer(&buf, wdata, wsize) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf)) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (final && buf.inbuf < buf.inbuf_end) { | 
					
						
							|  |  |  |         if (multibytecodec_decerror(self->codec, &self->state, | 
					
						
							|  |  |  |                         &buf, self->errors, MBERR_TOOFEW)) { | 
					
						
							|  |  |  |             /* recover the original pending buffer */ | 
					
						
							|  |  |  |             memcpy(self->pending, wdata, origpending); | 
					
						
							|  |  |  |             self->pendingsize = origpending; | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */ | 
					
						
							|  |  |  |         if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     res = _PyUnicodeWriter_Finish(&buf.writer); | 
					
						
							|  |  |  |     if (res == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (wdata != data) | 
					
						
							|  |  |  |         PyMem_Del(wdata); | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (wdata != NULL && wdata != data) | 
					
						
							|  |  |  |         PyMem_Del(wdata); | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     _PyUnicodeWriter_Dealloc(&buf.writer); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalDecoder.getstate | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _multibytecodec_MultibyteIncrementalDecoder_getstate_impl(MultibyteIncrementalDecoderObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=255009c4713b7f82 input=4006aa49bddbaa75]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *buffer; | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     PyObject *statelong; | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     buffer = PyBytes_FromStringAndSize((const char *)self->pending, | 
					
						
							|  |  |  |                                        self->pendingsize); | 
					
						
							|  |  |  |     if (buffer == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     statelong = (PyObject *)_PyLong_FromByteArray(self->state.c, | 
					
						
							|  |  |  |                                                   sizeof(self->state.c), | 
					
						
							|  |  |  |                                                   1 /* little-endian */ , | 
					
						
							|  |  |  |                                                   0 /* unsigned */ ); | 
					
						
							|  |  |  |     if (statelong == NULL) { | 
					
						
							|  |  |  |         Py_DECREF(buffer); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return Py_BuildValue("NN", buffer, statelong); | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalDecoder.setstate | 
					
						
							|  |  |  |     state: object(subclass_of='&PyTuple_Type') | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | _multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDecoderObject *self, | 
					
						
							|  |  |  |                                                           PyObject *state) | 
					
						
							|  |  |  | /*[clinic end generated code: output=106b2fbca3e2dcc2 input=e5d794e8baba1a47]*/ | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *buffer; | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     PyLongObject *statelong; | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     Py_ssize_t buffersize; | 
					
						
							|  |  |  |     char *bufferstr; | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     unsigned char statebytes[8]; | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     if (!PyArg_ParseTuple(state, "SO!;setstate(): illegal state argument", | 
					
						
							|  |  |  |                           &buffer, &PyLong_Type, &statelong)) | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes), | 
					
						
							|  |  |  |                             1 /* little-endian */ , | 
					
						
							|  |  |  |                             0 /* unsigned */ ) < 0) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     buffersize = PyBytes_Size(buffer); | 
					
						
							|  |  |  |     if (buffersize == -1) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (buffersize > MAXDECPENDING) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_UnicodeError, "pending buffer too large"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bufferstr = PyBytes_AsString(buffer); | 
					
						
							|  |  |  |     if (bufferstr == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     self->pendingsize = buffersize; | 
					
						
							|  |  |  |     memcpy(self->pending, bufferstr, self->pendingsize); | 
					
						
							| 
									
										
										
										
											2018-11-02 03:29:40 +00:00
										 |  |  |     memcpy(self->state.c, statebytes, sizeof(statebytes)); | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.MultibyteIncrementalDecoder.reset | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | _multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (self->codec->decreset != NULL && | 
					
						
							|  |  |  |         self->codec->decreset(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     self->pendingsize = 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef mbidecoder_methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF | 
					
						
							| 
									
										
										
										
											2018-11-01 10:48:49 +00:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_GETSTATE_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_SETSTATE_METHODDEF | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteIncrementalDecoderObject *self; | 
					
						
							|  |  |  |     PyObject *codec = NULL; | 
					
						
							|  |  |  |     char *errors = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", | 
					
						
							|  |  |  |                                      incnewkwarglist, &errors)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     if (self == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     codec = PyObject_GetAttrString((PyObject *)type, "codec"); | 
					
						
							|  |  |  |     if (codec == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (!MultibyteCodec_Check(codec)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self->codec = ((MultibyteCodecObject *)codec)->codec; | 
					
						
							|  |  |  |     self->pendingsize = 0; | 
					
						
							|  |  |  |     self->errors = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (self->errors == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (self->codec->decinit != NULL && | 
					
						
							|  |  |  |         self->codec->decinit(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(codec); | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(self); | 
					
						
							|  |  |  |     Py_XDECREF(codec); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbidecoder_traverse(MultibyteIncrementalDecoderObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (ERROR_ISCUSTOM(self->errors)) | 
					
						
							|  |  |  |         Py_VISIT(self->errors); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | mbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     ERROR_DECREF(self->errors); | 
					
						
							|  |  |  |     Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MultibyteIncrementalDecoder_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MultibyteIncrementalDecoder",      /* tp_name */ | 
					
						
							|  |  |  |     sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                  /* tp_itemsize */ | 
					
						
							|  |  |  |     /*  methods  */ | 
					
						
							|  |  |  |     (destructor)mbidecoder_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_repr */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_mapping */ | 
					
						
							|  |  |  |     0,                                  /* tp_hash */ | 
					
						
							|  |  |  |     0,                                  /* tp_call */ | 
					
						
							|  |  |  |     0,                                  /* tp_str */ | 
					
						
							|  |  |  |     PyObject_GenericGetAttr,            /* tp_getattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
					
						
							|  |  |  |         | Py_TPFLAGS_BASETYPE,          /* tp_flags */ | 
					
						
							|  |  |  |     0,                                  /* tp_doc */ | 
					
						
							|  |  |  |     (traverseproc)mbidecoder_traverse,          /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                  /* tp_clear */ | 
					
						
							|  |  |  |     0,                                  /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                  /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                  /* tp_iter */ | 
					
						
							|  |  |  |     0,                                  /* tp_iterext */ | 
					
						
							|  |  |  |     mbidecoder_methods,                 /* tp_methods */ | 
					
						
							|  |  |  |     0,                                  /* tp_members */ | 
					
						
							|  |  |  |     codecctx_getsets,                   /* tp_getset */ | 
					
						
							|  |  |  |     0,                                  /* tp_base */ | 
					
						
							|  |  |  |     0,                                  /* tp_dict */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                  /* tp_dictoffset */ | 
					
						
							|  |  |  |     mbidecoder_init,                    /* tp_init */ | 
					
						
							|  |  |  |     0,                                  /* tp_alloc */ | 
					
						
							|  |  |  |     mbidecoder_new,                     /* tp_new */ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | mbstreamreader_iread(MultibyteStreamReaderObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                      const char *method, Py_ssize_t sizehint) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteDecodeBuffer buf; | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     PyObject *cres, *res; | 
					
						
							|  |  |  |     Py_ssize_t rsize; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (sizehint == 0) | 
					
						
							| 
									
										
										
										
											2011-12-01 03:18:59 +01:00
										 |  |  |         return PyUnicode_New(0, 0); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-17 23:02:17 +02:00
										 |  |  |     _PyUnicodeWriter_Init(&buf.writer); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     buf.excobj = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     cres = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (;;) { | 
					
						
							|  |  |  |         int endoffile; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (sizehint < 0) | 
					
						
							|  |  |  |             cres = PyObject_CallMethod(self->stream, | 
					
						
							| 
									
										
										
										
											2014-09-28 11:27:24 +03:00
										 |  |  |                             method, NULL); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |             cres = PyObject_CallMethod(self->stream, | 
					
						
							| 
									
										
										
										
											2014-09-28 11:27:24 +03:00
										 |  |  |                             method, "i", sizehint); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (cres == NULL) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!PyBytes_Check(cres)) { | 
					
						
							|  |  |  |             PyErr_Format(PyExc_TypeError, | 
					
						
							|  |  |  |                          "stream function returned a " | 
					
						
							|  |  |  |                          "non-bytes object (%.100s)", | 
					
						
							| 
									
										
										
										
											2020-02-07 03:37:06 +01:00
										 |  |  |                          Py_TYPE(cres)->tp_name); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         endoffile = (PyBytes_GET_SIZE(cres) == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (self->pendingsize > 0) { | 
					
						
							|  |  |  |             PyObject *ctr; | 
					
						
							|  |  |  |             char *ctrdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (PyBytes_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { | 
					
						
							|  |  |  |                 PyErr_NoMemory(); | 
					
						
							|  |  |  |                 goto errorexit; | 
					
						
							| 
									
										
										
										
											2013-07-08 22:28:27 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             rsize = PyBytes_GET_SIZE(cres) + self->pendingsize; | 
					
						
							|  |  |  |             ctr = PyBytes_FromStringAndSize(NULL, rsize); | 
					
						
							|  |  |  |             if (ctr == NULL) | 
					
						
							|  |  |  |                 goto errorexit; | 
					
						
							|  |  |  |             ctrdata = PyBytes_AS_STRING(ctr); | 
					
						
							|  |  |  |             memcpy(ctrdata, self->pending, self->pendingsize); | 
					
						
							|  |  |  |             memcpy(ctrdata + self->pendingsize, | 
					
						
							|  |  |  |                     PyBytes_AS_STRING(cres), | 
					
						
							|  |  |  |                     PyBytes_GET_SIZE(cres)); | 
					
						
							|  |  |  |             Py_DECREF(cres); | 
					
						
							|  |  |  |             cres = ctr; | 
					
						
							|  |  |  |             self->pendingsize = 0; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rsize = PyBytes_GET_SIZE(cres); | 
					
						
							|  |  |  |         if (decoder_prepare_buffer(&buf, PyBytes_AS_STRING(cres), | 
					
						
							|  |  |  |                                    rsize) != 0) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (rsize > 0 && decoder_feed_buffer( | 
					
						
							|  |  |  |                         (MultibyteStatefulDecoderContext *)self, &buf)) | 
					
						
							|  |  |  |             goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (endoffile || sizehint < 0) { | 
					
						
							|  |  |  |             if (buf.inbuf < buf.inbuf_end && | 
					
						
							|  |  |  |                 multibytecodec_decerror(self->codec, &self->state, | 
					
						
							|  |  |  |                             &buf, self->errors, MBERR_TOOFEW)) | 
					
						
							|  |  |  |                 goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */ | 
					
						
							|  |  |  |             if (decoder_append_pending(STATEFUL_DCTX(self), | 
					
						
							|  |  |  |                                        &buf) != 0) | 
					
						
							|  |  |  |                 goto errorexit; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Py_DECREF(cres); | 
					
						
							|  |  |  |         cres = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |         if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sizehint = 1; /* read 1 more byte and retry */ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     res = _PyUnicodeWriter_Finish(&buf.writer); | 
					
						
							|  |  |  |     if (res == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_XDECREF(cres); | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(cres); | 
					
						
							|  |  |  |     Py_XDECREF(buf.excobj); | 
					
						
							| 
									
										
										
										
											2013-04-11 22:09:04 +02:00
										 |  |  |     _PyUnicodeWriter_Dealloc(&buf.writer); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamReader.read | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sizeobj: object = None | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, | 
					
						
							|  |  |  |                                                 PyObject *sizeobj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t size; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     if (sizeobj == Py_None) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         size = -1; | 
					
						
							|  |  |  |     else if (PyLong_Check(sizeobj)) | 
					
						
							|  |  |  |         size = PyLong_AsSsize_t(sizeobj); | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (size == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2007-01-14 03:31:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return mbstreamreader_iread(self, "read", size); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamReader.readline | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sizeobj: object = None | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, | 
					
						
							|  |  |  |                                                     PyObject *sizeobj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t size; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     if (sizeobj == Py_None) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         size = -1; | 
					
						
							|  |  |  |     else if (PyLong_Check(sizeobj)) | 
					
						
							|  |  |  |         size = PyLong_AsSsize_t(sizeobj); | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (size == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2007-01-14 03:31:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return mbstreamreader_iread(self, "readline", size); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamReader.readlines | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sizehintobj: object = None | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, | 
					
						
							|  |  |  |                                                      PyObject *sizehintobj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     PyObject *r, *sr; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_ssize_t sizehint; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     if (sizehintobj == Py_None) | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         sizehint = -1; | 
					
						
							|  |  |  |     else if (PyLong_Check(sizehintobj)) | 
					
						
							|  |  |  |         sizehint = PyLong_AsSsize_t(sizehintobj); | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (sizehint == -1 && PyErr_Occurred()) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     r = mbstreamreader_iread(self, "read", sizehint); | 
					
						
							|  |  |  |     if (r == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sr = PyUnicode_Splitlines(r, 1); | 
					
						
							|  |  |  |     Py_DECREF(r); | 
					
						
							|  |  |  |     return sr; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamReader.reset | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | _multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (self->codec->decreset != NULL && | 
					
						
							|  |  |  |         self->codec->decreset(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     self->pendingsize = 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef mbstreamreader_methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {NULL,              NULL}, | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyMemberDef mbstreamreader_members[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"stream",          T_OBJECT, | 
					
						
							|  |  |  |                     offsetof(MultibyteStreamReaderObject, stream), | 
					
						
							|  |  |  |                     READONLY, NULL}, | 
					
						
							|  |  |  |     {NULL,} | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteStreamReaderObject *self; | 
					
						
							|  |  |  |     PyObject *stream, *codec = NULL; | 
					
						
							|  |  |  |     char *errors = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", | 
					
						
							|  |  |  |                             streamkwarglist, &stream, &errors)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     if (self == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     codec = PyObject_GetAttrString((PyObject *)type, "codec"); | 
					
						
							|  |  |  |     if (codec == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (!MultibyteCodec_Check(codec)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self->codec = ((MultibyteCodecObject *)codec)->codec; | 
					
						
							|  |  |  |     self->stream = stream; | 
					
						
							|  |  |  |     Py_INCREF(stream); | 
					
						
							|  |  |  |     self->pendingsize = 0; | 
					
						
							|  |  |  |     self->errors = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (self->errors == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (self->codec->decinit != NULL && | 
					
						
							|  |  |  |         self->codec->decinit(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(codec); | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(self); | 
					
						
							|  |  |  |     Py_XDECREF(codec); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbstreamreader_traverse(MultibyteStreamReaderObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (ERROR_ISCUSTOM(self->errors)) | 
					
						
							|  |  |  |         Py_VISIT(self->errors); | 
					
						
							|  |  |  |     Py_VISIT(self->stream); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static void | 
					
						
							|  |  |  | mbstreamreader_dealloc(MultibyteStreamReaderObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     ERROR_DECREF(self->errors); | 
					
						
							|  |  |  |     Py_XDECREF(self->stream); | 
					
						
							|  |  |  |     Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MultibyteStreamReader_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MultibyteStreamReader",            /* tp_name */ | 
					
						
							|  |  |  |     sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                  /* tp_itemsize */ | 
					
						
							|  |  |  |     /*  methods  */ | 
					
						
							|  |  |  |     (destructor)mbstreamreader_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_repr */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_mapping */ | 
					
						
							|  |  |  |     0,                                  /* tp_hash */ | 
					
						
							|  |  |  |     0,                                  /* tp_call */ | 
					
						
							|  |  |  |     0,                                  /* tp_str */ | 
					
						
							|  |  |  |     PyObject_GenericGetAttr,            /* tp_getattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
					
						
							|  |  |  |         | Py_TPFLAGS_BASETYPE,          /* tp_flags */ | 
					
						
							|  |  |  |     0,                                  /* tp_doc */ | 
					
						
							|  |  |  |     (traverseproc)mbstreamreader_traverse,      /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                  /* tp_clear */ | 
					
						
							|  |  |  |     0,                                  /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                  /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                  /* tp_iter */ | 
					
						
							|  |  |  |     0,                                  /* tp_iterext */ | 
					
						
							|  |  |  |     mbstreamreader_methods,             /* tp_methods */ | 
					
						
							|  |  |  |     mbstreamreader_members,             /* tp_members */ | 
					
						
							|  |  |  |     codecctx_getsets,                   /* tp_getset */ | 
					
						
							|  |  |  |     0,                                  /* tp_base */ | 
					
						
							|  |  |  |     0,                                  /* tp_dict */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                  /* tp_dictoffset */ | 
					
						
							|  |  |  |     mbstreamreader_init,                /* tp_init */ | 
					
						
							|  |  |  |     0,                                  /* tp_alloc */ | 
					
						
							|  |  |  |     mbstreamreader_new,                 /* tp_new */ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                       PyObject *unistr) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *str, *wr; | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); | 
					
						
							|  |  |  |     if (str == NULL) | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 10:59:05 +02:00
										 |  |  |     wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, str); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_DECREF(str); | 
					
						
							|  |  |  |     if (wr == NULL) | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2004-07-18 03:06:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_DECREF(wr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamWriter.write | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     strobj: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, | 
					
						
							|  |  |  |                                             PyObject *strobj) | 
					
						
							|  |  |  | /*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (mbstreamwriter_iwrite(self, strobj)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamWriter.writelines | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lines: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2015-04-14 18:07:59 -04:00
										 |  |  | _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, | 
					
						
							|  |  |  |                                                  PyObject *lines) | 
					
						
							|  |  |  | /*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *strobj; | 
					
						
							|  |  |  |     int i, r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PySequence_Check(lines)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, | 
					
						
							|  |  |  |                         "arg must be a sequence object"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < PySequence_Length(lines); i++) { | 
					
						
							|  |  |  |         /* length can be changed even within this loop */ | 
					
						
							|  |  |  |         strobj = PySequence_GetItem(lines, i); | 
					
						
							|  |  |  |         if (strobj == NULL) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r = mbstreamwriter_iwrite(self, strobj); | 
					
						
							|  |  |  |         Py_DECREF(strobj); | 
					
						
							|  |  |  |         if (r == -1) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-04-19 20:03:52 +03:00
										 |  |  |     /* PySequence_Length() can fail */ | 
					
						
							|  |  |  |     if (PyErr_Occurred()) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  |  _multibytecodec.MultibyteStreamWriter.reset | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) | 
					
						
							|  |  |  | /*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject *pwrt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-16 22:17:31 +02:00
										 |  |  |     if (!self->pending) | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     pwrt = multibytecodec_encode(self->codec, &self->state, | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |                     self->pending, NULL, self->errors, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                     MBENC_FLUSH | MBENC_RESET); | 
					
						
							|  |  |  |     /* some pending buffer can be truncated when UnicodeEncodeError is
 | 
					
						
							|  |  |  |      * raised on 'strict' mode. but, 'reset' method is designed to | 
					
						
							|  |  |  |      * reset the pending buffer or states so failed string sequence | 
					
						
							|  |  |  |      * ought to be missed */ | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     Py_CLEAR(self->pending); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (pwrt == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(PyBytes_Check(pwrt)); | 
					
						
							|  |  |  |     if (PyBytes_Size(pwrt) > 0) { | 
					
						
							|  |  |  |         PyObject *wr; | 
					
						
							| 
									
										
										
										
											2011-10-09 10:38:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-11 10:59:05 +02:00
										 |  |  |         wr = _PyObject_CallMethodIdOneArg(self->stream, &PyId_write, pwrt); | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |         if (wr == NULL) { | 
					
						
							|  |  |  |             Py_DECREF(pwrt); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Py_DECREF(pwrt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteStreamWriterObject *self; | 
					
						
							|  |  |  |     PyObject *stream, *codec = NULL; | 
					
						
							|  |  |  |     char *errors = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", | 
					
						
							|  |  |  |                             streamkwarglist, &stream, &errors)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0); | 
					
						
							|  |  |  |     if (self == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     codec = PyObject_GetAttrString((PyObject *)type, "codec"); | 
					
						
							|  |  |  |     if (codec == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (!MultibyteCodec_Check(codec)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     self->codec = ((MultibyteCodecObject *)codec)->codec; | 
					
						
							|  |  |  |     self->stream = stream; | 
					
						
							|  |  |  |     Py_INCREF(stream); | 
					
						
							| 
									
										
										
										
											2013-04-14 02:06:32 +02:00
										 |  |  |     self->pending = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     self->errors = internal_error_callback(errors); | 
					
						
							|  |  |  |     if (self->errors == NULL) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  |     if (self->codec->encinit != NULL && | 
					
						
							|  |  |  |         self->codec->encinit(&self->state, self->codec->config) != 0) | 
					
						
							|  |  |  |         goto errorexit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Py_DECREF(codec); | 
					
						
							|  |  |  |     return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | errorexit: | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     Py_XDECREF(self); | 
					
						
							|  |  |  |     Py_XDECREF(codec); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2006-04-21 16:21:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | mbstreamwriter_traverse(MultibyteStreamWriterObject *self, | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |                         visitproc visit, void *arg) | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (ERROR_ISCUSTOM(self->errors)) | 
					
						
							|  |  |  |         Py_VISIT(self->errors); | 
					
						
							|  |  |  |     Py_VISIT(self->stream); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyObject_GC_UnTrack(self); | 
					
						
							|  |  |  |     ERROR_DECREF(self->errors); | 
					
						
							|  |  |  |     Py_XDECREF(self->stream); | 
					
						
							|  |  |  |     Py_TYPE(self)->tp_free(self); | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef mbstreamwriter_methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF | 
					
						
							|  |  |  |     _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF | 
					
						
							|  |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | static PyMemberDef mbstreamwriter_members[] = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {"stream",          T_OBJECT, | 
					
						
							|  |  |  |                     offsetof(MultibyteStreamWriterObject, stream), | 
					
						
							|  |  |  |                     READONLY, NULL}, | 
					
						
							|  |  |  |     {NULL,} | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyTypeObject MultibyteStreamWriter_Type = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyVarObject_HEAD_INIT(NULL, 0) | 
					
						
							|  |  |  |     "MultibyteStreamWriter",            /* tp_name */ | 
					
						
							|  |  |  |     sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ | 
					
						
							|  |  |  |     0,                                  /* tp_itemsize */ | 
					
						
							|  |  |  |     /*  methods  */ | 
					
						
							|  |  |  |     (destructor)mbstreamwriter_dealloc, /* tp_dealloc */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_vectorcall_offset */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_getattr */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattr */ | 
					
						
							| 
									
										
										
										
											2019-05-31 04:13:39 +02:00
										 |  |  |     0,                                  /* tp_as_async */ | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     0,                                  /* tp_repr */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_number */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_sequence */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_mapping */ | 
					
						
							|  |  |  |     0,                                  /* tp_hash */ | 
					
						
							|  |  |  |     0,                                  /* tp_call */ | 
					
						
							|  |  |  |     0,                                  /* tp_str */ | 
					
						
							|  |  |  |     PyObject_GenericGetAttr,            /* tp_getattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_setattro */ | 
					
						
							|  |  |  |     0,                                  /* tp_as_buffer */ | 
					
						
							|  |  |  |     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 
					
						
							|  |  |  |         | Py_TPFLAGS_BASETYPE,          /* tp_flags */ | 
					
						
							|  |  |  |     0,                                  /* tp_doc */ | 
					
						
							|  |  |  |     (traverseproc)mbstreamwriter_traverse,      /* tp_traverse */ | 
					
						
							|  |  |  |     0,                                  /* tp_clear */ | 
					
						
							|  |  |  |     0,                                  /* tp_richcompare */ | 
					
						
							|  |  |  |     0,                                  /* tp_weaklistoffset */ | 
					
						
							|  |  |  |     0,                                  /* tp_iter */ | 
					
						
							|  |  |  |     0,                                  /* tp_iterext */ | 
					
						
							|  |  |  |     mbstreamwriter_methods,             /* tp_methods */ | 
					
						
							|  |  |  |     mbstreamwriter_members,             /* tp_members */ | 
					
						
							|  |  |  |     codecctx_getsets,                   /* tp_getset */ | 
					
						
							|  |  |  |     0,                                  /* tp_base */ | 
					
						
							|  |  |  |     0,                                  /* tp_dict */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_get */ | 
					
						
							|  |  |  |     0,                                  /* tp_descr_set */ | 
					
						
							|  |  |  |     0,                                  /* tp_dictoffset */ | 
					
						
							|  |  |  |     mbstreamwriter_init,                /* tp_init */ | 
					
						
							|  |  |  |     0,                                  /* tp_alloc */ | 
					
						
							|  |  |  |     mbstreamwriter_new,                 /* tp_new */ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  | /*[clinic input]
 | 
					
						
							|  |  |  | _multibytecodec.__create_codec | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     arg: object | 
					
						
							|  |  |  |     / | 
					
						
							|  |  |  | [clinic start generated code]*/ | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | static PyObject * | 
					
						
							| 
									
										
										
										
											2016-07-07 17:35:15 +03:00
										 |  |  | _multibytecodec___create_codec(PyObject *module, PyObject *arg) | 
					
						
							|  |  |  | /*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/ | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     MultibyteCodecObject *self; | 
					
						
							|  |  |  |     MultibyteCodec *codec; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { | 
					
						
							|  |  |  |         PyErr_SetString(PyExc_ValueError, "argument type invalid"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); | 
					
						
							|  |  |  |     if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); | 
					
						
							|  |  |  |     if (self == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     self->codec = codec; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     return (PyObject *)self; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct PyMethodDef __methods[] = { | 
					
						
							| 
									
										
										
										
											2014-08-22 11:45:03 -04:00
										 |  |  |     _MULTIBYTECODEC___CREATE_CODEC_METHODDEF | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     {NULL, NULL}, | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct PyModuleDef _multibytecodecmodule = { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     PyModuleDef_HEAD_INIT, | 
					
						
							|  |  |  |     "_multibytecodec", | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     -1, | 
					
						
							|  |  |  |     __methods, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     NULL | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-21 10:40:58 +00:00
										 |  |  | PyMODINIT_FUNC | 
					
						
							| 
									
										
										
										
											2008-06-11 05:26:20 +00:00
										 |  |  | PyInit__multibytecodec(void) | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-09 15:52:27 +00:00
										 |  |  |     int i; | 
					
						
							|  |  |  |     PyObject *m; | 
					
						
							|  |  |  |     PyTypeObject *typelist[] = { | 
					
						
							|  |  |  |         &MultibyteIncrementalEncoder_Type, | 
					
						
							|  |  |  |         &MultibyteIncrementalDecoder_Type, | 
					
						
							|  |  |  |         &MultibyteStreamReader_Type, | 
					
						
							|  |  |  |         &MultibyteStreamWriter_Type, | 
					
						
							|  |  |  |         NULL | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyType_Ready(&MultibyteCodec_Type) < 0) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m = PyModule_Create(&_multibytecodecmodule); | 
					
						
							|  |  |  |     if (m == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; typelist[i] != NULL; i++) { | 
					
						
							|  |  |  |         if (PyType_Ready(typelist[i]) < 0) | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         Py_INCREF(typelist[i]); | 
					
						
							|  |  |  |         PyModule_AddObject(m, typelist[i]->tp_name, | 
					
						
							|  |  |  |                            (PyObject *)typelist[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PyErr_Occurred()) { | 
					
						
							|  |  |  |         Py_DECREF(m); | 
					
						
							|  |  |  |         m = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return m; | 
					
						
							| 
									
										
										
										
											2004-01-17 14:29:29 +00:00
										 |  |  | } |