Coverage Report

Created: 2026-09-03 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Objects/unicode_writer.c
Line
Count
Source
1
/*
2
3
Unicode implementation based on original code by Fredrik Lundh,
4
modified by Marc-Andre Lemburg <mal@lemburg.com>.
5
6
Major speed upgrades to the method implementations at the Reykjavik
7
NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke.
8
9
Copyright (c) Corporation for National Research Initiatives.
10
11
--------------------------------------------------------------------
12
The original string type implementation is:
13
14
  Copyright (c) 1999 by Secret Labs AB
15
  Copyright (c) 1999 by Fredrik Lundh
16
17
By obtaining, using, and/or copying this software and/or its
18
associated documentation, you agree that you have read, understood,
19
and will comply with the following terms and conditions:
20
21
Permission to use, copy, modify, and distribute this software and its
22
associated documentation for any purpose and without fee is hereby
23
granted, provided that the above copyright notice appears in all
24
copies, and that both that copyright notice and this permission notice
25
appear in supporting documentation, and that the name of Secret Labs
26
AB or the author not be used in advertising or publicity pertaining to
27
distribution of the software without specific, written prior
28
permission.
29
30
SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
31
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
32
FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
33
ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
34
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
35
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
36
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
37
--------------------------------------------------------------------
38
39
*/
40
41
#include "Python.h"
42
#include "pycore_freelist.h"      // _Py_FREELIST_FREE()
43
#include "pycore_long.h"          // _PyLong_FormatWriter()
44
#include "pycore_unicodeobject.h" // _PyUnicode_Result()
45
46
47
#ifdef MS_WINDOWS
48
   /* On Windows, overallocate by 50% is the best factor */
49
#  define OVERALLOCATE_FACTOR 2
50
#else
51
   /* On Linux, overallocate by 25% is the best factor */
52
3.44M
#  define OVERALLOCATE_FACTOR 4
53
#endif
54
55
56
/* Compilation of templated routines */
57
58
#define STRINGLIB_GET_EMPTY() _PyUnicode_GetEmpty()
59
60
#include "stringlib/ucs1lib.h"
61
#include "stringlib/find_max_char.h"
62
#include "stringlib/undef.h"
63
64
65
/* Copy an ASCII or latin1 char* string into a Python Unicode string.
66
67
   WARNING: The function doesn't copy the terminating null character and
68
   doesn't check the maximum character (may write a latin1 character in an
69
   ASCII string). */
70
static void
71
unicode_write_cstr(PyObject *unicode, Py_ssize_t index,
72
                   const char *str, Py_ssize_t len)
73
0
{
74
0
    int kind = PyUnicode_KIND(unicode);
75
0
    const void *data = PyUnicode_DATA(unicode);
76
0
    const char *end = str + len;
77
78
0
    assert(index + len <= PyUnicode_GET_LENGTH(unicode));
79
0
    switch (kind) {
80
0
    case PyUnicode_1BYTE_KIND: {
81
#ifdef Py_DEBUG
82
        if (PyUnicode_IS_ASCII(unicode)) {
83
            Py_UCS4 maxchar = ucs1lib_find_max_char(
84
                (const Py_UCS1*)str,
85
                (const Py_UCS1*)str + len);
86
            assert(maxchar < 128);
87
        }
88
#endif
89
0
        memcpy((char *) data + index, str, len);
90
0
        break;
91
0
    }
92
0
    case PyUnicode_2BYTE_KIND: {
93
0
        Py_UCS2 *start = (Py_UCS2 *)data + index;
94
0
        Py_UCS2 *ucs2 = start;
95
96
0
        for (; str < end; ++ucs2, ++str)
97
0
            *ucs2 = (Py_UCS2)*str;
98
99
0
        assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
100
0
        break;
101
0
    }
102
0
    case PyUnicode_4BYTE_KIND: {
103
0
        Py_UCS4 *start = (Py_UCS4 *)data + index;
104
0
        Py_UCS4 *ucs4 = start;
105
106
0
        for (; str < end; ++ucs4, ++str)
107
0
            *ucs4 = (Py_UCS4)*str;
108
109
0
        assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
110
0
        break;
111
0
    }
112
0
    default:
113
0
        Py_UNREACHABLE();
114
0
    }
115
0
}
116
117
118
static inline void
119
_PyUnicodeWriter_Update(_PyUnicodeWriter *writer)
120
2.42M
{
121
2.42M
    writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer);
122
2.42M
    writer->data = PyUnicode_DATA(writer->buffer);
123
124
2.42M
    if (!writer->readonly) {
125
2.39M
        writer->kind = PyUnicode_KIND(writer->buffer);
126
2.39M
        writer->size = PyUnicode_GET_LENGTH(writer->buffer);
127
2.39M
    }
128
27.8k
    else {
129
        /* use a value smaller than PyUnicode_1BYTE_KIND() so
130
           _PyUnicodeWriter_PrepareKind() will copy the buffer. */
131
27.8k
        writer->kind = 0;
132
27.8k
        assert(writer->kind <= PyUnicode_1BYTE_KIND);
133
134
        /* Copy-on-write mode: set buffer size to 0 so
135
         * _PyUnicodeWriter_Prepare() will copy (and enlarge) the buffer on
136
         * next write. */
137
27.8k
        writer->size = 0;
138
27.8k
    }
139
2.42M
}
140
141
142
void
143
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
144
1.78M
{
145
1.78M
    memset(writer, 0, sizeof(*writer));
146
147
    /* ASCII is the bare minimum */
148
1.78M
    writer->min_char = 127;
149
150
    /* use a kind value smaller than PyUnicode_1BYTE_KIND so
151
       _PyUnicodeWriter_PrepareKind() will copy the buffer. */
152
1.78M
    assert(writer->kind == 0);
153
1.78M
    assert(writer->kind < PyUnicode_1BYTE_KIND);
154
1.78M
}
155
156
157
PyUnicodeWriter*
158
PyUnicodeWriter_Create(Py_ssize_t length)
159
118k
{
160
118k
    if (length < 0) {
161
0
        PyErr_SetString(PyExc_ValueError,
162
0
                        "length must be positive");
163
0
        return NULL;
164
0
    }
165
166
118k
    const size_t size = sizeof(_PyUnicodeWriter);
167
118k
    PyUnicodeWriter *pub_writer;
168
118k
    pub_writer = _Py_FREELIST_POP_MEM(unicode_writers);
169
118k
    if (pub_writer == NULL) {
170
2.43k
        pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size);
171
2.43k
        if (pub_writer == NULL) {
172
0
            return (PyUnicodeWriter *)PyErr_NoMemory();
173
0
        }
174
2.43k
    }
175
118k
    _PyUnicodeWriter *writer = (_PyUnicodeWriter *)pub_writer;
176
177
118k
    _PyUnicodeWriter_Init(writer);
178
118k
    if (_PyUnicodeWriter_Prepare(writer, length, 127) < 0) {
179
0
        PyUnicodeWriter_Discard(pub_writer);
180
0
        return NULL;
181
0
    }
182
118k
    writer->overallocate = 1;
183
184
118k
    return pub_writer;
185
118k
}
186
187
188
void PyUnicodeWriter_Discard(PyUnicodeWriter *writer)
189
1.10k
{
190
1.10k
    if (writer == NULL) {
191
218
        return;
192
218
    }
193
884
    _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer);
194
884
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
195
884
}
196
197
198
// Initialize _PyUnicodeWriter with initial buffer
199
void
200
_PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer)
201
465k
{
202
465k
    memset(writer, 0, sizeof(*writer));
203
465k
    writer->buffer = buffer;
204
465k
    _PyUnicodeWriter_Update(writer);
205
465k
    writer->min_length = writer->size;
206
465k
}
207
208
209
int
210
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
211
                                 Py_ssize_t length, Py_UCS4 maxchar)
212
1.93M
{
213
1.93M
    Py_ssize_t newlen;
214
1.93M
    PyObject *newbuffer;
215
216
1.93M
    assert(length >= 0);
217
1.93M
    assert(maxchar <= _Py_MAX_UNICODE);
218
219
    /* ensure that the _PyUnicodeWriter_Prepare macro was used */
220
1.93M
    assert((maxchar > writer->maxchar && length >= 0)
221
1.93M
           || length > 0);
222
223
1.93M
    if (length > PY_SSIZE_T_MAX - writer->pos) {
224
0
        PyErr_NoMemory();
225
0
        return -1;
226
0
    }
227
1.93M
    newlen = writer->pos + length;
228
229
1.93M
    maxchar = Py_MAX(maxchar, writer->min_char);
230
231
1.93M
    if (writer->buffer == NULL) {
232
1.75M
        assert(!writer->readonly);
233
1.75M
        if (writer->overallocate
234
1.65M
            && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
235
            /* overallocate to limit the number of realloc() */
236
1.65M
            newlen += newlen / OVERALLOCATE_FACTOR;
237
1.65M
        }
238
1.75M
        if (newlen < writer->min_length)
239
1.60M
            newlen = writer->min_length;
240
241
1.75M
        writer->buffer = PyUnicode_New(newlen, maxchar);
242
1.75M
        if (writer->buffer == NULL)
243
0
            return -1;
244
1.75M
    }
245
178k
    else if (newlen > writer->size) {
246
73.3k
        if (writer->overallocate
247
70.6k
            && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
248
            /* overallocate to limit the number of realloc() */
249
70.6k
            newlen += newlen / OVERALLOCATE_FACTOR;
250
70.6k
        }
251
73.3k
        if (newlen < writer->min_length)
252
0
            newlen = writer->min_length;
253
254
73.3k
        if (maxchar > writer->maxchar || writer->readonly) {
255
            /* resize + widen */
256
9.01k
            maxchar = Py_MAX(maxchar, writer->maxchar);
257
9.01k
            newbuffer = PyUnicode_New(newlen, maxchar);
258
9.01k
            if (newbuffer == NULL)
259
0
                return -1;
260
9.01k
            _PyUnicode_FastCopyCharacters(newbuffer, 0,
261
9.01k
                                          writer->buffer, 0, writer->pos);
262
9.01k
            Py_DECREF(writer->buffer);
263
9.01k
            writer->readonly = 0;
264
9.01k
        }
265
64.3k
        else {
266
64.3k
            newbuffer = _PyUnicode_ResizeCompact(writer->buffer, newlen);
267
64.3k
            if (newbuffer == NULL)
268
0
                return -1;
269
64.3k
        }
270
73.3k
        writer->buffer = newbuffer;
271
73.3k
    }
272
105k
    else if (maxchar > writer->maxchar) {
273
105k
        assert(!writer->readonly);
274
105k
        newbuffer = PyUnicode_New(writer->size, maxchar);
275
105k
        if (newbuffer == NULL)
276
0
            return -1;
277
105k
        _PyUnicode_FastCopyCharacters(newbuffer, 0,
278
105k
                                      writer->buffer, 0, writer->pos);
279
105k
        Py_SETREF(writer->buffer, newbuffer);
280
105k
    }
281
1.93M
    _PyUnicodeWriter_Update(writer);
282
1.93M
    return 0;
283
284
1.93M
#undef OVERALLOCATE_FACTOR
285
1.93M
}
286
287
int
288
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
289
                                     int kind)
290
190
{
291
190
    Py_UCS4 maxchar;
292
293
    /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */
294
190
    assert(writer->kind < kind);
295
296
190
    switch (kind)
297
190
    {
298
0
    case PyUnicode_1BYTE_KIND: maxchar = 0xff; break;
299
190
    case PyUnicode_2BYTE_KIND: maxchar = 0xffff; break;
300
0
    case PyUnicode_4BYTE_KIND: maxchar = _Py_MAX_UNICODE; break;
301
0
    default:
302
0
        Py_UNREACHABLE();
303
190
    }
304
305
190
    return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar);
306
190
}
307
308
309
int
310
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch)
311
692k
{
312
692k
    return _PyUnicodeWriter_WriteCharInline(writer, ch);
313
692k
}
314
315
316
int
317
PyUnicodeWriter_WriteChar(PyUnicodeWriter *writer, Py_UCS4 ch)
318
692k
{
319
692k
    if (ch > _Py_MAX_UNICODE) {
320
0
        PyErr_SetString(PyExc_ValueError,
321
0
                        "character must be in range(0x110000)");
322
0
        return -1;
323
0
    }
324
325
692k
    return _PyUnicodeWriter_WriteChar((_PyUnicodeWriter*)writer, ch);
326
692k
}
327
328
329
int
330
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str)
331
636k
{
332
636k
    assert(PyUnicode_Check(str));
333
334
636k
    Py_UCS4 maxchar;
335
636k
    Py_ssize_t len;
336
337
636k
    len = PyUnicode_GET_LENGTH(str);
338
636k
    if (len == 0)
339
7.27k
        return 0;
340
629k
    maxchar = PyUnicode_MAX_CHAR_VALUE(str);
341
629k
    if (maxchar > writer->maxchar || len > writer->size - writer->pos) {
342
86.3k
        if (writer->buffer == NULL && !writer->overallocate) {
343
0
            assert(_PyUnicode_CheckConsistency(str, 1));
344
0
            writer->readonly = 1;
345
0
            writer->buffer = Py_NewRef(str);
346
0
            _PyUnicodeWriter_Update(writer);
347
0
            writer->pos += len;
348
0
            return 0;
349
0
        }
350
86.3k
        if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1)
351
0
            return -1;
352
86.3k
    }
353
629k
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
354
629k
                                  str, 0, len);
355
629k
    writer->pos += len;
356
629k
    return 0;
357
629k
}
358
359
360
int
361
PyUnicodeWriter_WriteStr(PyUnicodeWriter *writer, PyObject *obj)
362
247k
{
363
247k
    PyTypeObject *type = Py_TYPE(obj);
364
247k
    if (type == &PyUnicode_Type) {
365
247k
        return _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, obj);
366
247k
    }
367
368
0
    if (type == &PyLong_Type) {
369
0
        return _PyLong_FormatWriter((_PyUnicodeWriter*)writer, obj, 10, 0);
370
0
    }
371
372
0
    PyObject *str = PyObject_Str(obj);
373
0
    if (str == NULL) {
374
0
        return -1;
375
0
    }
376
377
0
    int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str);
378
0
    Py_DECREF(str);
379
0
    return res;
380
0
}
381
382
383
int
384
PyUnicodeWriter_WriteRepr(PyUnicodeWriter *writer, PyObject *obj)
385
0
{
386
0
    if (obj == NULL) {
387
0
        return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer, "<NULL>", 6);
388
0
    }
389
390
0
    if (Py_TYPE(obj) == &PyLong_Type) {
391
0
        return _PyLong_FormatWriter((_PyUnicodeWriter*)writer, obj, 10, 0);
392
0
    }
393
394
0
    PyObject *repr = PyObject_Repr(obj);
395
0
    if (repr == NULL) {
396
0
        return -1;
397
0
    }
398
399
0
    int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, repr);
400
0
    Py_DECREF(repr);
401
0
    return res;
402
0
}
403
404
405
int
406
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
407
                                Py_ssize_t start, Py_ssize_t end)
408
2.35M
{
409
2.35M
    assert(0 <= start);
410
2.35M
    assert(end <= PyUnicode_GET_LENGTH(str));
411
2.35M
    assert(start <= end);
412
413
2.35M
    if (start == 0 && end == PyUnicode_GET_LENGTH(str))
414
20.3k
        return _PyUnicodeWriter_WriteStr(writer, str);
415
416
2.33M
    Py_ssize_t len = end - start;
417
2.33M
    if (len == 0) {
418
0
        return 0;
419
0
    }
420
421
2.33M
    Py_UCS4 maxchar;
422
2.33M
    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
423
1.55M
        maxchar = _PyUnicode_FindMaxChar(str, start, end);
424
1.55M
    }
425
788k
    else {
426
788k
        maxchar = writer->maxchar;
427
788k
    }
428
2.33M
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
429
0
        return -1;
430
0
    }
431
432
2.33M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
433
2.33M
                                  str, start, len);
434
2.33M
    writer->pos += len;
435
2.33M
    return 0;
436
2.33M
}
437
438
439
int
440
PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
441
                               Py_ssize_t start, Py_ssize_t end)
442
655k
{
443
655k
    if (!PyUnicode_Check(str)) {
444
0
        PyErr_Format(PyExc_TypeError, "expect str, not %T", str);
445
0
        return -1;
446
0
    }
447
655k
    if (start < 0 || start > end) {
448
0
        PyErr_Format(PyExc_ValueError, "invalid start argument");
449
0
        return -1;
450
0
    }
451
655k
    if (end > PyUnicode_GET_LENGTH(str)) {
452
0
        PyErr_Format(PyExc_ValueError, "invalid end argument");
453
0
        return -1;
454
0
    }
455
456
655k
    return _PyUnicodeWriter_WriteSubstring((_PyUnicodeWriter*)writer, str,
457
655k
                                           start, end);
458
655k
}
459
460
461
int
462
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
463
                                  const char *ascii, Py_ssize_t len)
464
318k
{
465
318k
    if (len == -1)
466
0
        len = strlen(ascii);
467
468
318k
    if (len == 0) {
469
0
        return 0;
470
0
    }
471
472
318k
    assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128);
473
474
318k
    if (writer->buffer == NULL && !writer->overallocate) {
475
27.8k
        PyObject *str;
476
477
27.8k
        str = _PyUnicode_FromASCII(ascii, len);
478
27.8k
        if (str == NULL)
479
0
            return -1;
480
481
27.8k
        writer->readonly = 1;
482
27.8k
        writer->buffer = str;
483
27.8k
        _PyUnicodeWriter_Update(writer);
484
27.8k
        writer->pos += len;
485
27.8k
        return 0;
486
27.8k
    }
487
488
290k
    if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1)
489
0
        return -1;
490
491
290k
    switch (writer->kind)
492
290k
    {
493
281k
    case PyUnicode_1BYTE_KIND:
494
281k
    {
495
281k
        const Py_UCS1 *str = (const Py_UCS1 *)ascii;
496
281k
        Py_UCS1 *data = writer->data;
497
498
281k
        memcpy(data + writer->pos, str, len);
499
281k
        break;
500
0
    }
501
8.60k
    case PyUnicode_2BYTE_KIND:
502
8.60k
    {
503
8.60k
        _PyUnicode_CONVERT_BYTES(
504
8.60k
            Py_UCS1, Py_UCS2,
505
8.60k
            ascii, ascii + len,
506
8.60k
            (Py_UCS2 *)writer->data + writer->pos);
507
8.60k
        break;
508
0
    }
509
1.00k
    case PyUnicode_4BYTE_KIND:
510
1.00k
    {
511
1.00k
        _PyUnicode_CONVERT_BYTES(
512
1.00k
            Py_UCS1, Py_UCS4,
513
1.00k
            ascii, ascii + len,
514
1.00k
            (Py_UCS4 *)writer->data + writer->pos);
515
1.00k
        break;
516
0
    }
517
0
    default:
518
0
        Py_UNREACHABLE();
519
290k
    }
520
521
290k
    writer->pos += len;
522
290k
    return 0;
523
290k
}
524
525
526
int
527
PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
528
                           const char *str,
529
                           Py_ssize_t size)
530
28
{
531
28
    assert(writer != NULL);
532
28
    _Py_AssertHoldsTstate();
533
534
28
    _PyUnicodeWriter *priv_writer = (_PyUnicodeWriter*)writer;
535
28
    return _PyUnicodeWriter_WriteASCIIString(priv_writer, str, size);
536
28
}
537
538
539
int
540
PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
541
                          const char *str,
542
                          Py_ssize_t size)
543
151k
{
544
151k
    if (size < 0) {
545
151k
        size = strlen(str);
546
151k
    }
547
548
151k
    _PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
549
151k
    Py_ssize_t old_pos = _writer->pos;
550
151k
    int res = _PyUnicode_DecodeUTF8Writer(_writer, str, size,
551
151k
                                          _Py_ERROR_STRICT, NULL, NULL);
552
151k
    if (res < 0) {
553
0
        _writer->pos = old_pos;
554
0
    }
555
151k
    return res;
556
151k
}
557
558
559
int
560
PyUnicodeWriter_DecodeUTF8Stateful(PyUnicodeWriter *writer,
561
                                   const char *string,
562
                                   Py_ssize_t length,
563
                                   const char *errors,
564
                                   Py_ssize_t *consumed)
565
0
{
566
0
    if (length < 0) {
567
0
        length = strlen(string);
568
0
    }
569
570
0
    _PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
571
0
    Py_ssize_t old_pos = _writer->pos;
572
0
    int res = _PyUnicode_DecodeUTF8Writer(_writer, string, length,
573
0
                                          _Py_ERROR_UNKNOWN, errors,
574
0
                                          consumed);
575
0
    if (res < 0) {
576
0
        _writer->pos = old_pos;
577
0
        if (consumed) {
578
0
            *consumed = 0;
579
0
        }
580
0
    }
581
0
    return res;
582
0
}
583
584
585
int
586
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
587
                                   const char *str, Py_ssize_t len)
588
0
{
589
0
    Py_UCS4 maxchar;
590
591
0
    maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len);
592
0
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1)
593
0
        return -1;
594
0
    unicode_write_cstr(writer->buffer, writer->pos, str, len);
595
0
    writer->pos += len;
596
0
    return 0;
597
0
}
598
599
600
PyObject *
601
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
602
2.24M
{
603
2.24M
    PyObject *str;
604
605
2.24M
    if (writer->pos == 0) {
606
3.25k
        Py_CLEAR(writer->buffer);
607
3.25k
        return _PyUnicode_GetEmpty();
608
3.25k
    }
609
610
2.23M
    str = writer->buffer;
611
2.23M
    writer->buffer = NULL;
612
613
2.23M
    if (writer->readonly) {
614
27.8k
        assert(PyUnicode_GET_LENGTH(str) == writer->pos);
615
27.8k
        return str;
616
27.8k
    }
617
618
2.20M
    if (PyUnicode_GET_LENGTH(str) != writer->pos) {
619
1.66M
        PyObject *str2;
620
1.66M
        str2 = _PyUnicode_ResizeCompact(str, writer->pos);
621
1.66M
        if (str2 == NULL) {
622
0
            Py_DECREF(str);
623
0
            return NULL;
624
0
        }
625
1.66M
        str = str2;
626
1.66M
    }
627
628
2.20M
    assert(_PyUnicode_CheckConsistency(str, 1));
629
2.20M
    return _PyUnicode_Result(str);
630
2.20M
}
631
632
633
PyObject*
634
PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
635
117k
{
636
117k
    PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer);
637
117k
    assert(((_PyUnicodeWriter*)writer)->buffer == NULL);
638
117k
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
639
117k
    return str;
640
117k
}
641
642
643
void
644
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
645
7.17k
{
646
    Py_CLEAR(writer->buffer);
647
7.17k
}