From a7b654be305dc0be1cbe521eb8a3d05489de975c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 3 May 2012 23:58:55 +0200 Subject: [PATCH] unicode_writer: add finish() method and assertions to write_str() method * The write_str() method does nothing if the length is zero. * Replace "struct unicode_writer_t" with "unicode_writer_t" --- Objects/unicodeobject.c | 46 +++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d816a46549..d290da6cfa 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13656,16 +13656,16 @@ formatchar(PyObject *v) return (Py_UCS4) -1; } -struct unicode_writer_t { +typedef struct { PyObject *buffer; void *data; enum PyUnicode_Kind kind; Py_UCS4 maxchar; Py_ssize_t pos; -}; +} unicode_writer_t; Py_LOCAL_INLINE(void) -unicode_writer_update(struct unicode_writer_t *writer) +unicode_writer_update(unicode_writer_t *writer) { writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer); writer->data = PyUnicode_DATA(writer->buffer); @@ -13673,7 +13673,7 @@ unicode_writer_update(struct unicode_writer_t *writer) } Py_LOCAL_INLINE(int) -unicode_writer_init(struct unicode_writer_t *writer, +unicode_writer_init(unicode_writer_t *writer, Py_ssize_t length, Py_UCS4 maxchar) { writer->pos = 0; @@ -13685,7 +13685,7 @@ unicode_writer_init(struct unicode_writer_t *writer, } Py_LOCAL_INLINE(int) -unicode_writer_prepare(struct unicode_writer_t *writer, +unicode_writer_prepare(unicode_writer_t *writer, Py_ssize_t length, Py_UCS4 maxchar) { Py_ssize_t newlen; @@ -13729,13 +13729,26 @@ unicode_writer_prepare(struct unicode_writer_t *writer, Py_LOCAL_INLINE(int) unicode_writer_write_str( - struct unicode_writer_t *writer, + unicode_writer_t *writer, PyObject *str, Py_ssize_t start, Py_ssize_t length) { Py_UCS4 maxchar; + + assert(str != NULL); + assert(PyUnicode_Check(str)); + if (PyUnicode_READY(str) == -1) + return -1; + + assert(0 <= start); + assert(0 <= length); + assert(start + length <= PyUnicode_GET_LENGTH(str)); + if (length == 0) + return 0; + maxchar = _PyUnicode_FindMaxChar(str, start, start + length); if (unicode_writer_prepare(writer, length, maxchar) == -1) return -1; + assert((writer->pos + length) <= PyUnicode_GET_LENGTH(writer->buffer)); copy_characters(writer->buffer, writer->pos, str, start, length); @@ -13745,7 +13758,7 @@ unicode_writer_write_str( Py_LOCAL_INLINE(int) unicode_writer_write_char( - struct unicode_writer_t *writer, + unicode_writer_t *writer, Py_UCS4 ch) { if (unicode_writer_prepare(writer, 1, ch) == -1) @@ -13756,8 +13769,18 @@ unicode_writer_write_char( return 0; } +Py_LOCAL_INLINE(PyObject *) +unicode_writer_finish(unicode_writer_t *writer) +{ + if (PyUnicode_Resize(&writer->buffer, writer->pos) < 0) { + Py_DECREF(writer->buffer); + return NULL; + } + return writer->buffer; +} + Py_LOCAL_INLINE(void) -unicode_writer_dealloc(struct unicode_writer_t *writer) +unicode_writer_dealloc(unicode_writer_t *writer) { Py_CLEAR(writer->buffer); } @@ -13773,7 +13796,7 @@ PyUnicode_Format(PyObject *format, PyObject *args) PyObject *uformat; void *fmt; enum PyUnicode_Kind kind, fmtkind; - struct unicode_writer_t writer; + unicode_writer_t writer; if (format == NULL || args == NULL) { PyErr_BadInternalCall(); @@ -14185,16 +14208,13 @@ PyUnicode_Format(PyObject *format, PyObject *args) goto onError; } - if (PyUnicode_Resize(&writer.buffer, writer.pos) < 0) - goto onError; - if (args_owned) { Py_DECREF(args); } Py_DECREF(uformat); Py_XDECREF(temp); Py_XDECREF(second); - return writer.buffer; + return unicode_writer_finish(&writer); onError: Py_DECREF(uformat); -- 2.40.0