Coverage Report

Created: 2025-11-30 06:38

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
119M
#  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
76.5M
{
121
76.5M
    writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer);
122
76.5M
    writer->data = PyUnicode_DATA(writer->buffer);
123
124
76.5M
    if (!writer->readonly) {
125
76.5M
        writer->kind = PyUnicode_KIND(writer->buffer);
126
76.5M
        writer->size = PyUnicode_GET_LENGTH(writer->buffer);
127
76.5M
    }
128
18.1k
    else {
129
        /* use a value smaller than PyUnicode_1BYTE_KIND() so
130
           _PyUnicodeWriter_PrepareKind() will copy the buffer. */
131
18.1k
        writer->kind = 0;
132
18.1k
        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
18.1k
        writer->size = 0;
138
18.1k
    }
139
76.5M
}
140
141
142
void
143
_PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
144
61.3M
{
145
61.3M
    memset(writer, 0, sizeof(*writer));
146
147
    /* ASCII is the bare minimum */
148
61.3M
    writer->min_char = 127;
149
150
    /* use a kind value smaller than PyUnicode_1BYTE_KIND so
151
       _PyUnicodeWriter_PrepareKind() will copy the buffer. */
152
61.3M
    assert(writer->kind == 0);
153
61.3M
    assert(writer->kind < PyUnicode_1BYTE_KIND);
154
61.3M
}
155
156
157
PyUnicodeWriter*
158
PyUnicodeWriter_Create(Py_ssize_t length)
159
4.41M
{
160
4.41M
    if (length < 0) {
161
0
        PyErr_SetString(PyExc_ValueError,
162
0
                        "length must be positive");
163
0
        return NULL;
164
0
    }
165
166
4.41M
    const size_t size = sizeof(_PyUnicodeWriter);
167
4.41M
    PyUnicodeWriter *pub_writer;
168
4.41M
    pub_writer = _Py_FREELIST_POP_MEM(unicode_writers);
169
4.41M
    if (pub_writer == NULL) {
170
2.56M
        pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size);
171
2.56M
        if (pub_writer == NULL) {
172
0
            return (PyUnicodeWriter *)PyErr_NoMemory();
173
0
        }
174
2.56M
    }
175
4.41M
    _PyUnicodeWriter *writer = (_PyUnicodeWriter *)pub_writer;
176
177
4.41M
    _PyUnicodeWriter_Init(writer);
178
4.41M
    if (_PyUnicodeWriter_Prepare(writer, length, 127) < 0) {
179
0
        PyUnicodeWriter_Discard(pub_writer);
180
0
        return NULL;
181
0
    }
182
4.41M
    writer->overallocate = 1;
183
184
4.41M
    return pub_writer;
185
4.41M
}
186
187
188
void PyUnicodeWriter_Discard(PyUnicodeWriter *writer)
189
77.7k
{
190
77.7k
    if (writer == NULL) {
191
77.2k
        return;
192
77.2k
    }
193
483
    _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer);
194
483
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
195
483
}
196
197
198
// Initialize _PyUnicodeWriter with initial buffer
199
void
200
_PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer)
201
1.85M
{
202
1.85M
    memset(writer, 0, sizeof(*writer));
203
1.85M
    writer->buffer = buffer;
204
1.85M
    _PyUnicodeWriter_Update(writer);
205
1.85M
    writer->min_length = writer->size;
206
1.85M
}
207
208
209
int
210
_PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
211
                                 Py_ssize_t length, Py_UCS4 maxchar)
212
74.6M
{
213
74.6M
    Py_ssize_t newlen;
214
74.6M
    PyObject *newbuffer;
215
216
74.6M
    assert(length >= 0);
217
74.6M
    assert(maxchar <= _Py_MAX_UNICODE);
218
219
    /* ensure that the _PyUnicodeWriter_Prepare macro was used */
220
74.6M
    assert((maxchar > writer->maxchar && length >= 0)
221
74.6M
           || length > 0);
222
223
74.6M
    if (length > PY_SSIZE_T_MAX - writer->pos) {
224
0
        PyErr_NoMemory();
225
0
        return -1;
226
0
    }
227
74.6M
    newlen = writer->pos + length;
228
229
74.6M
    maxchar = Py_MAX(maxchar, writer->min_char);
230
231
74.6M
    if (writer->buffer == NULL) {
232
56.9M
        assert(!writer->readonly);
233
56.9M
        if (writer->overallocate
234
45.7M
            && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
235
            /* overallocate to limit the number of realloc() */
236
45.7M
            newlen += newlen / OVERALLOCATE_FACTOR;
237
45.7M
        }
238
56.9M
        if (newlen < writer->min_length)
239
52.3M
            newlen = writer->min_length;
240
241
56.9M
        writer->buffer = PyUnicode_New(newlen, maxchar);
242
56.9M
        if (writer->buffer == NULL)
243
0
            return -1;
244
56.9M
    }
245
17.7M
    else if (newlen > writer->size) {
246
14.5M
        if (writer->overallocate
247
14.1M
            && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
248
            /* overallocate to limit the number of realloc() */
249
14.1M
            newlen += newlen / OVERALLOCATE_FACTOR;
250
14.1M
        }
251
14.5M
        if (newlen < writer->min_length)
252
1.46k
            newlen = writer->min_length;
253
254
14.5M
        if (maxchar > writer->maxchar || writer->readonly) {
255
            /* resize + widen */
256
4.03M
            maxchar = Py_MAX(maxchar, writer->maxchar);
257
4.03M
            newbuffer = PyUnicode_New(newlen, maxchar);
258
4.03M
            if (newbuffer == NULL)
259
0
                return -1;
260
4.03M
            _PyUnicode_FastCopyCharacters(newbuffer, 0,
261
4.03M
                                          writer->buffer, 0, writer->pos);
262
4.03M
            Py_DECREF(writer->buffer);
263
4.03M
            writer->readonly = 0;
264
4.03M
        }
265
10.5M
        else {
266
10.5M
            newbuffer = _PyUnicode_ResizeCompact(writer->buffer, newlen);
267
10.5M
            if (newbuffer == NULL)
268
0
                return -1;
269
10.5M
        }
270
14.5M
        writer->buffer = newbuffer;
271
14.5M
    }
272
3.16M
    else if (maxchar > writer->maxchar) {
273
3.16M
        assert(!writer->readonly);
274
3.16M
        newbuffer = PyUnicode_New(writer->size, maxchar);
275
3.16M
        if (newbuffer == NULL)
276
0
            return -1;
277
3.16M
        _PyUnicode_FastCopyCharacters(newbuffer, 0,
278
3.16M
                                      writer->buffer, 0, writer->pos);
279
3.16M
        Py_SETREF(writer->buffer, newbuffer);
280
3.16M
    }
281
74.6M
    _PyUnicodeWriter_Update(writer);
282
74.6M
    return 0;
283
284
74.6M
#undef OVERALLOCATE_FACTOR
285
74.6M
}
286
287
int
288
_PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
289
                                     int kind)
290
267k
{
291
267k
    Py_UCS4 maxchar;
292
293
    /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */
294
267k
    assert(writer->kind < kind);
295
296
267k
    switch (kind)
297
267k
    {
298
0
    case PyUnicode_1BYTE_KIND: maxchar = 0xff; break;
299
267k
    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
267k
    }
304
305
267k
    return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar);
306
267k
}
307
308
309
int
310
_PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch)
311
103M
{
312
103M
    return _PyUnicodeWriter_WriteCharInline(writer, ch);
313
103M
}
314
315
316
int
317
PyUnicodeWriter_WriteChar(PyUnicodeWriter *writer, Py_UCS4 ch)
318
69.5M
{
319
69.5M
    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
69.5M
    return _PyUnicodeWriter_WriteChar((_PyUnicodeWriter*)writer, ch);
326
69.5M
}
327
328
329
int
330
_PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str)
331
87.6M
{
332
87.6M
    assert(PyUnicode_Check(str));
333
334
87.6M
    Py_UCS4 maxchar;
335
87.6M
    Py_ssize_t len;
336
337
87.6M
    len = PyUnicode_GET_LENGTH(str);
338
87.6M
    if (len == 0)
339
19.6M
        return 0;
340
67.9M
    maxchar = PyUnicode_MAX_CHAR_VALUE(str);
341
67.9M
    if (maxchar > writer->maxchar || len > writer->size - writer->pos) {
342
23.8M
        if (writer->buffer == NULL && !writer->overallocate) {
343
9.98k
            assert(_PyUnicode_CheckConsistency(str, 1));
344
9.98k
            writer->readonly = 1;
345
9.98k
            writer->buffer = Py_NewRef(str);
346
9.98k
            _PyUnicodeWriter_Update(writer);
347
9.98k
            writer->pos += len;
348
9.98k
            return 0;
349
9.98k
        }
350
23.8M
        if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1)
351
0
            return -1;
352
23.8M
    }
353
67.9M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
354
67.9M
                                  str, 0, len);
355
67.9M
    writer->pos += len;
356
67.9M
    return 0;
357
67.9M
}
358
359
360
int
361
PyUnicodeWriter_WriteStr(PyUnicodeWriter *writer, PyObject *obj)
362
4.56M
{
363
4.56M
    PyTypeObject *type = Py_TYPE(obj);
364
4.56M
    if (type == &PyUnicode_Type) {
365
4.56M
        return _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, obj);
366
4.56M
    }
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
7.62M
{
386
7.62M
    if (Py_TYPE(obj) == &PyLong_Type) {
387
526k
        return _PyLong_FormatWriter((_PyUnicodeWriter*)writer, obj, 10, 0);
388
526k
    }
389
390
7.10M
    PyObject *repr = PyObject_Repr(obj);
391
7.10M
    if (repr == NULL) {
392
0
        return -1;
393
0
    }
394
395
7.10M
    int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, repr);
396
7.10M
    Py_DECREF(repr);
397
7.10M
    return res;
398
7.10M
}
399
400
401
int
402
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
403
                                Py_ssize_t start, Py_ssize_t end)
404
79.2M
{
405
79.2M
    assert(0 <= start);
406
79.2M
    assert(end <= PyUnicode_GET_LENGTH(str));
407
79.2M
    assert(start <= end);
408
409
79.2M
    if (start == 0 && end == PyUnicode_GET_LENGTH(str))
410
137
        return _PyUnicodeWriter_WriteStr(writer, str);
411
412
79.2M
    Py_ssize_t len = end - start;
413
79.2M
    if (len == 0) {
414
0
        return 0;
415
0
    }
416
417
79.2M
    Py_UCS4 maxchar;
418
79.2M
    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
419
20.8M
        maxchar = _PyUnicode_FindMaxChar(str, start, end);
420
20.8M
    }
421
58.4M
    else {
422
58.4M
        maxchar = writer->maxchar;
423
58.4M
    }
424
79.2M
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
425
0
        return -1;
426
0
    }
427
428
79.2M
    _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
429
79.2M
                                  str, start, len);
430
79.2M
    writer->pos += len;
431
79.2M
    return 0;
432
79.2M
}
433
434
435
int
436
PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
437
                               Py_ssize_t start, Py_ssize_t end)
438
527k
{
439
527k
    if (!PyUnicode_Check(str)) {
440
0
        PyErr_Format(PyExc_TypeError, "expect str, not %T", str);
441
0
        return -1;
442
0
    }
443
527k
    if (start < 0 || start > end) {
444
0
        PyErr_Format(PyExc_ValueError, "invalid start argument");
445
0
        return -1;
446
0
    }
447
527k
    if (end > PyUnicode_GET_LENGTH(str)) {
448
0
        PyErr_Format(PyExc_ValueError, "invalid end argument");
449
0
        return -1;
450
0
    }
451
452
527k
    return _PyUnicodeWriter_WriteSubstring((_PyUnicodeWriter*)writer, str,
453
527k
                                           start, end);
454
527k
}
455
456
457
int
458
_PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
459
                                  const char *ascii, Py_ssize_t len)
460
51.6M
{
461
51.6M
    if (len == -1)
462
0
        len = strlen(ascii);
463
464
51.6M
    assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128);
465
466
51.6M
    if (writer->buffer == NULL && !writer->overallocate) {
467
8.18k
        PyObject *str;
468
469
8.18k
        str = _PyUnicode_FromASCII(ascii, len);
470
8.18k
        if (str == NULL)
471
0
            return -1;
472
473
8.18k
        writer->readonly = 1;
474
8.18k
        writer->buffer = str;
475
8.18k
        _PyUnicodeWriter_Update(writer);
476
8.18k
        writer->pos += len;
477
8.18k
        return 0;
478
8.18k
    }
479
480
51.6M
    if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1)
481
0
        return -1;
482
483
51.6M
    switch (writer->kind)
484
51.6M
    {
485
51.5M
    case PyUnicode_1BYTE_KIND:
486
51.5M
    {
487
51.5M
        const Py_UCS1 *str = (const Py_UCS1 *)ascii;
488
51.5M
        Py_UCS1 *data = writer->data;
489
490
51.5M
        memcpy(data + writer->pos, str, len);
491
51.5M
        break;
492
0
    }
493
11.9k
    case PyUnicode_2BYTE_KIND:
494
11.9k
    {
495
11.9k
        _PyUnicode_CONVERT_BYTES(
496
11.9k
            Py_UCS1, Py_UCS2,
497
11.9k
            ascii, ascii + len,
498
11.9k
            (Py_UCS2 *)writer->data + writer->pos);
499
11.9k
        break;
500
0
    }
501
4.40k
    case PyUnicode_4BYTE_KIND:
502
4.40k
    {
503
4.40k
        _PyUnicode_CONVERT_BYTES(
504
4.40k
            Py_UCS1, Py_UCS4,
505
4.40k
            ascii, ascii + len,
506
4.40k
            (Py_UCS4 *)writer->data + writer->pos);
507
4.40k
        break;
508
0
    }
509
0
    default:
510
0
        Py_UNREACHABLE();
511
51.6M
    }
512
513
51.6M
    writer->pos += len;
514
51.6M
    return 0;
515
51.6M
}
516
517
518
int
519
PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
520
                           const char *str,
521
                           Py_ssize_t size)
522
1.27M
{
523
1.27M
    assert(writer != NULL);
524
1.27M
    _Py_AssertHoldsTstate();
525
526
1.27M
    _PyUnicodeWriter *priv_writer = (_PyUnicodeWriter*)writer;
527
1.27M
    return _PyUnicodeWriter_WriteASCIIString(priv_writer, str, size);
528
1.27M
}
529
530
531
int
532
PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
533
                          const char *str,
534
                          Py_ssize_t size)
535
24
{
536
24
    if (size < 0) {
537
24
        size = strlen(str);
538
24
    }
539
540
24
    _PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
541
24
    Py_ssize_t old_pos = _writer->pos;
542
24
    int res = _PyUnicode_DecodeUTF8Writer(_writer, str, size,
543
24
                                          _Py_ERROR_STRICT, NULL, NULL);
544
24
    if (res < 0) {
545
0
        _writer->pos = old_pos;
546
0
    }
547
24
    return res;
548
24
}
549
550
551
int
552
PyUnicodeWriter_DecodeUTF8Stateful(PyUnicodeWriter *writer,
553
                                   const char *string,
554
                                   Py_ssize_t length,
555
                                   const char *errors,
556
                                   Py_ssize_t *consumed)
557
0
{
558
0
    if (length < 0) {
559
0
        length = strlen(string);
560
0
    }
561
562
0
    _PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
563
0
    Py_ssize_t old_pos = _writer->pos;
564
0
    int res = _PyUnicode_DecodeUTF8Writer(_writer, string, length,
565
0
                                          _Py_ERROR_UNKNOWN, errors,
566
0
                                          consumed);
567
0
    if (res < 0) {
568
0
        _writer->pos = old_pos;
569
0
        if (consumed) {
570
0
            *consumed = 0;
571
0
        }
572
0
    }
573
0
    return res;
574
0
}
575
576
577
int
578
_PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
579
                                   const char *str, Py_ssize_t len)
580
0
{
581
0
    Py_UCS4 maxchar;
582
583
0
    maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len);
584
0
    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1)
585
0
        return -1;
586
0
    unicode_write_cstr(writer->buffer, writer->pos, str, len);
587
0
    writer->pos += len;
588
0
    return 0;
589
0
}
590
591
592
PyObject *
593
_PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
594
57.9M
{
595
57.9M
    PyObject *str;
596
597
57.9M
    if (writer->pos == 0) {
598
748
        Py_CLEAR(writer->buffer);
599
748
        return _PyUnicode_GetEmpty();
600
748
    }
601
602
57.9M
    str = writer->buffer;
603
57.9M
    writer->buffer = NULL;
604
605
57.9M
    if (writer->readonly) {
606
16.6k
        assert(PyUnicode_GET_LENGTH(str) == writer->pos);
607
16.6k
        return str;
608
16.6k
    }
609
610
57.9M
    if (PyUnicode_GET_LENGTH(str) != writer->pos) {
611
56.5M
        PyObject *str2;
612
56.5M
        str2 = _PyUnicode_ResizeCompact(str, writer->pos);
613
56.5M
        if (str2 == NULL) {
614
0
            Py_DECREF(str);
615
0
            return NULL;
616
0
        }
617
56.5M
        str = str2;
618
56.5M
    }
619
620
57.9M
    assert(_PyUnicode_CheckConsistency(str, 1));
621
57.9M
    return _PyUnicode_Result(str);
622
57.9M
}
623
624
625
PyObject*
626
PyUnicodeWriter_Finish(PyUnicodeWriter *writer)
627
4.41M
{
628
4.41M
    PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer);
629
4.41M
    assert(((_PyUnicodeWriter*)writer)->buffer == NULL);
630
4.41M
    _Py_FREELIST_FREE(unicode_writers, writer, PyMem_Free);
631
4.41M
    return str;
632
4.41M
}
633
634
635
void
636
_PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
637
5.23M
{
638
    Py_CLEAR(writer->buffer);
639
5.23M
}