cinap_lenrekadd hg and python4bb9e2215 years agoHistory
8067 lines · 210.4 KB · C
RawDownload
 PyObject *PyUnicode_EncodeMBCS(const Py_UNICODE *p,				Py_ssize_t size,				const char *errors){    PyObject *repr = NULL;    int ret; #ifdef NEED_RETRY retry:    if (size > INT_MAX)	ret = encode_mbcs(&repr, p, INT_MAX);    else#endif	ret = encode_mbcs(&repr, p, (int)size);     if (ret < 0) {	Py_XDECREF(repr);	return NULL;    } #ifdef NEED_RETRY    if (size > INT_MAX) {	p += INT_MAX;	size -= INT_MAX;	goto retry;    }#endif     return repr;} PyObject *PyUnicode_AsMBCSString(PyObject *unicode){    if (!PyUnicode_Check(unicode)) {        PyErr_BadArgument();        return NULL;    }    return PyUnicode_EncodeMBCS(PyUnicode_AS_UNICODE(unicode),				PyUnicode_GET_SIZE(unicode),				NULL);} #undef NEED_RETRY #endif /* MS_WINDOWS */ /* --- Character Mapping Codec -------------------------------------------- */ PyObject *PyUnicode_DecodeCharmap(const char *s,				  Py_ssize_t size,				  PyObject *mapping,				  const char *errors){    const char *starts = s;    Py_ssize_t startinpos;    Py_ssize_t endinpos;    Py_ssize_t outpos;    const char *e;    PyUnicodeObject *v;    Py_UNICODE *p;    Py_ssize_t extrachars = 0;    PyObject *errorHandler = NULL;    PyObject *exc = NULL;    Py_UNICODE *mapstring = NULL;    Py_ssize_t maplen = 0;     /* Default to Latin-1 */    if (mapping == NULL)	return PyUnicode_DecodeLatin1(s, size, errors);     v = _PyUnicode_New(size);    if (v == NULL)	goto onError;    if (size == 0)	return (PyObject *)v;    p = PyUnicode_AS_UNICODE(v);    e = s + size;    if (PyUnicode_CheckExact(mapping)) {	mapstring = PyUnicode_AS_UNICODE(mapping);	maplen = PyUnicode_GET_SIZE(mapping);	while (s < e) {	    unsigned char ch = *s;	    Py_UNICODE x = 0xfffe; /* illegal value */ 	    if (ch < maplen)		x = mapstring[ch]; 	    if (x == 0xfffe) {		/* undefined mapping */		outpos = p-PyUnicode_AS_UNICODE(v);		startinpos = s-starts;		endinpos = startinpos+1;		if (unicode_decode_call_errorhandler(		     errors, &errorHandler,		     "charmap", "character maps to <undefined>",		     starts, size, &startinpos, &endinpos, &exc, &s,		     (PyObject **)&v, &outpos, &p)) {		    goto onError;		}		continue;	    }	    *p++ = x;	    ++s;	}    }    else {	while (s < e) {	    unsigned char ch = *s;	    PyObject *w, *x; 	    /* Get mapping (char ordinal -> integer, Unicode char or None) */	    w = PyInt_FromLong((long)ch);	    if (w == NULL)		goto onError;	    x = PyObject_GetItem(mapping, w);	    Py_DECREF(w);	    if (x == NULL) {		if (PyErr_ExceptionMatches(PyExc_LookupError)) {		    /* No mapping found means: mapping is undefined. */		    PyErr_Clear();		    x = Py_None;		    Py_INCREF(x);		} else		    goto onError;	    }    	    /* Apply mapping */	    if (PyInt_Check(x)) {		long value = PyInt_AS_LONG(x);		if (value < 0 || value > 65535) {		    PyErr_SetString(PyExc_TypeError,				    "character mapping must be in range(65536)");		    Py_DECREF(x);		    goto onError;		}		*p++ = (Py_UNICODE)value;	    }	    else if (x == Py_None) {		/* undefined mapping */		outpos = p-PyUnicode_AS_UNICODE(v);		startinpos = s-starts;		endinpos = startinpos+1;		if (unicode_decode_call_errorhandler(		     errors, &errorHandler,		     "charmap", "character maps to <undefined>",		     starts, size, &startinpos, &endinpos, &exc, &s,		     (PyObject **)&v, &outpos, &p)) {		    Py_DECREF(x);		    goto onError;		}		Py_DECREF(x);		continue;	    }	    else if (PyUnicode_Check(x)) {		Py_ssize_t targetsize = PyUnicode_GET_SIZE(x);    		if (targetsize == 1)		    /* 1-1 mapping */		    *p++ = *PyUnicode_AS_UNICODE(x);    		else if (targetsize > 1) {		    /* 1-n mapping */		    if (targetsize > extrachars) {			/* resize first */			Py_ssize_t oldpos = p - PyUnicode_AS_UNICODE(v);			Py_ssize_t needed = (targetsize - extrachars) + \				     (targetsize << 2);			extrachars += needed;			/* XXX overflow detection missing */			if (_PyUnicode_Resize(&v,					     PyUnicode_GET_SIZE(v) + needed) < 0) {			    Py_DECREF(x);			    goto onError;			}			p = PyUnicode_AS_UNICODE(v) + oldpos;		    }		    Py_UNICODE_COPY(p,				    PyUnicode_AS_UNICODE(x),				    targetsize);		    p += targetsize;		    extrachars -= targetsize;		}		/* 1-0 mapping: skip the character */	    }	    else {		/* wrong return value */		PyErr_SetString(PyExc_TypeError,		      "character mapping must return integer, None or unicode");		Py_DECREF(x);		goto onError;	    }	    Py_DECREF(x);	    ++s;	}    }    if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_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(errorHandler);    Py_XDECREF(exc);    Py_XDECREF(v);    return NULL;} /* Charmap encoding: the lookup table */ struct encoding_map{  PyObject_HEAD  unsigned char level1[32];  int count2, count3;  unsigned char level23[1];}; static PyObject*encoding_map_size(PyObject *obj, PyObject* args){    struct encoding_map *map = (struct encoding_map*)obj;    return PyInt_FromLong(sizeof(*map) - 1 + 16*map->count2 +                           128*map->count3);} static PyMethodDef encoding_map_methods[] = {	{"size", encoding_map_size, METH_NOARGS,          PyDoc_STR("Return the size (in bytes) of this object") },        { 0 }}; static voidencoding_map_dealloc(PyObject* o){	PyObject_FREE(o);} static PyTypeObject EncodingMapType = {	PyObject_HEAD_INIT(NULL)        0,                      /*ob_size*/        "EncodingMap",          /*tp_name*/        sizeof(struct encoding_map),   /*tp_basicsize*/        0,                      /*tp_itemsize*/        /* methods */        encoding_map_dealloc,   /*tp_dealloc*/        0,                      /*tp_print*/        0,                      /*tp_getattr*/        0,                      /*tp_setattr*/        0,                      /*tp_compare*/        0,                      /*tp_repr*/        0,                      /*tp_as_number*/        0,                      /*tp_as_sequence*/        0,                      /*tp_as_mapping*/        0,                      /*tp_hash*/        0,                      /*tp_call*/        0,                      /*tp_str*/        0,                      /*tp_getattro*/        0,                      /*tp_setattro*/        0,                      /*tp_as_buffer*/        Py_TPFLAGS_DEFAULT,     /*tp_flags*/        0,                      /*tp_doc*/        0,                      /*tp_traverse*/        0,                      /*tp_clear*/        0,                      /*tp_richcompare*/        0,                      /*tp_weaklistoffset*/        0,                      /*tp_iter*/        0,                      /*tp_iternext*/        encoding_map_methods,   /*tp_methods*/        0,                      /*tp_members*/        0,                      /*tp_getset*/        0,                      /*tp_base*/        0,                      /*tp_dict*/        0,                      /*tp_descr_get*/        0,                      /*tp_descr_set*/        0,                      /*tp_dictoffset*/        0,                      /*tp_init*/        0,                      /*tp_alloc*/        0,                      /*tp_new*/        0,                      /*tp_free*/        0,                      /*tp_is_gc*/}; PyObject*PyUnicode_BuildEncodingMap(PyObject* string){    Py_UNICODE *decode;    PyObject *result;    struct encoding_map *mresult;    int i;    int need_dict = 0;    unsigned char level1[32];    unsigned char level2[512];    unsigned char *mlevel1, *mlevel2, *mlevel3;    int count2 = 0, count3 = 0;     if (!PyUnicode_Check(string) || PyUnicode_GetSize(string) != 256) {        PyErr_BadArgument();        return NULL;    }    decode = PyUnicode_AS_UNICODE(string);    memset(level1, 0xFF, sizeof level1);    memset(level2, 0xFF, sizeof level2);     /* If there isn't a one-to-one mapping of NULL to \0,       or if there are non-BMP characters, we need to use       a mapping dictionary. */    if (decode[0] != 0)        need_dict = 1;    for (i = 1; i < 256; i++) {        int l1, l2;        if (decode[i] == 0            #ifdef Py_UNICODE_WIDE            || decode[i] > 0xFFFF            #endif        ) {            need_dict = 1;            break;        }        if (decode[i] == 0xFFFE)            /* unmapped character */            continue;        l1 = decode[i] >> 11;        l2 = decode[i] >> 7;        if (level1[l1] == 0xFF)            level1[l1] = count2++;        if (level2[l2] == 0xFF)            level2[l2] = count3++;     }     if (count2 >= 0xFF || count3 >= 0xFF)        need_dict = 1;     if (need_dict) {        PyObject *result = PyDict_New();        PyObject *key, *value;        if (!result)            return NULL;        for (i = 0; i < 256; i++) {            key = value = NULL;            key = PyInt_FromLong(decode[i]);            value = PyInt_FromLong(i);            if (!key || !value)                goto failed1;            if (PyDict_SetItem(result, key, value) == -1)                goto failed1;            Py_DECREF(key);            Py_DECREF(value);        }        return result;      failed1:        Py_XDECREF(key);        Py_XDECREF(value);        Py_DECREF(result);        return NULL;    }     /* Create a three-level trie */    result = PyObject_MALLOC(sizeof(struct encoding_map) +                             16*count2 + 128*count3 - 1);    if (!result)        return PyErr_NoMemory();    PyObject_Init(result, &EncodingMapType);    mresult = (struct encoding_map*)result;    mresult->count2 = count2;    mresult->count3 = count3;    mlevel1 = mresult->level1;    mlevel2 = mresult->level23;    mlevel3 = mresult->level23 + 16*count2;    memcpy(mlevel1, level1, 32);    memset(mlevel2, 0xFF, 16*count2);    memset(mlevel3, 0, 128*count3);    count3 = 0;    for (i = 1; i < 256; i++) {        int o1, o2, o3, i2, i3;        if (decode[i] == 0xFFFE)            /* unmapped character */            continue;        o1 = decode[i]>>11;        o2 = (decode[i]>>7) & 0xF;        i2 = 16*mlevel1[o1] + o2;        if (mlevel2[i2] == 0xFF)            mlevel2[i2] = count3++;        o3 = decode[i] & 0x7F;        i3 = 128*mlevel2[i2] + o3;        mlevel3[i3] = i;    }    return result;} static intencoding_map_lookup(Py_UNICODE c, PyObject *mapping){    struct encoding_map *map = (struct encoding_map*)mapping;    int l1 = c>>11;    int l2 = (c>>7) & 0xF;    int l3 = c & 0x7F;    int i; #ifdef Py_UNICODE_WIDE    if (c > 0xFFFF) {	return -1;    }#endif    if (c == 0)        return 0;    /* level 1*/    i = map->level1[l1];    if (i == 0xFF) {        return -1;    }    /* level 2*/    i = map->level23[16*i+l2];    if (i == 0xFF) {        return -1;    }    /* level 3 */    i = map->level23[16*map->count2 + 128*i + l3];    if (i == 0) {        return -1;    }    return i;} /* Lookup the character ch in the mapping. If the character   can't be found, Py_None is returned (or NULL, if another   error occurred). */static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping){    PyObject *w = PyInt_FromLong((long)c);    PyObject *x;     if (w == NULL)	 return NULL;    x = PyObject_GetItem(mapping, w);    Py_DECREF(w);    if (x == NULL) {	if (PyErr_ExceptionMatches(PyExc_LookupError)) {	    /* No mapping found means: mapping is undefined. */	    PyErr_Clear();	    x = Py_None;	    Py_INCREF(x);	    return x;	} else	    return NULL;    }    else if (x == Py_None)	return x;    else if (PyInt_Check(x)) {	long value = PyInt_AS_LONG(x);	if (value < 0 || value > 255) {	    PyErr_SetString(PyExc_TypeError,			     "character mapping must be in range(256)");	    Py_DECREF(x);	    return NULL;	}	return x;    }    else if (PyString_Check(x))	return x;    else {	/* wrong return value */	PyErr_SetString(PyExc_TypeError,	      "character mapping must return integer, None or str");	Py_DECREF(x);	return NULL;    }} static intcharmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize){	Py_ssize_t outsize = PyString_GET_SIZE(*outobj);	/* exponentially overallocate to minimize reallocations */	if (requiredsize < 2*outsize)	    requiredsize = 2*outsize;	if (_PyString_Resize(outobj, requiredsize)) {	    return 0;	}	return 1;} typedef enum charmapencode_result {   enc_SUCCESS, enc_FAILED, enc_EXCEPTION }charmapencode_result;/* lookup the character, put the result in the output string and adjust   various state variables. Reallocate the output string if not enough   space is available. Return a new reference to the object that   was put in the output buffer, or Py_None, if the mapping was undefined   (in which case no character was written) or NULL, if a   reallocation error occurred. The caller must decref the result */staticcharmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,    PyObject **outobj, Py_ssize_t *outpos){    PyObject *rep;    char *outstart;    Py_ssize_t outsize = PyString_GET_SIZE(*outobj); 

Lines 3001–3500 of 8067. Previous lines