cinap_lenrekadd hg and python4bb9e2215 years agoHistory
8067 lines · 210.4 KB · C
RawDownload
{    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