{ make_encode_exception(exceptionObject, encoding, unicode, size, startpos, endpos, reason); if (*exceptionObject != NULL) PyCodec_StrictErrors(*exceptionObject);} /* error handling callback helper: build arguments, call the callback and check the arguments, put the result into newpos and return the replacement string, which has to be freed by the caller */static PyObject *unicode_encode_call_errorhandler(const char *errors, PyObject **errorHandler, const char *encoding, const char *reason, const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject, Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos){ static char *argparse = "O!n;encoding error handler must return (unicode, int) tuple"; PyObject *restuple; PyObject *resunicode; if (*errorHandler == NULL) { *errorHandler = PyCodec_LookupError(errors); if (*errorHandler == NULL) return NULL; } make_encode_exception(exceptionObject, encoding, unicode, size, startpos, endpos, reason); if (*exceptionObject == NULL) return NULL; restuple = PyObject_CallFunctionObjArgs( *errorHandler, *exceptionObject, NULL); if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { PyErr_Format(PyExc_TypeError, &argparse[4]); Py_DECREF(restuple); return NULL; } if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &resunicode, newpos)) { Py_DECREF(restuple); return NULL; } if (*newpos<0) *newpos = size+*newpos; if (*newpos<0 || *newpos>size) { PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos); Py_DECREF(restuple); return NULL; } Py_INCREF(resunicode); Py_DECREF(restuple); return resunicode;} static PyObject *unicode_encode_ucs1(const Py_UNICODE *p, Py_ssize_t size, const char *errors, int limit){ /* output object */ PyObject *res; /* pointers to the beginning and end+1 of input */ const Py_UNICODE *startp = p; const Py_UNICODE *endp = p + size; /* pointer to the beginning of the unencodable characters */ /* const Py_UNICODE *badp = NULL; */ /* pointer into the output */ char *str; /* current output position */ Py_ssize_t respos = 0; Py_ssize_t ressize; const char *encoding = (limit == 256) ? "latin-1" : "ascii"; const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)"; PyObject *errorHandler = NULL; PyObject *exc = NULL; /* the following variable is used for caching string comparisons * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ int known_errorHandler = -1; /* allocate enough for a simple encoding without replacements, if we need more, we'll resize */ res = PyString_FromStringAndSize(NULL, size); if (res == NULL) goto onError; if (size == 0) return res; str = PyString_AS_STRING(res); ressize = size; while (p<endp) { Py_UNICODE c = *p; /* can we encode this? */ if (c<limit) { /* no overflow check, because we know that the space is enough */ *str++ = (char)c; ++p; } else { Py_ssize_t unicodepos = p-startp; Py_ssize_t requiredsize; PyObject *repunicode; Py_ssize_t repsize; Py_ssize_t newpos; Py_ssize_t respos; Py_UNICODE *uni2; /* startpos for collecting unencodable chars */ const Py_UNICODE *collstart = p; const Py_UNICODE *collend = p; /* find all unecodable characters */ while ((collend < endp) && ((*collend)>=limit)) ++collend; /* cache callback name lookup (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_encode_exception(&exc, encoding, startp, size, collstart-startp, collend-startp, reason); goto onError; case 2: /* replace */ while (collstart++<collend) *str++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ respos = str-PyString_AS_STRING(res); /* determine replacement size (temporarily (mis)uses p) */ for (p = collstart, repsize = 0; p < collend; ++p) { if (*p<10) repsize += 2+1+1; else if (*p<100) repsize += 2+2+1; else if (*p<1000) repsize += 2+3+1; else if (*p<10000) repsize += 2+4+1;#ifndef Py_UNICODE_WIDE else repsize += 2+5+1;#else else if (*p<100000) repsize += 2+5+1; else if (*p<1000000) repsize += 2+6+1; else repsize += 2+7+1;#endif } requiredsize = respos+repsize+(endp-collend); if (requiredsize > ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; if (_PyString_Resize(&res, requiredsize)) goto onError; str = PyString_AS_STRING(res) + respos; ressize = requiredsize; } /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) { str += sprintf(str, "&#%d;", (int)*p); } p = collend; break; default: repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, encoding, reason, startp, size, &exc, collstart-startp, collend-startp, &newpos); if (repunicode == NULL) goto onError; /* need more space? (at least enough for what we have+the replacement+the rest of the string, so we won't have to check space for encodable characters) */ respos = str-PyString_AS_STRING(res); repsize = PyUnicode_GET_SIZE(repunicode); requiredsize = respos+repsize+(endp-collend); if (requiredsize > ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; if (_PyString_Resize(&res, requiredsize)) { Py_DECREF(repunicode); goto onError; } str = PyString_AS_STRING(res) + respos; ressize = requiredsize; } /* check if there is anything unencodable in the replacement and copy it to the output */ for (uni2 = PyUnicode_AS_UNICODE(repunicode);repsize-->0; ++uni2, ++str) { c = *uni2; if (c >= limit) { raise_encode_exception(&exc, encoding, startp, size, unicodepos, unicodepos+1, reason); Py_DECREF(repunicode); goto onError; } *str = (char)c; } p = startp + newpos; Py_DECREF(repunicode); } } } /* Resize if we allocated to much */ respos = str-PyString_AS_STRING(res); if (respos<ressize) /* If this falls res will be NULL */ _PyString_Resize(&res, respos); Py_XDECREF(errorHandler); Py_XDECREF(exc); return res; onError: Py_XDECREF(res); Py_XDECREF(errorHandler); Py_XDECREF(exc); return NULL;} PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p, Py_ssize_t size, const char *errors){ return unicode_encode_ucs1(p, size, errors, 256);} PyObject *PyUnicode_AsLatin1String(PyObject *unicode){ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL);} /* --- 7-bit ASCII Codec -------------------------------------------------- */ PyObject *PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors){ const char *starts = s; PyUnicodeObject *v; Py_UNICODE *p; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; const char *e; PyObject *errorHandler = NULL; PyObject *exc = NULL; /* ASCII is equivalent to the first 128 ordinals in Unicode. */ if (size == 1 && *(unsigned char*)s < 128) { Py_UNICODE r = *(unsigned char*)s; return PyUnicode_FromUnicode(&r, 1); } v = _PyUnicode_New(size); if (v == NULL) goto onError; if (size == 0) return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; while (s < e) { register unsigned char c = (unsigned char)*s; if (c < 128) { *p++ = c; ++s; } else { startinpos = s-starts; endinpos = startinpos + 1; outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v); if (unicode_decode_call_errorhandler( errors, &errorHandler, "ascii", "ordinal not in range(128)", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) goto onError; } } if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v)) if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0) goto onError; Py_XDECREF(errorHandler); Py_XDECREF(exc); return (PyObject *)v; onError: Py_XDECREF(v); Py_XDECREF(errorHandler); Py_XDECREF(exc); return NULL;} PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p, Py_ssize_t size, const char *errors){ return unicode_encode_ucs1(p, size, errors, 128);} PyObject *PyUnicode_AsASCIIString(PyObject *unicode){ if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL);} #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) /* --- MBCS codecs for Windows -------------------------------------------- */ #if SIZEOF_INT < SIZEOF_SSIZE_T#define NEED_RETRY#endif /* XXX This code is limited to "true" double-byte encodings, as a) it assumes an incomplete character consists of a single byte, and b) IsDBCSLeadByte (probably) does not work for non-DBCS multi-byte encodings, see IsDBCSLeadByteEx documentation. */ static int is_dbcs_lead_byte(const char *s, int offset){ const char *curr = s + offset; if (IsDBCSLeadByte(*curr)) { const char *prev = CharPrev(s, curr); return (prev == curr) || !IsDBCSLeadByte(*prev) || (curr - prev == 2); } return 0;} /* * Decode MBCS string into unicode object. If 'final' is set, converts * trailing lead-byte too. Returns consumed size if succeed, -1 otherwise. */static int decode_mbcs(PyUnicodeObject **v, const char *s, /* MBCS string */ int size, /* sizeof MBCS string */ int final){ Py_UNICODE *p; Py_ssize_t n = 0; int usize = 0; assert(size >= 0); /* Skip trailing lead-byte unless 'final' is set */ if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1)) --size; /* First get the size of the result */ if (size > 0) { usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0); if (usize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } if (*v == NULL) { /* Create unicode object */ *v = _PyUnicode_New(usize); if (*v == NULL) return -1; } else { /* Extend unicode object */ n = PyUnicode_GET_SIZE(*v); if (_PyUnicode_Resize(v, n + usize) < 0) return -1; } /* Do the conversion */ if (size > 0) { p = PyUnicode_AS_UNICODE(*v) + n; if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } return size;} PyObject *PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed){ PyUnicodeObject *v = NULL; int done; if (consumed) *consumed = 0; #ifdef NEED_RETRY retry: if (size > INT_MAX) done = decode_mbcs(&v, s, INT_MAX, 0); else#endif done = decode_mbcs(&v, s, (int)size, !consumed); if (done < 0) { Py_XDECREF(v); return NULL; } if (consumed) *consumed += done; #ifdef NEED_RETRY if (size > INT_MAX) { s += done; size -= done; goto retry; }#endif return (PyObject *)v;} PyObject *PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors){ return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL);} /* * Convert unicode into string object (MBCS). * Returns 0 if succeed, -1 otherwise. */static int encode_mbcs(PyObject **repr, const Py_UNICODE *p, /* unicode */ int size) /* size of unicode */{ int mbcssize = 0; Py_ssize_t n = 0; assert(size >= 0); /* First get the size of the result */ if (size > 0) { mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL); if (mbcssize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } if (*repr == NULL) { /* Create string object */ *repr = PyString_FromStringAndSize(NULL, mbcssize); if (*repr == NULL) return -1; } else { /* Extend string object */ n = PyString_Size(*repr); if (_PyString_Resize(repr, n + mbcssize) < 0) return -1; } /* Do the conversion */ if (size > 0) { char *s = PyString_AS_STRING(*repr) + n; if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } return 0;}Lines 2501–3000 of 8067. Previous lines Load more
{ make_encode_exception(exceptionObject, encoding, unicode, size, startpos, endpos, reason); if (*exceptionObject != NULL) PyCodec_StrictErrors(*exceptionObject); } /* error handling callback helper: build arguments, call the callback and check the arguments, put the result into newpos and return the replacement string, which has to be freed by the caller */ static PyObject *unicode_encode_call_errorhandler(const char *errors, PyObject **errorHandler, const char *encoding, const char *reason, const Py_UNICODE *unicode, Py_ssize_t size, PyObject **exceptionObject, Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos) { static char *argparse = "O!n;encoding error handler must return (unicode, int) tuple"; PyObject *restuple; PyObject *resunicode; if (*errorHandler == NULL) { *errorHandler = PyCodec_LookupError(errors); if (*errorHandler == NULL) return NULL; } make_encode_exception(exceptionObject, encoding, unicode, size, startpos, endpos, reason); if (*exceptionObject == NULL) return NULL; restuple = PyObject_CallFunctionObjArgs( *errorHandler, *exceptionObject, NULL); if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { PyErr_Format(PyExc_TypeError, &argparse[4]); Py_DECREF(restuple); return NULL; } if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &resunicode, newpos)) { Py_DECREF(restuple); return NULL; } if (*newpos<0) *newpos = size+*newpos; if (*newpos<0 || *newpos>size) { PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos); Py_DECREF(restuple); return NULL; } Py_INCREF(resunicode); Py_DECREF(restuple); return resunicode; } static PyObject *unicode_encode_ucs1(const Py_UNICODE *p, Py_ssize_t size, const char *errors, int limit) { /* output object */ PyObject *res; /* pointers to the beginning and end+1 of input */ const Py_UNICODE *startp = p; const Py_UNICODE *endp = p + size; /* pointer to the beginning of the unencodable characters */ /* const Py_UNICODE *badp = NULL; */ /* pointer into the output */ char *str; /* current output position */ Py_ssize_t respos = 0; Py_ssize_t ressize; const char *encoding = (limit == 256) ? "latin-1" : "ascii"; const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)"; PyObject *errorHandler = NULL; PyObject *exc = NULL; /* the following variable is used for caching string comparisons * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ int known_errorHandler = -1; /* allocate enough for a simple encoding without replacements, if we need more, we'll resize */ res = PyString_FromStringAndSize(NULL, size); if (res == NULL) goto onError; if (size == 0) return res; str = PyString_AS_STRING(res); ressize = size; while (p<endp) { Py_UNICODE c = *p; /* can we encode this? */ if (c<limit) { /* no overflow check, because we know that the space is enough */ *str++ = (char)c; ++p; } else { Py_ssize_t unicodepos = p-startp; Py_ssize_t requiredsize; PyObject *repunicode; Py_ssize_t repsize; Py_ssize_t newpos; Py_ssize_t respos; Py_UNICODE *uni2; /* startpos for collecting unencodable chars */ const Py_UNICODE *collstart = p; const Py_UNICODE *collend = p; /* find all unecodable characters */ while ((collend < endp) && ((*collend)>=limit)) ++collend; /* cache callback name lookup (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { if ((errors==NULL) || (!strcmp(errors, "strict"))) known_errorHandler = 1; else if (!strcmp(errors, "replace")) known_errorHandler = 2; else if (!strcmp(errors, "ignore")) known_errorHandler = 3; else if (!strcmp(errors, "xmlcharrefreplace")) known_errorHandler = 4; else known_errorHandler = 0; } switch (known_errorHandler) { case 1: /* strict */ raise_encode_exception(&exc, encoding, startp, size, collstart-startp, collend-startp, reason); goto onError; case 2: /* replace */ while (collstart++<collend) *str++ = '?'; /* fall through */ case 3: /* ignore */ p = collend; break; case 4: /* xmlcharrefreplace */ respos = str-PyString_AS_STRING(res); /* determine replacement size (temporarily (mis)uses p) */ for (p = collstart, repsize = 0; p < collend; ++p) { if (*p<10) repsize += 2+1+1; else if (*p<100) repsize += 2+2+1; else if (*p<1000) repsize += 2+3+1; else if (*p<10000) repsize += 2+4+1; #ifndef Py_UNICODE_WIDE else repsize += 2+5+1; #else else if (*p<100000) repsize += 2+5+1; else if (*p<1000000) repsize += 2+6+1; else repsize += 2+7+1; #endif } requiredsize = respos+repsize+(endp-collend); if (requiredsize > ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; if (_PyString_Resize(&res, requiredsize)) goto onError; str = PyString_AS_STRING(res) + respos; ressize = requiredsize; } /* generate replacement (temporarily (mis)uses p) */ for (p = collstart; p < collend; ++p) { str += sprintf(str, "&#%d;", (int)*p); } p = collend; break; default: repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, encoding, reason, startp, size, &exc, collstart-startp, collend-startp, &newpos); if (repunicode == NULL) goto onError; /* need more space? (at least enough for what we have+the replacement+the rest of the string, so we won't have to check space for encodable characters) */ respos = str-PyString_AS_STRING(res); repsize = PyUnicode_GET_SIZE(repunicode); requiredsize = respos+repsize+(endp-collend); if (requiredsize > ressize) { if (requiredsize<2*ressize) requiredsize = 2*ressize; if (_PyString_Resize(&res, requiredsize)) { Py_DECREF(repunicode); goto onError; } str = PyString_AS_STRING(res) + respos; ressize = requiredsize; } /* check if there is anything unencodable in the replacement and copy it to the output */ for (uni2 = PyUnicode_AS_UNICODE(repunicode);repsize-->0; ++uni2, ++str) { c = *uni2; if (c >= limit) { raise_encode_exception(&exc, encoding, startp, size, unicodepos, unicodepos+1, reason); Py_DECREF(repunicode); goto onError; } *str = (char)c; } p = startp + newpos; Py_DECREF(repunicode); } } } /* Resize if we allocated to much */ respos = str-PyString_AS_STRING(res); if (respos<ressize) /* If this falls res will be NULL */ _PyString_Resize(&res, respos); Py_XDECREF(errorHandler); Py_XDECREF(exc); return res; onError: Py_XDECREF(res); Py_XDECREF(errorHandler); Py_XDECREF(exc); return NULL; } PyObject *PyUnicode_EncodeLatin1(const Py_UNICODE *p, Py_ssize_t size, const char *errors) { return unicode_encode_ucs1(p, size, errors, 256); } PyObject *PyUnicode_AsLatin1String(PyObject *unicode) { if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL); } /* --- 7-bit ASCII Codec -------------------------------------------------- */ PyObject *PyUnicode_DecodeASCII(const char *s, Py_ssize_t size, const char *errors) { const char *starts = s; PyUnicodeObject *v; Py_UNICODE *p; Py_ssize_t startinpos; Py_ssize_t endinpos; Py_ssize_t outpos; const char *e; PyObject *errorHandler = NULL; PyObject *exc = NULL; /* ASCII is equivalent to the first 128 ordinals in Unicode. */ if (size == 1 && *(unsigned char*)s < 128) { Py_UNICODE r = *(unsigned char*)s; return PyUnicode_FromUnicode(&r, 1); } v = _PyUnicode_New(size); if (v == NULL) goto onError; if (size == 0) return (PyObject *)v; p = PyUnicode_AS_UNICODE(v); e = s + size; while (s < e) { register unsigned char c = (unsigned char)*s; if (c < 128) { *p++ = c; ++s; } else { startinpos = s-starts; endinpos = startinpos + 1; outpos = p - (Py_UNICODE *)PyUnicode_AS_UNICODE(v); if (unicode_decode_call_errorhandler( errors, &errorHandler, "ascii", "ordinal not in range(128)", starts, size, &startinpos, &endinpos, &exc, &s, (PyObject **)&v, &outpos, &p)) goto onError; } } if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v)) if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0) goto onError; Py_XDECREF(errorHandler); Py_XDECREF(exc); return (PyObject *)v; onError: Py_XDECREF(v); Py_XDECREF(errorHandler); Py_XDECREF(exc); return NULL; } PyObject *PyUnicode_EncodeASCII(const Py_UNICODE *p, Py_ssize_t size, const char *errors) { return unicode_encode_ucs1(p, size, errors, 128); } PyObject *PyUnicode_AsASCIIString(PyObject *unicode) { if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); return NULL; } return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), NULL); } #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) /* --- MBCS codecs for Windows -------------------------------------------- */ #if SIZEOF_INT < SIZEOF_SSIZE_T #define NEED_RETRY #endif /* XXX This code is limited to "true" double-byte encodings, as a) it assumes an incomplete character consists of a single byte, and b) IsDBCSLeadByte (probably) does not work for non-DBCS multi-byte encodings, see IsDBCSLeadByteEx documentation. */ static int is_dbcs_lead_byte(const char *s, int offset) { const char *curr = s + offset; if (IsDBCSLeadByte(*curr)) { const char *prev = CharPrev(s, curr); return (prev == curr) || !IsDBCSLeadByte(*prev) || (curr - prev == 2); } return 0; } /* * Decode MBCS string into unicode object. If 'final' is set, converts * trailing lead-byte too. Returns consumed size if succeed, -1 otherwise. */ static int decode_mbcs(PyUnicodeObject **v, const char *s, /* MBCS string */ int size, /* sizeof MBCS string */ int final) { Py_UNICODE *p; Py_ssize_t n = 0; int usize = 0; assert(size >= 0); /* Skip trailing lead-byte unless 'final' is set */ if (!final && size >= 1 && is_dbcs_lead_byte(s, size - 1)) --size; /* First get the size of the result */ if (size > 0) { usize = MultiByteToWideChar(CP_ACP, 0, s, size, NULL, 0); if (usize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } if (*v == NULL) { /* Create unicode object */ *v = _PyUnicode_New(usize); if (*v == NULL) return -1; } else { /* Extend unicode object */ n = PyUnicode_GET_SIZE(*v); if (_PyUnicode_Resize(v, n + usize) < 0) return -1; } /* Do the conversion */ if (size > 0) { p = PyUnicode_AS_UNICODE(*v) + n; if (0 == MultiByteToWideChar(CP_ACP, 0, s, size, p, usize)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } return size; } PyObject *PyUnicode_DecodeMBCSStateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) { PyUnicodeObject *v = NULL; int done; if (consumed) *consumed = 0; #ifdef NEED_RETRY retry: if (size > INT_MAX) done = decode_mbcs(&v, s, INT_MAX, 0); else #endif done = decode_mbcs(&v, s, (int)size, !consumed); if (done < 0) { Py_XDECREF(v); return NULL; } if (consumed) *consumed += done; #ifdef NEED_RETRY if (size > INT_MAX) { s += done; size -= done; goto retry; } #endif return (PyObject *)v; } PyObject *PyUnicode_DecodeMBCS(const char *s, Py_ssize_t size, const char *errors) { return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL); } /* * Convert unicode into string object (MBCS). * Returns 0 if succeed, -1 otherwise. */ static int encode_mbcs(PyObject **repr, const Py_UNICODE *p, /* unicode */ int size) /* size of unicode */ { int mbcssize = 0; Py_ssize_t n = 0; assert(size >= 0); /* First get the size of the result */ if (size > 0) { mbcssize = WideCharToMultiByte(CP_ACP, 0, p, size, NULL, 0, NULL, NULL); if (mbcssize == 0) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } if (*repr == NULL) { /* Create string object */ *repr = PyString_FromStringAndSize(NULL, mbcssize); if (*repr == NULL) return -1; } else { /* Extend string object */ n = PyString_Size(*repr); if (_PyString_Resize(repr, n + mbcssize) < 0) return -1; } /* Do the conversion */ if (size > 0) { char *s = PyString_AS_STRING(*repr) + n; if (0 == WideCharToMultiByte(CP_ACP, 0, p, size, s, mbcssize, NULL, NULL)) { PyErr_SetFromWindowsErrWithFilename(0, NULL); return -1; } } return 0; }