cinap_lenrekadd hg and python4bb9e2215 years agoHistory
8067 lines · 210.4 KB · C
RawDownload
    }    return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode),				PyUnicode_GET_SIZE(unicode),				NULL);} /* --- UTF-16 Codec ------------------------------------------------------- */ PyObject *PyUnicode_DecodeUTF16(const char *s,		      Py_ssize_t size,		      const char *errors,		      int *byteorder){    return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL);} PyObject *PyUnicode_DecodeUTF16Stateful(const char *s,			      Py_ssize_t size,			      const char *errors,			      int *byteorder,			      Py_ssize_t *consumed){    const char *starts = s;    Py_ssize_t startinpos;    Py_ssize_t endinpos;    Py_ssize_t outpos;    PyUnicodeObject *unicode;    Py_UNICODE *p;    const unsigned char *q, *e;    int bo = 0;       /* assume native ordering by default */    const char *errmsg = "";    /* Offsets from q for retrieving byte pairs in the right order. */#ifdef BYTEORDER_IS_LITTLE_ENDIAN    int ihi = 1, ilo = 0;#else    int ihi = 0, ilo = 1;#endif    PyObject *errorHandler = NULL;    PyObject *exc = NULL;     /* Note: size will always be longer than the resulting Unicode       character count */    unicode = _PyUnicode_New(size);    if (!unicode)        return NULL;    if (size == 0)        return (PyObject *)unicode;     /* Unpack UTF-16 encoded data */    p = unicode->str;    q = (unsigned char *)s;    e = q + size;     if (byteorder)        bo = *byteorder;     /* Check for BOM marks (U+FEFF) in the input and adjust current       byte order setting accordingly. In native mode, the leading BOM       mark is skipped, in all other modes, it is copied to the output       stream as-is (giving a ZWNBSP character). */    if (bo == 0) {        if (size >= 2) {            const Py_UNICODE bom = (q[ihi] << 8) | q[ilo];#ifdef BYTEORDER_IS_LITTLE_ENDIAN	    if (bom == 0xFEFF) {		q += 2;		bo = -1;	    }	    else if (bom == 0xFFFE) {		q += 2;		bo = 1;	    }#else	    if (bom == 0xFEFF) {		q += 2;		bo = 1;	    }	    else if (bom == 0xFFFE) {		q += 2;		bo = -1;	    }#endif	}    }     if (bo == -1) {        /* force LE */        ihi = 1;        ilo = 0;    }    else if (bo == 1) {        /* force BE */        ihi = 0;        ilo = 1;    }     while (q < e) {	Py_UNICODE ch;	/* remaining bytes at the end? (size should be even) */	if (e-q<2) {	    if (consumed)		break;	    errmsg = "truncated data";	    startinpos = ((const char *)q)-starts;	    endinpos = ((const char *)e)-starts;	    goto utf16Error;	    /* The remaining input chars are ignored if the callback	       chooses to skip the input */	}	ch = (q[ihi] << 8) | q[ilo]; 	q += 2; 	if (ch < 0xD800 || ch > 0xDFFF) {	    *p++ = ch;	    continue;	} 	/* UTF-16 code pair: */	if (q >= e) {	    errmsg = "unexpected end of data";	    startinpos = (((const char *)q)-2)-starts;	    endinpos = ((const char *)e)-starts;	    goto utf16Error;	}	if (0xD800 <= ch && ch <= 0xDBFF) {	    Py_UNICODE ch2 = (q[ihi] << 8) | q[ilo];	    q += 2;	    if (0xDC00 <= ch2 && ch2 <= 0xDFFF) {#ifndef Py_UNICODE_WIDE		*p++ = ch;		*p++ = ch2;#else		*p++ = (((ch & 0x3FF)<<10) | (ch2 & 0x3FF)) + 0x10000;#endif		continue;	    }	    else {                errmsg = "illegal UTF-16 surrogate";		startinpos = (((const char *)q)-4)-starts;		endinpos = startinpos+2;		goto utf16Error;	    } 	}	errmsg = "illegal encoding";	startinpos = (((const char *)q)-2)-starts;	endinpos = startinpos+2;	/* Fall through to report the error */     utf16Error:	outpos = p-PyUnicode_AS_UNICODE(unicode);	if (unicode_decode_call_errorhandler(	         errors, &errorHandler,	         "utf16", errmsg,	         starts, size, &startinpos, &endinpos, &exc, (const char **)&q,	         (PyObject **)&unicode, &outpos, &p))	    goto onError;    }     if (byteorder)        *byteorder = bo;     if (consumed)	*consumed = (const char *)q-starts;     /* Adjust length */    if (_PyUnicode_Resize(&unicode, p - unicode->str) < 0)        goto onError;     Py_XDECREF(errorHandler);    Py_XDECREF(exc);    return (PyObject *)unicode; onError:    Py_DECREF(unicode);    Py_XDECREF(errorHandler);    Py_XDECREF(exc);    return NULL;} PyObject *PyUnicode_EncodeUTF16(const Py_UNICODE *s,		      Py_ssize_t size,		      const char *errors,		      int byteorder){    PyObject *v;    unsigned char *p;#ifdef Py_UNICODE_WIDE    int i, pairs;#else    const int pairs = 0;#endif    /* Offsets from p for storing byte pairs in the right order. */#ifdef BYTEORDER_IS_LITTLE_ENDIAN    int ihi = 1, ilo = 0;#else    int ihi = 0, ilo = 1;#endif #define STORECHAR(CH)                   \    do {                                \        p[ihi] = ((CH) >> 8) & 0xff;    \        p[ilo] = (CH) & 0xff;           \        p += 2;                         \    } while(0) #ifdef Py_UNICODE_WIDE    for (i = pairs = 0; i < size; i++)	if (s[i] >= 0x10000)	    pairs++;#endif    v = PyString_FromStringAndSize(NULL,		  2 * (size + pairs + (byteorder == 0)));    if (v == NULL)        return NULL;     p = (unsigned char *)PyString_AS_STRING(v);    if (byteorder == 0)	STORECHAR(0xFEFF);    if (size == 0)        return v;     if (byteorder == -1) {        /* force LE */        ihi = 1;        ilo = 0;    }    else if (byteorder == 1) {        /* force BE */        ihi = 0;        ilo = 1;    }     while (size-- > 0) {	Py_UNICODE ch = *s++;	Py_UNICODE ch2 = 0;#ifdef Py_UNICODE_WIDE	if (ch >= 0x10000) {	    ch2 = 0xDC00 | ((ch-0x10000) & 0x3FF);	    ch  = 0xD800 | ((ch-0x10000) >> 10);	}#endif        STORECHAR(ch);        if (ch2)            STORECHAR(ch2);    }    return v;#undef STORECHAR} PyObject *PyUnicode_AsUTF16String(PyObject *unicode){    if (!PyUnicode_Check(unicode)) {        PyErr_BadArgument();        return NULL;    }    return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(unicode),				 PyUnicode_GET_SIZE(unicode),				 NULL,				 0);} /* --- Unicode Escape Codec ----------------------------------------------- */ static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,					Py_ssize_t size,					const char *errors){    const char *starts = s;    Py_ssize_t startinpos;    Py_ssize_t endinpos;    Py_ssize_t outpos;    int i;    PyUnicodeObject *v;    Py_UNICODE *p;    const char *end;    char* message;    Py_UCS4 chr = 0xffffffff; /* in case 'getcode' messes up */    PyObject *errorHandler = NULL;    PyObject *exc = NULL;     /* Escaped strings will always be longer than the resulting       Unicode string, so we start with size here and then reduce the       length after conversion to the true value.       (but if the error callback returns a long replacement string       we'll have to allocate more space) */    v = _PyUnicode_New(size);    if (v == NULL)        goto onError;    if (size == 0)        return (PyObject *)v;     p = PyUnicode_AS_UNICODE(v);    end = s + size;     while (s < end) {        unsigned char c;        Py_UNICODE x;        int digits;         /* Non-escape characters are interpreted as Unicode ordinals */        if (*s != '\\') {            *p++ = (unsigned char) *s++;            continue;        }         startinpos = s-starts;        /* \ - Escapes */        s++;        switch (*s++) {         /* \x escapes */        case '\n': break;        case '\\': *p++ = '\\'; break;        case '\'': *p++ = '\''; break;        case '\"': *p++ = '\"'; break;        case 'b': *p++ = '\b'; break;        case 'f': *p++ = '\014'; break; /* FF */        case 't': *p++ = '\t'; break;        case 'n': *p++ = '\n'; break;        case 'r': *p++ = '\r'; break;        case 'v': *p++ = '\013'; break; /* VT */        case 'a': *p++ = '\007'; break; /* BEL, not classic C */         /* \OOO (octal) escapes */        case '0': case '1': case '2': case '3':        case '4': case '5': case '6': case '7':            x = s[-1] - '0';            if ('0' <= *s && *s <= '7') {                x = (x<<3) + *s++ - '0';                if ('0' <= *s && *s <= '7')                    x = (x<<3) + *s++ - '0';            }            *p++ = x;            break;         /* hex escapes */        /* \xXX */        case 'x':            digits = 2;            message = "truncated \\xXX escape";            goto hexescape;         /* \uXXXX */        case 'u':            digits = 4;            message = "truncated \\uXXXX escape";            goto hexescape;         /* \UXXXXXXXX */        case 'U':            digits = 8;            message = "truncated \\UXXXXXXXX escape";        hexescape:            chr = 0;            outpos = p-PyUnicode_AS_UNICODE(v);            if (s+digits>end) {                endinpos = size;                if (unicode_decode_call_errorhandler(                    errors, &errorHandler,                    "unicodeescape", "end of string in escape sequence",                    starts, size, &startinpos, &endinpos, &exc, &s,                    (PyObject **)&v, &outpos, &p))                    goto onError;                goto nextByte;            }            for (i = 0; i < digits; ++i) {                c = (unsigned char) s[i];                if (!isxdigit(c)) {                    endinpos = (s+i+1)-starts;                    if (unicode_decode_call_errorhandler(                        errors, &errorHandler,                        "unicodeescape", message,                        starts, size, &startinpos, &endinpos, &exc, &s,                        (PyObject **)&v, &outpos, &p))                        goto onError;                    goto nextByte;                }                chr = (chr<<4) & ~0xF;                if (c >= '0' && c <= '9')                    chr += c - '0';                else if (c >= 'a' && c <= 'f')                    chr += 10 + c - 'a';                else                    chr += 10 + c - 'A';            }            s += i;            if (chr == 0xffffffff && PyErr_Occurred())                /* _decoding_error will have already written into the                   target buffer. */                break;        store:            /* when we get here, chr is a 32-bit unicode character */            if (chr <= 0xffff)                /* UCS-2 character */                *p++ = (Py_UNICODE) chr;            else if (chr <= 0x10ffff) {                /* UCS-4 character. Either store directly, or as                   surrogate pair. */#ifdef Py_UNICODE_WIDE                *p++ = chr;#else                chr -= 0x10000L;                *p++ = 0xD800 + (Py_UNICODE) (chr >> 10);                *p++ = 0xDC00 + (Py_UNICODE) (chr & 0x03FF);#endif            } else {                endinpos = s-starts;                outpos = p-PyUnicode_AS_UNICODE(v);                if (unicode_decode_call_errorhandler(                    errors, &errorHandler,                    "unicodeescape", "illegal Unicode character",                    starts, size, &startinpos, &endinpos, &exc, &s,                    (PyObject **)&v, &outpos, &p))                    goto onError;            }            break;         /* \N{name} */        case 'N':            message = "malformed \\N character escape";            if (ucnhash_CAPI == NULL) {                /* load the unicode data module */                PyObject *m, *api;                m = PyImport_ImportModule("unicodedata");                if (m == NULL)                    goto ucnhashError;                api = PyObject_GetAttrString(m, "ucnhash_CAPI");                Py_DECREF(m);                if (api == NULL)                    goto ucnhashError;                ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCObject_AsVoidPtr(api);                Py_DECREF(api);                if (ucnhash_CAPI == NULL)                    goto ucnhashError;            }            if (*s == '{') {                const char *start = s+1;                /* look for the closing brace */                while (*s != '}' && s < end)                    s++;                if (s > start && s < end && *s == '}') {                    /* found a name.  look it up in the unicode database */                    message = "unknown Unicode character name";                    s++;                    if (ucnhash_CAPI->getcode(NULL, start, (int)(s-start-1), &chr))                        goto store;                }            }            endinpos = s-starts;            outpos = p-PyUnicode_AS_UNICODE(v);            if (unicode_decode_call_errorhandler(                errors, &errorHandler,                "unicodeescape", message,                starts, size, &startinpos, &endinpos, &exc, &s,                (PyObject **)&v, &outpos, &p))                goto onError;            break;         default:            if (s > end) {                message = "\\ at end of string";                s--;                endinpos = s-starts;                outpos = p-PyUnicode_AS_UNICODE(v);                if (unicode_decode_call_errorhandler(                    errors, &errorHandler,                    "unicodeescape", message,                    starts, size, &startinpos, &endinpos, &exc, &s,                    (PyObject **)&v, &outpos, &p))                    goto onError;            }            else {                *p++ = '\\';                *p++ = (unsigned char)s[-1];            }            break;        }        nextByte:        ;    }    if (_PyUnicode_Resize(&v, p - PyUnicode_AS_UNICODE(v)) < 0)        goto onError;    Py_XDECREF(errorHandler);    Py_XDECREF(exc);    return (PyObject *)v; ucnhashError:    PyErr_SetString(        PyExc_UnicodeError,        "\\N escapes not supported (can't load unicodedata module)"        );    Py_XDECREF(v);    Py_XDECREF(errorHandler);

Lines 1501–2000 of 8067. Previous lines