Permalink
15597 lines (13878 sloc) 452 KB
/*
Unicode implementation based on original code by Fredrik Lundh,
modified by Marc-Andre Lemburg <mal@lemburg.com>.
Major speed upgrades to the method implementations at the Reykjavik
NeedForSpeed 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 its
associated 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 its
associated documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies, and that both that copyright notice and this permission notice
appear in supporting documentation, and that the name of Secret Labs
AB or the author not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------
*/
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "internal/pystate.h"
#include "ucnhash.h"
#include "bytes_methods.h"
#include "stringlib/eq.h"
#ifdef MS_WINDOWS
#include <windows.h>
#endif
/*[clinic input]
class str "PyObject *" "&PyUnicode_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4884c934de622cf6]*/
/*[python input]
class Py_UCS4_converter(CConverter):
type = 'Py_UCS4'
converter = 'convert_uc'
def converter_init(self):
if self.default is not unspecified:
self.c_default = ascii(self.default)
if len(self.c_default) > 4 or self.c_default[0] != "'":
self.c_default = hex(ord(self.default))
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=88f5dd06cd8e7a61]*/
/* --- Globals ------------------------------------------------------------
NOTE: In the interpreter's initialization phase, some globals are currently
initialized dynamically as needed. In the process Unicode objects may
be created before the Unicode type is ready.
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Maximum code point of Unicode 6.0: 0x10ffff (1,114,111) */
#define MAX_UNICODE 0x10ffff
#ifdef Py_DEBUG
# define _PyUnicode_CHECK(op) _PyUnicode_CheckConsistency(op, 0)
#else
# define _PyUnicode_CHECK(op) PyUnicode_Check(op)
#endif
#define _PyUnicode_UTF8(op) \
(((PyCompactUnicodeObject*)(op))->utf8)
#define PyUnicode_UTF8(op) \
(assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \
((char*)((PyASCIIObject*)(op) + 1)) : \
_PyUnicode_UTF8(op))
#define _PyUnicode_UTF8_LENGTH(op) \
(((PyCompactUnicodeObject*)(op))->utf8_length)
#define PyUnicode_UTF8_LENGTH(op) \
(assert(_PyUnicode_CHECK(op)), \
assert(PyUnicode_IS_READY(op)), \
PyUnicode_IS_COMPACT_ASCII(op) ? \
((PyASCIIObject*)(op))->length : \
_PyUnicode_UTF8_LENGTH(op))
#define _PyUnicode_WSTR(op) \
(((PyASCIIObject*)(op))->wstr)
#define _PyUnicode_WSTR_LENGTH(op) \
(((PyCompactUnicodeObject*)(op))->wstr_length)
#define _PyUnicode_LENGTH(op) \
(((PyASCIIObject *)(op))->length)
#define _PyUnicode_STATE(op) \
(((PyASCIIObject *)(op))->state)
#define _PyUnicode_HASH(op) \
(((PyASCIIObject *)(op))->hash)
#define _PyUnicode_KIND(op) \
(assert(_PyUnicode_CHECK(op)), \
((PyASCIIObject *)(op))->state.kind)
#define _PyUnicode_GET_LENGTH(op) \
(assert(_PyUnicode_CHECK(op)), \
((PyASCIIObject *)(op))->length)
#define _PyUnicode_DATA_ANY(op) \
(((PyUnicodeObject*)(op))->data.any)
#undef PyUnicode_READY
#define PyUnicode_READY(op) \
(assert(_PyUnicode_CHECK(op)), \
(PyUnicode_IS_READY(op) ? \
0 : \
_PyUnicode_Ready(op)))
#define _PyUnicode_SHARE_UTF8(op) \
(assert(_PyUnicode_CHECK(op)), \
assert(!PyUnicode_IS_COMPACT_ASCII(op)), \
(_PyUnicode_UTF8(op) == PyUnicode_DATA(op)))
#define _PyUnicode_SHARE_WSTR(op) \
(assert(_PyUnicode_CHECK(op)), \
(_PyUnicode_WSTR(unicode) == PyUnicode_DATA(op)))
/* true if the Unicode object has an allocated UTF-8 memory block
(not shared with other data) */
#define _PyUnicode_HAS_UTF8_MEMORY(op) \
((!PyUnicode_IS_COMPACT_ASCII(op) \
&& _PyUnicode_UTF8(op) \
&& _PyUnicode_UTF8(op) != PyUnicode_DATA(op)))
/* true if the Unicode object has an allocated wstr memory block
(not shared with other data) */
#define _PyUnicode_HAS_WSTR_MEMORY(op) \
((_PyUnicode_WSTR(op) && \
(!PyUnicode_IS_READY(op) || \
_PyUnicode_WSTR(op) != PyUnicode_DATA(op))))
/* Generic helper macro to convert characters of different types.
from_type and to_type have to be valid type names, begin and end
are pointers to the source characters which should be of type
"from_type *". to is a pointer of type "to_type *" and points to the
buffer where the result characters are written to. */
#define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \
do { \
to_type *_to = (to_type *)(to); \
const from_type *_iter = (from_type *)(begin); \
const from_type *_end = (from_type *)(end); \
Py_ssize_t n = (_end) - (_iter); \
const from_type *_unrolled_end = \
_iter + _Py_SIZE_ROUND_DOWN(n, 4); \
while (_iter < (_unrolled_end)) { \
_to[0] = (to_type) _iter[0]; \
_to[1] = (to_type) _iter[1]; \
_to[2] = (to_type) _iter[2]; \
_to[3] = (to_type) _iter[3]; \
_iter += 4; _to += 4; \
} \
while (_iter < (_end)) \
*_to++ = (to_type) *_iter++; \
} while (0)
#ifdef MS_WINDOWS
/* On Windows, overallocate by 50% is the best factor */
# define OVERALLOCATE_FACTOR 2
#else
/* On Linux, overallocate by 25% is the best factor */
# define OVERALLOCATE_FACTOR 4
#endif
/* This dictionary holds all interned unicode strings. Note that references
to strings in this dictionary are *not* counted in the string's ob_refcnt.
When the interned string reaches a refcnt of 0 the string deallocation
function will delete the reference from this dictionary.
Another way to look at this is that to say that the actual reference
count of a string is: s->ob_refcnt + (s->state ? 2 : 0)
*/
static PyObject *interned = NULL;
/* The empty Unicode object is shared to improve performance. */
static PyObject *unicode_empty = NULL;
#define _Py_INCREF_UNICODE_EMPTY() \
do { \
if (unicode_empty != NULL) \
Py_INCREF(unicode_empty); \
else { \
unicode_empty = PyUnicode_New(0, 0); \
if (unicode_empty != NULL) { \
Py_INCREF(unicode_empty); \
assert(_PyUnicode_CheckConsistency(unicode_empty, 1)); \
} \
} \
} while (0)
#define _Py_RETURN_UNICODE_EMPTY() \
do { \
_Py_INCREF_UNICODE_EMPTY(); \
return unicode_empty; \
} while (0)
/* Forward declaration */
static inline int
_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch);
/* List of static strings. */
static _Py_Identifier *static_strings = NULL;
/* Single character Unicode strings in the Latin-1 range are being
shared as well. */
static PyObject *unicode_latin1[256] = {NULL};
/* Fast detection of the most frequent whitespace characters */
const unsigned char _Py_ascii_whitespace[] = {
0, 0, 0, 0, 0, 0, 0, 0,
/* case 0x0009: * CHARACTER TABULATION */
/* case 0x000A: * LINE FEED */
/* case 0x000B: * LINE TABULATION */
/* case 0x000C: * FORM FEED */
/* case 0x000D: * CARRIAGE RETURN */
0, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
/* case 0x001C: * FILE SEPARATOR */
/* case 0x001D: * GROUP SEPARATOR */
/* case 0x001E: * RECORD SEPARATOR */
/* case 0x001F: * UNIT SEPARATOR */
0, 0, 0, 0, 1, 1, 1, 1,
/* case 0x0020: * SPACE */
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
/* forward */
static PyUnicodeObject *_PyUnicode_New(Py_ssize_t length);
static PyObject* get_latin1_char(unsigned char ch);
static int unicode_modifiable(PyObject *unicode);
static PyObject *
_PyUnicode_FromUCS1(const Py_UCS1 *s, Py_ssize_t size);
static PyObject *
_PyUnicode_FromUCS2(const Py_UCS2 *s, Py_ssize_t size);
static PyObject *
_PyUnicode_FromUCS4(const Py_UCS4 *s, Py_ssize_t size);
static PyObject *
unicode_encode_call_errorhandler(const char *errors,
PyObject **errorHandler,const char *encoding, const char *reason,
PyObject *unicode, PyObject **exceptionObject,
Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos);
static void
raise_encode_exception(PyObject **exceptionObject,
const char *encoding,
PyObject *unicode,
Py_ssize_t startpos, Py_ssize_t endpos,
const char *reason);
/* Same for linebreaks */
static const unsigned char ascii_linebreak[] = {
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x000A, * LINE FEED */
/* 0x000B, * LINE TABULATION */
/* 0x000C, * FORM FEED */
/* 0x000D, * CARRIAGE RETURN */
0, 0, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
/* 0x001C, * FILE SEPARATOR */
/* 0x001D, * GROUP SEPARATOR */
/* 0x001E, * RECORD SEPARATOR */
0, 0, 0, 0, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static int convert_uc(PyObject *obj, void *addr);
#include "clinic/unicodeobject.c.h"
typedef enum {
_Py_ERROR_UNKNOWN=0,
_Py_ERROR_STRICT,
_Py_ERROR_SURROGATEESCAPE,
_Py_ERROR_REPLACE,
_Py_ERROR_IGNORE,
_Py_ERROR_BACKSLASHREPLACE,
_Py_ERROR_SURROGATEPASS,
_Py_ERROR_XMLCHARREFREPLACE,
_Py_ERROR_OTHER
} _Py_error_handler;
static _Py_error_handler
get_error_handler(const char *errors)
{
if (errors == NULL || strcmp(errors, "strict") == 0) {
return _Py_ERROR_STRICT;
}
if (strcmp(errors, "surrogateescape") == 0) {
return _Py_ERROR_SURROGATEESCAPE;
}
if (strcmp(errors, "replace") == 0) {
return _Py_ERROR_REPLACE;
}
if (strcmp(errors, "ignore") == 0) {
return _Py_ERROR_IGNORE;
}
if (strcmp(errors, "backslashreplace") == 0) {
return _Py_ERROR_BACKSLASHREPLACE;
}
if (strcmp(errors, "surrogatepass") == 0) {
return _Py_ERROR_SURROGATEPASS;
}
if (strcmp(errors, "xmlcharrefreplace") == 0) {
return _Py_ERROR_XMLCHARREFREPLACE;
}
return _Py_ERROR_OTHER;
}
/* The max unicode value is always 0x10FFFF while using the PEP-393 API.
This function is kept for backward compatibility with the old API. */
Py_UNICODE
PyUnicode_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
}
#ifdef Py_DEBUG
int
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
{
PyASCIIObject *ascii;
unsigned int kind;
assert(PyUnicode_Check(op));
ascii = (PyASCIIObject *)op;
kind = ascii->state.kind;
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
assert(kind == PyUnicode_1BYTE_KIND);
assert(ascii->state.ready == 1);
}
else {
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
void *data;
if (ascii->state.compact == 1) {
data = compact + 1;
assert(kind == PyUnicode_1BYTE_KIND
|| kind == PyUnicode_2BYTE_KIND
|| kind == PyUnicode_4BYTE_KIND);
assert(ascii->state.ascii == 0);
assert(ascii->state.ready == 1);
assert (compact->utf8 != data);
}
else {
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
data = unicode->data.any;
if (kind == PyUnicode_WCHAR_KIND) {
assert(ascii->length == 0);
assert(ascii->hash == -1);
assert(ascii->state.compact == 0);
assert(ascii->state.ascii == 0);
assert(ascii->state.ready == 0);
assert(ascii->state.interned == SSTATE_NOT_INTERNED);
assert(ascii->wstr != NULL);
assert(data == NULL);
assert(compact->utf8 == NULL);
}
else {
assert(kind == PyUnicode_1BYTE_KIND
|| kind == PyUnicode_2BYTE_KIND
|| kind == PyUnicode_4BYTE_KIND);
assert(ascii->state.compact == 0);
assert(ascii->state.ready == 1);
assert(data != NULL);
if (ascii->state.ascii) {
assert (compact->utf8 == data);
assert (compact->utf8_length == ascii->length);
}
else
assert (compact->utf8 != data);
}
}
if (kind != PyUnicode_WCHAR_KIND) {
if (
#if SIZEOF_WCHAR_T == 2
kind == PyUnicode_2BYTE_KIND
#else
kind == PyUnicode_4BYTE_KIND
#endif
)
{
assert(ascii->wstr == data);
assert(compact->wstr_length == ascii->length);
} else
assert(ascii->wstr != data);
}
if (compact->utf8 == NULL)
assert(compact->utf8_length == 0);
if (ascii->wstr == NULL)
assert(compact->wstr_length == 0);
}
/* check that the best kind is used */
if (check_content && kind != PyUnicode_WCHAR_KIND)
{
Py_ssize_t i;
Py_UCS4 maxchar = 0;
void *data;
Py_UCS4 ch;
data = PyUnicode_DATA(ascii);
for (i=0; i < ascii->length; i++)
{
ch = PyUnicode_READ(kind, data, i);
if (ch > maxchar)
maxchar = ch;
}
if (kind == PyUnicode_1BYTE_KIND) {
if (ascii->state.ascii == 0) {
assert(maxchar >= 128);
assert(maxchar <= 255);
}
else
assert(maxchar < 128);
}
else if (kind == PyUnicode_2BYTE_KIND) {
assert(maxchar >= 0x100);
assert(maxchar <= 0xFFFF);
}
else {
assert(maxchar >= 0x10000);
assert(maxchar <= MAX_UNICODE);
}
assert(PyUnicode_READ(kind, data, ascii->length) == 0);
}
return 1;
}
#endif
static PyObject*
unicode_result_wchar(PyObject *unicode)
{
#ifndef Py_DEBUG
Py_ssize_t len;
len = _PyUnicode_WSTR_LENGTH(unicode);
if (len == 0) {
Py_DECREF(unicode);
_Py_RETURN_UNICODE_EMPTY();
}
if (len == 1) {
wchar_t ch = _PyUnicode_WSTR(unicode)[0];
if ((Py_UCS4)ch < 256) {
PyObject *latin1_char = get_latin1_char((unsigned char)ch);
Py_DECREF(unicode);
return latin1_char;
}
}
if (_PyUnicode_Ready(unicode) < 0) {
Py_DECREF(unicode);
return NULL;
}
#else
assert(Py_REFCNT(unicode) == 1);
/* don't make the result ready in debug mode to ensure that the caller
makes the string ready before using it */
assert(_PyUnicode_CheckConsistency(unicode, 1));
#endif
return unicode;
}
static PyObject*
unicode_result_ready(PyObject *unicode)
{
Py_ssize_t length;
length = PyUnicode_GET_LENGTH(unicode);
if (length == 0) {
if (unicode != unicode_empty) {
Py_DECREF(unicode);
_Py_RETURN_UNICODE_EMPTY();
}
return unicode_empty;
}
if (length == 1) {
void *data = PyUnicode_DATA(unicode);
int kind = PyUnicode_KIND(unicode);
Py_UCS4 ch = PyUnicode_READ(kind, data, 0);
if (ch < 256) {
PyObject *latin1_char = unicode_latin1[ch];
if (latin1_char != NULL) {
if (unicode != latin1_char) {
Py_INCREF(latin1_char);
Py_DECREF(unicode);
}
return latin1_char;
}
else {
assert(_PyUnicode_CheckConsistency(unicode, 1));
Py_INCREF(unicode);
unicode_latin1[ch] = unicode;
return unicode;
}
}
}
assert(_PyUnicode_CheckConsistency(unicode, 1));
return unicode;
}
static PyObject*
unicode_result(PyObject *unicode)
{
assert(_PyUnicode_CHECK(unicode));
if (PyUnicode_IS_READY(unicode))
return unicode_result_ready(unicode);
else
return unicode_result_wchar(unicode);
}
static PyObject*
unicode_result_unchanged(PyObject *unicode)
{
if (PyUnicode_CheckExact(unicode)) {
if (PyUnicode_READY(unicode) == -1)
return NULL;
Py_INCREF(unicode);
return unicode;
}
else
/* Subtype -- return genuine unicode string with the same value. */
return _PyUnicode_Copy(unicode);
}
/* Implementation of the "backslashreplace" error handler for 8-bit encodings:
ASCII, Latin1, UTF-8, etc. */
static char*
backslashreplace(_PyBytesWriter *writer, char *str,
PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend)
{
Py_ssize_t size, i;
Py_UCS4 ch;
enum PyUnicode_Kind kind;
void *data;
assert(PyUnicode_IS_READY(unicode));
kind = PyUnicode_KIND(unicode);
data = PyUnicode_DATA(unicode);
size = 0;
/* determine replacement size */
for (i = collstart; i < collend; ++i) {
Py_ssize_t incr;
ch = PyUnicode_READ(kind, data, i);
if (ch < 0x100)
incr = 2+2;
else if (ch < 0x10000)
incr = 2+4;
else {
assert(ch <= MAX_UNICODE);
incr = 2+8;
}
if (size > PY_SSIZE_T_MAX - incr) {
PyErr_SetString(PyExc_OverflowError,
"encoded result is too long for a Python string");
return NULL;
}
size += incr;
}
str = _PyBytesWriter_Prepare(writer, str, size);
if (str == NULL)
return NULL;
/* generate replacement */
for (i = collstart; i < collend; ++i) {
ch = PyUnicode_READ(kind, data, i);
*str++ = '\\';
if (ch >= 0x00010000) {
*str++ = 'U';
*str++ = Py_hexdigits[(ch>>28)&0xf];
*str++ = Py_hexdigits[(ch>>24)&0xf];
*str++ = Py_hexdigits[(ch>>20)&0xf];
*str++ = Py_hexdigits[(ch>>16)&0xf];
*str++ = Py_hexdigits[(ch>>12)&0xf];
*str++ = Py_hexdigits[(ch>>8)&0xf];
}
else if (ch >= 0x100) {
*str++ = 'u';
*str++ = Py_hexdigits[(ch>>12)&0xf];
*str++ = Py_hexdigits[(ch>>8)&0xf];
}
else
*str++ = 'x';
*str++ = Py_hexdigits[(ch>>4)&0xf];
*str++ = Py_hexdigits[ch&0xf];
}
return str;
}
/* Implementation of the "xmlcharrefreplace" error handler for 8-bit encodings:
ASCII, Latin1, UTF-8, etc. */
static char*
xmlcharrefreplace(_PyBytesWriter *writer, char *str,
PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend)
{
Py_ssize_t size, i;
Py_UCS4 ch;
enum PyUnicode_Kind kind;
void *data;
assert(PyUnicode_IS_READY(unicode));
kind = PyUnicode_KIND(unicode);
data = PyUnicode_DATA(unicode);
size = 0;
/* determine replacement size */
for (i = collstart; i < collend; ++i) {
Py_ssize_t incr;
ch = PyUnicode_READ(kind, data, i);
if (ch < 10)
incr = 2+1+1;
else if (ch < 100)
incr = 2+2+1;
else if (ch < 1000)
incr = 2+3+1;
else if (ch < 10000)
incr = 2+4+1;
else if (ch < 100000)
incr = 2+5+1;
else if (ch < 1000000)
incr = 2+6+1;
else {
assert(ch <= MAX_UNICODE);
incr = 2+7+1;
}
if (size > PY_SSIZE_T_MAX - incr) {
PyErr_SetString(PyExc_OverflowError,
"encoded result is too long for a Python string");
return NULL;
}
size += incr;
}
str = _PyBytesWriter_Prepare(writer, str, size);
if (str == NULL)
return NULL;
/* generate replacement */
for (i = collstart; i < collend; ++i) {
str += sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i));
}
return str;
}
/* --- 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 */
#if LONG_BIT >= 128
#define BLOOM_WIDTH 128
#elif LONG_BIT >= 64
#define BLOOM_WIDTH 64
#elif LONG_BIT >= 32
#define BLOOM_WIDTH 32
#else
#error "LONG_BIT is smaller than 32"
#endif
#define BLOOM_MASK unsigned long
static BLOOM_MASK bloom_linebreak = ~(BLOOM_MASK)0;
#define BLOOM(mask, ch) ((mask & (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
#define BLOOM_LINEBREAK(ch) \
((ch) < 128U ? ascii_linebreak[(ch)] : \
(BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch)))
static inline BLOOM_MASK
make_bloom_mask(int kind, void* ptr, Py_ssize_t len)
{
#define BLOOM_UPDATE(TYPE, MASK, PTR, LEN) \
do { \
TYPE *data = (TYPE *)PTR; \
TYPE *end = data + LEN; \
Py_UCS4 ch; \
for (; data != end; data++) { \
ch = *data; \
MASK |= (1UL << (ch & (BLOOM_WIDTH - 1))); \
} \
break; \
} while (0)
/* calculate simple bloom-style bitmask for a given unicode string */
BLOOM_MASK mask;
mask = 0;
switch (kind) {
case PyUnicode_1BYTE_KIND:
BLOOM_UPDATE(Py_UCS1, mask, ptr, len);
break;
case PyUnicode_2BYTE_KIND:
BLOOM_UPDATE(Py_UCS2, mask, ptr, len);
break;
case PyUnicode_4BYTE_KIND:
BLOOM_UPDATE(Py_UCS4, mask, ptr, len);
break;
default:
Py_UNREACHABLE();
}
return mask;
#undef BLOOM_UPDATE
}
static int
ensure_unicode(PyObject *obj)
{
if (!PyUnicode_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"must be str, not %.100s",
Py_TYPE(obj)->tp_name);
return -1;
}
return PyUnicode_READY(obj);
}
/* Compilation of templated routines */
#include "stringlib/asciilib.h"
#include "stringlib/fastsearch.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/find_max_char.h"
#include "stringlib/localeutil.h"
#include "stringlib/undef.h"
#include "stringlib/ucs1lib.h"
#include "stringlib/fastsearch.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/replace.h"
#include "stringlib/find_max_char.h"
#include "stringlib/localeutil.h"
#include "stringlib/undef.h"
#include "stringlib/ucs2lib.h"
#include "stringlib/fastsearch.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/replace.h"
#include "stringlib/find_max_char.h"
#include "stringlib/localeutil.h"
#include "stringlib/undef.h"
#include "stringlib/ucs4lib.h"
#include "stringlib/fastsearch.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/replace.h"
#include "stringlib/find_max_char.h"
#include "stringlib/localeutil.h"
#include "stringlib/undef.h"
#include "stringlib/unicodedefs.h"
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/undef.h"
/* --- Unicode Object ----------------------------------------------------- */
static inline Py_ssize_t
findchar(const void *s, int kind,
Py_ssize_t size, Py_UCS4 ch,
int direction)
{
switch (kind) {
case PyUnicode_1BYTE_KIND:
if ((Py_UCS1) ch != ch)
return -1;
if (direction > 0)
return ucs1lib_find_char((Py_UCS1 *) s, size, (Py_UCS1) ch);
else
return ucs1lib_rfind_char((Py_UCS1 *) s, size, (Py_UCS1) ch);
case PyUnicode_2BYTE_KIND:
if ((Py_UCS2) ch != ch)
return -1;
if (direction > 0)
return ucs2lib_find_char((Py_UCS2 *) s, size, (Py_UCS2) ch);
else
return ucs2lib_rfind_char((Py_UCS2 *) s, size, (Py_UCS2) ch);
case PyUnicode_4BYTE_KIND:
if (direction > 0)
return ucs4lib_find_char((Py_UCS4 *) s, size, ch);
else
return ucs4lib_rfind_char((Py_UCS4 *) s, size, ch);
default:
Py_UNREACHABLE();
}
}
#ifdef Py_DEBUG
/* Fill the data of a Unicode string with invalid characters to detect bugs
earlier.
_PyUnicode_CheckConsistency(str, 1) detects invalid characters, at least for
ASCII and UCS-4 strings. U+00FF is invalid in ASCII and U+FFFFFFFF is an
invalid character in Unicode 6.0. */
static void
unicode_fill_invalid(PyObject *unicode, Py_ssize_t old_length)
{
int kind = PyUnicode_KIND(unicode);
Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode);
Py_ssize_t length = _PyUnicode_LENGTH(unicode);
if (length <= old_length)
return;
memset(data + old_length * kind, 0xff, (length - old_length) * kind);
}
#endif
static PyObject*
resize_compact(PyObject *unicode, Py_ssize_t length)
{
Py_ssize_t char_size;
Py_ssize_t struct_size;
Py_ssize_t new_size;
int share_wstr;
PyObject *new_unicode;
#ifdef Py_DEBUG
Py_ssize_t old_length = _PyUnicode_LENGTH(unicode);
#endif
assert(unicode_modifiable(unicode));
assert(PyUnicode_IS_READY(unicode));
assert(PyUnicode_IS_COMPACT(unicode));
char_size = PyUnicode_KIND(unicode);
if (PyUnicode_IS_ASCII(unicode))
struct_size = sizeof(PyASCIIObject);
else
struct_size = sizeof(PyCompactUnicodeObject);
share_wstr = _PyUnicode_SHARE_WSTR(unicode);
if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) {
PyErr_NoMemory();
return NULL;
}
new_size = (struct_size + (length + 1) * char_size);
if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) {
PyObject_DEL(_PyUnicode_UTF8(unicode));
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
}
_Py_DEC_REFTOTAL;
_Py_ForgetReference(unicode);
new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size);
if (new_unicode == NULL) {
_Py_NewReference(unicode);
PyErr_NoMemory();
return NULL;
}
unicode = new_unicode;
_Py_NewReference(unicode);
_PyUnicode_LENGTH(unicode) = length;
if (share_wstr) {
_PyUnicode_WSTR(unicode) = PyUnicode_DATA(unicode);
if (!PyUnicode_IS_ASCII(unicode))
_PyUnicode_WSTR_LENGTH(unicode) = length;
}
else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) {
PyObject_DEL(_PyUnicode_WSTR(unicode));
_PyUnicode_WSTR(unicode) = NULL;
if (!PyUnicode_IS_ASCII(unicode))
_PyUnicode_WSTR_LENGTH(unicode) = 0;
}
#ifdef Py_DEBUG
unicode_fill_invalid(unicode, old_length);
#endif
PyUnicode_WRITE(PyUnicode_KIND(unicode), PyUnicode_DATA(unicode),
length, 0);
assert(_PyUnicode_CheckConsistency(unicode, 0));
return unicode;
}
static int
resize_inplace(PyObject *unicode, Py_ssize_t length)
{
wchar_t *wstr;
Py_ssize_t new_size;
assert(!PyUnicode_IS_COMPACT(unicode));
assert(Py_REFCNT(unicode) == 1);
if (PyUnicode_IS_READY(unicode)) {
Py_ssize_t char_size;
int share_wstr, share_utf8;
void *data;
#ifdef Py_DEBUG
Py_ssize_t old_length = _PyUnicode_LENGTH(unicode);
#endif
data = _PyUnicode_DATA_ANY(unicode);
char_size = PyUnicode_KIND(unicode);
share_wstr = _PyUnicode_SHARE_WSTR(unicode);
share_utf8 = _PyUnicode_SHARE_UTF8(unicode);
if (length > (PY_SSIZE_T_MAX / char_size - 1)) {
PyErr_NoMemory();
return -1;
}
new_size = (length + 1) * char_size;
if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode))
{
PyObject_DEL(_PyUnicode_UTF8(unicode));
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
}
data = (PyObject *)PyObject_REALLOC(data, new_size);
if (data == NULL) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_DATA_ANY(unicode) = data;
if (share_wstr) {
_PyUnicode_WSTR(unicode) = data;
_PyUnicode_WSTR_LENGTH(unicode) = length;
}
if (share_utf8) {
_PyUnicode_UTF8(unicode) = data;
_PyUnicode_UTF8_LENGTH(unicode) = length;
}
_PyUnicode_LENGTH(unicode) = length;
PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0);
#ifdef Py_DEBUG
unicode_fill_invalid(unicode, old_length);
#endif
if (share_wstr || _PyUnicode_WSTR(unicode) == NULL) {
assert(_PyUnicode_CheckConsistency(unicode, 0));
return 0;
}
}
assert(_PyUnicode_WSTR(unicode) != NULL);
/* check for integer overflow */
if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) {
PyErr_NoMemory();
return -1;
}
new_size = sizeof(wchar_t) * (length + 1);
wstr = _PyUnicode_WSTR(unicode);
wstr = PyObject_REALLOC(wstr, new_size);
if (!wstr) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_WSTR(unicode) = wstr;
_PyUnicode_WSTR(unicode)[length] = 0;
_PyUnicode_WSTR_LENGTH(unicode) = length;
assert(_PyUnicode_CheckConsistency(unicode, 0));
return 0;
}
static PyObject*
resize_copy(PyObject *unicode, Py_ssize_t length)
{
Py_ssize_t copy_length;
if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) {
PyObject *copy;
assert(PyUnicode_IS_READY(unicode));
copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode));
if (copy == NULL)
return NULL;
copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode));
_PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length);
return copy;
}
else {
PyObject *w;
w = (PyObject*)_PyUnicode_New(length);
if (w == NULL)
return NULL;
copy_length = _PyUnicode_WSTR_LENGTH(unicode);
copy_length = Py_MIN(copy_length, length);
memcpy(_PyUnicode_WSTR(w), _PyUnicode_WSTR(unicode),
copy_length * sizeof(wchar_t));
return w;
}
}
/* We allocate one more byte to make sure the string is
Ux0000 terminated; some code (e.g. new_identifier)
relies on that.
XXX This allocator could further be enhanced by assuring that the
free list never reduces its size below 1.
*/
static PyUnicodeObject *
_PyUnicode_New(Py_ssize_t length)
{
PyUnicodeObject *unicode;
size_t new_size;
/* Optimization for empty strings */
if (length == 0 && unicode_empty != NULL) {
Py_INCREF(unicode_empty);
return (PyUnicodeObject*)unicode_empty;
}
/* Ensure we won't overflow the size. */
if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) {
return (PyUnicodeObject *)PyErr_NoMemory();
}
if (length < 0) {
PyErr_SetString(PyExc_SystemError,
"Negative size passed to _PyUnicode_New");
return NULL;
}
unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type);
if (unicode == NULL)
return NULL;
new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
_PyUnicode_WSTR_LENGTH(unicode) = length;
_PyUnicode_HASH(unicode) = -1;
_PyUnicode_STATE(unicode).interned = 0;
_PyUnicode_STATE(unicode).kind = 0;
_PyUnicode_STATE(unicode).compact = 0;
_PyUnicode_STATE(unicode).ready = 0;
_PyUnicode_STATE(unicode).ascii = 0;
_PyUnicode_DATA_ANY(unicode) = NULL;
_PyUnicode_LENGTH(unicode) = 0;
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
_PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_MALLOC(new_size);
if (!_PyUnicode_WSTR(unicode)) {
Py_DECREF(unicode);
PyErr_NoMemory();
return NULL;
}
/* 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.
*/
_PyUnicode_WSTR(unicode)[0] = 0;
_PyUnicode_WSTR(unicode)[length] = 0;
assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0));
return unicode;
}
static const char*
unicode_kind_name(PyObject *unicode)
{
/* don't check consistency: unicode_kind_name() is called from
_PyUnicode_Dump() */
if (!PyUnicode_IS_COMPACT(unicode))
{
if (!PyUnicode_IS_READY(unicode))
return "wstr";
switch (PyUnicode_KIND(unicode))
{
case PyUnicode_1BYTE_KIND:
if (PyUnicode_IS_ASCII(unicode))
return "legacy ascii";
else
return "legacy latin1";
case PyUnicode_2BYTE_KIND:
return "legacy UCS2";
case PyUnicode_4BYTE_KIND:
return "legacy UCS4";
default:
return "<legacy invalid kind>";
}
}
assert(PyUnicode_IS_READY(unicode));
switch (PyUnicode_KIND(unicode)) {
case PyUnicode_1BYTE_KIND:
if (PyUnicode_IS_ASCII(unicode))
return "ascii";
else
return "latin1";
case PyUnicode_2BYTE_KIND:
return "UCS2";
case PyUnicode_4BYTE_KIND:
return "UCS4";
default:
return "<invalid compact kind>";
}
}
#ifdef Py_DEBUG
/* Functions wrapping macros for use in debugger */
char *_PyUnicode_utf8(void *unicode){
return PyUnicode_UTF8(unicode);
}
void *_PyUnicode_compact_data(void *unicode) {
return _PyUnicode_COMPACT_DATA(unicode);
}
void *_PyUnicode_data(void *unicode){
printf("obj %p\n", unicode);
printf("compact %d\n", PyUnicode_IS_COMPACT(unicode));
printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode));
printf("ascii op %p\n", ((void*)((PyASCIIObject*)(unicode) + 1)));
printf("compact op %p\n", ((void*)((PyCompactUnicodeObject*)(unicode) + 1)));
printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode));
return PyUnicode_DATA(unicode);
}
void
_PyUnicode_Dump(PyObject *op)
{
PyASCIIObject *ascii = (PyASCIIObject *)op;
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
void *data;
if (ascii->state.compact)
{
if (ascii->state.ascii)
data = (ascii + 1);
else
data = (compact + 1);
}
else
data = unicode->data.any;
printf("%s: len=%" PY_FORMAT_SIZE_T "u, ",
unicode_kind_name(op), ascii->length);
if (ascii->wstr == data)
printf("shared ");
printf("wstr=%p", ascii->wstr);
if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) {
printf(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length);
if (!ascii->state.compact && compact->utf8 == unicode->data.any)
printf("shared ");
printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)",
compact->utf8, compact->utf8_length);
}
printf(", data=%p\n", data);
}
#endif
PyObject *
PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
{
PyObject *obj;
PyCompactUnicodeObject *unicode;
void *data;
enum PyUnicode_Kind kind;
int is_sharing, is_ascii;
Py_ssize_t char_size;
Py_ssize_t struct_size;
/* Optimization for empty strings */
if (size == 0 && unicode_empty != NULL) {
Py_INCREF(unicode_empty);
return unicode_empty;
}
is_ascii = 0;
is_sharing = 0;
struct_size = sizeof(PyCompactUnicodeObject);
if (maxchar < 128) {
kind = PyUnicode_1BYTE_KIND;
char_size = 1;
is_ascii = 1;
struct_size = sizeof(PyASCIIObject);
}
else if (maxchar < 256) {
kind = PyUnicode_1BYTE_KIND;
char_size = 1;
}
else if (maxchar < 65536) {
kind = PyUnicode_2BYTE_KIND;
char_size = 2;
if (sizeof(wchar_t) == 2)
is_sharing = 1;
}
else {
if (maxchar > MAX_UNICODE) {
PyErr_SetString(PyExc_SystemError,
"invalid maximum character passed to PyUnicode_New");
return NULL;
}
kind = PyUnicode_4BYTE_KIND;
char_size = 4;
if (sizeof(wchar_t) == 4)
is_sharing = 1;
}
/* Ensure we won't overflow the size. */
if (size < 0) {
PyErr_SetString(PyExc_SystemError,
"Negative size passed to PyUnicode_New");
return NULL;
}
if (size > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1))
return PyErr_NoMemory();
/* Duplicated allocation code from _PyObject_New() instead of a call to
* PyObject_New() so we are able to allocate space for the object and
* it's data buffer.
*/
obj = (PyObject *) PyObject_MALLOC(struct_size + (size + 1) * char_size);
if (obj == NULL)
return PyErr_NoMemory();
obj = PyObject_INIT(obj, &PyUnicode_Type);
if (obj == NULL)
return NULL;
unicode = (PyCompactUnicodeObject *)obj;
if (is_ascii)
data = ((PyASCIIObject*)obj) + 1;
else
data = unicode + 1;
_PyUnicode_LENGTH(unicode) = size;
_PyUnicode_HASH(unicode) = -1;
_PyUnicode_STATE(unicode).interned = 0;
_PyUnicode_STATE(unicode).kind = kind;
_PyUnicode_STATE(unicode).compact = 1;
_PyUnicode_STATE(unicode).ready = 1;
_PyUnicode_STATE(unicode).ascii = is_ascii;
if (is_ascii) {
((char*)data)[size] = 0;
_PyUnicode_WSTR(unicode) = NULL;
}
else if (kind == PyUnicode_1BYTE_KIND) {
((char*)data)[size] = 0;
_PyUnicode_WSTR(unicode) = NULL;
_PyUnicode_WSTR_LENGTH(unicode) = 0;
unicode->utf8 = NULL;
unicode->utf8_length = 0;
}
else {
unicode->utf8 = NULL;
unicode->utf8_length = 0;
if (kind == PyUnicode_2BYTE_KIND)
((Py_UCS2*)data)[size] = 0;
else /* kind == PyUnicode_4BYTE_KIND */
((Py_UCS4*)data)[size] = 0;
if (is_sharing) {
_PyUnicode_WSTR_LENGTH(unicode) = size;
_PyUnicode_WSTR(unicode) = (wchar_t *)data;
}
else {
_PyUnicode_WSTR_LENGTH(unicode) = 0;
_PyUnicode_WSTR(unicode) = NULL;
}
}
#ifdef Py_DEBUG
unicode_fill_invalid((PyObject*)unicode, 0);
#endif
assert(_PyUnicode_CheckConsistency((PyObject*)unicode, 0));
return obj;
}
#if SIZEOF_WCHAR_T == 2
/* Helper function to convert a 16-bits wchar_t representation to UCS4, this
will decode surrogate pairs, the other conversions are implemented as macros
for efficiency.
This function assumes that unicode can hold one more code point than wstr
characters for a terminating null character. */
static void
unicode_convert_wchar_to_ucs4(const wchar_t *begin, const wchar_t *end,
PyObject *unicode)
{
const wchar_t *iter;
Py_UCS4 *ucs4_out;
assert(unicode != NULL);
assert(_PyUnicode_CHECK(unicode));
assert(_PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
ucs4_out = PyUnicode_4BYTE_DATA(unicode);
for (iter = begin; iter < end; ) {
assert(ucs4_out < (PyUnicode_4BYTE_DATA(unicode) +
_PyUnicode_GET_LENGTH(unicode)));
if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0])
&& (iter+1) < end
&& Py_UNICODE_IS_LOW_SURROGATE(iter[1]))
{
*ucs4_out++ = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]);
iter += 2;
}
else {
*ucs4_out++ = *iter;
iter++;
}
}
assert(ucs4_out == (PyUnicode_4BYTE_DATA(unicode) +
_PyUnicode_GET_LENGTH(unicode)));
}
#endif
static int
unicode_check_modifiable(PyObject *unicode)
{
if (!unicode_modifiable(unicode)) {
PyErr_SetString(PyExc_SystemError,
"Cannot modify a string currently used");
return -1;
}
return 0;
}
static int
_copy_characters(PyObject *to, Py_ssize_t to_start,
PyObject *from, Py_ssize_t from_start,
Py_ssize_t how_many, int check_maxchar)
{
unsigned int from_kind, to_kind;
void *from_data, *to_data;
assert(0 <= how_many);
assert(0 <= from_start);
assert(0 <= to_start);
assert(PyUnicode_Check(from));
assert(PyUnicode_IS_READY(from));
assert(from_start + how_many <= PyUnicode_GET_LENGTH(from));
assert(PyUnicode_Check(to));
assert(PyUnicode_IS_READY(to));
assert(to_start + how_many <= PyUnicode_GET_LENGTH(to));
if (how_many == 0)
return 0;
from_kind = PyUnicode_KIND(from);
from_data = PyUnicode_DATA(from);
to_kind = PyUnicode_KIND(to);
to_data = PyUnicode_DATA(to);
#ifdef Py_DEBUG
if (!check_maxchar
&& PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to))
{
const Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to);
Py_UCS4 ch;
Py_ssize_t i;
for (i=0; i < how_many; i++) {
ch = PyUnicode_READ(from_kind, from_data, from_start + i);
assert(ch <= to_maxchar);
}
}
#endif
if (from_kind == to_kind) {
if (check_maxchar
&& !PyUnicode_IS_ASCII(from) && PyUnicode_IS_ASCII(to))
{
/* Writing Latin-1 characters into an ASCII string requires to
check that all written characters are pure ASCII */
Py_UCS4 max_char;
max_char = ucs1lib_find_max_char(from_data,
(Py_UCS1*)from_data + how_many);
if (max_char >= 128)
return -1;
}
memcpy((char*)to_data + to_kind * to_start,
(char*)from_data + from_kind * from_start,
to_kind * how_many);
}
else if (from_kind == PyUnicode_1BYTE_KIND
&& to_kind == PyUnicode_2BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS1, Py_UCS2,
PyUnicode_1BYTE_DATA(from) + from_start,
PyUnicode_1BYTE_DATA(from) + from_start + how_many,
PyUnicode_2BYTE_DATA(to) + to_start
);
}
else if (from_kind == PyUnicode_1BYTE_KIND
&& to_kind == PyUnicode_4BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS1, Py_UCS4,
PyUnicode_1BYTE_DATA(from) + from_start,
PyUnicode_1BYTE_DATA(from) + from_start + how_many,
PyUnicode_4BYTE_DATA(to) + to_start
);
}
else if (from_kind == PyUnicode_2BYTE_KIND
&& to_kind == PyUnicode_4BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS2, Py_UCS4,
PyUnicode_2BYTE_DATA(from) + from_start,
PyUnicode_2BYTE_DATA(from) + from_start + how_many,
PyUnicode_4BYTE_DATA(to) + to_start
);
}
else {
assert (PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to));
if (!check_maxchar) {
if (from_kind == PyUnicode_2BYTE_KIND
&& to_kind == PyUnicode_1BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS2, Py_UCS1,
PyUnicode_2BYTE_DATA(from) + from_start,
PyUnicode_2BYTE_DATA(from) + from_start + how_many,
PyUnicode_1BYTE_DATA(to) + to_start
);
}
else if (from_kind == PyUnicode_4BYTE_KIND
&& to_kind == PyUnicode_1BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS4, Py_UCS1,
PyUnicode_4BYTE_DATA(from) + from_start,
PyUnicode_4BYTE_DATA(from) + from_start + how_many,
PyUnicode_1BYTE_DATA(to) + to_start
);
}
else if (from_kind == PyUnicode_4BYTE_KIND
&& to_kind == PyUnicode_2BYTE_KIND)
{
_PyUnicode_CONVERT_BYTES(
Py_UCS4, Py_UCS2,
PyUnicode_4BYTE_DATA(from) + from_start,
PyUnicode_4BYTE_DATA(from) + from_start + how_many,
PyUnicode_2BYTE_DATA(to) + to_start
);
}
else {
Py_UNREACHABLE();
}
}
else {
const Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to);
Py_UCS4 ch;
Py_ssize_t i;
for (i=0; i < how_many; i++) {
ch = PyUnicode_READ(from_kind, from_data, from_start + i);
if (ch > to_maxchar)
return -1;
PyUnicode_WRITE(to_kind, to_data, to_start + i, ch);
}
}
}
return 0;
}
void
_PyUnicode_FastCopyCharacters(
PyObject *to, Py_ssize_t to_start,
PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many)
{
(void)_copy_characters(to, to_start, from, from_start, how_many, 0);
}
Py_ssize_t
PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start,
PyObject *from, Py_ssize_t from_start,
Py_ssize_t how_many)
{
int err;
if (!PyUnicode_Check(from) || !PyUnicode_Check(to)) {
PyErr_BadInternalCall();
return -1;
}
if (PyUnicode_READY(from) == -1)
return -1;
if (PyUnicode_READY(to) == -1)
return -1;
if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) {
PyErr_SetString(PyExc_IndexError, "string index out of range");
return -1;
}
if ((size_t)to_start > (size_t)PyUnicode_GET_LENGTH(to)) {
PyErr_SetString(PyExc_IndexError, "string index out of range");
return -1;
}
if (how_many < 0) {
PyErr_SetString(PyExc_SystemError, "how_many cannot be negative");
return -1;
}
how_many = Py_MIN(PyUnicode_GET_LENGTH(from)-from_start, how_many);
if (to_start + how_many > PyUnicode_GET_LENGTH(to)) {
PyErr_Format(PyExc_SystemError,
"Cannot write %zi characters at %zi "
"in a string of %zi characters",
how_many, to_start, PyUnicode_GET_LENGTH(to));
return -1;
}
if (how_many == 0)
return 0;
if (unicode_check_modifiable(to))
return -1;
err = _copy_characters(to, to_start, from, from_start, how_many, 1);
if (err) {
PyErr_Format(PyExc_SystemError,
"Cannot copy %s characters "
"into a string of %s characters",
unicode_kind_name(from),
unicode_kind_name(to));
return -1;
}
return how_many;
}
/* Find the maximum code point and count the number of surrogate pairs so a
correct string length can be computed before converting a string to UCS4.
This function counts single surrogates as a character and not as a pair.
Return 0 on success, or -1 on error. */
static int
find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end,
Py_UCS4 *maxchar, Py_ssize_t *num_surrogates)
{
const wchar_t *iter;
Py_UCS4 ch;
assert(num_surrogates != NULL && maxchar != NULL);
*num_surrogates = 0;
*maxchar = 0;
for (iter = begin; iter < end; ) {
#if SIZEOF_WCHAR_T == 2
if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0])
&& (iter+1) < end
&& Py_UNICODE_IS_LOW_SURROGATE(iter[1]))
{
ch = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]);
++(*num_surrogates);
iter += 2;
}
else
#endif
{
ch = *iter;
iter++;
}
if (ch > *maxchar) {
*maxchar = ch;
if (*maxchar > MAX_UNICODE) {
PyErr_Format(PyExc_ValueError,
"character U+%x is not in range [U+0000; U+10ffff]",
ch);
return -1;
}
}
}
return 0;
}
int
_PyUnicode_Ready(PyObject *unicode)
{
wchar_t *end;
Py_UCS4 maxchar = 0;
Py_ssize_t num_surrogates;
#if SIZEOF_WCHAR_T == 2
Py_ssize_t length_wo_surrogates;
#endif
/* _PyUnicode_Ready() is only intended for old-style API usage where
strings were created using _PyObject_New() and where no canonical
representation (the str field) has been set yet aka strings
which are not yet ready. */
assert(_PyUnicode_CHECK(unicode));
assert(_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND);
assert(_PyUnicode_WSTR(unicode) != NULL);
assert(_PyUnicode_DATA_ANY(unicode) == NULL);
assert(_PyUnicode_UTF8(unicode) == NULL);
/* Actually, it should neither be interned nor be anything else: */
assert(_PyUnicode_STATE(unicode).interned == SSTATE_NOT_INTERNED);
end = _PyUnicode_WSTR(unicode) + _PyUnicode_WSTR_LENGTH(unicode);
if (find_maxchar_surrogates(_PyUnicode_WSTR(unicode), end,
&maxchar, &num_surrogates) == -1)
return -1;
if (maxchar < 256) {
_PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(_PyUnicode_WSTR_LENGTH(unicode) + 1);
if (!_PyUnicode_DATA_ANY(unicode)) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_CONVERT_BYTES(wchar_t, unsigned char,
_PyUnicode_WSTR(unicode), end,
PyUnicode_1BYTE_DATA(unicode));
PyUnicode_1BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0';
_PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode);
_PyUnicode_STATE(unicode).kind = PyUnicode_1BYTE_KIND;
if (maxchar < 128) {
_PyUnicode_STATE(unicode).ascii = 1;
_PyUnicode_UTF8(unicode) = _PyUnicode_DATA_ANY(unicode);
_PyUnicode_UTF8_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode);
}
else {
_PyUnicode_STATE(unicode).ascii = 0;
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
}
PyObject_FREE(_PyUnicode_WSTR(unicode));
_PyUnicode_WSTR(unicode) = NULL;
_PyUnicode_WSTR_LENGTH(unicode) = 0;
}
/* In this case we might have to convert down from 4-byte native
wchar_t to 2-byte unicode. */
else if (maxchar < 65536) {
assert(num_surrogates == 0 &&
"FindMaxCharAndNumSurrogatePairs() messed up");
#if SIZEOF_WCHAR_T == 2
/* We can share representations and are done. */
_PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode);
PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0';
_PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode);
_PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND;
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
#else
/* sizeof(wchar_t) == 4 */
_PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(
2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1));
if (!_PyUnicode_DATA_ANY(unicode)) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_CONVERT_BYTES(wchar_t, Py_UCS2,
_PyUnicode_WSTR(unicode), end,
PyUnicode_2BYTE_DATA(unicode));
PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0';
_PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode);
_PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND;
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
PyObject_FREE(_PyUnicode_WSTR(unicode));
_PyUnicode_WSTR(unicode) = NULL;
_PyUnicode_WSTR_LENGTH(unicode) = 0;
#endif
}
/* maxchar exeeds 16 bit, wee need 4 bytes for unicode characters */
else {
#if SIZEOF_WCHAR_T == 2
/* in case the native representation is 2-bytes, we need to allocate a
new normalized 4-byte version. */
length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates;
if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(4 * (length_wo_surrogates + 1));
if (!_PyUnicode_DATA_ANY(unicode)) {
PyErr_NoMemory();
return -1;
}
_PyUnicode_LENGTH(unicode) = length_wo_surrogates;
_PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND;
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
/* unicode_convert_wchar_to_ucs4() requires a ready string */
_PyUnicode_STATE(unicode).ready = 1;
unicode_convert_wchar_to_ucs4(_PyUnicode_WSTR(unicode), end, unicode);
PyObject_FREE(_PyUnicode_WSTR(unicode));
_PyUnicode_WSTR(unicode) = NULL;
_PyUnicode_WSTR_LENGTH(unicode) = 0;
#else
assert(num_surrogates == 0);
_PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode);
_PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode);
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
_PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND;
#endif
PyUnicode_4BYTE_DATA(unicode)[_PyUnicode_LENGTH(unicode)] = '\0';
}
_PyUnicode_STATE(unicode).ready = 1;
assert(_PyUnicode_CheckConsistency(unicode, 1));
return 0;
}
static void
unicode_dealloc(PyObject *unicode)
{
switch (PyUnicode_CHECK_INTERNED(unicode)) {
case SSTATE_NOT_INTERNED:
break;
case SSTATE_INTERNED_MORTAL:
/* revive dead object temporarily for DelItem */
Py_REFCNT(unicode) = 3;
if (PyDict_DelItem(interned, unicode) != 0)
Py_FatalError(
"deletion of interned string failed");
break;
case SSTATE_INTERNED_IMMORTAL:
Py_FatalError("Immortal interned string died.");
/* fall through */
default:
Py_FatalError("Inconsistent interned string state.");
}
if (_PyUnicode_HAS_WSTR_MEMORY(unicode))
PyObject_DEL(_PyUnicode_WSTR(unicode));
if (_PyUnicode_HAS_UTF8_MEMORY(unicode))
PyObject_DEL(_PyUnicode_UTF8(unicode));
if (!PyUnicode_IS_COMPACT(unicode) && _PyUnicode_DATA_ANY(unicode))
PyObject_DEL(_PyUnicode_DATA_ANY(unicode));
Py_TYPE(unicode)->tp_free(unicode);
}
#ifdef Py_DEBUG
static int
unicode_is_singleton(PyObject *unicode)
{
PyASCIIObject *ascii = (PyASCIIObject *)unicode;
if (unicode == unicode_empty)
return 1;
if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1)
{
Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0);
if (ch < 256 && unicode_latin1[ch] == unicode)
return 1;
}
return 0;
}
#endif
static int
unicode_modifiable(PyObject *unicode)
{
assert(_PyUnicode_CHECK(unicode));
if (Py_REFCNT(unicode) != 1)
return 0;
if (_PyUnicode_HASH(unicode) != -1)
return 0;
if (PyUnicode_CHECK_INTERNED(unicode))
return 0;
if (!PyUnicode_CheckExact(unicode))
return 0;
#ifdef Py_DEBUG
/* singleton refcount is greater than 1 */
assert(!unicode_is_singleton(unicode));
#endif
return 1;
}
static int
unicode_resize(PyObject **p_unicode, Py_ssize_t length)
{
PyObject *unicode;
Py_ssize_t old_length;
assert(p_unicode != NULL);
unicode = *p_unicode;
assert(unicode != NULL);
assert(PyUnicode_Check(unicode));
assert(0 <= length);
if (_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND)
old_length = PyUnicode_WSTR_LENGTH(unicode);
else
old_length = PyUnicode_GET_LENGTH(unicode);
if (old_length == length)
return 0;
if (length == 0) {
_Py_INCREF_UNICODE_EMPTY();
if (!unicode_empty)
return -1;
Py_SETREF(*p_unicode, unicode_empty);
return 0;
}
if (!unicode_modifiable(unicode)) {
PyObject *copy = resize_copy(unicode, length);
if (copy == NULL)
return -1;
Py_SETREF(*p_unicode, copy);
return 0;
}
if (PyUnicode_IS_COMPACT(unicode)) {
PyObject *new_unicode = resize_compact(unicode, length);
if (new_unicode == NULL)
return -1;
*p_unicode = new_unicode;
return 0;
}
return resize_inplace(unicode, length);
}
int
PyUnicode_Resize(PyObject **p_unicode, Py_ssize_t length)
{
PyObject *unicode;
if (p_unicode == NULL) {
PyErr_BadInternalCall();
return -1;
}
unicode = *p_unicode;
if (unicode == NULL || !PyUnicode_Check(unicode) || length < 0)
{
PyErr_BadInternalCall();
return -1;
}
return unicode_resize(p_unicode, length);
}
/* Copy an ASCII or latin1 char* string into a Python Unicode string.
WARNING: The function doesn't copy the terminating null character and
doesn't check the maximum character (may write a latin1 character in an
ASCII string). */
static void
unicode_write_cstr(PyObject *unicode, Py_ssize_t index,
const char *str, Py_ssize_t len)
{
enum PyUnicode_Kind kind = PyUnicode_KIND(unicode);
void *data = PyUnicode_DATA(unicode);
const char *end = str + len;
switch (kind) {
case PyUnicode_1BYTE_KIND: {
assert(index + len <= PyUnicode_GET_LENGTH(unicode));
#ifdef Py_DEBUG
if (PyUnicode_IS_ASCII(unicode)) {
Py_UCS4 maxchar = ucs1lib_find_max_char(
(const Py_UCS1*)str,
(const Py_UCS1*)str + len);
assert(maxchar < 128);
}
#endif
memcpy((char *) data + index, str, len);
break;
}
case PyUnicode_2BYTE_KIND: {
Py_UCS2 *start = (Py_UCS2 *)data + index;
Py_UCS2 *ucs2 = start;
assert(index <= PyUnicode_GET_LENGTH(unicode));
for (; str < end; ++ucs2, ++str)
*ucs2 = (Py_UCS2)*str;
assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
break;
}
default: {
Py_UCS4 *start = (Py_UCS4 *)data + index;
Py_UCS4 *ucs4 = start;
assert(kind == PyUnicode_4BYTE_KIND);
assert(index <= PyUnicode_GET_LENGTH(unicode));
for (; str < end; ++ucs4, ++str)
*ucs4 = (Py_UCS4)*str;
assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
}
}
}
static PyObject*
get_latin1_char(unsigned char ch)
{
PyObject *unicode = unicode_latin1[ch];
if (!unicode) {
unicode = PyUnicode_New(1, ch);
if (!unicode)
return NULL;
PyUnicode_1BYTE_DATA(unicode)[0] = ch;
assert(_PyUnicode_CheckConsistency(unicode, 1));
unicode_latin1[ch] = unicode;
}
Py_INCREF(unicode);
return unicode;
}
static PyObject*
unicode_char(Py_UCS4 ch)
{
PyObject *unicode;
assert(ch <= MAX_UNICODE);
if (ch < 256)
return get_latin1_char(ch);
unicode = PyUnicode_New(1, ch);
if (unicode == NULL)
return NULL;
assert(PyUnicode_KIND(unicode) != PyUnicode_1BYTE_KIND);
if (PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND) {
PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch;
} else {
assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
PyUnicode_4BYTE_DATA(unicode)[0] = ch;
}
assert(_PyUnicode_CheckConsistency(unicode, 1));
return unicode;
}
PyObject *
PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)
{
if (u == NULL)
return (PyObject*)_PyUnicode_New(size);
if (size < 0) {
PyErr_BadInternalCall();
return NULL;
}
return PyUnicode_FromWideChar(u, size);
}
PyObject *
PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size)
{
PyObject *unicode;
Py_UCS4 maxchar = 0;
Py_ssize_t num_surrogates;
if (u == NULL && size != 0) {
PyErr_BadInternalCall();
return NULL;
}
if (size == -1) {
size = wcslen(u);
}
/* If the Unicode data is known at construction time, we can apply
some optimizations which share commonly used objects. */
/* Optimization for empty strings */
if (size == 0)
_Py_RETURN_UNICODE_EMPTY();
/* Single character Unicode objects in the Latin-1 range are
shared when using this constructor */
if (size == 1 && (Py_UCS4)*u < 256)
return get_latin1_char((unsigned char)*u);
/* If not empty and not single character, copy the Unicode data
into the new object */
if (find_maxchar_surrogates(u, u + size,
&maxchar, &num_surrogates) == -1)
return NULL;
unicode = PyUnicode_New(size - num_surrogates, maxchar);
if (!unicode)
return NULL;
switch (PyUnicode_KIND(unicode)) {
case PyUnicode_1BYTE_KIND:
_PyUnicode_CONVERT_BYTES(Py_UNICODE, unsigned char,
u, u + size, PyUnicode_1BYTE_DATA(unicode));
break;
case PyUnicode_2BYTE_KIND:
#if Py_UNICODE_SIZE == 2
memcpy(PyUnicode_2BYTE_DATA(unicode), u, size * 2);
#else
_PyUnicode_CONVERT_BYTES(Py_UNICODE, Py_UCS2,
u, u + size, PyUnicode_2BYTE_DATA(unicode));
#endif
break;
case PyUnicode_4BYTE_KIND:
#if SIZEOF_WCHAR_T == 2
/* This is the only case which has to process surrogates, thus
a simple copy loop is not enough and we need a function. */
unicode_convert_wchar_to_ucs4(u, u + size, unicode);
#else
assert(num_surrogates == 0);
memcpy(PyUnicode_4BYTE_DATA(unicode), u, size * 4);
#endif
break;
default:
Py_UNREACHABLE();
}
return unicode_result(unicode);
}
PyObject *
PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
{
if (size < 0) {
PyErr_SetString(PyExc_SystemError,
"Negative size passed to PyUnicode_FromStringAndSize");
return NULL;
}
if (u != NULL)
return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL);
else
return (PyObject *)_PyUnicode_New(size);
}
PyObject *
PyUnicode_FromString(const char *u)
{
size_t size = strlen(u);
if (size > PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError, "input too long");
return NULL;
}
return PyUnicode_DecodeUTF8Stateful(u, (Py_ssize_t)size, NULL, NULL);
}
PyObject *
_PyUnicode_FromId(_Py_Identifier *id)
{
if (!id->object) {
id->object = PyUnicode_DecodeUTF8Stateful(id->string,
strlen(id->string),
NULL, NULL);
if (!id->object)
return NULL;
PyUnicode_InternInPlace(&id->object);
assert(!id->next);
id->next = static_strings;
static_strings = id;
}
return id->object;
}
void
_PyUnicode_ClearStaticStrings()
{
_Py_Identifier *tmp, *s = static_strings;
while (s) {
Py_CLEAR(s->object);
tmp = s->next;
s->next = NULL;
s = tmp;
}
static_strings = NULL;
}
/* Internal function, doesn't check maximum character */
PyObject*
_PyUnicode_FromASCII(const char *buffer, Py_ssize_t size)
{
const unsigned char *s = (const unsigned char *)buffer;
PyObject *unicode;
if (size == 1) {
#ifdef Py_DEBUG
assert((unsigned char)s[0] < 128);
#endif
return get_latin1_char(s[0]);
}
unicode = PyUnicode_New(size, 127);
if (!unicode)
return NULL;
memcpy(PyUnicode_1BYTE_DATA(unicode), s, size);
assert(_PyUnicode_CheckConsistency(unicode, 1));
return unicode;
}
static Py_UCS4
kind_maxchar_limit(unsigned int kind)
{
switch (kind) {
case PyUnicode_1BYTE_KIND:
return 0x80;
case PyUnicode_2BYTE_KIND:
return 0x100;
case PyUnicode_4BYTE_KIND:
return 0x10000;
default:
Py_UNREACHABLE();
}
}
static PyObject*
_PyUnicode_FromUCS1(const Py_UCS1* u, Py_ssize_t size)
{
PyObject *res;
unsigned char max_char;
if (size == 0)
_Py_RETURN_UNICODE_EMPTY();
assert(size > 0);
if (size == 1)
return get_latin1_char(u[0]);
max_char = ucs1lib_find_max_char(u, u + size);
res = PyUnicode_New(size, max_char);
if (!res)
return NULL;
memcpy(PyUnicode_1BYTE_DATA(res), u, size);
assert(_PyUnicode_CheckConsistency(res, 1));
return res;
}
static PyObject*
_PyUnicode_FromUCS2(const Py_UCS2 *u, Py_ssize_t size)
{
PyObject *res;
Py_UCS2 max_char;
if (size == 0)
_Py_RETURN_UNICODE_EMPTY();
assert(size > 0);
if (size == 1)
return unicode_char(u[0]);
max_char = ucs2lib_find_max_char(u, u + size);
res = PyUnicode_New(size, max_char);
if (!res)
return NULL;
if (max_char >= 256)
memcpy(PyUnicode_2BYTE_DATA(res), u, sizeof(Py_UCS2)*size);
else {
_PyUnicode_CONVERT_BYTES(
Py_UCS2, Py_UCS1, u, u + size, PyUnicode_1BYTE_DATA(res));
}
assert(_PyUnicode_CheckConsistency(res, 1));
return res;
}
static PyObject*
_PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size)
{
PyObject *res;
Py_UCS4 max_char;
if (size == 0)
_Py_RETURN_UNICODE_EMPTY();
assert(size > 0);
if (size == 1)
return unicode_char(u[0]);
max_char = ucs4lib_find_max_char(u, u + size);
res = PyUnicode_New(size, max_char);
if (!res)
return NULL;
if (max_char < 256)
_PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, u, u + size,
PyUnicode_1BYTE_DATA(res));
else if (max_char < 0x10000)
_PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, u, u + size,
PyUnicode_2BYTE_DATA(res));
else
memcpy(PyUnicode_4BYTE_DATA(res), u, sizeof(Py_UCS4)*size);
assert(_PyUnicode_CheckConsistency(res, 1));
return res;
}
PyObject*
PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size)
{
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "size must be positive");
return NULL;
}
switch (kind) {
case PyUnicode_1BYTE_KIND:
return _PyUnicode_FromUCS1(buffer, size);
case PyUnicode_2BYTE_KIND:
return _PyUnicode_FromUCS2(buffer, size);
case PyUnicode_4BYTE_KIND:
return _PyUnicode_FromUCS4(buffer, size);
default:
PyErr_SetString(PyExc_SystemError, "invalid kind");
return NULL;
}
}
Py_UCS4
_PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end)
{
enum PyUnicode_Kind kind;
void *startptr, *endptr;
assert(PyUnicode_IS_READY(unicode));
assert(0 <= start);
assert(end <= PyUnicode_GET_LENGTH(unicode));
assert(start <= end);
if (start == 0 && end == PyUnicode_GET_LENGTH(unicode))
return PyUnicode_MAX_CHAR_VALUE(unicode);
if (start == end)
return 127;
if (PyUnicode_IS_ASCII(unicode))
return 127;
kind = PyUnicode_KIND(unicode);
startptr = PyUnicode_DATA(unicode);
endptr = (char *)startptr + end * kind;
startptr = (char *)startptr + start * kind;
switch(kind) {
case PyUnicode_1BYTE_KIND:
return ucs1lib_find_max_char(startptr, endptr);
case PyUnicode_2BYTE_KIND:
return ucs2lib_find_max_char(startptr, endptr);
case PyUnicode_4BYTE_KIND:
return ucs4lib_find_max_char(startptr, endptr);
default:
Py_UNREACHABLE();
}
}
/* Ensure that a string uses the most efficient storage, if it is not the
case: create a new string with of the right kind. Write NULL into *p_unicode
on error. */
static void
unicode_adjust_maxchar(PyObject **p_unicode)
{
PyObject *unicode, *copy;
Py_UCS4 max_char;
Py_ssize_t len;
unsigned int kind;
assert(p_unicode != NULL);
unicode = *p_unicode;
assert(PyUnicode_IS_READY(unicode));
if (PyUnicode_IS_ASCII(unicode))
return;
len = PyUnicode_GET_LENGTH(unicode);
kind = PyUnicode_KIND(unicode);
if (kind == PyUnicode_1BYTE_KIND) {
const Py_UCS1 *u = PyUnicode_1BYTE_DATA(unicode);
max_char = ucs1lib_find_max_char(u, u + len);
if (max_char >= 128)
return;
}
else if (kind == PyUnicode_2BYTE_KIND) {
const Py_UCS2 *u = PyUnicode_2BYTE_DATA(unicode);
max_char = ucs2lib_find_max_char(u, u + len);
if (max_char >= 256)
return;
}
else {
const Py_UCS4 *u = PyUnicode_4BYTE_DATA(unicode);
assert(kind == PyUnicode_4BYTE_KIND);
max_char = ucs4lib_find_max_char(u, u + len);
if (max_char >= 0x10000)
return;
}
copy = PyUnicode_New(len, max_char);
if (copy != NULL)
_PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, len);
Py_DECREF(unicode);
*p_unicode = copy;
}
PyObject*
_PyUnicode_Copy(PyObject *unicode)
{
Py_ssize_t length;
PyObject *copy;
if (!PyUnicode_Check(unicode)) {
PyErr_BadInternalCall();
return NULL;
}
if (PyUnicode_READY(unicode) == -1)
return NULL;
length = PyUnicode_GET_LENGTH(unicode);
copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode));
if (!copy)
return NULL;
assert(PyUnicode_KIND(copy) == PyUnicode_KIND(unicode));
memcpy(PyUnicode_DATA(copy), PyUnicode_DATA(unicode),
length * PyUnicode_KIND(unicode));
assert(_PyUnicode_CheckConsistency(copy, 1));
return copy;
}
/* Widen Unicode objects to larger buffers. Don't write terminating null
character. Return NULL on error. */
void*
_PyUnicode_AsKind(PyObject *s, unsigned int kind)
{
Py_ssize_t len;
void *result;
unsigned int skind;
if (PyUnicode_READY(s) == -1)
return NULL;
len = PyUnicode_GET_LENGTH(s);
skind = PyUnicode_KIND(s);
if (skind >= kind) {
PyErr_SetString(PyExc_SystemError, "invalid widening attempt");
return NULL;
}
switch (kind) {
case PyUnicode_2BYTE_KIND:
result = PyMem_New(Py_UCS2, len);
if (!result)
return PyErr_NoMemory();
assert(skind == PyUnicode_1BYTE_KIND);
_PyUnicode_CONVERT_BYTES(
Py_UCS1, Py_UCS2,
PyUnicode_1BYTE_DATA(s),
PyUnicode_1BYTE_DATA(s) + len,
result);
return result;
case PyUnicode_4BYTE_KIND:
result = PyMem_New(Py_UCS4, len);
if (!result)
return PyErr_NoMemory();
if (skind == PyUnicode_2BYTE_KIND) {
_PyUnicode_CONVERT_BYTES(
Py_UCS2, Py_UCS4,
PyUnicode_2BYTE_DATA(s),
PyUnicode_2BYTE_DATA(s) + len,
result);
}
else {
assert(skind == PyUnicode_1BYTE_KIND);
_PyUnicode_CONVERT_BYTES(
Py_UCS1, Py_UCS4,
PyUnicode_1BYTE_DATA(s),
PyUnicode_1BYTE_DATA(s) + len,
result);
}
return result;
default:
break;
}
PyErr_SetString(PyExc_SystemError, "invalid kind");
return NULL;
}
static Py_UCS4*
as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize,
int copy_null)
{
int kind;
void *data;
Py_ssize_t len, targetlen;
if (PyUnicode_READY(string) == -1)
return NULL;
kind = PyUnicode_KIND(string);
data = PyUnicode_DATA(string);
len = PyUnicode_GET_LENGTH(string);
targetlen = len;
if (copy_null)
targetlen++;
if (!target) {
target = PyMem_New(Py_UCS4, targetlen);
if (!target) {
PyErr_NoMemory();
return NULL;
}
}
else {
if (targetsize < targetlen) {
PyErr_Format(PyExc_SystemError,
"string is longer than the buffer");
if (copy_null && 0 < targetsize)
target[0] = 0;
return NULL;
}
}
if (kind == PyUnicode_1BYTE_KIND) {
Py_UCS1 *start = (Py_UCS1 *) data;
_PyUnicode_CONVERT_BYTES(Py_UCS1, Py_UCS4, start, start + len, target);
}
else if (kind == PyUnicode_2BYTE_KIND) {
Py_UCS2 *start = (Py_UCS2 *) data;
_PyUnicode_CONVERT_BYTES(Py_UCS2, Py_UCS4, start, start + len, target);
}
else {
assert(kind == PyUnicode_4BYTE_KIND);
memcpy(target, data, len * sizeof(Py_UCS4));
}
if (copy_null)
target[len] = 0;
return target;
}
Py_UCS4*
PyUnicode_AsUCS4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize,
int copy_null)
{
if (target == NULL || targetsize < 0) {
PyErr_BadInternalCall();
return NULL;
}
return as_ucs4(string, target, targetsize, copy_null);
}
Py_UCS4*
PyUnicode_AsUCS4Copy(PyObject *string)
{
return as_ucs4(string, NULL, 0, 1);
}
/* maximum number of characters required for output of %lld or %p.
We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
plus 1 for the sign. 53/22 is an upper bound for log10(256). */
#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22)
static int
unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str,
Py_ssize_t width, Py_ssize_t precision)
{
Py_ssize_t length, fill, arglen;
Py_UCS4 maxchar;
if (PyUnicode_READY(str) == -1)
return -1;
length = PyUnicode_GET_LENGTH(str);
if ((precision == -1 || precision >= length)
&& width <= length)
return _PyUnicodeWriter_WriteStr(writer, str);
if (precision != -1)
length = Py_MIN(precision, length);
arglen = Py_MAX(length, width);
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
maxchar = _PyUnicode_FindMaxChar(str, 0, length);
else
maxchar = writer->maxchar;
if (_PyUnicodeWriter_Prepare(writer, arglen, maxchar) == -1)
return -1;
if (width > length) {
fill = width - length;
if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1)
return -1;
writer->pos += fill;
}
_PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
str, 0, length);
writer->pos += length;
return 0;
}
static int
unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str,
Py_ssize_t width, Py_ssize_t precision)
{
/* UTF-8 */
Py_ssize_t length;
PyObject *unicode;
int res;
length = strlen(str);
if (precision != -1)
length = Py_MIN(length, precision);
unicode = PyUnicode_DecodeUTF8Stateful(str, length, "replace", NULL);
if (unicode == NULL)
return -1;
res = unicode_fromformat_write_str(writer, unicode, width, -1);
Py_DECREF(unicode);
return res;
}
static const char*
unicode_fromformat_arg(_PyUnicodeWriter *writer,
const char *f, va_list *vargs)
{
const char *p;
Py_ssize_t len;
int zeropad;
Py_ssize_t width;
Py_ssize_t precision;
int longflag;
int longlongflag;
int size_tflag;
Py_ssize_t fill;
p = f;
f++;
zeropad = 0;
if (*f == '0') {
zeropad = 1;
f++;
}
/* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */
width = -1;
if (Py_ISDIGIT((unsigned)*f)) {
width = *f - '0';
f++;
while (Py_ISDIGIT((unsigned)*f)) {
if (width > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) {
PyErr_SetString(PyExc_ValueError,
"width too big");
return NULL;
}
width = (width * 10) + (*f - '0');
f++;
}
}
precision = -1;
if (*f == '.') {
f++;
if (Py_ISDIGIT((unsigned)*f)) {
precision = (*f - '0');
f++;
while (Py_ISDIGIT((unsigned)*f)) {
if (precision > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) {
PyErr_SetString(PyExc_ValueError,
"precision too big");
return NULL;
}
precision = (precision * 10) + (*f - '0');
f++;
}
}
if (*f == '%') {
/* "%.3%s" => f points to "3" */
f--;
}
}
if (*f == '\0') {
/* bogus format "%.123" => go backward, f points to "3" */
f--;
}
/* Handle %ld, %lu, %lld and %llu. */
longflag = 0;
longlongflag = 0;
size_tflag = 0;
if (*f == 'l') {
if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') {
longflag = 1;
++f;
}
else if (f[1] == 'l' &&
(f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) {
longlongflag = 1;
f += 2;
}
}
/* handle the size_t flag. */
else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) {
size_tflag = 1;
++f;
}
if (f[1] == '\0')
writer->overallocate = 0;
switch (*f) {
case 'c':
{
int ordinal = va_arg(*vargs, int);
if (ordinal < 0 || ordinal > MAX_UNICODE) {
PyErr_SetString(PyExc_OverflowError,
"character argument not in range(0x110000)");
return NULL;
}
if (_PyUnicodeWriter_WriteCharInline(writer, ordinal) < 0)
return NULL;
break;
}
case 'i':
case 'd':
case 'u':
case 'x':
{
/* used by sprintf */
char buffer[MAX_LONG_LONG_CHARS];
Py_ssize_t arglen;
if (*f == 'u') {
if (longflag)
len = sprintf(buffer, "%lu",
va_arg(*vargs, unsigned long));
else if (longlongflag)
len = sprintf(buffer, "%llu",
va_arg(*vargs, unsigned long long));
else if (size_tflag)
len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "u",
va_arg(*vargs, size_t));
else
len = sprintf(buffer, "%u",
va_arg(*vargs, unsigned int));
}
else if (*f == 'x') {
len = sprintf(buffer, "%x", va_arg(*vargs, int));
}
else {
if (longflag)
len = sprintf(buffer, "%li",
va_arg(*vargs, long));
else if (longlongflag)
len = sprintf(buffer, "%lli",
va_arg(*vargs, long long));
else if (size_tflag)
len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "i",
va_arg(*vargs, Py_ssize_t));
else
len = sprintf(buffer, "%i",
va_arg(*vargs, int));
}
assert(len >= 0);
if (precision < len)
precision = len;
arglen = Py_MAX(precision, width);
if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1)
return NULL;
if (width > precision) {
Py_UCS4 fillchar;
fill = width - precision;
fillchar = zeropad?'0':' ';
if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1)
return NULL;
writer->pos += fill;
}
if (precision > len) {
fill = precision - len;
if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1)
return NULL;
writer->pos += fill;
}
if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0)
return NULL;
break;
}
case 'p':
{
char number[MAX_LONG_LONG_CHARS];
len = sprintf(number, "%p", va_arg(*vargs, void*));
assert(len >= 0);
/* %p is ill-defined: ensure leading 0x. */
if (number[1] == 'X')
number[1] = 'x';
else if (number[1] != 'x') {
memmove(number + 2, number,
strlen(number) + 1);
number[0] = '0';
number[1] = 'x';
len += 2;
}
if (_PyUnicodeWriter_WriteASCIIString(writer, number, len) < 0)
return NULL;
break;
}
case 's':
{
/* UTF-8 */
const char *s = va_arg(*vargs, const char*);
if (unicode_fromformat_write_cstr(writer, s, width, precision) < 0)
return NULL;
break;
}
case 'U':
{
PyObject *obj = va_arg(*vargs, PyObject *);
assert(obj && _PyUnicode_CHECK(obj));
if (unicode_fromformat_write_str(writer, obj, width, precision) == -1)
return NULL;
break;
}
case 'V':
{
PyObject *obj = va_arg(*vargs, PyObject *);
const char *str = va_arg(*vargs, const char *);
if (obj) {
assert(_PyUnicode_CHECK(obj));
if (unicode_fromformat_write_str(writer, obj, width, precision) == -1)
return NULL;
}
else {
assert(str != NULL);
if (unicode_fromformat_write_cstr(writer, str, width, precision) < 0)
return NULL;
}
break;
}
case 'S':
{
PyObject *obj = va_arg(*vargs, PyObject *);
PyObject *str;
assert(obj);
str = PyObject_Str(obj);
if (!str)
return NULL;
if (unicode_fromformat_write_str(writer, str, width, precision) == -1) {
Py_DECREF(str);
return NULL;
}
Py_DECREF(str);
break;
}
case 'R':
{
PyObject *obj = va_arg(*vargs, PyObject *);
PyObject *repr;
assert(obj);
repr = PyObject_Repr(obj);
if (!repr)
return NULL;
if (unicode_fromformat_write_str(writer, repr, width, precision) == -1) {
Py_DECREF(repr);
return NULL;
}
Py_DECREF(repr);
break;
}
case 'A':
{
PyObject *obj = va_arg(*vargs, PyObject *);
PyObject *ascii;
assert(obj);
ascii = PyObject_ASCII(obj);
if (!ascii)
return NULL;
if (unicode_fromformat_write_str(writer, ascii, width, precision) == -1) {
Py_DECREF(ascii);
return NULL;
}
Py_DECREF(ascii);
break;
}
case '%':
if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0)
return NULL;
break;
default:
/* if we stumble upon an unknown formatting code, copy the rest
of the format string to the output string. (we cannot just
skip the code, since there's no way to know what's in the
argument list) */
len = strlen(p);
if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1)
return NULL;
f = p+len;
return f;
}
f++;
return f;
}
PyObject *
PyUnicode_FromFormatV(const char *format, va_list vargs)
{
va_list vargs2;
const char *f;
_PyUnicodeWriter writer;
_PyUnicodeWriter_Init(&writer);
writer.min_length = strlen(format) + 100;
writer.overallocate = 1;
// Copy varags to be able to pass a reference to a subfunction.
va_copy(vargs2, vargs);
for (f = format; *f; ) {
if (*f == '%') {
f = unicode_fromformat_arg(&writer, f, &vargs2);
if (f == NULL)
goto fail;
}
else {
const char *p;
Py_ssize_t len;
p = f;
do
{
if ((unsigned char)*p > 127) {
PyErr_Format(PyExc_ValueError,
"PyUnicode_FromFormatV() expects an ASCII-encoded format "
"string, got a non-ASCII byte: 0x%02x",
(unsigned char)*p);
goto fail;
}
p++;
}
while (*p != '\0' && *p != '%');
len = p - f;
if (*p == '\0')
writer.overallocate = 0;
if (_PyUnicodeWriter_WriteASCIIString(&writer, f, len) < 0)
goto fail;
f = p;
}
}
va_end(vargs2);
return _PyUnicodeWriter_Finish(&writer);
fail:
va_end(vargs2);
_PyUnicodeWriter_Dealloc(&writer);
return NULL;
}
PyObject *
PyUnicode_FromFormat(const char *format, ...)
{
PyObject* ret;
va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
va_start(vargs, format);
#else
va_start(vargs);
#endif
ret = PyUnicode_FromFormatV(format, vargs);
va_end(vargs);
return ret;
}
#ifdef HAVE_WCHAR_H
/* Convert a Unicode object to a wide character string.
- If w is NULL: return the number of wide characters (including the null
character) required to convert the unicode object. Ignore size argument.
- Otherwise: return the number of wide characters (excluding the null
character) written into w. Write at most size wide characters (including
the null character). */
Py_ssize_t
PyUnicode_AsWideChar(PyObject *unicode,
wchar_t *w,
Py_ssize_t size)
{
Py_ssize_t res;
const wchar_t *wstr;
if (unicode == NULL) {
PyErr_BadInternalCall();
return -1;
}
wstr = PyUnicode_AsUnicodeAndSize(unicode, &res);
if (wstr == NULL)
return -1;
if (w != NULL) {
if (size > res)
size = res + 1;
else
res = size;
memcpy(w, wstr, size * sizeof(wchar_t));
return res;
}
else
return res + 1;
}
wchar_t*
PyUnicode_AsWideCharString(PyObject *unicode,
Py_ssize_t *size)
{
const wchar_t *wstr;
wchar_t *buffer;
Py_ssize_t buflen;
if (unicode == NULL) {
PyErr_BadInternalCall();
return NULL;
}
wstr = PyUnicode_AsUnicodeAndSize(unicode, &buflen);
if (wstr == NULL) {
return NULL;
}
if (size == NULL && wcslen(wstr) != (size_t)buflen) {
PyErr_SetString(PyExc_ValueError,
"embedded null character");
return NULL;
}
buffer = PyMem_NEW(wchar_t, buflen + 1);
if (buffer == NULL) {
PyErr_NoMemory();
return NULL;
}
memcpy(buffer, wstr, (buflen + 1) * sizeof(wchar_t));
if (size != NULL)
*size = buflen;
return buffer;
}
#endif /* HAVE_WCHAR_H */
PyObject *
PyUnicode_FromOrdinal(int ordinal)
{
if (ordinal < 0 || ordinal > MAX_UNICODE) {
PyErr_SetString(PyExc_ValueError,
"chr() arg not in range(0x110000)");
return NULL;
}
return unicode_char((Py_UCS4)ordinal);
}
PyObject *
PyUnicode_FromObject(PyObject *obj)
{
/* XXX Perhaps we should make this API an alias of
PyObject_Str() instead ?! */
if (PyUnicode_CheckExact(obj)) {
if (PyUnicode_READY(obj) == -1)
return NULL;
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_Copy(obj);
}
PyErr_Format(PyExc_TypeError,
"Can't convert '%.100s' object to str implicitly",
Py_TYPE(obj)->tp_name);
return NULL;
}
PyObject *
PyUnicode_FromEncodedObject(PyObject *obj,
const char *encoding,
const char *errors)
{
Py_buffer buffer;
PyObject *v;
if (obj == NULL) {
PyErr_BadInternalCall();
return NULL;
}
/* Decoding bytes objects is the most common case and should be fast */
if (PyBytes_Check(obj)) {
if (PyBytes_GET_SIZE(obj) == 0)
_Py_RETURN_UNICODE_EMPTY();
v = PyUnicode_Decode(
PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj),
encoding, errors);
return v;
}
if (PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError,
"decoding str is not supported");
return NULL;
}
/* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
PyErr_Format(PyExc_TypeError,
"decoding to str: need a bytes-like object, %.80s found",
Py_TYPE(obj)->tp_name);
return NULL;
}
if (buffer.len == 0) {
PyBuffer_Release(&buffer);
_Py_RETURN_UNICODE_EMPTY();
}
v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
PyBuffer_Release(&buffer);
return v;
}
/* Normalize an encoding name: similar to encodings.normalize_encoding(), but
also convert to lowercase. Return 1 on success, or 0 on error (encoding is
longer than lower_len-1). */
int
_Py_normalize_encoding(const char *encoding,
char *lower,
size_t lower_len)
{
const char *e;
char *l;
char *l_end;
int punct;
assert(encoding != NULL);
e = encoding;
l = lower;
l_end = &lower[lower_len - 1];
punct = 0;
while (1) {
char c = *e;
if (c == 0) {
break;
}
if (Py_ISALNUM(c) || c == '.') {
if (punct && l != lower) {
if (l == l_end) {
return 0;
}
*l++ = '_';
}
punct = 0;
if (l == l_end) {
return 0;
}
*l++ = Py_TOLOWER(c);
}
else {
punct = 1;
}
e++;
}
*l = '\0';
return 1;
}
PyObject *
PyUnicode_Decode(const char *s,
Py_ssize_t size,
const char *encoding,
const char *errors)
{
PyObject *buffer = NULL, *unicode;
Py_buffer info;
char buflower[11]; /* strlen("iso-8859-1\0") == 11, longest shortcut */
if (encoding == NULL) {
return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
}
/* Shortcuts for common default encodings */
if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) {
char *lower = buflower;
/* Fast paths */
if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') {
lower += 3;
if (*lower == '_') {
/* Match "utf8" and "utf_8" */
lower++;
}
if (lower[0] == '8' && lower[1] == 0) {
return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
}
else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) {
return PyUnicode_DecodeUTF16(s, size, errors, 0);
}
else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) {
return PyUnicode_DecodeUTF32(s, size, errors, 0);
}
}
else {
if (strcmp(lower, "ascii") == 0
|| strcmp(lower, "us_ascii") == 0) {
return PyUnicode_DecodeASCII(s, size, errors);
}
#ifdef MS_WINDOWS
else if (strcmp(lower, "mbcs") == 0) {
return PyUnicode_DecodeMBCS(s, size, errors);
}
#endif
else if (strcmp(lower, "latin1") == 0
|| strcmp(lower, "latin_1") == 0
|| strcmp(lower, "iso_8859_1") == 0
|| strcmp(lower, "iso8859_1") == 0) {
return PyUnicode_DecodeLatin1(s, size, errors);
}
}
}
/* Decode via the codec registry */
buffer = NULL;
if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0)
goto onError;
buffer = PyMemoryView_FromBuffer(&info);
if (buffer == NULL)
goto onError;
unicode = _PyCodec_DecodeText(buffer, encoding, errors);
if (unicode == NULL)
goto onError;
if (!PyUnicode_Check(unicode)) {
PyErr_Format(PyExc_TypeError,
"'%.400s' decoder returned '%.400s' instead of 'str'; "
"use codecs.decode() to decode to arbitrary types",
encoding,
Py_TYPE(unicode)->tp_name);
Py_DECREF(unicode);
goto onError;
}
Py_DECREF(buffer);
return unicode_result(unicode);
onError:
Py_XDECREF(buffer);
return NULL;
}
PyObject *
PyUnicode_AsDecodedObject(PyObject *unicode,
const char *encoding,
const char *errors)
{
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
return NULL;
}
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyUnicode_AsDecodedObject() is deprecated; "
"use PyCodec_Decode() to decode from str", 1) < 0)
return NULL;
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
/* Decode via the codec registry */
return PyCodec_Decode(unicode, encoding, errors);
}
PyObject *
PyUnicode_AsDecodedUnicode(PyObject *unicode,
const char *encoding,
const char *errors)
{
PyObject *v;
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
goto onError;
}
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyUnicode_AsDecodedUnicode() is deprecated; "
"use PyCodec_Decode() to decode from str to str", 1) < 0)
return NULL;
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
/* Decode via the codec registry */
v = PyCodec_Decode(unicode, encoding, errors);
if (v == NULL)
goto onError;
if (!PyUnicode_Check(v)) {
PyErr_Format(PyExc_TypeError,
"'%.400s' decoder returned '%.400s' instead of 'str'; "
"use codecs.decode() to decode to arbitrary types",
encoding,
Py_TYPE(unicode)->tp_name);
Py_DECREF(v);
goto onError;
}
return unicode_result(v);
onError:
return NULL;
}
PyObject *
PyUnicode_Encode(const Py_UNICODE *s,
Py_ssize_t size,
const char *encoding,
const char *errors)
{
PyObject *v, *unicode;
unicode = PyUnicode_FromWideChar(s, size);
if (unicode == NULL)
return NULL;
v = PyUnicode_AsEncodedString(unicode, encoding, errors);
Py_DECREF(unicode);
return v;
}
PyObject *
PyUnicode_AsEncodedObject(PyObject *unicode,
const char *encoding,
const char *errors)
{
PyObject *v;
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
goto onError;
}
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyUnicode_AsEncodedObject() is deprecated; "
"use PyUnicode_AsEncodedString() to encode from str to bytes "
"or PyCodec_Encode() for generic encoding", 1) < 0)
return NULL;
if (encoding == NULL)
encoding = PyUnicode_GetDefaultEncoding();
/* Encode via the codec registry */
v = PyCodec_Encode(unicode, encoding, errors);
if (v == NULL)
goto onError;
return v;
onError:
return NULL;
}
static int
locale_error_handler(const char *errors, int *surrogateescape)
{
_Py_error_handler error_handler = get_error_handler(errors);
switch (error_handler)
{
case _Py_ERROR_STRICT:
*surrogateescape = 0;
return 0;
case _Py_ERROR_SURROGATEESCAPE:
*surrogateescape = 1;
return 0;
default:
PyErr_Format(PyExc_ValueError,
"only 'strict' and 'surrogateescape' error handlers "
"are supported, not '%s'",
errors);
return -1;
}
}
static PyObject *
unicode_encode_locale(PyObject *unicode, const char *errors,
int current_locale)
{
int surrogateescape;
if (locale_error_handler(errors, &surrogateescape) < 0)
return NULL;
Py_ssize_t wlen;
wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &wlen);
if (wstr == NULL) {
return NULL;
}
Py_ssize_t wlen2 = wcslen(wstr);
if (wlen2 != wlen) {
PyMem_Free(wstr);
PyErr_SetString(PyExc_ValueError, "embedded null character");
return NULL;
}
char *str;
size_t error_pos;
const char *reason;
int res = _Py_EncodeLocaleEx(wstr, &str, &error_pos, &reason,
current_locale, surrogateescape);
if (res != 0) {
if (res == -2) {
PyObject *exc;
exc = PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns",
"locale", unicode,
(Py_ssize_t)error_pos,
(Py_ssize_t)(error_pos+1),
reason);
if (exc != NULL) {
PyCodec_StrictErrors(exc);
Py_DECREF(exc);
}
return NULL;
}
else {
PyErr_NoMemory();
PyMem_Free(wstr);
return NULL;
}
}
PyMem_Free(wstr);
PyObject *bytes = PyBytes_FromString(str);
PyMem_RawFree(str);
return bytes;
}
PyObject *
PyUnicode_EncodeLocale(PyObject *unicode, const char *errors)
{
return unicode_encode_locale(unicode, errors, 1);
}
PyObject *
PyUnicode_EncodeFSDefault(PyObject *unicode)
{
#if defined(__APPLE__)
return _PyUnicode_AsUTF8String(unicode, Py_FileSystemDefaultEncodeErrors);
#else
PyInterpreterState *interp = PyThreadState_GET()->interp;
/* Bootstrap check: if the filesystem codec is implemented in Python, we
cannot use it to encode and decode filenames before it is loaded. Load
the Python codec requires to encode at least its own filename. Use the C
version of the locale codec until the codec registry is initialized and
the Python codec is loaded.
Py_FileSystemDefaultEncoding is shared between all interpreters, we
cannot only rely on it: check also interp->fscodec_initialized for
subinterpreters. */
if (Py_FileSystemDefaultEncoding && interp->fscodec_initialized) {
return PyUnicode_AsEncodedString(unicode,
Py_FileSystemDefaultEncoding,
Py_FileSystemDefaultEncodeErrors);
}
else {
return unicode_encode_locale(unicode,
Py_FileSystemDefaultEncodeErrors, 0);
}
#endif
}
PyObject *
PyUnicode_AsEncodedString(PyObject *unicode,
const char *encoding,
const char *errors)
{
PyObject *v;
char buflower[11]; /* strlen("iso_8859_1\0") == 11, longest shortcut */
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
return NULL;
}
if (encoding == NULL) {
return _PyUnicode_AsUTF8String(unicode, errors);
}
/* Shortcuts for common default encodings */
if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) {
char *lower = buflower;
/* Fast paths */
if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') {
lower += 3;
if (*lower == '_') {
/* Match "utf8" and "utf_8" */
lower++;
}
if (lower[0] == '8' && lower[1] == 0) {
return _PyUnicode_AsUTF8String(unicode, errors);
}
else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) {
return _PyUnicode_EncodeUTF16(unicode, errors, 0);
}
else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) {
return _PyUnicode_EncodeUTF32(unicode, errors, 0);
}
}
else {
if (strcmp(lower, "ascii") == 0
|| strcmp(lower, "us_ascii") == 0) {
return _PyUnicode_AsASCIIString(unicode, errors);
}
#ifdef MS_WINDOWS
else if (strcmp(lower, "mbcs") == 0) {
return PyUnicode_EncodeCodePage(CP_ACP, unicode, errors);
}
#endif
else if (strcmp(lower, "latin1") == 0 ||
strcmp(lower, "latin_1") == 0 ||
strcmp(lower, "iso_8859_1") == 0 ||
strcmp(lower, "iso8859_1") == 0) {
return _PyUnicode_AsLatin1String(unicode, errors);
}
}
}
/* Encode via the codec registry */
v = _PyCodec_EncodeText(unicode, encoding, errors);
if (v == NULL)
return NULL;
/* The normal path */
if (PyBytes_Check(v))
return v;