Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/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
18.3M
#  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
void
66
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
67
44.2M
{
68
44.2M
    memset(writer, 0, sizeof(*writer));
69
70
    /* ASCII is the bare minimum */
71
44.2M
    writer->min_char = 127;
72
73
    /* use a kind value smaller than PyUnicode_1BYTE_KIND so
74
       _PyUnicodeWriter_PrepareKind() will copy the buffer. */
75
44.2M
    assert(writer->kind == 0);
76
44.2M
    assert(writer->kind < PyUnicode_1BYTE_KIND);
77
44.2M
}
78
79
80
PyUnicodeWriter*
81
PyUnicodeWriter_Create(Py_ssize_t length)
82
4.44M
{
83
4.44M
    if (length < 0) {
84
0
        PyErr_SetString(PyExc_ValueError,
85
0
                        "length must be positive");
86
0
        return NULL;
87
0
    }
88
89
4.44M
    const size_t size = sizeof(_PyUnicodeWriter);
90
4.44M
    PyUnicodeWriter *pub_writer;
91
4.44M
    pub_writer = _Py_FREELIST_POP_MEM(unicode_writers);
92
4.44M
    if (pub_writer == NULL) {
93
2.49M
        pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size);
94
2.49M
        if (pub_writer == NULL) {
95
0
            return (PyUnicodeWriter *)PyErr_NoMemory();
96
0
        }
97
2.49M
    }
98
4.44M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter *)pub_writer;
99
100
4.44M
    _PyUnicodeWriter_Init(writer);
101
    // The buffer is created lazily at the first write, except if
102
    // the read-only optimization is used.
103
4.44M
    writer->min_length = length;
104
4.44M
    writer->overallocate = 1;
105
106
4.44M
    return pub_writer;
107
4.44M
}
108
109
110
void
111
PyUnicodeWriter_Discard(PyUnicodeWriter *writer)
112
78.5k
{
113
78.5k
    if (writer == NULL) {
114
78.0k
        return;
115
78.0k
    }
116
502
    _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer);
117
502
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
118
502
}
119
120
121
// Initialize _PyUnicodeWriter with initial buffer
122
void
123
_PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer)
124
10.4M
{
125
10.4M
    assert(PyUnstable_Object_IsUniquelyReferenced(buffer));
126
127
10.4M
    memset(writer, 0, sizeof(*writer));
128
10.4M
    _PyUnicodeWriter_SetBuffer(writer, buffer);
129
10.4M
    writer->min_length = writer->size;
130
10.4M
    assert(_PyUnicodeWriter_CanWrite(writer));
131
10.4M
}
132
133
134
int
135
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
136
                                 Py_ssize_t length, Py_UCS4 maxchar)
137
61.3M
{
138
61.3M
    assert(length >= 0);
139
61.3M
    assert(maxchar <= _Py_MAX_UNICODE);
140
141
    // Check that _PyUnicodeWriter_Prepare() or _PyUnicodeWriter_PrepareKind()
142
    // was used
143
61.3M
    assert(maxchar > writer->maxchar
144
61.3M
           || (length > (writer->size - writer->pos) && length >= 1));
145
146
61.3M
    if (length > PY_SSIZE_T_MAX - writer->pos) {
147
0
        PyErr_NoMemory();
148
0
        return -1;
149
0
    }
150
61.3M
    Py_ssize_t alloc = writer->pos + length;
151
152
61.3M
    maxchar = Py_MAX(maxchar, writer->min_char);
153
154
61.3M
    PyObject *new_buffer;
155
61.3M
    if (writer->buffer == NULL) {
156
30.5M
        assert(!writer->readonly);
157
158
        // Do not overallocate at the first allocation, but use min_length
159
30.5M
        if (alloc < writer->min_length) {
160
23.9M
            alloc = writer->min_length;
161
23.9M
        }
162
163
30.5M
        new_buffer = PyUnicode_New(alloc, maxchar);
164
30.5M
        if (new_buffer == NULL) {
165
0
            return -1;
166
0
        }
167
30.5M
    }
168
30.8M
    else if (alloc > writer->size) {
169
        // Do not overallocate at the first allocation, but use min_length
170
22.3M
        int overallocate = (writer->overallocate && !writer->readonly);
171
22.3M
        if (overallocate
172
9.15M
            && alloc <= (PY_SSIZE_T_MAX - alloc / OVERALLOCATE_FACTOR)) {
173
            /* overallocate to limit the number of realloc() */
174
9.15M
            alloc += alloc / OVERALLOCATE_FACTOR;
175
9.15M
        }
176
22.3M
        if (alloc < writer->min_length) {
177
8.80M
            alloc = writer->min_length;
178
8.80M
        }
179
180
22.3M
        if (maxchar > writer->maxchar || writer->readonly) {
181
            /* resize + widen */
182
14.6M
            maxchar = Py_MAX(maxchar, writer->maxchar);
183
14.6M
            new_buffer = PyUnicode_New(alloc, maxchar);
184
14.6M
            if (new_buffer == NULL) {
185
0
                return -1;
186
0
            }
187
14.6M
            _PyUnicode_FastCopyCharacters(new_buffer, 0,
188
14.6M
                                          writer->buffer, 0, writer->pos);
189
14.6M
        }
190
7.72M
        else {
191
7.72M
            new_buffer = _PyUnicode_ResizeCompact(writer->buffer, alloc);
192
7.72M
            if (new_buffer == NULL) {
193
0
                return -1;
194
0
            }
195
            // Do not DECREF the old buffer
196
7.72M
            writer->buffer = NULL;
197
7.72M
        }
198
22.3M
    }
199
8.48M
    else {
200
8.48M
        assert(maxchar > writer->maxchar);
201
8.48M
        assert(!writer->readonly);
202
203
8.48M
        new_buffer = PyUnicode_New(writer->size, maxchar);
204
8.48M
        if (new_buffer == NULL) {
205
0
            return -1;
206
0
        }
207
8.48M
        _PyUnicode_FastCopyCharacters(new_buffer, 0,
208
8.48M
                                      writer->buffer, 0, writer->pos);
209
8.48M
    }
210
211
61.3M
    _PyUnicodeWriter_SetBuffer(writer, new_buffer);
212
61.3M
    return 0;
213
214
61.3M
#undef OVERALLOCATE_FACTOR
215
61.3M
}
216
217
int
218
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
219
                                     int kind)
220
194k
{
221
194k
    Py_UCS4 maxchar;
222
223
    /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */
224
194k
    assert(writer->kind < kind);
225
226
194k
    switch (kind)
227
194k
    {
228
0
    case PyUnicode_1BYTE_KIND: maxchar = 0xff; break;
229
194k
    case PyUnicode_2BYTE_KIND: maxchar = 0xffff; break;
230
0
    case PyUnicode_4BYTE_KIND: maxchar = _Py_MAX_UNICODE; break;
231
0
    default:
232
0
        Py_UNREACHABLE();
233
194k
    }
234
235
194k
    return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar);
236
194k
}
237
238
239
int
240
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch)
241
71.5M
{
242
71.5M
    return _PyUnicodeWriter_WriteCharInline(writer, ch);
243
71.5M
}
244
245
246
int
247
PyUnicodeWriter_WriteChar(PyUnicodeWriter *writer, Py_UCS4 ch)
248
71.5M
{
249
71.5M
    if (ch > _Py_MAX_UNICODE) {
250
0
        PyErr_SetString(PyExc_ValueError,
251
0
                        "character must be in range(0x110000)");
252
0
        return -1;
253
0
    }
254
255
71.5M
    return _PyUnicodeWriter_WriteChar((_PyUnicodeWriter*)writer, ch);
256
71.5M
}
257
258
259
int
260
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str)
261
53.0M
{
262
53.0M
    assert(PyUnicode_Check(str));
263
264
53.0M
    Py_ssize_t len = PyUnicode_GET_LENGTH(str);
265
53.0M
    if (len == 0) {
266
6.56M
        return 0;
267
6.56M
    }
268
46.4M
    Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(str);
269
270
46.4M
    if (maxchar > writer->maxchar || len > writer->size - writer->pos) {
271
18.3M
        if (writer->buffer == NULL && PyUnicode_CheckExact(str)) {
272
8.73M
            assert(_PyUnicode_CheckConsistency(str, 1));
273
8.73M
            _PyUnicodeWriter_SetReadOnly(writer, Py_NewRef(str), len);
274
8.73M
            return 0;
275
8.73M
        }
276
9.58M
        if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1)
277
0
            return -1;
278
9.58M
    }
279
280
46.4M
    assert(_PyUnicodeWriter_CanWrite(writer));
281
37.7M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
282
37.7M
                                  str, 0, len);
283
37.7M
    writer->pos += len;
284
37.7M
    return 0;
285
46.4M
}
286
287
288
int
289
PyUnicodeWriter_WriteStr(PyUnicodeWriter *pub_writer, PyObject *obj)
290
17.2M
{
291
17.2M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter*)pub_writer;
292
17.2M
    PyTypeObject *type = Py_TYPE(obj);
293
17.2M
    if (type == &PyUnicode_Type) {
294
12.5M
        return _PyUnicodeWriter_WriteStr(writer, obj);
295
12.5M
    }
296
297
4.63M
    if (type == &PyLong_Type) {
298
33
        return _PyLong_FormatWriter(writer, obj, 10, 0);
299
33
    }
300
301
4.63M
    PyObject *str = PyObject_Str(obj);
302
4.63M
    if (str == NULL) {
303
0
        return -1;
304
0
    }
305
306
4.63M
    int res = _PyUnicodeWriter_WriteStr(writer, str);
307
4.63M
    Py_DECREF(str);
308
4.63M
    return res;
309
4.63M
}
310
311
312
int
313
PyUnicodeWriter_WriteRepr(PyUnicodeWriter *pub_writer, PyObject *obj)
314
8.57M
{
315
8.57M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter*)pub_writer;
316
8.57M
    if (obj == NULL) {
317
0
        return _PyUnicodeWriter_WriteASCIIString(writer, "<NULL>", 6);
318
0
    }
319
320
8.57M
    if (Py_TYPE(obj) == &PyLong_Type) {
321
828k
        return _PyLong_FormatWriter(writer, obj, 10, 0);
322
828k
    }
323
    // Fast path for None; see gh-159813 for the rationale.
324
7.74M
    if (obj == Py_None) {
325
52.6k
        return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4);
326
52.6k
    }
327
328
7.69M
    PyObject *repr = PyObject_Repr(obj);
329
7.69M
    if (repr == NULL) {
330
0
        return -1;
331
0
    }
332
333
7.69M
    int res = _PyUnicodeWriter_WriteStr(writer, repr);
334
7.69M
    Py_DECREF(repr);
335
7.69M
    return res;
336
7.69M
}
337
338
339
int
340
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
341
                                Py_ssize_t start, Py_ssize_t end)
342
43.1M
{
343
43.1M
    assert(0 <= start);
344
43.1M
    assert(start <= end);
345
43.1M
    assert(end <= PyUnicode_GET_LENGTH(str));
346
347
43.1M
    if (start == 0 && end == PyUnicode_GET_LENGTH(str)) {
348
12
        return _PyUnicodeWriter_WriteStr(writer, str);
349
12
    }
350
351
43.1M
    Py_ssize_t len = end - start;
352
43.1M
    if (len == 0) {
353
0
        return 0;
354
0
    }
355
356
43.1M
    Py_UCS4 maxchar;
357
43.1M
    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
358
11.8M
        maxchar = _PyUnicode_FindMaxChar(str, start, end);
359
11.8M
    }
360
31.2M
    else {
361
31.2M
        maxchar = writer->maxchar;
362
31.2M
    }
363
43.1M
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
364
0
        return -1;
365
0
    }
366
43.1M
    assert(_PyUnicodeWriter_CanWrite(writer));
367
368
43.1M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
369
43.1M
                                  str, start, len);
370
43.1M
    writer->pos += len;
371
43.1M
    return 0;
372
43.1M
}
373
374
375
int
376
PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
377
                               Py_ssize_t start, Py_ssize_t end)
378
577k
{
379
577k
    if (!PyUnicode_Check(str)) {
380
0
        PyErr_Format(PyExc_TypeError, "expect str, not %T", str);
381
0
        return -1;
382
0
    }
383
577k
    if (start < 0 || start > end) {
384
0
        PyErr_Format(PyExc_ValueError, "invalid start argument");
385
0
        return -1;
386
0
    }
387
577k
    if (end > PyUnicode_GET_LENGTH(str)) {
388
0
        PyErr_Format(PyExc_ValueError, "invalid end argument");
389
0
        return -1;
390
0
    }
391
392
577k
    return _PyUnicodeWriter_WriteSubstring((_PyUnicodeWriter*)writer, str,
393
577k
                                           start, end);
394
577k
}
395
396
397
int
398
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
399
                                  const char *ascii, Py_ssize_t len)
400
45.5M
{
401
45.5M
    if (len == -1)
402
0
        len = strlen(ascii);
403
404
45.5M
    if (len == 0) {
405
76.5k
        return 0;
406
76.5k
    }
407
408
45.5M
    assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) <= 127);
409
410
45.4M
    if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1) {
411
0
        return -1;
412
0
    }
413
45.4M
    assert(_PyUnicodeWriter_CanWrite(writer));
414
415
45.4M
    switch (writer->kind)
416
45.4M
    {
417
45.4M
    case PyUnicode_1BYTE_KIND:
418
45.4M
    {
419
45.4M
        const Py_UCS1 *str = (const Py_UCS1 *)ascii;
420
45.4M
        Py_UCS1 *data = writer->data;
421
422
45.4M
        memcpy(data + writer->pos, str, len);
423
45.4M
        break;
424
0
    }
425
11.2k
    case PyUnicode_2BYTE_KIND:
426
11.2k
    {
427
11.2k
        _PyUnicode_CONVERT_BYTES(
428
11.2k
            Py_UCS1, Py_UCS2,
429
11.2k
            ascii, ascii + len,
430
11.2k
            (Py_UCS2 *)writer->data + writer->pos);
431
11.2k
        break;
432
0
    }
433
6.47k
    case PyUnicode_4BYTE_KIND:
434
6.47k
    {
435
6.47k
        _PyUnicode_CONVERT_BYTES(
436
6.47k
            Py_UCS1, Py_UCS4,
437
6.47k
            ascii, ascii + len,
438
6.47k
            (Py_UCS4 *)writer->data + writer->pos);
439
6.47k
        break;
440
0
    }
441
0
    default:
442
0
        Py_UNREACHABLE();
443
45.4M
    }
444
445
45.4M
    writer->pos += len;
446
45.4M
    return 0;
447
45.4M
}
448
449
450
int
451
PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
452
                           const char *str,
453
                           Py_ssize_t size)
454
702k
{
455
702k
    assert(writer != NULL);
456
702k
    _Py_AssertHoldsTstate();
457
458
702k
    return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer, str, size);
459
702k
}
460
461
462
int
463
PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
464
                          const char *str,
465
                          Py_ssize_t size)
466
4
{
467
4
    if (size < 0) {
468
4
        size = strlen(str);
469
4
    }
470
471
4
    return _PyUnicode_DecodeUTF8Writer((_PyUnicodeWriter*)writer, str, size,
472
4
                                       _Py_ERROR_STRICT, NULL, NULL);
473
4
}
474
475
476
int
477
PyUnicodeWriter_DecodeUTF8Stateful(PyUnicodeWriter *writer,
478
                                   const char *str,
479
                                   Py_ssize_t size,
480
                                   const char *errors,
481
                                   Py_ssize_t *consumed)
482
0
{
483
0
    if (size < 0) {
484
0
        size = strlen(str);
485
0
    }
486
487
0
    return _PyUnicode_DecodeUTF8Writer((_PyUnicodeWriter*)writer, str, size,
488
0
                                       _Py_ERROR_UNKNOWN, errors,
489
0
                                       consumed);
490
0
}
491
492
493
int
494
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
495
                                   const char *str, Py_ssize_t len)
496
0
{
497
0
    if (len == 0) {
498
0
        return 0;
499
0
    }
500
501
0
    const Py_UCS1 *ucs1 = (const Py_UCS1 *)str;
502
0
    Py_UCS4 maxchar = ucs1lib_find_max_char(ucs1, ucs1 + len);
503
0
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
504
0
        return -1;
505
0
    }
506
0
    assert(_PyUnicodeWriter_CanWrite(writer));
507
508
0
    Py_ssize_t index = writer->pos;
509
0
    switch (writer->kind) {
510
0
    case PyUnicode_1BYTE_KIND: {
511
0
        memcpy((Py_UCS1 *)writer->data + index, ucs1, len);
512
0
        break;
513
0
    }
514
0
    case PyUnicode_2BYTE_KIND: {
515
0
        Py_UCS2 *ucs2 = (Py_UCS2 *)writer->data + index;
516
0
        const Py_UCS1 *end = ucs1 + len;
517
0
        for (; ucs1 < end; ++ucs2, ++ucs1) {
518
0
            *ucs2 = (Py_UCS2)*ucs1;
519
0
        }
520
0
        break;
521
0
    }
522
0
    case PyUnicode_4BYTE_KIND: {
523
0
        Py_UCS4 *ucs4 = (Py_UCS4 *)writer->data + index;
524
0
        const Py_UCS1 *end = ucs1 + len;
525
0
        for (; ucs1 < end; ++ucs4, ++ucs1) {
526
0
            *ucs4 = (Py_UCS4)*ucs1;
527
0
        }
528
0
        break;
529
0
    }
530
0
    default:
531
0
        Py_UNREACHABLE();
532
0
    }
533
534
0
    writer->pos += len;
535
0
    return 0;
536
0
}
537
538
539
PyObject *
540
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
541
51.2M
{
542
#ifdef Py_DEBUG
543
    // Check for buffer overflow
544
    if (writer->buffer != NULL) {
545
        Py_ssize_t pos = PyUnicode_GET_LENGTH(writer->buffer);
546
        Py_UCS4 ch = PyUnicode_READ_CHAR(writer->buffer, pos);
547
        if (ch != 0) {
548
            _Py_FatalErrorFormat(__func__,
549
                                 "Buffer overflow detected in "
550
                                 "PyUnicodeWriter %p at position %zd",
551
                                 writer, pos);
552
        }
553
    }
554
#endif
555
556
51.2M
    PyObject *str = writer->buffer;
557
51.2M
    writer->buffer = NULL;
558
559
51.2M
    Py_ssize_t final_size = writer->pos;
560
51.2M
    if (final_size == 0) {
561
        // Get the empty string singleton
562
1.85k
        PyObject *empty = _PyUnicode_GetEmpty();
563
1.85k
        Py_XDECREF(str);  // writer->buffer can be NULL if the position is 0
564
1.85k
        return empty;
565
1.85k
    }
566
567
51.2M
    if (writer->readonly) {
568
26.4k
        assert(final_size == PyUnicode_GET_LENGTH(str));
569
26.4k
        goto done;
570
26.4k
    }
571
51.2M
    assert(final_size <= PyUnicode_GET_LENGTH(str));
572
573
51.1M
    if (final_size == 1 && PyUnicode_KIND(str) == PyUnicode_1BYTE_KIND) {
574
        // Get the single character singleton
575
153k
        assert(PyUnicode_GET_LENGTH(str) >= 1);
576
153k
        const Py_UCS1 *data = PyUnicode_1BYTE_DATA(str);
577
153k
        Py_UCS1 ch = data[0];
578
153k
        Py_DECREF(str);
579
153k
        str = _Py_LATIN1_CHR(ch);
580
153k
        goto done;
581
153k
    }
582
583
51.0M
    if (writer->recheck_maxchar) {
584
0
        Py_UCS4 maxchar = _PyUnicode_FindMaxChar(str, 0, final_size);
585
0
        if (maxchar != writer->maxchar) {
586
            // Adjust the string kind
587
0
            PyObject *str2 = PyUnicode_New(final_size, maxchar);
588
0
            if (str2 == NULL) {
589
0
                Py_DECREF(str);
590
0
                return NULL;
591
0
            }
592
0
            _PyUnicode_FastCopyCharacters(str2, 0, str, 0, final_size);
593
0
            Py_SETREF(str, str2);
594
0
            goto done;
595
0
        }
596
0
    }
597
598
51.0M
    if (PyUnicode_GET_LENGTH(str) != final_size) {
599
        // Truncate the string
600
42.6M
        PyObject *str2 = _PyUnicode_ResizeCompact(str, final_size);
601
42.6M
        if (str2 == NULL) {
602
0
            Py_DECREF(str);
603
0
            return NULL;
604
0
        }
605
42.6M
        str = str2;
606
42.6M
        goto done;
607
42.6M
    }
608
609
51.2M
done:
610
51.2M
    assert(_PyUnicode_CheckConsistency(str, 1));
611
51.2M
    return str;
612
51.0M
}
613
614
615
PyObject *
616
_PyUnicodeWriter_FinishWithSize(_PyUnicodeWriter *writer, Py_ssize_t size)
617
0
{
618
0
    assert(0 <= size);
619
0
    if (writer->buffer != NULL) {
620
0
        assert(size <= writer->pos);
621
0
        assert(size <= PyUnicode_GET_LENGTH(writer->buffer));
622
0
        if (size < writer->pos) {
623
            // Truncate the string: we may need to adjust the string kind
624
0
            writer->recheck_maxchar = 1;
625
0
        }
626
0
    }
627
0
    else {
628
0
        assert(size == 0);
629
0
    }
630
0
    writer->pos = size;
631
0
    return _PyUnicodeWriter_Finish(writer);
632
0
}
633
634
635
PyObject*
636
PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
637
4.44M
{
638
4.44M
    PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer);
639
4.44M
    assert(((_PyUnicodeWriter*)writer)->buffer == NULL);
640
4.44M
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
641
4.44M
    return str;
642
4.44M
}
643
644
645
void
646
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
647
3.46M
{
648
    Py_CLEAR(writer->buffer);
649
3.46M
}