cinap_lenrekadd hg and python4bb9e2215 years agoHistory
8067 lines · 210.4 KB · C
RawDownload
/* Unicode implementation based on original code by Fredrik Lundh,modified by Marc-Andre Lemburg <mal@lemburg.com> according to theUnicode Integration Proposal (see file Misc/unicode.txt). Major speed upgrades to the method implementations at the ReykjavikNeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke. Copyright (c) Corporation for National Research Initiatives. --------------------------------------------------------------------The original string type implementation is:     Copyright (c) 1999 by Secret Labs AB    Copyright (c) 1999 by Fredrik Lundh By obtaining, using, and/or copying this software and/or itsassociated documentation, you agree that you have read, understood,and will comply with the following terms and conditions: Permission to use, copy, modify, and distribute this software and itsassociated documentation for any purpose and without fee is herebygranted, provided that the above copyright notice appears in allcopies, and that both that copyright notice and this permission noticeappear in supporting documentation, and that the name of Secret LabsAB or the author not be used in advertising or publicity pertaining todistribution of the software without specific, written priorpermission. SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TOTHIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ANDFITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FORANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGESWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ANACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUTOF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-------------------------------------------------------------------- */ #define PY_SSIZE_T_CLEAN#include "Python.h" #include "unicodeobject.h"#include "ucnhash.h" #ifdef MS_WINDOWS#include <windows.h>#endif /* Limit for the Unicode object free list */ #define MAX_UNICODE_FREELIST_SIZE       1024 /* Limit for the Unicode object free list stay alive optimization.    The implementation will keep allocated Unicode memory intact for   all objects on the free list having a size less than this   limit. This reduces malloc() overhead for small Unicode objects.    At worst this will result in MAX_UNICODE_FREELIST_SIZE *   (sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT +   malloc()-overhead) bytes of unused garbage.    Setting the limit to 0 effectively turns the feature off.    Note: This is an experimental feature ! If you get core dumps when   using Unicode objects, turn this feature off. */ #define KEEPALIVE_SIZE_LIMIT       9 /* Endianness switches; defaults to little endian */ #ifdef WORDS_BIGENDIAN# define BYTEORDER_IS_BIG_ENDIAN#else# define BYTEORDER_IS_LITTLE_ENDIAN#endif /* --- Globals ------------------------------------------------------------    The globals are initialized by the _PyUnicode_Init() API and should   not be used before calling that API. */  #ifdef __cplusplusextern "C" {#endif /* Free list for Unicode objects */static PyUnicodeObject *unicode_freelist;static int unicode_freelist_size; /* The empty Unicode object is shared to improve performance. */static PyUnicodeObject *unicode_empty; /* Single character Unicode strings in the Latin-1 range are being   shared as well. */static PyUnicodeObject *unicode_latin1[256]; /* Default encoding to use and assume when NULL is passed as encoding   parameter; it is initialized by _PyUnicode_Init().    Always use the PyUnicode_SetDefaultEncoding() and   PyUnicode_GetDefaultEncoding() APIs to access this global. */static char unicode_default_encoding[100]; Py_UNICODEPyUnicode_GetMax(void){#ifdef Py_UNICODE_WIDE	return 0x10FFFF;#else	/* This is actually an illegal character, so it should	   not be passed to unichr. */	return 0xFFFF;#endif} /* --- Bloom Filters ----------------------------------------------------- */ /* stuff to implement simple "bloom filters" for Unicode characters.   to keep things simple, we use a single bitmask, using the least 5   bits from each unicode characters as the bit index. */ /* the linebreak mask is set up by Unicode_Init below */ #define BLOOM_MASK unsigned long static BLOOM_MASK bloom_linebreak; #define BLOOM(mask, ch) ((mask & (1 << ((ch) & 0x1F)))) #define BLOOM_LINEBREAK(ch)\    (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK((ch))) Py_LOCAL_INLINE(BLOOM_MASK) make_bloom_mask(Py_UNICODE* ptr, Py_ssize_t len){    /* calculate simple bloom-style bitmask for a given unicode string */     long mask;    Py_ssize_t i;     mask = 0;    for (i = 0; i < len; i++)        mask |= (1 << (ptr[i] & 0x1F));     return mask;} Py_LOCAL_INLINE(int) unicode_member(Py_UNICODE chr, Py_UNICODE* set, Py_ssize_t setlen){    Py_ssize_t i;     for (i = 0; i < setlen; i++)        if (set[i] == chr)            return 1;     return 0;} #define BLOOM_MEMBER(mask, chr, set, setlen)\    BLOOM(mask, chr) && unicode_member(chr, set, setlen) /* --- Unicode Object ----------------------------------------------------- */ staticint unicode_resize(register PyUnicodeObject *unicode,                      Py_ssize_t length){    void *oldstr;     /* Shortcut if there's nothing much to do. */    if (unicode->length == length)	goto reset;     /* Resizing shared object (unicode_empty or single character       objects) in-place is not allowed. Use PyUnicode_Resize()       instead ! */     if (unicode == unicode_empty || 	(unicode->length == 1 && 	 unicode->str[0] < 256U &&	 unicode_latin1[unicode->str[0]] == unicode)) {        PyErr_SetString(PyExc_SystemError,                        "can't resize shared unicode objects");        return -1;    }     /* We allocate one more byte to make sure the string is Ux0000 terminated.       The overallocation is also used by fastsearch, which assumes that it's       safe to look at str[length] (without making any assumptions about what       it contains). */     oldstr = unicode->str;    PyMem_RESIZE(unicode->str, Py_UNICODE, length + 1);    if (!unicode->str) {	unicode->str = (Py_UNICODE *)oldstr;        PyErr_NoMemory();        return -1;    }    unicode->str[length] = 0;    unicode->length = length;  reset:    /* Reset the object caches */    if (unicode->defenc) {        Py_DECREF(unicode->defenc);        unicode->defenc = NULL;    }    unicode->hash = -1;     return 0;} /* We allocate one more byte to make sure the string is   Ux0000 terminated -- XXX is this needed ?    XXX This allocator could further be enhanced by assuring that the       free list never reduces its size below 1. */ staticPyUnicodeObject *_PyUnicode_New(Py_ssize_t length){    register PyUnicodeObject *unicode;     /* Optimization for empty strings */    if (length == 0 && unicode_empty != NULL) {        Py_INCREF(unicode_empty);        return unicode_empty;    }     /* Unicode freelist & memory allocation */    if (unicode_freelist) {        unicode = unicode_freelist;        unicode_freelist = *(PyUnicodeObject **)unicode;        unicode_freelist_size--;	if (unicode->str) {	    /* Keep-Alive optimization: we only upsize the buffer,	       never downsize it. */	    if ((unicode->length < length) &&                unicode_resize(unicode, length) < 0) {		PyMem_DEL(unicode->str);		goto onError;	    }	}        else {	    unicode->str = PyMem_NEW(Py_UNICODE, length + 1);        }        PyObject_INIT(unicode, &PyUnicode_Type);    }    else {        unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type);        if (unicode == NULL)            return NULL;	unicode->str = PyMem_NEW(Py_UNICODE, length + 1);    }     if (!unicode->str) {	PyErr_NoMemory();	goto onError;    }    /* Initialize the first element to guard against cases where     * the caller fails before initializing str -- unicode_resize()     * reads str[0], and the Keep-Alive optimization can keep memory     * allocated for str alive across a call to unicode_dealloc(unicode).     * We don't want unicode_resize to read uninitialized memory in     * that case.     */    unicode->str[0] = 0;    unicode->str[length] = 0;    unicode->length = length;    unicode->hash = -1;    unicode->defenc = NULL;    return unicode;  onError:    _Py_ForgetReference((PyObject *)unicode);    PyObject_Del(unicode);    return NULL;} staticvoid unicode_dealloc(register PyUnicodeObject *unicode){    if (PyUnicode_CheckExact(unicode) &&	unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) {        /* Keep-Alive optimization */	if (unicode->length >= KEEPALIVE_SIZE_LIMIT) {	    PyMem_DEL(unicode->str);	    unicode->str = NULL;	    unicode->length = 0;	}	if (unicode->defenc) {	    Py_DECREF(unicode->defenc);	    unicode->defenc = NULL;	}	/* Add to free list */        *(PyUnicodeObject **)unicode = unicode_freelist;        unicode_freelist = unicode;        unicode_freelist_size++;    }    else {	PyMem_DEL(unicode->str);	Py_XDECREF(unicode->defenc);	unicode->ob_type->tp_free((PyObject *)unicode);    }} int PyUnicode_Resize(PyObject **unicode, Py_ssize_t length){    register PyUnicodeObject *v;     /* Argument checks */    if (unicode == NULL) {	PyErr_BadInternalCall();	return -1;    }    v = (PyUnicodeObject *)*unicode;    if (v == NULL || !PyUnicode_Check(v) || v->ob_refcnt != 1 || length < 0) {	PyErr_BadInternalCall();	return -1;    }     /* Resizing unicode_empty and single character objects is not       possible since these are being shared. We simply return a fresh       copy with the same Unicode content. */    if (v->length != length &&	(v == unicode_empty || v->length == 1)) {	PyUnicodeObject *w = _PyUnicode_New(length);	if (w == NULL)	    return -1;	Py_UNICODE_COPY(w->str, v->str,			length < v->length ? length : v->length);	Py_DECREF(*unicode);	*unicode = (PyObject *)w;	return 0;    }     /* Note that we don't have to modify *unicode for unshared Unicode       objects, since we can modify them in-place. */    return unicode_resize(v, length);} /* Internal API for use in unicodeobject.c only ! */#define _PyUnicode_Resize(unicodevar, length) \        PyUnicode_Resize(((PyObject **)(unicodevar)), length) PyObject *PyUnicode_FromUnicode(const Py_UNICODE *u,				Py_ssize_t size){    PyUnicodeObject *unicode;     /* If the Unicode data is known at construction time, we can apply       some optimizations which share commonly used objects. */    if (u != NULL) { 	/* Optimization for empty strings */	if (size == 0 && unicode_empty != NULL) {	    Py_INCREF(unicode_empty);	    return (PyObject *)unicode_empty;	} 	/* Single character Unicode objects in the Latin-1 range are	   shared when using this constructor */	if (size == 1 && *u < 256) {	    unicode = unicode_latin1[*u];	    if (!unicode) {		unicode = _PyUnicode_New(1);		if (!unicode)		    return NULL;		unicode->str[0] = *u;		unicode_latin1[*u] = unicode;	    }	    Py_INCREF(unicode);	    return (PyObject *)unicode;	}    }     unicode = _PyUnicode_New(size);    if (!unicode)        return NULL;     /* Copy the Unicode data into the new object */    if (u != NULL)	Py_UNICODE_COPY(unicode->str, u, size);     return (PyObject *)unicode;} #ifdef HAVE_WCHAR_H PyObject *PyUnicode_FromWideChar(register const wchar_t *w,				 Py_ssize_t size){    PyUnicodeObject *unicode;     if (w == NULL) {	PyErr_BadInternalCall();	return NULL;    }     unicode = _PyUnicode_New(size);    if (!unicode)        return NULL;     /* Copy the wchar_t data into the new object */#ifdef HAVE_USABLE_WCHAR_T    memcpy(unicode->str, w, size * sizeof(wchar_t));#else    {	register Py_UNICODE *u;	register Py_ssize_t i;	u = PyUnicode_AS_UNICODE(unicode);	for (i = size; i > 0; i--)	    *u++ = *w++;    }#endif     return (PyObject *)unicode;} Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode,				wchar_t *w,				Py_ssize_t size){    if (unicode == NULL) {	PyErr_BadInternalCall();	return -1;    }     /* If possible, try to copy the 0-termination as well */    if (size > PyUnicode_GET_SIZE(unicode))	size = PyUnicode_GET_SIZE(unicode) + 1; #ifdef HAVE_USABLE_WCHAR_T    memcpy(w, unicode->str, size * sizeof(wchar_t));#else    {	register Py_UNICODE *u;	register Py_ssize_t i;	u = PyUnicode_AS_UNICODE(unicode);	for (i = size; i > 0; i--)	    *w++ = *u++;    }#endif     if (size > PyUnicode_GET_SIZE(unicode))        return PyUnicode_GET_SIZE(unicode);    else    return size;} #endif PyObject *PyUnicode_FromOrdinal(int ordinal){    Py_UNICODE s[1]; #ifdef Py_UNICODE_WIDE    if (ordinal < 0 || ordinal > 0x10ffff) {	PyErr_SetString(PyExc_ValueError,			"unichr() arg not in range(0x110000) "			"(wide Python build)");	return NULL;    }#else    if (ordinal < 0 || ordinal > 0xffff) {	PyErr_SetString(PyExc_ValueError,			"unichr() arg not in range(0x10000) "			"(narrow Python build)");	return NULL;    }#endif     s[0] = (Py_UNICODE)ordinal;    return PyUnicode_FromUnicode(s, 1);} PyObject *PyUnicode_FromObject(register PyObject *obj){    /* XXX Perhaps we should make this API an alias of           PyObject_Unicode() instead ?! */    if (PyUnicode_CheckExact(obj)) {	Py_INCREF(obj);	return obj;    }    if (PyUnicode_Check(obj)) {	/* For a Unicode subtype that's not a Unicode object,	   return a true Unicode object with the same data. */	return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),

Lines 1–500 of 8067.