Skip to content
Permalink
master
Go to file
100 contributors

Users who have contributed to this file

@vstinner @serhiy-storchaka @benjaminp @gvanrossum @pitrou @malemburg @doerwalter @loewis @tiran @birkenfeld @tim-one @ezio-melotti
16272 lines (14438 sloc) 471 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 "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_bytes_methods.h" // _Py_bytes_lower()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_interp.h" // PyInterpreterState.fs_codec
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_pathconfig.h" // _Py_DumpPathConfig()
#include "pycore_pylifecycle.h" // _Py_SetFileSystemEncoding()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "ucnhash.h" // _PyUnicode_Name_CAPI
#include "stringlib/eq.h" // unicode_eq()
#ifdef MS_WINDOWS
#include <windows.h>
#endif
/* Uncomment to display statistics on interned strings at exit
in _PyUnicode_ClearInterned(). */
/* #define INTERNED_STATS 1 */
/*[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)
/* Don't use deprecated macro of unicodeobject.h */
#undef PyUnicode_WSTR_LENGTH
#define PyUnicode_WSTR_LENGTH(op) \
(PyUnicode_IS_COMPACT_ASCII(op) ? \
((PyASCIIObject*)op)->length : \
((PyCompactUnicodeObject*)op)->wstr_length)
#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 = (const from_type *)(begin);\
const from_type *_end = (const 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
/* bpo-40521: Interned strings are shared by all interpreters. */
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
# define INTERNED_STRINGS
#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)
*/
#ifdef INTERNED_STRINGS
static PyObject *interned = NULL;
#endif
static struct _Py_unicode_state*
get_unicode_state(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return &interp->unicode;
}
// Return a borrowed reference to the empty string singleton.
static inline PyObject* unicode_get_empty(void)
{
struct _Py_unicode_state *state = get_unicode_state();
// unicode_get_empty() must not be called before _PyUnicode_Init()
// or after _PyUnicode_Fini()
assert(state->empty_string != NULL);
return state->empty_string;
}
// Return a strong reference to the empty string singleton.
static inline PyObject* unicode_new_empty(void)
{
PyObject *empty = unicode_get_empty();
Py_INCREF(empty);
return empty;
}
#define _Py_RETURN_UNICODE_EMPTY() \
do { \
return unicode_new_empty(); \
} while (0)
static inline void
unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value,
Py_ssize_t start, Py_ssize_t length)
{
assert(0 <= start);
assert(kind != PyUnicode_WCHAR_KIND);
switch (kind) {
case PyUnicode_1BYTE_KIND: {
assert(value <= 0xff);
Py_UCS1 ch = (unsigned char)value;
Py_UCS1 *to = (Py_UCS1 *)data + start;
memset(to, ch, length);
break;
}
case PyUnicode_2BYTE_KIND: {
assert(value <= 0xffff);
Py_UCS2 ch = (Py_UCS2)value;
Py_UCS2 *to = (Py_UCS2 *)data + start;
const Py_UCS2 *end = to + length;
for (; to < end; ++to) *to = ch;
break;
}
case PyUnicode_4BYTE_KIND: {
assert(value <= MAX_UNICODE);
Py_UCS4 ch = value;
Py_UCS4 * to = (Py_UCS4 *)data + start;
const Py_UCS4 *end = to + length;
for (; to < end; ++to) *to = ch;
break;
}
default: Py_UNREACHABLE();
}
}
/* Forward declaration */
static inline int
_PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch);
static inline void
_PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer);
static PyObject *
unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler,
const char *errors);
static PyObject *
unicode_decode_utf8(const char *s, Py_ssize_t size,
_Py_error_handler error_handler, const char *errors,
Py_ssize_t *consumed);
/* List of static strings. */
static _Py_Identifier *static_strings = 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"
_Py_error_handler
_Py_GetErrorHandler(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;
}
static _Py_error_handler
get_error_handler_wide(const wchar_t *errors)
{
if (errors == NULL || wcscmp(errors, L"strict") == 0) {
return _Py_ERROR_STRICT;
}
if (wcscmp(errors, L"surrogateescape") == 0) {
return _Py_ERROR_SURROGATEESCAPE;
}
if (wcscmp(errors, L"replace") == 0) {
return _Py_ERROR_REPLACE;
}
if (wcscmp(errors, L"ignore") == 0) {
return _Py_ERROR_IGNORE;
}
if (wcscmp(errors, L"backslashreplace") == 0) {
return _Py_ERROR_BACKSLASHREPLACE;
}
if (wcscmp(errors, L"surrogatepass") == 0) {
return _Py_ERROR_SURROGATEPASS;
}
if (wcscmp(errors, L"xmlcharrefreplace") == 0) {
return _Py_ERROR_XMLCHARREFREPLACE;
}
return _Py_ERROR_OTHER;
}
static inline int
unicode_check_encoding_errors(const char *encoding, const char *errors)
{
if (encoding == NULL && errors == NULL) {
return 0;
}
PyInterpreterState *interp = _PyInterpreterState_GET();
#ifndef Py_DEBUG
/* In release mode, only check in development mode (-X dev) */
if (!_PyInterpreterState_GetConfig(interp)->dev_mode) {
return 0;
}
#else
/* Always check in debug mode */
#endif
/* Avoid calling _PyCodec_Lookup() and PyCodec_LookupError() before the
codec registry is ready: before_PyUnicode_InitEncodings() is called. */
if (!interp->unicode.fs_codec.encoding) {
return 0;
}
/* Disable checks during Python finalization. For example, it allows to
call _PyObject_Dump() during finalization for debugging purpose. */
if (interp->finalizing) {
return 0;
}
if (encoding != NULL) {
PyObject *handler = _PyCodec_Lookup(encoding);
if (handler == NULL) {
return -1;
}
Py_DECREF(handler);
}
if (errors != NULL) {
PyObject *handler = PyCodec_LookupError(errors);
if (handler == NULL) {
return -1;
}
Py_DECREF(handler);
}
return 0;
}
int
_PyUnicode_CheckConsistency(PyObject *op, int check_content)
{
#define CHECK(expr) \
do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
PyASCIIObject *ascii;
unsigned int kind;
assert(op != NULL);
CHECK(PyUnicode_Check(op));
ascii = (PyASCIIObject *)op;
kind = ascii->state.kind;
if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
CHECK(kind == PyUnicode_1BYTE_KIND);
CHECK(ascii->state.ready == 1);
}
else {
PyCompactUnicodeObject *compact = (PyCompactUnicodeObject *)op;
void *data;
if (ascii->state.compact == 1) {
data = compact + 1;
CHECK(kind == PyUnicode_1BYTE_KIND
|| kind == PyUnicode_2BYTE_KIND
|| kind == PyUnicode_4BYTE_KIND);
CHECK(ascii->state.ascii == 0);
CHECK(ascii->state.ready == 1);
CHECK(compact->utf8 != data);
}
else {
PyUnicodeObject *unicode = (PyUnicodeObject *)op;
data = unicode->data.any;
if (kind == PyUnicode_WCHAR_KIND) {
CHECK(ascii->length == 0);
CHECK(ascii->hash == -1);
CHECK(ascii->state.compact == 0);
CHECK(ascii->state.ascii == 0);
CHECK(ascii->state.ready == 0);
CHECK(ascii->state.interned == SSTATE_NOT_INTERNED);
CHECK(ascii->wstr != NULL);
CHECK(data == NULL);
CHECK(compact->utf8 == NULL);
}
else {
CHECK(kind == PyUnicode_1BYTE_KIND
|| kind == PyUnicode_2BYTE_KIND
|| kind == PyUnicode_4BYTE_KIND);
CHECK(ascii->state.compact == 0);
CHECK(ascii->state.ready == 1);
CHECK(data != NULL);
if (ascii->state.ascii) {
CHECK(compact->utf8 == data);
CHECK(compact->utf8_length == ascii->length);
}
else
CHECK(compact->utf8 != data);
}
}
if (kind != PyUnicode_WCHAR_KIND) {
if (
#if SIZEOF_WCHAR_T == 2
kind == PyUnicode_2BYTE_KIND
#else
kind == PyUnicode_4BYTE_KIND
#endif
)
{
CHECK(ascii->wstr == data);
CHECK(compact->wstr_length == ascii->length);
} else
CHECK(ascii->wstr != data);
}
if (compact->utf8 == NULL)
CHECK(compact->utf8_length == 0);
if (ascii->wstr == NULL)
CHECK(compact->wstr_length == 0);
}
/* check that the best kind is used: O(n) operation */
if (check_content && kind != PyUnicode_WCHAR_KIND) {
Py_ssize_t i;
Py_UCS4 maxchar = 0;
const 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) {
CHECK(maxchar >= 128);
CHECK(maxchar <= 255);
}
else
CHECK(maxchar < 128);
}
else if (kind == PyUnicode_2BYTE_KIND) {
CHECK(maxchar >= 0x100);
CHECK(maxchar <= 0xFFFF);
}
else {
CHECK(maxchar >= 0x10000);
CHECK(maxchar <= MAX_UNICODE);
}
CHECK(PyUnicode_READ(kind, data, ascii->length) == 0);
}
return 1;
#undef CHECK
}
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) {
Py_DECREF(unicode);
return get_latin1_char((unsigned char)ch);
}
}
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) {
PyObject *empty = unicode_get_empty();
if (unicode != empty) {
Py_DECREF(unicode);
Py_INCREF(empty);
}
return empty;
}
if (length == 1) {
int kind = PyUnicode_KIND(unicode);
if (kind == PyUnicode_1BYTE_KIND) {
Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode);
Py_UCS1 ch = data[0];
struct _Py_unicode_state *state = get_unicode_state();
PyObject *latin1_char = state->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);
state->latin1[ch] = unicode;
return unicode;
}
}
else {
assert(PyUnicode_READ_CHAR(unicode, 0) >= 256);
}
}
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;
const 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;
const 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 _PyUnicode_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, const 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 */
#define STRINGLIB_GET_EMPTY() unicode_get_empty()
#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/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/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/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/undef.h"
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
#include "stringlib/unicodedefs.h"
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/undef.h"
_Py_COMP_DIAG_POP
#undef STRINGLIB_GET_EMPTY
/* --- 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((const Py_UCS1 *) s, size, (Py_UCS1) ch);
else
return ucs1lib_rfind_char((const 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((const Py_UCS2 *) s, size, (Py_UCS2) ch);
else
return ucs2lib_rfind_char((const Py_UCS2 *) s, size, (Py_UCS2) ch);
case PyUnicode_4BYTE_KIND:
if (direction > 0)
return ucs4lib_find_char((const Py_UCS4 *) s, size, ch);
else
return ucs4lib_rfind_char((const 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;
}
#ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
#ifdef Py_TRACE_REFS
_Py_ForgetReference(unicode);
#endif
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) {
return (PyUnicodeObject *)unicode_new_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 */
const char *_PyUnicode_utf8(void *unicode_raw){
PyObject *unicode = _PyObject_CAST(unicode_raw);
return PyUnicode_UTF8(unicode);
}
const void *_PyUnicode_compact_data(void *unicode_raw) {
PyObject *unicode = _PyObject_CAST(unicode_raw);
return _PyUnicode_COMPACT_DATA(unicode);
}
const void *_PyUnicode_data(void *unicode_raw) {
PyObject *unicode = _PyObject_CAST(unicode_raw);
printf("obj %p\n", (void*)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;
const 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=%zu, ", unicode_kind_name(op), ascii->length);
if (ascii->wstr == data)
printf("shared ");
printf("wstr=%p", (void *)ascii->wstr);
if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) {
printf(" (%zu), ", compact->wstr_length);
if (!ascii->state.compact && compact->utf8 == unicode->data.any) {
printf("shared ");
}
printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length);
}
printf(", data=%p\n", data);
}
#endif
static int
unicode_create_empty_string_singleton(struct _Py_unicode_state *state)
{
// Use size=1 rather than size=0, so PyUnicode_New(0, maxchar) can be
// optimized to always use state->empty_string without having to check if
// it is NULL or not.
PyObject *empty = PyUnicode_New(1, 0);
if (empty == NULL) {
return -1;
}
PyUnicode_1BYTE_DATA(empty)[0] = 0;
_PyUnicode_LENGTH(empty) = 0;
assert(_PyUnicode_CheckConsistency(empty, 1));
assert(state->empty_string == NULL);
state->empty_string = empty;
return 0;
}
PyObject *
PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
{
/* Optimization for empty strings */
if (size == 0) {
return unicode_new_empty();
}
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;
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();
}
_PyObject_Init(obj, &PyUnicode_Type);
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;
const void *from_data;
void *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))
{
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,
(const Py_UCS1*)from_data + how_many);
if (max_char >= 128)
return -1;
}
memcpy((char*)to_data + to_kind * to_start,
(const 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:
#ifdef INTERNED_STRINGS
/* Revive the dead object temporarily. PyDict_DelItem() removes two
references (key and value) which were ignored by
PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2
to prevent calling unicode_dealloc() again. Adjust refcnt after
PyDict_DelItem(). */
assert(Py_REFCNT(unicode) == 0);
Py_SET_REFCNT(unicode, 3);
if (PyDict_DelItem(interned, unicode) != 0) {
_PyErr_WriteUnraisableMsg("deletion of interned string failed",
NULL);
}
assert(Py_REFCNT(unicode) == 1);
Py_SET_REFCNT(unicode, 0);
#endif
break;
case SSTATE_INTERNED_IMMORTAL:
_PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died");
break;
default:
Py_UNREACHABLE();
}
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)
{
struct _Py_unicode_state *state = get_unicode_state();
if (unicode == state->empty_string) {
return 1;
}
PyASCIIObject *ascii = (PyASCIIObject *)unicode;
if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1)
{
Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0);
if (ch < 256 && state->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) {
PyObject *empty = unicode_new_empty();
Py_SETREF(*p_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);
const void *data = PyUnicode_DATA(unicode);
const char *end = str + len;
assert(index + len <= PyUnicode_GET_LENGTH(unicode));
switch (kind) {
case PyUnicode_1BYTE_KIND: {
#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;
for (; str < end; ++ucs2, ++str)
*ucs2 = (Py_UCS2)*str;
assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
break;
}
case PyUnicode_4BYTE_KIND: {
Py_UCS4 *start = (Py_UCS4 *)data + index;
Py_UCS4 *ucs4 = start;
for (; str < end; ++ucs4, ++str)
*ucs4 = (Py_UCS4)*str;
assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
break;
}
default:
Py_UNREACHABLE();
}
}
static PyObject*
get_latin1_char(Py_UCS1 ch)
{
struct _Py_unicode_state *state = get_unicode_state();
PyObject *unicode = state->latin1[ch];
if (unicode) {
Py_INCREF(unicode);
return unicode;
}
unicode = PyUnicode_New(1, ch);
if (!unicode) {
return NULL;
}
PyUnicode_1BYTE_DATA(unicode)[0] = ch;
assert(_PyUnicode_CheckConsistency(unicode, 1));
Py_INCREF(unicode);
state->latin1[ch] = 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) {
if (size > 0) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyUnicode_FromUnicode(NULL, size) is deprecated; "
"use PyUnicode_New() instead", 1) < 0) {
return 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 {
if (size > 0) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PyUnicode_FromStringAndSize(NULL, size) is deprecated; "
"use PyUnicode_New() instead", 1) < 0) {
return NULL;
}
}
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) {
return id->object;
}
PyObject *obj;
obj = PyUnicode_DecodeUTF8Stateful(id->string,
strlen(id->string),
NULL, NULL);
if (!obj) {
return NULL;
}
PyUnicode_InternInPlace(&obj);
assert(!id->next);
id->object = obj;
id->next = static_strings;
static_strings = id;
return id->object;
}
static void
unicode_clear_static_strings(void)
{
_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;
const 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 if (kind == PyUnicode_4BYTE_KIND) {
const Py_UCS4 *u = PyUnicode_4BYTE_DATA(unicode);
max_char = ucs4lib_find_max_char(u, u + len);
if (max_char >= 0x10000)
return;
}
else
Py_UNREACHABLE();
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. */
static void*
unicode_askind(unsigned int skind, void const *data, Py_ssize_t len, unsigned int kind)
{
void *result;
assert(skind < kind);
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,
(const Py_UCS1 *)data,
((const Py_UCS1 *)data) + 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,
(const Py_UCS2 *)data,
((const Py_UCS2 *)data) + len,
result);
}
else {
assert(skind == PyUnicode_1BYTE_KIND);
_PyUnicode_CONVERT_BYTES(
Py_UCS1, Py_UCS4,
(const Py_UCS1 *)data,
((const Py_UCS1 *)data) + len,
result);
}
return result;
default:
Py_UNREACHABLE();
return NULL;
}
}
static Py_UCS4*
as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize,
int copy_null)
{
int kind;
const 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) {
const Py_UCS1 *start = (const Py_UCS1 *) data;
_PyUnicode_CONVERT_BYTES(Py_UCS1, Py_UCS4, start, start + len, target);
}
else if (kind == PyUnicode_2BYTE_KIND) {
const Py_UCS2 *start = (const Py_UCS2 *) data;
_PyUnicode_CONVERT_BYTES(Py_UCS2, Py_UCS4, start, start + len, target);
}
else if (kind == PyUnicode_4BYTE_KIND) {
memcpy(target, data, len * sizeof(Py_UCS4));
}
else {
Py_UNREACHABLE();
}
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;
if (precision == -1) {
length = strlen(str);
}
else {
length = 0;
while (length < precision && str[length]) {
length++;
}
}
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, "%zu", 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, "%zi", 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;
}
static Py_ssize_t
unicode_get_widechar_size(PyObject *unicode)
{
Py_ssize_t res;
assert(unicode != NULL);
assert(_PyUnicode_CHECK(unicode));
#if USE_UNICODE_WCHAR_CACHE
if (_PyUnicode_WSTR(unicode) != NULL) {
return PyUnicode_WSTR_LENGTH(unicode);
}
#endif /* USE_UNICODE_WCHAR_CACHE */
assert(PyUnicode_IS_READY(unicode));
res = _PyUnicode_LENGTH(unicode);
#if SIZEOF_WCHAR_T == 2
if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) {
const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode);
const Py_UCS4 *end = s + res;
for (; s < end; ++s) {
if (*s > 0xFFFF) {
++res;
}
}
}
#endif
return res;
}
static void
unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size)
{
assert(unicode != NULL);
assert(_PyUnicode_CHECK(unicode));
#if USE_UNICODE_WCHAR_CACHE
const wchar_t *wstr = _PyUnicode_WSTR(unicode);
if (wstr != NULL) {
memcpy(w, wstr, size * sizeof(wchar_t));
return;
}
#else /* USE_UNICODE_WCHAR_CACHE */
if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) {
memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t));
return;
}
#endif /* USE_UNICODE_WCHAR_CACHE */
assert(PyUnicode_IS_READY(unicode));
if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) {
const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode);
for (; size--; ++s, ++w) {
*w = *s;
}
}
else {
#if SIZEOF_WCHAR_T == 4
assert(PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND);
const Py_UCS2 *s = PyUnicode_2BYTE_DATA(unicode);
for (; size--; ++s, ++w) {
*w = *s;
}
#else
assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode);
for (; size--; ++s, ++w) {
Py_UCS4 ch = *s;
if (ch > 0xFFFF) {
assert(ch <= MAX_UNICODE);
/* encode surrogate pair in this case */
*w++ = Py_UNICODE_HIGH_SURROGATE(ch);
if (!size--)
break;
*w = Py_UNICODE_LOW_SURROGATE(ch);
}
else {
*w = ch;
}
}
#endif
}
}
#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;
if (unicode == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
return -1;
}
res = unicode_get_widechar_size(unicode);
if (w == NULL) {
return res + 1;
}
if (size > res) {
size = res + 1;
}
else {
res = size;
}
unicode_copy_as_widechar(unicode, w, size);
return res;
}
wchar_t*
PyUnicode_AsWideCharString(PyObject *unicode,
Py_ssize_t *size)
{
wchar_t *buffer;
Py_ssize_t buflen;
if (unicode == NULL) {
PyErr_BadInternalCall();
return NULL;
}
if (!PyUnicode_Check(unicode)) {
PyErr_BadArgument();
return NULL;
}
buflen = unicode_get_widechar_size(unicode);
buffer = (wchar_t *) PyMem_NEW(wchar_t, (buflen + 1));
if (buffer == NULL) {
PyErr_NoMemory();
return NULL;
}
unicode_copy_as_widechar(unicode, buffer, buflen + 1);
if (size != NULL) {
*size = buflen;
}
else if (wcslen(buffer) != (size_t)buflen) {
PyMem_FREE(buffer);
PyErr_SetString(PyExc_ValueError,
"embedded null character");
return NULL;
}
return buffer;
}
#endif /* HAVE_WCHAR_H */
int
_PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr)
{
wchar_t **p = (wchar_t **)ptr;
if (obj == NULL) {
#if !USE_UNICODE_WCHAR_CACHE
PyMem_Free(*p);
#endif /* USE_UNICODE_WCHAR_CACHE */
*p = NULL;
return 1;
}
if (PyUnicode_Check(obj)) {
#if USE_UNICODE_WCHAR_CACHE
*p = (wchar_t *)_PyUnicode_AsUnicode(obj);
if (*p == NULL) {
return 0;
}
return 1;
#else /* USE_UNICODE_WCHAR_CACHE */
*p = PyUnicode_AsWideCharString(obj, NULL);
if (*p == NULL) {
return 0;
}
return Py_CLEANUP_SUPPORTED;
#endif /* USE_UNICODE_WCHAR_CACHE */
}
PyErr_Format(PyExc_TypeError,
"argument must be str, not %.50s",
Py_TYPE(obj)->tp_name);
return 0;
}
int
_PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr)
{
wchar_t **p = (wchar_t **)ptr;
if (obj == NULL) {
#if !USE_UNICODE_WCHAR_CACHE
PyMem_Free(*p);
#endif /* USE_UNICODE_WCHAR_CACHE */
*p = NULL;
return 1;
}
if (obj == Py_None) {
*p = NULL;
return 1;
}
if (PyUnicode_Check(obj)) {
#if USE_UNICODE_WCHAR_CACHE
*p = (wchar_t *)_PyUnicode_AsUnicode(obj);
if (*p == NULL) {
return 0;
}
return 1;
#else /* USE_UNICODE_WCHAR_CACHE */
*p = PyUnicode_AsWideCharString(obj, NULL);
if (*p == NULL) {
return 0;
}
return Py_CLEANUP_SUPPORTED;
#endif /* USE_UNICODE_WCHAR_CACHE */
}
PyErr_Format(PyExc_TypeError,
"argument must be str or None, not %.50s",
Py_TYPE(obj)->tp_name);
return 0;
}
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) {
if (unicode_check_encoding_errors(encoding, errors) < 0) {
return NULL;
}
_Py_RETURN_UNICODE_EMPTY();
}
return PyUnicode_Decode(
PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj),
encoding, errors);
}
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);
if (unicode_check_encoding_errors(encoding, errors) < 0) {
return NULL;
}
_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 (unicode_check_encoding_errors(encoding, errors) < 0) {
return NULL;
}
if (size == 0) {
_Py_RETURN_UNICODE_EMPTY();
}
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 PyObject *
unicode_encode_locale(PyObject *unicode, _Py_error_handler error_handler,
int current_locale)
{
Py_ssize_t wlen;
wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &wlen);
if (wstr == NULL) {
return NULL;
}
if ((size_t)wlen != wcslen(wstr)) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
PyMem_Free(wstr);
return NULL;
}
char *str;
size_t error_pos;
const char *reason;
int res = _Py_EncodeLocaleEx(wstr, &str, &error_pos, &reason,
current_locale, error_handler);
PyMem_Free(wstr);
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);
}
}
else if (res == -3) {
PyErr_SetString(PyExc_ValueError, "unsupported error handler");
}
else {
PyErr_NoMemory();
}
return NULL;
}
PyObject *bytes = PyBytes_FromString(str);
PyMem_RawFree(str);
return bytes;
}
PyObject *
PyUnicode_EncodeLocale(PyObject *unicode, const char *errors)
{
_Py_error_handler error_handler = _Py_GetErrorHandler(errors);
return unicode_encode_locale(unicode, error_handler, 1);
}
PyObject *
PyUnicode_EncodeFSDefault(PyObject *unicode)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
struct _Py_unicode_fs_codec *fs_codec = &interp->unicode.fs_codec;
if (fs_codec->utf8) {
return unicode_encode_utf8(unicode,
fs_codec->error_handler,
fs_codec->errors);
}
#ifndef _Py_FORCE_UTF8_FS_ENCODING
else if (fs_codec->encoding) {
return PyUnicode_AsEncodedString(unicode,
fs_codec->encoding,
fs_codec->errors);
}
#endif
else {
/* Before _PyUnicode_InitEncodings() is called, the Python codec
machinery is not ready and so cannot be used:
use wcstombs() in this case. */
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
const wchar_t *filesystem_errors = config->filesystem_errors;
assert(filesystem_errors != NULL);
_Py_error_handler errors = get_error_handler_wide(filesystem_errors);
assert(errors != _Py_ERROR_UNKNOWN);
#ifdef _Py_FORCE_UTF8_FS_ENCODING
return unicode_encode_utf8(unicode, errors, NULL);
#else
return unicode_encode_locale(unicode, errors, 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 (unicode_check_encoding_errors(encoding, errors) < 0) {
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) {