14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * multibytecodec.c: Common Multibyte Codec Implementation 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Written by Hye-Shik Chang <perky@FreeBSD.org> 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define PY_SSIZE_T_CLEAN 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h" 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "structmember.h" 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "multibytecodec.h" 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct { 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const Py_UNICODE *inbuf, *inbuf_top, *inbuf_end; 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unsigned char *outbuf, *outbuf_end; 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *excobj, *outobj; 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} MultibyteEncodeBuffer; 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct { 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const unsigned char *inbuf, *inbuf_top, *inbuf_end; 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *outbuf, *outbuf_end; 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *excobj, *outobj; 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} MultibyteDecodeBuffer; 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(MultibyteCodec_Encode__doc__, 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"I.encode(unicode[, errors]) -> (string, length consumed)\n\ 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm\n\ 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmReturn an encoded string version of `unicode'. errors may be given to\n\ 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmset a different error handling scheme. Default is 'strict' meaning that\n\ 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmencoding errors raise a UnicodeEncodeError. Other possible values are\n\ 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\ 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmregistered with codecs.register_error that can handle UnicodeEncodeErrors."); 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(MultibyteCodec_Decode__doc__, 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"I.decode(string[, errors]) -> (unicodeobject, length consumed)\n\ 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm\n\ 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmDecodes `string' using I, an MultibyteCodec instance. errors may be given\n\ 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmto set a different error handling scheme. Default is 'strict' meaning\n\ 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthat encoding errors raise a UnicodeDecodeError. Other possible values\n\ 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmare 'ignore' and 'replace' as well as any other name registered with\n\ 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcodecs.register_error that is able to handle UnicodeDecodeErrors."); 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *codeckwarglist[] = {"input", "errors", NULL}; 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *incnewkwarglist[] = {"errors", NULL}; 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *incrementalkwarglist[] = {"input", "final", NULL}; 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *streamkwarglist[] = {"stream", "errors", NULL}; 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *multibytecodec_encode(MultibyteCodec *, 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State *, const Py_UNICODE **, Py_ssize_t, 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *, int); 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define MBENC_RESET MBENC_MAX<<1 /* reset after an encoding session */ 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmake_tuple(PyObject *object, Py_ssize_t len) 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *v, *w; 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (object == NULL) 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm v = PyTuple_New(2); 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (v == NULL) { 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(object); 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyTuple_SET_ITEM(v, 0, object); 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm w = PyInt_FromSsize_t(len); 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (w == NULL) { 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(v); 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyTuple_SET_ITEM(v, 1, w); 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return v; 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminternal_error_callback(const char *errors) 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == NULL || strcmp(errors, "strict") == 0) 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ERROR_STRICT; 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (strcmp(errors, "ignore") == 0) 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ERROR_IGNORE; 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (strcmp(errors, "replace") == 0) 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ERROR_REPLACE; 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyString_FromString(errors); 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcall_error_callback(PyObject *errors, PyObject *exc) 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, *cb, *r; 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(PyString_Check(errors)); 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cb = PyCodec_LookupError(PyString_AS_STRING(errors)); 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cb == NULL) 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = PyTuple_New(1); 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (args == NULL) { 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cb); 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyTuple_SET_ITEM(args, 0, exc); 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(exc); 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = PyObject_CallObject(cb, args); 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(args); 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cb); 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return r; 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcodecctx_errors_get(MultibyteStatefulCodecContext *self) 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *errors; 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == ERROR_STRICT) 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errors = "strict"; 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (self->errors == ERROR_IGNORE) 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errors = "ignore"; 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (self->errors == ERROR_REPLACE) 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errors = "replace"; 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(self->errors); 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self->errors; 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyString_FromString(errors); 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcodecctx_errors_set(MultibyteStatefulCodecContext *self, PyObject *value, 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm void *closure) 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *cb; 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyString_Check(value)) { 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "errors must be a string"); 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cb = internal_error_callback(PyString_AS_STRING(value)); 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cb == NULL) 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(self->errors); 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = cb; 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* This getset handlers list is used by all the stateful codec objects */ 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyGetSetDef codecctx_getsets[] = { 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"errors", (getter)codecctx_errors_get, 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (setter)codecctx_errors_set, 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyDoc_STR("how to treat errors")}, 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL,} 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexpand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t orgpos, orgsize, incsize; 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm orgpos = (Py_ssize_t)((char *)buf->outbuf - 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(buf->outobj)); 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm orgsize = PyString_GET_SIZE(buf->outobj); 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (orgsize > PY_SSIZE_T_MAX - incsize) 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_PyString_Resize(&buf->outobj, orgsize + incsize) == -1) 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf = (unsigned char *)PyString_AS_STRING(buf->outobj) +orgpos; 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf_end = (unsigned char *)PyString_AS_STRING(buf->outobj) 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm + PyString_GET_SIZE(buf->outobj); 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define REQUIRE_ENCODEBUFFER(buf, s) { \ 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \ 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (expand_encodebuffer(buf, s) == -1) \ 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; \ 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexpand_decodebuffer(MultibyteDecodeBuffer *buf, Py_ssize_t esize) 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t orgpos, orgsize; 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm orgpos = (Py_ssize_t)(buf->outbuf - PyUnicode_AS_UNICODE(buf->outobj)); 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm orgsize = PyUnicode_GET_SIZE(buf->outobj); 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&buf->outobj, orgsize + ( 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize)) == -1) 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj) + orgpos; 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf_end = PyUnicode_AS_UNICODE(buf->outobj) 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm + PyUnicode_GET_SIZE(buf->outobj); 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define REQUIRE_DECODEBUFFER(buf, s) { \ 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \ 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (expand_decodebuffer(buf, s) == -1) \ 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; \ 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * MultibyteCodec object 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmultibytecodec_encerror(MultibyteCodec *codec, 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State *state, 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteEncodeBuffer *buf, 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors, Py_ssize_t e) 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *retobj = NULL, *retstr = NULL, *tobj; 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t retstrsize, newpos; 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t esize, start, end; 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *reason; 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (e > 0) { 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reason = "illegal multibyte sequence"; 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm esize = e; 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm switch (e) { 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_TOOSMALL: 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_ENCODEBUFFER(buf, -1); 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; /* retry it */ 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_TOOFEW: 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reason = "incomplete multibyte sequence"; 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_INTERNAL: 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_RuntimeError, 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "internal codec error"); 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default: 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_RuntimeError, 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "unknown runtime error"); 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_REPLACE) { 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const Py_UNICODE replchar = '?', *inbuf = &replchar; 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t r; 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t outleft; 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = codec->encode(state, codec->config, &inbuf, 1, 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf->outbuf, outleft, 0); 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == MBERR_TOOSMALL) { 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_ENCODEBUFFER(buf, -1); 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm continue; 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r != 0) { 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_ENCODEBUFFER(buf, 1); 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *buf->outbuf++ = '?'; 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf += esize; 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm end = start + esize; 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* use cached exception object if available */ 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->excobj == NULL) { 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->excobj = PyUnicodeEncodeError_Create(codec->encoding, 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf_top, 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf_end - buf->inbuf_top, 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start, end, reason); 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->excobj == NULL) 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicodeEncodeError_SetStart(buf->excobj, start) != 0 || 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicodeEncodeError_SetEnd(buf->excobj, end) != 0 || 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicodeEncodeError_SetReason(buf->excobj, reason) != 0) 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_STRICT) { 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyCodec_StrictErrors(buf->excobj); 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retobj = call_error_callback(errors, buf->excobj); 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (retobj == NULL) 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm !PyUnicode_Check((tobj = PyTuple_GET_ITEM(retobj, 0))) || 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) || 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) { 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "encoding error handler must return " 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "(unicode, int) tuple"); 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm { 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const Py_UNICODE *uraw = PyUnicode_AS_UNICODE(tobj); 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retstr = multibytecodec_encode(codec, state, &uraw, 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(tobj), ERROR_STRICT, 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MBENC_FLUSH); 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (retstr == NULL) 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retstrsize = PyString_GET_SIZE(retstr); 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_ENCODEBUFFER(buf, retstrsize); 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(buf->outbuf, PyString_AS_STRING(retstr), retstrsize); 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf += retstrsize; 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newpos < 0 && !PyErr_Occurred()) 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_IndexError, 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "position %zd from error handler out of bounds", 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos); 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf = buf->inbuf_top + newpos; 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(retobj); 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(retstr); 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(retobj); 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(retstr); 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmultibytecodec_decerror(MultibyteCodec *codec, 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State *state, 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer *buf, 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors, Py_ssize_t e) 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *retobj = NULL, *retuni = NULL; 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t retunisize, newpos; 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *reason; 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t esize, start, end; 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (e > 0) { 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reason = "illegal multibyte sequence"; 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm esize = e; 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm switch (e) { 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_TOOSMALL: 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_DECODEBUFFER(buf, -1); 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; /* retry it */ 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_TOOFEW: 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reason = "incomplete multibyte sequence"; 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm esize = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case MBERR_INTERNAL: 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_RuntimeError, 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "internal codec error"); 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default: 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_RuntimeError, 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "unknown runtime error"); 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_REPLACE) { 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_DECODEBUFFER(buf, 1); 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *buf->outbuf++ = Py_UNICODE_REPLACEMENT_CHARACTER; 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_IGNORE || errors == ERROR_REPLACE) { 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf += esize; 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start = (Py_ssize_t)(buf->inbuf - buf->inbuf_top); 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm end = start + esize; 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* use cached exception object if available */ 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->excobj == NULL) { 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->excobj = PyUnicodeDecodeError_Create(codec->encoding, 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (const char *)buf->inbuf_top, 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top), 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm start, end, reason); 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->excobj == NULL) 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicodeDecodeError_SetStart(buf->excobj, start) || 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicodeDecodeError_SetEnd(buf->excobj, end) || 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicodeDecodeError_SetReason(buf->excobj, reason)) 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errors == ERROR_STRICT) { 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyCodec_StrictErrors(buf->excobj); 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retobj = call_error_callback(errors, buf->excobj); 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (retobj == NULL) 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyTuple_Check(retobj) || PyTuple_GET_SIZE(retobj) != 2 || 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm !PyUnicode_Check((retuni = PyTuple_GET_ITEM(retobj, 0))) || 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm !(PyInt_Check(PyTuple_GET_ITEM(retobj, 1)) || 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyLong_Check(PyTuple_GET_ITEM(retobj, 1)))) { 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "decoding error handler must return " 4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "(unicode, int) tuple"); 4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retunisize = PyUnicode_GET_SIZE(retuni); 4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (retunisize > 0) { 4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm REQUIRE_DECODEBUFFER(buf, retunisize); 4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy((char *)buf->outbuf, PyUnicode_AS_DATA(retuni), 4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retunisize * Py_UNICODE_SIZE); 4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf += retunisize; 4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos = PyInt_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); 4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newpos < 0 && !PyErr_Occurred()) 4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos += (Py_ssize_t)(buf->inbuf_end - buf->inbuf_top); 4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (newpos < 0 || buf->inbuf_top + newpos > buf->inbuf_end) { 4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Clear(); 4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_Format(PyExc_IndexError, 4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "position %zd from error handler out of bounds", 4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm newpos); 4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf = buf->inbuf_top + newpos; 4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(retobj); 4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(retobj); 4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmultibytecodec_encode(MultibyteCodec *codec, 4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State *state, 4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const Py_UNICODE **data, Py_ssize_t datalen, 4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errors, int flags) 4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteEncodeBuffer buf; 4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t finalsize, r = 0; 4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (datalen == 0 && !(flags & MBENC_RESET)) 4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyString_FromString(""); 4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.excobj = NULL; 4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.inbuf = buf.inbuf_top = *data; 4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.inbuf_end = buf.inbuf_top + datalen; 4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (datalen > (PY_SSIZE_T_MAX - 16) / 2) { 4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_NoMemory(); 4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outobj = PyString_FromStringAndSize(NULL, datalen * 2 + 16); 4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf.outobj == NULL) 4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outbuf = (unsigned char *)PyString_AS_STRING(buf.outobj); 4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outbuf_end = buf.outbuf + PyString_GET_SIZE(buf.outobj); 4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (buf.inbuf < buf.inbuf_end) { 4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t inleft, outleft; 4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* we don't reuse inleft and outleft here. 4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * error callbacks can relocate the cursor anywhere on buffer*/ 4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); 4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); 4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = codec->encode(state, codec->config, &buf.inbuf, inleft, 5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf.outbuf, outleft, flags); 5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) 5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (multibytecodec_encerror(codec, state, &buf, errors,r)) 5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (r == MBERR_TOOFEW) 5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec->encreset != NULL && (flags & MBENC_RESET)) 5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t outleft; 5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); 5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = codec->encreset(state, codec->config, &buf.outbuf, 5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft); 5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == 0) 5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (multibytecodec_encerror(codec, state, 5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf, errors, r)) 5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finalsize = (Py_ssize_t)((char *)buf.outbuf - 5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(buf.outobj)); 5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (finalsize != PyString_GET_SIZE(buf.outobj)) 5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (_PyString_Resize(&buf.outobj, finalsize) == -1) 5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *data = buf.inbuf; 5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return buf.outobj; 5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.outobj); 5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmMultibyteCodec_Encode(MultibyteCodecObject *self, 5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwargs) 5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State state; 5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *data; 5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errorcb, *r, *arg, *ucvt; 5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *errors = NULL; 5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t datalen; 5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode", 5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codeckwarglist, &arg, &errors)) 5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Check(arg)) 5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ucvt = NULL; 5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm arg = ucvt = PyObject_Unicode(arg); 5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (arg == NULL) 5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (!PyUnicode_Check(arg)) { 5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "couldn't convert the object to unicode."); 5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ucvt); 5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm data = PyUnicode_AS_UNICODE(arg); 5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datalen = PyUnicode_GET_SIZE(arg); 5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errorcb = internal_error_callback(errors); 5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errorcb == NULL) { 5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(ucvt); 5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->encinit != NULL && 5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->encinit(&state, self->codec->config) != 0) 5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = multibytecodec_encode(self->codec, &state, 5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (const Py_UNICODE **)&data, datalen, errorcb, 5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MBENC_FLUSH | MBENC_RESET); 5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == NULL) 5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(errorcb); 5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(ucvt); 5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return make_tuple(r, datalen); 5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(errorcb); 5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(ucvt); 5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmMultibyteCodec_Decode(MultibyteCodecObject *self, 5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwargs) 5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_State state; 6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer buf; 6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *errorcb; 6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_buffer pdata; 6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *data, *errors = NULL; 6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t datalen, finalsize; 6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|z:decode", 6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codeckwarglist, &pdata, &errors)) 6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm data = pdata.buf; 6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datalen = pdata.len; 6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm errorcb = internal_error_callback(errors); 6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (errorcb == NULL) { 6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (datalen == 0) { 6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(errorcb); 6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return make_tuple(PyUnicode_FromUnicode(NULL, 0), 0); 6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.excobj = NULL; 6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.inbuf = buf.inbuf_top = (unsigned char *)data; 6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.inbuf_end = buf.inbuf_top + datalen; 6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outobj = PyUnicode_FromUnicode(NULL, datalen); 6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf.outobj == NULL) 6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outbuf = PyUnicode_AS_UNICODE(buf.outobj); 6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outbuf_end = buf.outbuf + PyUnicode_GET_SIZE(buf.outobj); 6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decinit != NULL && 6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decinit(&state, self->codec->config) != 0) 6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (buf.inbuf < buf.inbuf_end) { 6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t inleft, outleft, r; 6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); 6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); 6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = self->codec->decode(&state, self->codec->config, 6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf.inbuf, inleft, &buf.outbuf, outleft); 6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == 0) 6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (multibytecodec_decerror(self->codec, &state, 6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf, errorcb, r)) 6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finalsize = (Py_ssize_t)(buf.outbuf - 6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(buf.outobj)); 6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (finalsize != PyUnicode_GET_SIZE(buf.outobj)) 6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&buf.outobj, finalsize) == -1) 6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(errorcb); 6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return make_tuple(buf.outobj, datalen); 6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(errorcb); 6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.outobj); 6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef multibytecodec_methods[] = { 6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"encode", (PyCFunction)MultibyteCodec_Encode, 6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS | METH_KEYWORDS, 6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_Encode__doc__}, 6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"decode", (PyCFunction)MultibyteCodec_Decode, 6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS | METH_KEYWORDS, 6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec_Decode__doc__}, 6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmultibytecodec_dealloc(MultibyteCodecObject *self) 6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_Del(self); 6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject MultibyteCodec_Type = { 6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "MultibyteCodec", /* tp_name */ 6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(MultibyteCodecObject), /* tp_basicsize */ 6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_itemsize */ 6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* methods */ 6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)multibytecodec_dealloc, /* tp_dealloc */ 6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_print */ 6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_getattr */ 6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattr */ 7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_compare */ 7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_repr */ 7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_number */ 7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_sequence */ 7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_mapping */ 7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_hash */ 7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_call */ 7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_str */ 7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GenericGetAttr, /* tp_getattro */ 7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattro */ 7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_buffer */ 7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT, /* tp_flags */ 7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_doc */ 7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_traverse */ 7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iterext */ 7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm multibytecodec_methods, /* tp_methods */ 7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Utility functions for stateful codec mechanism 7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define STATEFUL_DCTX(o) ((MultibyteStatefulDecoderContext *)(o)) 7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define STATEFUL_ECTX(o) ((MultibyteStatefulEncoderContext *)(o)) 7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmencoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, 7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *unistr, int final) 7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *ucvt, *r = NULL; 7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE *inbuf, *inbuf_end, *inbuf_tmp = NULL; 7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t datalen, origpending; 7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Check(unistr)) 7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ucvt = NULL; 7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm unistr = ucvt = PyObject_Unicode(unistr); 7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (unistr == NULL) 7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (!PyUnicode_Check(unistr)) { 7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "couldn't convert the object to unicode."); 7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(ucvt); 7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datalen = PyUnicode_GET_SIZE(unistr); 7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm origpending = ctx->pendingsize; 7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (origpending > 0) { 7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (datalen > PY_SSIZE_T_MAX - ctx->pendingsize) { 7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_NoMemory(); 7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* inbuf_tmp == NULL */ 7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inbuf_tmp = PyMem_New(Py_UNICODE, datalen + ctx->pendingsize); 7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (inbuf_tmp == NULL) 7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(inbuf_tmp, ctx->pending, 7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE_SIZE * ctx->pendingsize); 7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(inbuf_tmp + ctx->pendingsize, 7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(unistr), 7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE_SIZE * datalen); 7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datalen += ctx->pendingsize; 7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize = 0; 7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inbuf = inbuf_tmp; 7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inbuf = (Py_UNICODE *)PyUnicode_AS_UNICODE(unistr); 7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inbuf_end = inbuf + datalen; 7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = multibytecodec_encode(ctx->codec, &ctx->state, 7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (const Py_UNICODE **)&inbuf, datalen, 7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); 7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == NULL) { 7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* recover the original pending buffer */ 7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (origpending > 0) 7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(ctx->pending, inbuf_tmp, 7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_UNICODE_SIZE * origpending); 7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize = origpending; 7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (inbuf < inbuf_end) { 7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize = (Py_ssize_t)(inbuf_end - inbuf); 7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ctx->pendingsize > MAXENCPENDING) { 7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* normal codecs can't reach here */ 7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize = 0; 7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_UnicodeError, 7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "pending buffer overflow"); 7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(ctx->pending, inbuf, 8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize * Py_UNICODE_SIZE); 8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (inbuf_tmp != NULL) 8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyMem_Del(inbuf_tmp); 8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(ucvt); 8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return r; 8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (inbuf_tmp != NULL) 8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyMem_Del(inbuf_tmp); 8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(r); 8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(ucvt); 8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdecoder_append_pending(MultibyteStatefulDecoderContext *ctx, 8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer *buf) 8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t npendings; 8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm npendings = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (npendings + ctx->pendingsize > MAXDECPENDING || 8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm npendings > PY_SSIZE_T_MAX - ctx->pendingsize) { 8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_UnicodeError, "pending buffer overflow"); 8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(ctx->pending + ctx->pendingsize, buf->inbuf, npendings); 8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctx->pendingsize += npendings; 8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdecoder_prepare_buffer(MultibyteDecodeBuffer *buf, const char *data, 8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t size) 8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf = buf->inbuf_top = (const unsigned char *)data; 8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->inbuf_end = buf->inbuf_top + size; 8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->outobj == NULL) { /* only if outobj is not allocated yet */ 8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outobj = PyUnicode_FromUnicode(NULL, size); 8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf->outobj == NULL) 8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf = PyUnicode_AS_UNICODE(buf->outobj); 8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf->outbuf_end = buf->outbuf + 8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_GET_SIZE(buf->outobj); 8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdecoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, 8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer *buf) 8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while (buf->inbuf < buf->inbuf_end) { 8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t inleft, outleft; 8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t r; 8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); 8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); 8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = ctx->codec->decode(&ctx->state, ctx->codec->config, 8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf->inbuf, inleft, &buf->outbuf, outleft); 8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == 0 || r == MBERR_TOOFEW) 8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (multibytecodec_decerror(ctx->codec, &ctx->state, 8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf, ctx->errors, r)) 8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * MultibyteIncrementalEncoder object 8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_encode(MultibyteIncrementalEncoderObject *self, 8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwargs) 8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *data; 8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int final = 0; 8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode", 8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incrementalkwarglist, &data, &final)) 8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return encoder_encode_stateful(STATEFUL_ECTX(self), data, final); 8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_reset(MultibyteIncrementalEncoderObject *self) 8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decreset != NULL && 8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decreset(&self->state, self->codec->config) != 0) 8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef mbiencoder_methods[] = { 9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"encode", (PyCFunction)mbiencoder_encode, 9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS | METH_KEYWORDS, NULL}, 9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"reset", (PyCFunction)mbiencoder_reset, 9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_NOARGS, NULL}, 9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteIncrementalEncoderObject *self; 9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *codec = NULL; 9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *errors = NULL; 9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalEncoder", 9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incnewkwarglist, &errors)) 9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self = (MultibyteIncrementalEncoderObject *)type->tp_alloc(type, 0); 9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self == NULL) 9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codec = PyObject_GetAttrString((PyObject *)type, "codec"); 9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec == NULL) 9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!MultibyteCodec_Check(codec)) { 9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec = ((MultibyteCodecObject *)codec)->codec; 9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = internal_error_callback(errors); 9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->encinit != NULL && 9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->encinit(&self->state, self->codec->config) != 0) 9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(codec); 9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (PyObject *)self; 9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self); 9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(codec); 9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_init(PyObject *self, PyObject *args, PyObject *kwds) 9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_traverse(MultibyteIncrementalEncoderObject *self, 9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm visitproc visit, void *arg) 9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ERROR_ISCUSTOM(self->errors)) 9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->errors); 9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbiencoder_dealloc(MultibyteIncrementalEncoderObject *self) 9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GC_UnTrack(self); 9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(self->errors); 9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free(self); 9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject MultibyteIncrementalEncoder_Type = { 9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "MultibyteIncrementalEncoder", /* tp_name */ 9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(MultibyteIncrementalEncoderObject), /* tp_basicsize */ 9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_itemsize */ 9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* methods */ 9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)mbiencoder_dealloc, /* tp_dealloc */ 9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_print */ 9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_getattr */ 9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattr */ 9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_compare */ 9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_repr */ 9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_number */ 9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_sequence */ 9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_mapping */ 9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_hash */ 9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_call */ 9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_str */ 9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GenericGetAttr, /* tp_getattro */ 9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattro */ 9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_buffer */ 9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | Py_TPFLAGS_BASETYPE, /* tp_flags */ 9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_doc */ 9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (traverseproc)mbiencoder_traverse, /* tp_traverse */ 10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iterext */ 10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbiencoder_methods, /* tp_methods */ 10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_members */ 10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codecctx_getsets, /* tp_getset */ 10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbiencoder_init, /* tp_init */ 10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbiencoder_new, /* tp_new */ 10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * MultibyteIncrementalDecoder object 10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_decode(MultibyteIncrementalDecoderObject *self, 10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *args, PyObject *kwargs) 10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer buf; 10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *data, *wdata = NULL; 10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_buffer pdata; 10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t wsize, finalsize = 0, size, origpending; 10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int final = 0; 10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*|i:decode", 10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incrementalkwarglist, &pdata, &final)) 10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm data = pdata.buf; 10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm size = pdata.len; 10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outobj = buf.excobj = NULL; 10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm origpending = self->pendingsize; 10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pendingsize == 0) { 10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wsize = size; 10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wdata = data; 10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (size > PY_SSIZE_T_MAX - self->pendingsize) { 10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_NoMemory(); 10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wsize = size + self->pendingsize; 10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wdata = PyMem_Malloc(wsize); 10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (wdata == NULL) 10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(wdata, self->pending, self->pendingsize); 10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(wdata + self->pendingsize, data, size); 10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoder_prepare_buffer(&buf, wdata, wsize) != 0) 10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoder_feed_buffer(STATEFUL_DCTX(self), &buf)) 10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (final && buf.inbuf < buf.inbuf_end) { 10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (multibytecodec_decerror(self->codec, &self->state, 10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf, self->errors, MBERR_TOOFEW)) { 10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* recover the original pending buffer */ 10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(self->pending, wdata, origpending); 10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = origpending; 10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf.inbuf < buf.inbuf_end) { /* pending sequence still exists */ 10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoder_append_pending(STATEFUL_DCTX(self), &buf) != 0) 10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finalsize = (Py_ssize_t)(buf.outbuf - PyUnicode_AS_UNICODE(buf.outobj)); 10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (finalsize != PyUnicode_GET_SIZE(buf.outobj)) 10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&buf.outobj, finalsize) == -1) 10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (wdata != data) 10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyMem_Del(wdata); 10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return buf.outobj; 10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyBuffer_Release(&pdata); 10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (wdata != NULL && wdata != data) 10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyMem_Del(wdata); 10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.outobj); 10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_reset(MultibyteIncrementalDecoderObject *self) 11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decreset != NULL && 11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decreset(&self->state, self->codec->config) != 0) 11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef mbidecoder_methods[] = { 11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"decode", (PyCFunction)mbidecoder_decode, 11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS | METH_KEYWORDS, NULL}, 11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"reset", (PyCFunction)mbidecoder_reset, 11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_NOARGS, NULL}, 11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteIncrementalDecoderObject *self; 11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *codec = NULL; 11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *errors = NULL; 11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s:IncrementalDecoder", 11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm incnewkwarglist, &errors)) 11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self = (MultibyteIncrementalDecoderObject *)type->tp_alloc(type, 0); 11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self == NULL) 11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codec = PyObject_GetAttrString((PyObject *)type, "codec"); 11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec == NULL) 11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!MultibyteCodec_Check(codec)) { 11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec = ((MultibyteCodecObject *)codec)->codec; 11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = internal_error_callback(errors); 11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decinit != NULL && 11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decinit(&self->state, self->codec->config) != 0) 11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(codec); 11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (PyObject *)self; 11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self); 11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(codec); 11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_init(PyObject *self, PyObject *args, PyObject *kwds) 11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_traverse(MultibyteIncrementalDecoderObject *self, 11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm visitproc visit, void *arg) 11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ERROR_ISCUSTOM(self->errors)) 11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->errors); 11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbidecoder_dealloc(MultibyteIncrementalDecoderObject *self) 11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GC_UnTrack(self); 11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(self->errors); 11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free(self); 11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject MultibyteIncrementalDecoder_Type = { 11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "MultibyteIncrementalDecoder", /* tp_name */ 11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(MultibyteIncrementalDecoderObject), /* tp_basicsize */ 11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_itemsize */ 11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* methods */ 11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)mbidecoder_dealloc, /* tp_dealloc */ 11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_print */ 11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_getattr */ 11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattr */ 11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_compare */ 11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_repr */ 11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_number */ 11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_sequence */ 11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_mapping */ 11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_hash */ 12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_call */ 12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_str */ 12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GenericGetAttr, /* tp_getattro */ 12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattro */ 12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_buffer */ 12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | Py_TPFLAGS_BASETYPE, /* tp_flags */ 12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_doc */ 12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (traverseproc)mbidecoder_traverse, /* tp_traverse */ 12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iterext */ 12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbidecoder_methods, /* tp_methods */ 12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_members */ 12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codecctx_getsets, /* tp_getset */ 12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbidecoder_init, /* tp_init */ 12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbidecoder_new, /* tp_new */ 12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * MultibyteStreamReader object 12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_iread(MultibyteStreamReaderObject *self, 12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *method, Py_ssize_t sizehint) 12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteDecodeBuffer buf; 12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *cres; 12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t rsize, finalsize = 0; 12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizehint == 0) 12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return PyUnicode_FromUnicode(NULL, 0); 12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm buf.outobj = buf.excobj = NULL; 12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cres = NULL; 12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (;;) { 12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int endoffile; 12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizehint < 0) 12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cres = PyObject_CallMethod(self->stream, 12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (char *)method, NULL); 12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cres = PyObject_CallMethod(self->stream, 12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (char *)method, "i", sizehint); 12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (cres == NULL) 12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyString_Check(cres)) { 12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "stream function returned a " 12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "non-string object"); 12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm endoffile = (PyString_GET_SIZE(cres) == 0); 12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->pendingsize > 0) { 12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *ctr; 12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *ctrdata; 12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyString_GET_SIZE(cres) > PY_SSIZE_T_MAX - self->pendingsize) { 12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_NoMemory(); 12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rsize = PyString_GET_SIZE(cres) + self->pendingsize; 12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctr = PyString_FromStringAndSize(NULL, rsize); 12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ctr == NULL) 12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ctrdata = PyString_AS_STRING(ctr); 12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(ctrdata, self->pending, self->pendingsize); 12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memcpy(ctrdata + self->pendingsize, 12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_AS_STRING(cres), 12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyString_GET_SIZE(cres)); 12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cres); 12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cres = ctr; 12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rsize = PyString_GET_SIZE(cres); 12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoder_prepare_buffer(&buf, PyString_AS_STRING(cres), 12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rsize) != 0) 12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (rsize > 0 && decoder_feed_buffer( 12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (MultibyteStatefulDecoderContext *)self, &buf)) 12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (endoffile || sizehint < 0) { 12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf.inbuf < buf.inbuf_end && 13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm multibytecodec_decerror(self->codec, &self->state, 13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf, self->errors, MBERR_TOOFEW)) 13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (buf.inbuf < buf.inbuf_end) { /* pending sequence exists */ 13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (decoder_append_pending(STATEFUL_DCTX(self), 13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &buf) != 0) 13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finalsize = (Py_ssize_t)(buf.outbuf - 13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyUnicode_AS_UNICODE(buf.outobj)); 13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(cres); 13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cres = NULL; 13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizehint < 0 || finalsize != 0 || rsize == 0) 13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizehint = 1; /* read 1 more byte and retry */ 13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (finalsize != PyUnicode_GET_SIZE(buf.outobj)) 13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyUnicode_Resize(&buf.outobj, finalsize) == -1) 13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(cres); 13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return buf.outobj; 13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(cres); 13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.excobj); 13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(buf.outobj); 13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args) 13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *sizeobj = NULL; 13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t size; 13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_UnpackTuple(args, "read", 0, 1, &sizeobj)) 13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizeobj == Py_None || sizeobj == NULL) 13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm size = -1; 13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (PyInt_Check(sizeobj)) 13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm size = PyInt_AsSsize_t(sizeobj); 13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return mbstreamreader_iread(self, "read", size); 13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args) 13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *sizeobj = NULL; 13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t size; 13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_UnpackTuple(args, "readline", 0, 1, &sizeobj)) 13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizeobj == Py_None || sizeobj == NULL) 13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm size = -1; 13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (PyInt_Check(sizeobj)) 13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm size = PyInt_AsSsize_t(sizeobj); 13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return mbstreamreader_iread(self, "readline", size); 13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args) 13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *sizehintobj = NULL, *r, *sr; 13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_ssize_t sizehint; 13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_UnpackTuple(args, "readlines", 0, 1, &sizehintobj)) 13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (sizehintobj == Py_None || sizehintobj == NULL) 13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizehint = -1; 13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else if (PyInt_Check(sizehintobj)) 13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizehint = PyInt_AsSsize_t(sizehintobj); 13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else { 13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "arg 1 must be an integer"); 13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = mbstreamreader_iread(self, "read", sizehint); 13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == NULL) 13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sr = PyUnicode_Splitlines(r, 1); 14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(r); 14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return sr; 14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_reset(MultibyteStreamReaderObject *self) 14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decreset != NULL && 14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decreset(&self->state, self->codec->config) != 0) 14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef mbstreamreader_methods[] = { 14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"read", (PyCFunction)mbstreamreader_read, 14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS, NULL}, 14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"readline", (PyCFunction)mbstreamreader_readline, 14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS, NULL}, 14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"readlines", (PyCFunction)mbstreamreader_readlines, 14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_VARARGS, NULL}, 14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"reset", (PyCFunction)mbstreamreader_reset, 14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_NOARGS, NULL}, 14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMemberDef mbstreamreader_members[] = { 14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"stream", T_OBJECT, 14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offsetof(MultibyteStreamReaderObject, stream), 14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm READONLY, NULL}, 14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL,} 14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteStreamReaderObject *self; 14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *stream, *codec = NULL; 14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *errors = NULL; 14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamReader", 14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm streamkwarglist, &stream, &errors)) 14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self = (MultibyteStreamReaderObject *)type->tp_alloc(type, 0); 14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self == NULL) 14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codec = PyObject_GetAttrString((PyObject *)type, "codec"); 14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec == NULL) 14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!MultibyteCodec_Check(codec)) { 14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec = ((MultibyteCodecObject *)codec)->codec; 14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->stream = stream; 14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(stream); 14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = internal_error_callback(errors); 14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->decinit != NULL && 14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->decinit(&self->state, self->codec->config) != 0) 14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(codec); 14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (PyObject *)self; 14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self); 14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(codec); 14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_init(PyObject *self, PyObject *args, PyObject *kwds) 14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_traverse(MultibyteStreamReaderObject *self, 14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm visitproc visit, void *arg) 14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ERROR_ISCUSTOM(self->errors)) 14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->errors); 14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->stream); 14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamreader_dealloc(MultibyteStreamReaderObject *self) 14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GC_UnTrack(self); 14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(self->errors); 15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self->stream); 15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free(self); 15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject MultibyteStreamReader_Type = { 15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "MultibyteStreamReader", /* tp_name */ 15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(MultibyteStreamReaderObject), /* tp_basicsize */ 15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_itemsize */ 15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* methods */ 15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)mbstreamreader_dealloc, /* tp_dealloc */ 15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_print */ 15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_getattr */ 15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattr */ 15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_compare */ 15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_repr */ 15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_number */ 15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_sequence */ 15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_mapping */ 15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_hash */ 15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_call */ 15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_str */ 15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GenericGetAttr, /* tp_getattro */ 15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattro */ 15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_buffer */ 15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | Py_TPFLAGS_BASETYPE, /* tp_flags */ 15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_doc */ 15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (traverseproc)mbstreamreader_traverse, /* tp_traverse */ 15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iterext */ 15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamreader_methods, /* tp_methods */ 15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamreader_members, /* tp_members */ 15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codecctx_getsets, /* tp_getset */ 15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamreader_init, /* tp_init */ 15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamreader_new, /* tp_new */ 15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * MultibyteStreamWriter object 15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_iwrite(MultibyteStreamWriterObject *self, 15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *unistr) 15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *str, *wr; 15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); 15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (str == NULL) 15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wr = PyObject_CallMethod(self->stream, "write", "O", str); 15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(str); 15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (wr == NULL) 15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(wr); 15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) 15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (mbstreamwriter_iwrite(self, strobj)) 15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) 15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *strobj; 15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int i, r; 15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PySequence_Check(lines)) { 15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, 15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "arg must be a sequence object"); 15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (i = 0; i < PySequence_Length(lines); i++) { 15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* length can be changed even within this loop */ 15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm strobj = PySequence_GetItem(lines, i); 15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (strobj == NULL) 15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = mbstreamwriter_iwrite(self, strobj); 15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(strobj); 16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (r == -1) 16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_reset(MultibyteStreamWriterObject *self) 16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const Py_UNICODE *pending; 16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *pwrt; 16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pending = self->pending; 16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pwrt = multibytecodec_encode(self->codec, &self->state, 16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &pending, self->pendingsize, self->errors, 16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MBENC_FLUSH | MBENC_RESET); 16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* some pending buffer can be truncated when UnicodeEncodeError is 16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * raised on 'strict' mode. but, 'reset' method is designed to 16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * reset the pending buffer or states so failed string sequence 16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * ought to be missed */ 16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (pwrt == NULL) 16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyString_Size(pwrt) > 0) { 16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *wr; 16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm wr = PyObject_CallMethod(self->stream, "write", "O", pwrt); 16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (wr == NULL) { 16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(pwrt); 16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(pwrt); 16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_RETURN_NONE; 16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteStreamWriterObject *self; 16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *stream, *codec = NULL; 16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *errors = NULL; 16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s:StreamWriter", 16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm streamkwarglist, &stream, &errors)) 16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self = (MultibyteStreamWriterObject *)type->tp_alloc(type, 0); 16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self == NULL) 16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codec = PyObject_GetAttrString((PyObject *)type, "codec"); 16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec == NULL) 16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!MultibyteCodec_Check(codec)) { 16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); 16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec = ((MultibyteCodecObject *)codec)->codec; 16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->stream = stream; 16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(stream); 16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->pendingsize = 0; 16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->errors = internal_error_callback(errors); 16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->errors == NULL) 16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self->codec->encinit != NULL && 16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec->encinit(&self->state, self->codec->config) != 0) 16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto errorexit; 16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_DECREF(codec); 16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (PyObject *)self; 16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerrorexit: 16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self); 16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(codec); 16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_init(PyObject *self, PyObject *args, PyObject *kwds) 16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int 16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_traverse(MultibyteStreamWriterObject *self, 16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm visitproc visit, void *arg) 16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (ERROR_ISCUSTOM(self->errors)) 16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->errors); 16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_VISIT(self->stream); 16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void 16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmbstreamwriter_dealloc(MultibyteStreamWriterObject *self) 16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GC_UnTrack(self); 17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERROR_DECREF(self->errors); 17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_XDECREF(self->stream); 17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TYPE(self)->tp_free(self); 17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef mbstreamwriter_methods[] = { 17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"write", (PyCFunction)mbstreamwriter_write, 17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_O, NULL}, 17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"writelines", (PyCFunction)mbstreamwriter_writelines, 17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_O, NULL}, 17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"reset", (PyCFunction)mbstreamwriter_reset, 17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm METH_NOARGS, NULL}, 17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMemberDef mbstreamwriter_members[] = { 17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"stream", T_OBJECT, 17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm offsetof(MultibyteStreamWriterObject, stream), 17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm READONLY, NULL}, 17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL,} 17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyTypeObject MultibyteStreamWriter_Type = { 17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyVarObject_HEAD_INIT(NULL, 0) 17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "MultibyteStreamWriter", /* tp_name */ 17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sizeof(MultibyteStreamWriterObject), /* tp_basicsize */ 17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_itemsize */ 17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* methods */ 17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (destructor)mbstreamwriter_dealloc, /* tp_dealloc */ 17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_print */ 17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_getattr */ 17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattr */ 17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_compare */ 17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_repr */ 17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_number */ 17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_sequence */ 17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_mapping */ 17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_hash */ 17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_call */ 17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_str */ 17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject_GenericGetAttr, /* tp_getattro */ 17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_setattro */ 17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_as_buffer */ 17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm | Py_TPFLAGS_BASETYPE, /* tp_flags */ 17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_doc */ 17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (traverseproc)mbstreamwriter_traverse, /* tp_traverse */ 17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_clear */ 17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_richcompare */ 17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_weaklistoffset */ 17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iter */ 17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_iterext */ 17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamwriter_methods, /* tp_methods */ 17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamwriter_members, /* tp_members */ 17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codecctx_getsets, /* tp_getset */ 17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_base */ 17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dict */ 17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_get */ 17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_descr_set */ 17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_dictoffset */ 17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamwriter_init, /* tp_init */ 17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 0, /* tp_alloc */ 17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm mbstreamwriter_new, /* tp_new */ 17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/** 17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Exposed factory function 17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * 17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__create_codec(PyObject *ignore, PyObject *arg) 17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodecObject *self; 17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm MultibyteCodec *codec; 17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { 17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString(PyExc_ValueError, "argument type invalid"); 17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); 17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) 17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self = PyObject_New(MultibyteCodecObject, &MultibyteCodec_Type); 17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (self == NULL) 17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self->codec = codec; 17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return (PyObject *)self; 17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct PyMethodDef __methods[] = { 17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"__create_codec", (PyCFunction)__create_codec, METH_O}, 17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {NULL, NULL}, 17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyMODINIT_FUNC 18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminit_multibytecodec(void) 18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int i; 18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *m; 18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyTypeObject *typelist[] = { 18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &MultibyteIncrementalEncoder_Type, 18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &MultibyteIncrementalDecoder_Type, 18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &MultibyteStreamReader_Type, 18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm &MultibyteStreamWriter_Type, 18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm NULL 18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }; 18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyType_Ready(&MultibyteCodec_Type) < 0) 18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = Py_InitModule("_multibytecodec", __methods); 18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (m == NULL) 18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (i = 0; typelist[i] != NULL; i++) { 18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyType_Ready(typelist[i]) < 0) 18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_INCREF(typelist[i]); 18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyModule_AddObject(m, typelist[i]->tp_name, 18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (PyObject *)typelist[i]); 18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (PyErr_Occurred()) 18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_FatalError("can't initialize the _multibytecodec module"); 18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1830