Coverage Report

Created: 2026-10-17 06:15

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.2M
#  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
43.7M
{
68
43.7M
    memset(writer, 0, sizeof(*writer));
69
70
    /* ASCII is the bare minimum */
71
43.7M
    writer->min_char = 127;
72
73
    /* use a kind value smaller than PyUnicode_1BYTE_KIND so
74
       _PyUnicodeWriter_PrepareKind() will copy the buffer. */
75
43.7M
    assert(writer->kind == 0);
76
43.7M
    assert(writer->kind < PyUnicode_1BYTE_KIND);
77
43.7M
}
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.32M
        pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size);
94
2.32M
        if (pub_writer == NULL) {
95
0
            return (PyUnicodeWriter *)PyErr_NoMemory();
96
0
        }
97
2.32M
    }
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
76.0k
{
113
76.0k
    if (writer == NULL) {
114
75.5k
        return;
115
75.5k
    }
116
505
    _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer);
117
505
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
118
505
}
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
60.5M
{
138
60.5M
    assert(length >= 0);
139
60.5M
    assert(maxchar <= _Py_MAX_UNICODE);
140
141
    // Check that _PyUnicodeWriter_Prepare() or _PyUnicodeWriter_PrepareKind()
142
    // was used
143
60.5M
    assert(maxchar > writer->maxchar
144
60.5M
           || (length > (writer->size - writer->pos) && length >= 1));
145
146
60.5M
    if (length > PY_SSIZE_T_MAX - writer->pos) {
147
0
        PyErr_NoMemory();
148
0
        return -1;
149
0
    }
150
60.5M
    Py_ssize_t alloc = writer->pos + length;
151
152
60.5M
    maxchar = Py_MAX(maxchar, writer->min_char);
153
154
60.5M
    PyObject *new_buffer;
155
60.5M
    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.8M
            alloc = writer->min_length;
161
23.8M
        }
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
29.9M
    else if (alloc > writer->size) {
169
        // Do not overallocate at the first allocation, but use min_length
170
21.8M
        int overallocate = (writer->overallocate && !writer->readonly);
171
21.8M
        if (overallocate
172
9.12M
            && alloc <= (PY_SSIZE_T_MAX - alloc / OVERALLOCATE_FACTOR)) {
173
            /* overallocate to limit the number of realloc() */
174
9.12M
            alloc += alloc / OVERALLOCATE_FACTOR;
175
9.12M
        }
176
21.8M
        if (alloc < writer->min_length) {
177
8.48M
            alloc = writer->min_length;
178
8.48M
        }
179
180
21.8M
        if (maxchar > writer->maxchar || writer->readonly) {
181
            /* resize + widen */
182
13.8M
            maxchar = Py_MAX(maxchar, writer->maxchar);
183
13.8M
            new_buffer = PyUnicode_New(alloc, maxchar);
184
13.8M
            if (new_buffer == NULL) {
185
0
                return -1;
186
0
            }
187
13.8M
            _PyUnicode_FastCopyCharacters(new_buffer, 0,
188
13.8M
                                          writer->buffer, 0, writer->pos);
189
13.8M
        }
190
7.96M
        else {
191
7.96M
            new_buffer = _PyUnicode_ResizeCompact(writer->buffer, alloc);
192
7.96M
            if (new_buffer == NULL) {
193
0
                return -1;
194
0
            }
195
            // Do not DECREF the old buffer
196
7.96M
            writer->buffer = NULL;
197
7.96M
        }
198
21.8M
    }
199
8.18M
    else {
200
8.18M
        assert(maxchar > writer->maxchar);
201
8.18M
        assert(!writer->readonly);
202
203
8.18M
        new_buffer = PyUnicode_New(writer->size, maxchar);
204
8.18M
        if (new_buffer == NULL) {
205
0
            return -1;
206
0
        }
207
8.18M
        _PyUnicode_FastCopyCharacters(new_buffer, 0,
208
8.18M
                                      writer->buffer, 0, writer->pos);
209
8.18M
    }
210
211
60.5M
    _PyUnicodeWriter_SetBuffer(writer, new_buffer);
212
60.5M
    return 0;
213
214
60.5M
#undef OVERALLOCATE_FACTOR
215
60.5M
}
216
217
int
218
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
219
                                     int kind)
220
178k
{
221
178k
    Py_UCS4 maxchar;
222
223
    /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */
224
178k
    assert(writer->kind < kind);
225
226
178k
    switch (kind)
227
178k
    {
228
0
    case PyUnicode_1BYTE_KIND: maxchar = 0xff; break;
229
178k
    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
178k
    }
234
235
178k
    return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar);
236
178k
}
237
238
239
int
240
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch)
241
70.8M
{
242
70.8M
    return _PyUnicodeWriter_WriteCharInline(writer, ch);
243
70.8M
}
244
245
246
int
247
PyUnicodeWriter_WriteChar(PyUnicodeWriter *writer, Py_UCS4 ch)
248
70.8M
{
249
70.8M
    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
70.8M
    return _PyUnicodeWriter_WriteChar((_PyUnicodeWriter*)writer, ch);
256
70.8M
}
257
258
259
int
260
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str)
261
52.5M
{
262
52.5M
    assert(PyUnicode_Check(str));
263
264
52.5M
    Py_ssize_t len = PyUnicode_GET_LENGTH(str);
265
52.5M
    if (len == 0) {
266
6.05M
        return 0;
267
6.05M
    }
268
46.5M
    Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(str);
269
270
46.5M
    if (maxchar > writer->maxchar || len > writer->size - writer->pos) {
271
17.3M
        if (writer->buffer == NULL && PyUnicode_CheckExact(str)) {
272
8.42M
            assert(_PyUnicode_CheckConsistency(str, 1));
273
8.42M
            _PyUnicodeWriter_SetReadOnly(writer, Py_NewRef(str), len);
274
8.42M
            return 0;
275
8.42M
        }
276
8.90M
        if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1)
277
0
            return -1;
278
8.90M
    }
279
280
46.5M
    assert(_PyUnicodeWriter_CanWrite(writer));
281
38.1M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
282
38.1M
                                  str, 0, len);
283
38.1M
    writer->pos += len;
284
38.1M
    return 0;
285
46.5M
}
286
287
288
int
289
PyUnicodeWriter_WriteStr(PyUnicodeWriter *pub_writer, PyObject *obj)
290
17.0M
{
291
17.0M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter*)pub_writer;
292
17.0M
    PyTypeObject *type = Py_TYPE(obj);
293
17.0M
    if (type == &PyUnicode_Type) {
294
11.9M
        return _PyUnicodeWriter_WriteStr(writer, obj);
295
11.9M
    }
296
297
5.03M
    if (type == &PyLong_Type) {
298
26
        return _PyLong_FormatWriter(writer, obj, 10, 0);
299
26
    }
300
301
5.03M
    PyObject *str = PyObject_Str(obj);
302
5.03M
    if (str == NULL) {
303
0
        return -1;
304
0
    }
305
306
5.03M
    int res = _PyUnicodeWriter_WriteStr(writer, str);
307
5.03M
    Py_DECREF(str);
308
5.03M
    return res;
309
5.03M
}
310
311
312
int
313
PyUnicodeWriter_WriteRepr(PyUnicodeWriter *pub_writer, PyObject *obj)
314
7.83M
{
315
7.83M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter*)pub_writer;
316
7.83M
    if (obj == NULL) {
317
0
        return _PyUnicodeWriter_WriteASCIIString(writer, "<NULL>", 6);
318
0
    }
319
320
7.83M
    if (Py_TYPE(obj) == &PyLong_Type) {
321
384k
        return _PyLong_FormatWriter(writer, obj, 10, 0);
322
384k
    }
323
324
7.45M
    PyObject *repr = PyObject_Repr(obj);
325
7.45M
    if (repr == NULL) {
326
0
        return -1;
327
0
    }
328
329
7.45M
    int res = _PyUnicodeWriter_WriteStr(writer, repr);
330
7.45M
    Py_DECREF(repr);
331
7.45M
    return res;
332
7.45M
}
333
334
335
int
336
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
337
                                Py_ssize_t start, Py_ssize_t end)
338
42.2M
{
339
42.2M
    assert(0 <= start);
340
42.2M
    assert(start <= end);
341
42.2M
    assert(end <= PyUnicode_GET_LENGTH(str));
342
343
42.2M
    if (start == 0 && end == PyUnicode_GET_LENGTH(str)) {
344
41
        return _PyUnicodeWriter_WriteStr(writer, str);
345
41
    }
346
347
42.2M
    Py_ssize_t len = end - start;
348
42.2M
    if (len == 0) {
349
0
        return 0;
350
0
    }
351
352
42.2M
    Py_UCS4 maxchar;
353
42.2M
    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
354
11.9M
        maxchar = _PyUnicode_FindMaxChar(str, start, end);
355
11.9M
    }
356
30.3M
    else {
357
30.3M
        maxchar = writer->maxchar;
358
30.3M
    }
359
42.2M
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
360
0
        return -1;
361
0
    }
362
42.2M
    assert(_PyUnicodeWriter_CanWrite(writer));
363
364
42.2M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
365
42.2M
                                  str, start, len);
366
42.2M
    writer->pos += len;
367
42.2M
    return 0;
368
42.2M
}
369
370
371
int
372
PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
373
                               Py_ssize_t start, Py_ssize_t end)
374
696k
{
375
696k
    if (!PyUnicode_Check(str)) {
376
0
        PyErr_Format(PyExc_TypeError, "expect str, not %T", str);
377
0
        return -1;
378
0
    }
379
696k
    if (start < 0 || start > end) {
380
0
        PyErr_Format(PyExc_ValueError, "invalid start argument");
381
0
        return -1;
382
0
    }
383
696k
    if (end > PyUnicode_GET_LENGTH(str)) {
384
0
        PyErr_Format(PyExc_ValueError, "invalid end argument");
385
0
        return -1;
386
0
    }
387
388
696k
    return _PyUnicodeWriter_WriteSubstring((_PyUnicodeWriter*)writer, str,
389
696k
                                           start, end);
390
696k
}
391
392
393
int
394
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
395
                                  const char *ascii, Py_ssize_t len)
396
44.1M
{
397
44.1M
    if (len == -1)
398
0
        len = strlen(ascii);
399
400
44.1M
    if (len == 0) {
401
67.7k
        return 0;
402
67.7k
    }
403
404
44.1M
    assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) <= 127);
405
406
44.0M
    if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1) {
407
0
        return -1;
408
0
    }
409
44.0M
    assert(_PyUnicodeWriter_CanWrite(writer));
410
411
44.0M
    switch (writer->kind)
412
44.0M
    {
413
44.0M
    case PyUnicode_1BYTE_KIND:
414
44.0M
    {
415
44.0M
        const Py_UCS1 *str = (const Py_UCS1 *)ascii;
416
44.0M
        Py_UCS1 *data = writer->data;
417
418
44.0M
        memcpy(data + writer->pos, str, len);
419
44.0M
        break;
420
0
    }
421
11.6k
    case PyUnicode_2BYTE_KIND:
422
11.6k
    {
423
11.6k
        _PyUnicode_CONVERT_BYTES(
424
11.6k
            Py_UCS1, Py_UCS2,
425
11.6k
            ascii, ascii + len,
426
11.6k
            (Py_UCS2 *)writer->data + writer->pos);
427
11.6k
        break;
428
0
    }
429
8.08k
    case PyUnicode_4BYTE_KIND:
430
8.08k
    {
431
8.08k
        _PyUnicode_CONVERT_BYTES(
432
8.08k
            Py_UCS1, Py_UCS4,
433
8.08k
            ascii, ascii + len,
434
8.08k
            (Py_UCS4 *)writer->data + writer->pos);
435
8.08k
        break;
436
0
    }
437
0
    default:
438
0
        Py_UNREACHABLE();
439
44.0M
    }
440
441
44.0M
    writer->pos += len;
442
44.0M
    return 0;
443
44.0M
}
444
445
446
int
447
PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
448
                           const char *str,
449
                           Py_ssize_t size)
450
1.00M
{
451
1.00M
    assert(writer != NULL);
452
1.00M
    _Py_AssertHoldsTstate();
453
454
1.00M
    return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer, str, size);
455
1.00M
}
456
457
458
int
459
PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
460
                          const char *str,
461
                          Py_ssize_t size)
462
4
{
463
4
    if (size < 0) {
464
4
        size = strlen(str);
465
4
    }
466
467
4
    return _PyUnicode_DecodeUTF8Writer((_PyUnicodeWriter*)writer, str, size,
468
4
                                       _Py_ERROR_STRICT, NULL, NULL);
469
4
}
470
471
472
int
473
PyUnicodeWriter_DecodeUTF8Stateful(PyUnicodeWriter *writer,
474
                                   const char *str,
475
                                   Py_ssize_t size,
476
                                   const char *errors,
477
                                   Py_ssize_t *consumed)
478
0
{
479
0
    if (size < 0) {
480
0
        size = strlen(str);
481
0
    }
482
483
0
    return _PyUnicode_DecodeUTF8Writer((_PyUnicodeWriter*)writer, str, size,
484
0
                                       _Py_ERROR_UNKNOWN, errors,
485
0
                                       consumed);
486
0
}
487
488
489
int
490
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
491
                                   const char *str, Py_ssize_t len)
492
0
{
493
0
    if (len == 0) {
494
0
        return 0;
495
0
    }
496
497
0
    const Py_UCS1 *ucs1 = (const Py_UCS1 *)str;
498
0
    Py_UCS4 maxchar = ucs1lib_find_max_char(ucs1, ucs1 + len);
499
0
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
500
0
        return -1;
501
0
    }
502
0
    assert(_PyUnicodeWriter_CanWrite(writer));
503
504
0
    Py_ssize_t index = writer->pos;
505
0
    switch (writer->kind) {
506
0
    case PyUnicode_1BYTE_KIND: {
507
0
        memcpy((Py_UCS1 *)writer->data + index, ucs1, len);
508
0
        break;
509
0
    }
510
0
    case PyUnicode_2BYTE_KIND: {
511
0
        Py_UCS2 *ucs2 = (Py_UCS2 *)writer->data + index;
512
0
        const Py_UCS1 *end = ucs1 + len;
513
0
        for (; ucs1 < end; ++ucs2, ++ucs1) {
514
0
            *ucs2 = (Py_UCS2)*ucs1;
515
0
        }
516
0
        break;
517
0
    }
518
0
    case PyUnicode_4BYTE_KIND: {
519
0
        Py_UCS4 *ucs4 = (Py_UCS4 *)writer->data + index;
520
0
        const Py_UCS1 *end = ucs1 + len;
521
0
        for (; ucs1 < end; ++ucs4, ++ucs1) {
522
0
            *ucs4 = (Py_UCS4)*ucs1;
523
0
        }
524
0
        break;
525
0
    }
526
0
    default:
527
0
        Py_UNREACHABLE();
528
0
    }
529
530
0
    writer->pos += len;
531
0
    return 0;
532
0
}
533
534
535
PyObject *
536
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
537
50.5M
{
538
#ifdef Py_DEBUG
539
    // Check for buffer overflow
540
    if (writer->buffer != NULL) {
541
        Py_ssize_t pos = PyUnicode_GET_LENGTH(writer->buffer);
542
        Py_UCS4 ch = PyUnicode_READ_CHAR(writer->buffer, pos);
543
        if (ch != 0) {
544
            _Py_FatalErrorFormat(__func__,
545
                                 "Buffer overflow detected in "
546
                                 "PyUnicodeWriter %p at position %zd",
547
                                 writer, pos);
548
        }
549
    }
550
#endif
551
552
50.5M
    PyObject *str = writer->buffer;
553
50.5M
    writer->buffer = NULL;
554
555
50.5M
    Py_ssize_t final_size = writer->pos;
556
50.5M
    if (final_size == 0) {
557
        // Get the empty string singleton
558
1.65k
        PyObject *empty = _PyUnicode_GetEmpty();
559
1.65k
        Py_XDECREF(str);  // writer->buffer can be NULL if the position is 0
560
1.65k
        return empty;
561
1.65k
    }
562
563
50.5M
    if (writer->readonly) {
564
24.1k
        assert(final_size == PyUnicode_GET_LENGTH(str));
565
24.1k
        goto done;
566
24.1k
    }
567
50.5M
    assert(final_size <= PyUnicode_GET_LENGTH(str));
568
569
50.5M
    if (final_size == 1 && PyUnicode_KIND(str) == PyUnicode_1BYTE_KIND) {
570
        // Get the single character singleton
571
154k
        assert(PyUnicode_GET_LENGTH(str) >= 1);
572
154k
        const Py_UCS1 *data = PyUnicode_1BYTE_DATA(str);
573
154k
        Py_UCS1 ch = data[0];
574
154k
        Py_DECREF(str);
575
154k
        str = _Py_LATIN1_CHR(ch);
576
154k
        goto done;
577
154k
    }
578
579
50.3M
    if (writer->recheck_maxchar) {
580
0
        Py_UCS4 maxchar = _PyUnicode_FindMaxChar(str, 0, final_size);
581
0
        if (maxchar != writer->maxchar) {
582
            // Adjust the string kind
583
0
            PyObject *str2 = PyUnicode_New(final_size, maxchar);
584
0
            if (str2 == NULL) {
585
0
                Py_DECREF(str);
586
0
                return NULL;
587
0
            }
588
0
            _PyUnicode_FastCopyCharacters(str2, 0, str, 0, final_size);
589
0
            Py_SETREF(str, str2);
590
0
            goto done;
591
0
        }
592
0
    }
593
594
50.3M
    if (PyUnicode_GET_LENGTH(str) != final_size) {
595
        // Truncate the string
596
41.8M
        PyObject *str2 = _PyUnicode_ResizeCompact(str, final_size);
597
41.8M
        if (str2 == NULL) {
598
0
            Py_DECREF(str);
599
0
            return NULL;
600
0
        }
601
41.8M
        str = str2;
602
41.8M
        goto done;
603
41.8M
    }
604
605
50.5M
done:
606
50.5M
    assert(_PyUnicode_CheckConsistency(str, 1));
607
50.5M
    return str;
608
50.3M
}
609
610
611
PyObject *
612
_PyUnicodeWriter_FinishWithSize(_PyUnicodeWriter *writer, Py_ssize_t size)
613
0
{
614
0
    assert(0 <= size);
615
0
    if (writer->buffer != NULL) {
616
0
        assert(size <= writer->pos);
617
0
        assert(size <= PyUnicode_GET_LENGTH(writer->buffer));
618
0
        if (size < writer->pos) {
619
            // Truncate the string: we may need to adjust the string kind
620
0
            writer->recheck_maxchar = 1;
621
0
        }
622
0
    }
623
0
    else {
624
0
        assert(size == 0);
625
0
    }
626
0
    writer->pos = size;
627
0
    return _PyUnicodeWriter_Finish(writer);
628
0
}
629
630
631
PyObject*
632
PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
633
4.44M
{
634
4.44M
    PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer);
635
4.44M
    assert(((_PyUnicodeWriter*)writer)->buffer == NULL);
636
4.44M
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
637
4.44M
    return str;
638
4.44M
}
639
640
641
void
642
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
643
3.72M
{
644
    Py_CLEAR(writer->buffer);
645
3.72M
}