Commit a7b654be authored by Victor Stinner's avatar Victor Stinner

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"
parent b1454480
...@@ -13656,16 +13656,16 @@ formatchar(PyObject *v) ...@@ -13656,16 +13656,16 @@ formatchar(PyObject *v)
return (Py_UCS4) -1; return (Py_UCS4) -1;
} }
struct unicode_writer_t { typedef struct {
PyObject *buffer; PyObject *buffer;
void *data; void *data;
enum PyUnicode_Kind kind; enum PyUnicode_Kind kind;
Py_UCS4 maxchar; Py_UCS4 maxchar;
Py_ssize_t pos; Py_ssize_t pos;
}; } unicode_writer_t;
Py_LOCAL_INLINE(void) 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->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer);
writer->data = PyUnicode_DATA(writer->buffer); writer->data = PyUnicode_DATA(writer->buffer);
...@@ -13673,7 +13673,7 @@ unicode_writer_update(struct unicode_writer_t *writer) ...@@ -13673,7 +13673,7 @@ unicode_writer_update(struct unicode_writer_t *writer)
} }
Py_LOCAL_INLINE(int) 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) Py_ssize_t length, Py_UCS4 maxchar)
{ {
writer->pos = 0; writer->pos = 0;
...@@ -13685,7 +13685,7 @@ unicode_writer_init(struct unicode_writer_t *writer, ...@@ -13685,7 +13685,7 @@ unicode_writer_init(struct unicode_writer_t *writer,
} }
Py_LOCAL_INLINE(int) 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 length, Py_UCS4 maxchar)
{ {
Py_ssize_t newlen; Py_ssize_t newlen;
...@@ -13729,13 +13729,26 @@ unicode_writer_prepare(struct unicode_writer_t *writer, ...@@ -13729,13 +13729,26 @@ unicode_writer_prepare(struct unicode_writer_t *writer,
Py_LOCAL_INLINE(int) Py_LOCAL_INLINE(int)
unicode_writer_write_str( unicode_writer_write_str(
struct unicode_writer_t *writer, unicode_writer_t *writer,
PyObject *str, Py_ssize_t start, Py_ssize_t length) PyObject *str, Py_ssize_t start, Py_ssize_t length)
{ {
Py_UCS4 maxchar; 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); maxchar = _PyUnicode_FindMaxChar(str, start, start + length);
if (unicode_writer_prepare(writer, length, maxchar) == -1) if (unicode_writer_prepare(writer, length, maxchar) == -1)
return -1; return -1;
assert((writer->pos + length) <= PyUnicode_GET_LENGTH(writer->buffer)); assert((writer->pos + length) <= PyUnicode_GET_LENGTH(writer->buffer));
copy_characters(writer->buffer, writer->pos, copy_characters(writer->buffer, writer->pos,
str, start, length); str, start, length);
...@@ -13745,7 +13758,7 @@ unicode_writer_write_str( ...@@ -13745,7 +13758,7 @@ unicode_writer_write_str(
Py_LOCAL_INLINE(int) Py_LOCAL_INLINE(int)
unicode_writer_write_char( unicode_writer_write_char(
struct unicode_writer_t *writer, unicode_writer_t *writer,
Py_UCS4 ch) Py_UCS4 ch)
{ {
if (unicode_writer_prepare(writer, 1, ch) == -1) if (unicode_writer_prepare(writer, 1, ch) == -1)
...@@ -13756,8 +13769,18 @@ unicode_writer_write_char( ...@@ -13756,8 +13769,18 @@ unicode_writer_write_char(
return 0; 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) Py_LOCAL_INLINE(void)
unicode_writer_dealloc(struct unicode_writer_t *writer) unicode_writer_dealloc(unicode_writer_t *writer)
{ {
Py_CLEAR(writer->buffer); Py_CLEAR(writer->buffer);
} }
...@@ -13773,7 +13796,7 @@ PyUnicode_Format(PyObject *format, PyObject *args) ...@@ -13773,7 +13796,7 @@ PyUnicode_Format(PyObject *format, PyObject *args)
PyObject *uformat; PyObject *uformat;
void *fmt; void *fmt;
enum PyUnicode_Kind kind, fmtkind; enum PyUnicode_Kind kind, fmtkind;
struct unicode_writer_t writer; unicode_writer_t writer;
if (format == NULL || args == NULL) { if (format == NULL || args == NULL) {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
...@@ -14185,16 +14208,13 @@ PyUnicode_Format(PyObject *format, PyObject *args) ...@@ -14185,16 +14208,13 @@ PyUnicode_Format(PyObject *format, PyObject *args)
goto onError; goto onError;
} }
if (PyUnicode_Resize(&writer.buffer, writer.pos) < 0)
goto onError;
if (args_owned) { if (args_owned) {
Py_DECREF(args); Py_DECREF(args);
} }
Py_DECREF(uformat); Py_DECREF(uformat);
Py_XDECREF(temp); Py_XDECREF(temp);
Py_XDECREF(second); Py_XDECREF(second);
return writer.buffer; return unicode_writer_finish(&writer);
onError: onError:
Py_DECREF(uformat); Py_DECREF(uformat);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment