~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Objects/bytearrayobject.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* PyByteArray (bytearray) implementation */
 
2
 
 
3
#define PY_SSIZE_T_CLEAN
 
4
#include "Python.h"
 
5
#include "structmember.h"
 
6
#include "bytes_methods.h"
 
7
 
 
8
char _PyByteArray_empty_string[] = "";
 
9
 
 
10
void
 
11
PyByteArray_Fini(void)
 
12
{
 
13
}
 
14
 
 
15
int
 
16
PyByteArray_Init(void)
 
17
{
 
18
    return 1;
 
19
}
 
20
 
 
21
/* end nullbytes support */
 
22
 
 
23
/* Helpers */
 
24
 
 
25
static int
 
26
_getbytevalue(PyObject* arg, int *value)
 
27
{
 
28
    long face_value;
 
29
 
 
30
    if (PyLong_Check(arg)) {
 
31
        face_value = PyLong_AsLong(arg);
 
32
    } else {
 
33
        PyObject *index = PyNumber_Index(arg);
 
34
        if (index == NULL) {
 
35
            PyErr_Format(PyExc_TypeError, "an integer is required");
 
36
            *value = -1;
 
37
            return 0;
 
38
        }
 
39
        face_value = PyLong_AsLong(index);
 
40
        Py_DECREF(index);
 
41
    }
 
42
 
 
43
    if (face_value < 0 || face_value >= 256) {
 
44
        /* this includes the OverflowError in case the long is too large */
 
45
        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
 
46
        *value = -1;
 
47
        return 0;
 
48
    }
 
49
 
 
50
    *value = face_value;
 
51
    return 1;
 
52
}
 
53
 
 
54
static int
 
55
bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
 
56
{
 
57
    int ret;
 
58
    void *ptr;
 
59
    if (view == NULL) {
 
60
        obj->ob_exports++;
 
61
        return 0;
 
62
    }
 
63
    ptr = (void *) PyByteArray_AS_STRING(obj);
 
64
    ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
 
65
    if (ret >= 0) {
 
66
        obj->ob_exports++;
 
67
    }
 
68
    return ret;
 
69
}
 
70
 
 
71
static void
 
72
bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
 
73
{
 
74
    obj->ob_exports--;
 
75
}
 
76
 
 
77
static Py_ssize_t
 
78
_getbuffer(PyObject *obj, Py_buffer *view)
 
79
{
 
80
    PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
 
81
 
 
82
    if (buffer == NULL || buffer->bf_getbuffer == NULL)
 
83
    {
 
84
        PyErr_Format(PyExc_TypeError,
 
85
                     "Type %.100s doesn't support the buffer API",
 
86
                     Py_TYPE(obj)->tp_name);
 
87
        return -1;
 
88
    }
 
89
 
 
90
    if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
 
91
            return -1;
 
92
    return view->len;
 
93
}
 
94
 
 
95
static int
 
96
_canresize(PyByteArrayObject *self)
 
97
{
 
98
    if (self->ob_exports > 0) {
 
99
        PyErr_SetString(PyExc_BufferError,
 
100
                "Existing exports of data: object cannot be re-sized");
 
101
        return 0;
 
102
    }
 
103
    return 1;
 
104
}
 
105
 
 
106
/* Direct API functions */
 
107
 
 
108
PyObject *
 
109
PyByteArray_FromObject(PyObject *input)
 
110
{
 
111
    return PyObject_CallFunctionObjArgs((PyObject *)&PyByteArray_Type,
 
112
                                        input, NULL);
 
113
}
 
114
 
 
115
PyObject *
 
116
PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
 
117
{
 
118
    PyByteArrayObject *new;
 
119
    Py_ssize_t alloc;
 
120
 
 
121
    if (size < 0) {
 
122
        PyErr_SetString(PyExc_SystemError,
 
123
            "Negative size passed to PyByteArray_FromStringAndSize");
 
124
        return NULL;
 
125
    }
 
126
 
 
127
    /* Prevent buffer overflow when setting alloc to size+1. */
 
128
    if (size == PY_SSIZE_T_MAX) {
 
129
        return PyErr_NoMemory();
 
130
    }
 
131
 
 
132
    new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
 
133
    if (new == NULL)
 
134
        return NULL;
 
135
 
 
136
    if (size == 0) {
 
137
        new->ob_bytes = NULL;
 
138
        alloc = 0;
 
139
    }
 
140
    else {
 
141
        alloc = size + 1;
 
142
        new->ob_bytes = PyObject_Malloc(alloc);
 
143
        if (new->ob_bytes == NULL) {
 
144
            Py_DECREF(new);
 
145
            return PyErr_NoMemory();
 
146
        }
 
147
        if (bytes != NULL && size > 0)
 
148
            memcpy(new->ob_bytes, bytes, size);
 
149
        new->ob_bytes[size] = '\0';  /* Trailing null byte */
 
150
    }
 
151
    Py_SIZE(new) = size;
 
152
    new->ob_alloc = alloc;
 
153
    new->ob_start = new->ob_bytes;
 
154
    new->ob_exports = 0;
 
155
 
 
156
    return (PyObject *)new;
 
157
}
 
158
 
 
159
Py_ssize_t
 
160
PyByteArray_Size(PyObject *self)
 
161
{
 
162
    assert(self != NULL);
 
163
    assert(PyByteArray_Check(self));
 
164
 
 
165
    return PyByteArray_GET_SIZE(self);
 
166
}
 
167
 
 
168
char  *
 
169
PyByteArray_AsString(PyObject *self)
 
170
{
 
171
    assert(self != NULL);
 
172
    assert(PyByteArray_Check(self));
 
173
 
 
174
    return PyByteArray_AS_STRING(self);
 
175
}
 
176
 
 
177
int
 
178
PyByteArray_Resize(PyObject *self, Py_ssize_t size)
 
179
{
 
180
    void *sval;
 
181
    PyByteArrayObject *obj = ((PyByteArrayObject *)self);
 
182
    Py_ssize_t alloc = obj->ob_alloc;
 
183
    Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes;
 
184
 
 
185
    assert(self != NULL);
 
186
    assert(PyByteArray_Check(self));
 
187
    assert(size >= 0);
 
188
    assert(logical_offset >= 0);
 
189
    assert(logical_offset <= alloc);
 
190
 
 
191
    if (size == Py_SIZE(self)) {
 
192
        return 0;
 
193
    }
 
194
    if (!_canresize(obj)) {
 
195
        return -1;
 
196
    }
 
197
 
 
198
    if (size + logical_offset + 1 < alloc) {
 
199
        /* Current buffer is large enough to host the requested size,
 
200
           decide on a strategy. */
 
201
        if (size < alloc / 2) {
 
202
            /* Major downsize; resize down to exact size */
 
203
            alloc = size + 1;
 
204
        }
 
205
        else {
 
206
            /* Minor downsize; quick exit */
 
207
            Py_SIZE(self) = size;
 
208
            PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
 
209
            return 0;
 
210
        }
 
211
    }
 
212
    else {
 
213
        /* Need growing, decide on a strategy */
 
214
        if (size <= alloc * 1.125) {
 
215
            /* Moderate upsize; overallocate similar to list_resize() */
 
216
            alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
 
217
        }
 
218
        else {
 
219
            /* Major upsize; resize up to exact size */
 
220
            alloc = size + 1;
 
221
        }
 
222
    }
 
223
 
 
224
    if (logical_offset > 0) {
 
225
        sval = PyObject_Malloc(alloc);
 
226
        if (sval == NULL) {
 
227
            PyErr_NoMemory();
 
228
            return -1;
 
229
        }
 
230
        memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self)));
 
231
        PyObject_Free(obj->ob_bytes);
 
232
    }
 
233
    else {
 
234
        sval = PyObject_Realloc(obj->ob_bytes, alloc);
 
235
        if (sval == NULL) {
 
236
            PyErr_NoMemory();
 
237
            return -1;
 
238
        }
 
239
    }
 
240
 
 
241
    obj->ob_bytes = obj->ob_start = sval;
 
242
    Py_SIZE(self) = size;
 
243
    obj->ob_alloc = alloc;
 
244
    obj->ob_bytes[size] = '\0'; /* Trailing null byte */
 
245
 
 
246
    return 0;
 
247
}
 
248
 
 
249
PyObject *
 
250
PyByteArray_Concat(PyObject *a, PyObject *b)
 
251
{
 
252
    Py_ssize_t size;
 
253
    Py_buffer va, vb;
 
254
    PyByteArrayObject *result = NULL;
 
255
 
 
256
    va.len = -1;
 
257
    vb.len = -1;
 
258
    if (_getbuffer(a, &va) < 0  ||
 
259
        _getbuffer(b, &vb) < 0) {
 
260
            PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
 
261
                         Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
 
262
            goto done;
 
263
    }
 
264
 
 
265
    size = va.len + vb.len;
 
266
    if (size < 0) {
 
267
            PyErr_NoMemory();
 
268
            goto done;
 
269
    }
 
270
 
 
271
    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, size);
 
272
    if (result != NULL) {
 
273
        memcpy(result->ob_bytes, va.buf, va.len);
 
274
        memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
 
275
    }
 
276
 
 
277
  done:
 
278
    if (va.len != -1)
 
279
        PyBuffer_Release(&va);
 
280
    if (vb.len != -1)
 
281
        PyBuffer_Release(&vb);
 
282
    return (PyObject *)result;
 
283
}
 
284
 
 
285
/* Functions stuffed into the type object */
 
286
 
 
287
static Py_ssize_t
 
288
bytearray_length(PyByteArrayObject *self)
 
289
{
 
290
    return Py_SIZE(self);
 
291
}
 
292
 
 
293
static PyObject *
 
294
bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
 
295
{
 
296
    Py_ssize_t mysize;
 
297
    Py_ssize_t size;
 
298
    Py_buffer vo;
 
299
 
 
300
    if (_getbuffer(other, &vo) < 0) {
 
301
        PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
 
302
                     Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
 
303
        return NULL;
 
304
    }
 
305
 
 
306
    mysize = Py_SIZE(self);
 
307
    size = mysize + vo.len;
 
308
    if (size < 0) {
 
309
        PyBuffer_Release(&vo);
 
310
        return PyErr_NoMemory();
 
311
    }
 
312
    if (size < self->ob_alloc) {
 
313
        Py_SIZE(self) = size;
 
314
        PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
 
315
    }
 
316
    else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
 
317
        PyBuffer_Release(&vo);
 
318
        return NULL;
 
319
    }
 
320
    memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
 
321
    PyBuffer_Release(&vo);
 
322
    Py_INCREF(self);
 
323
    return (PyObject *)self;
 
324
}
 
325
 
 
326
static PyObject *
 
327
bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
 
328
{
 
329
    PyByteArrayObject *result;
 
330
    Py_ssize_t mysize;
 
331
    Py_ssize_t size;
 
332
 
 
333
    if (count < 0)
 
334
        count = 0;
 
335
    mysize = Py_SIZE(self);
 
336
    if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
 
337
        return PyErr_NoMemory();
 
338
    size = mysize * count;
 
339
    result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
 
340
    if (result != NULL && size != 0) {
 
341
        if (mysize == 1)
 
342
            memset(result->ob_bytes, self->ob_bytes[0], size);
 
343
        else {
 
344
            Py_ssize_t i;
 
345
            for (i = 0; i < count; i++)
 
346
                memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
 
347
        }
 
348
    }
 
349
    return (PyObject *)result;
 
350
}
 
351
 
 
352
static PyObject *
 
353
bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
 
354
{
 
355
    Py_ssize_t mysize;
 
356
    Py_ssize_t size;
 
357
    char *buf;
 
358
 
 
359
    if (count < 0)
 
360
        count = 0;
 
361
    mysize = Py_SIZE(self);
 
362
    if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
 
363
        return PyErr_NoMemory();
 
364
    size = mysize * count;
 
365
    if (PyByteArray_Resize((PyObject *)self, size) < 0)
 
366
        return NULL;
 
367
 
 
368
    buf = PyByteArray_AS_STRING(self);
 
369
    if (mysize == 1)
 
370
        memset(buf, buf[0], size);
 
371
    else {
 
372
        Py_ssize_t i;
 
373
        for (i = 1; i < count; i++)
 
374
            memcpy(buf + i*mysize, buf, mysize);
 
375
    }
 
376
 
 
377
    Py_INCREF(self);
 
378
    return (PyObject *)self;
 
379
}
 
380
 
 
381
static PyObject *
 
382
bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
 
383
{
 
384
    if (i < 0)
 
385
        i += Py_SIZE(self);
 
386
    if (i < 0 || i >= Py_SIZE(self)) {
 
387
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
 
388
        return NULL;
 
389
    }
 
390
    return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
 
391
}
 
392
 
 
393
static PyObject *
 
394
bytearray_subscript(PyByteArrayObject *self, PyObject *index)
 
395
{
 
396
    if (PyIndex_Check(index)) {
 
397
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
 
398
 
 
399
        if (i == -1 && PyErr_Occurred())
 
400
            return NULL;
 
401
 
 
402
        if (i < 0)
 
403
            i += PyByteArray_GET_SIZE(self);
 
404
 
 
405
        if (i < 0 || i >= Py_SIZE(self)) {
 
406
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
 
407
            return NULL;
 
408
        }
 
409
        return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
 
410
    }
 
411
    else if (PySlice_Check(index)) {
 
412
        Py_ssize_t start, stop, step, slicelength, cur, i;
 
413
        if (PySlice_GetIndicesEx(index,
 
414
                                 PyByteArray_GET_SIZE(self),
 
415
                                 &start, &stop, &step, &slicelength) < 0) {
 
416
            return NULL;
 
417
        }
 
418
 
 
419
        if (slicelength <= 0)
 
420
            return PyByteArray_FromStringAndSize("", 0);
 
421
        else if (step == 1) {
 
422
            return PyByteArray_FromStringAndSize(
 
423
                PyByteArray_AS_STRING(self) + start, slicelength);
 
424
        }
 
425
        else {
 
426
            char *source_buf = PyByteArray_AS_STRING(self);
 
427
            char *result_buf;
 
428
            PyObject *result;
 
429
 
 
430
            result = PyByteArray_FromStringAndSize(NULL, slicelength);
 
431
            if (result == NULL)
 
432
                return NULL;
 
433
 
 
434
            result_buf = PyByteArray_AS_STRING(result);
 
435
            for (cur = start, i = 0; i < slicelength;
 
436
                 cur += step, i++) {
 
437
                     result_buf[i] = source_buf[cur];
 
438
            }
 
439
            return result;
 
440
        }
 
441
    }
 
442
    else {
 
443
        PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers");
 
444
        return NULL;
 
445
    }
 
446
}
 
447
 
 
448
static int
 
449
bytearray_setslice_linear(PyByteArrayObject *self,
 
450
                          Py_ssize_t lo, Py_ssize_t hi,
 
451
                          char *bytes, Py_ssize_t bytes_len)
 
452
{
 
453
    Py_ssize_t avail = hi - lo;
 
454
    char *buf = PyByteArray_AS_STRING(self);
 
455
    Py_ssize_t growth = bytes_len - avail;
 
456
    int res = 0;
 
457
    assert(avail >= 0);
 
458
 
 
459
    if (growth < 0) {
 
460
        if (!_canresize(self))
 
461
            return -1;
 
462
 
 
463
        if (lo == 0) {
 
464
            /* Shrink the buffer by advancing its logical start */
 
465
            self->ob_start -= growth;
 
466
            /*
 
467
              0   lo               hi             old_size
 
468
              |   |<----avail----->|<-----tail------>|
 
469
              |      |<-bytes_len->|<-----tail------>|
 
470
              0    new_lo         new_hi          new_size
 
471
            */
 
472
        }
 
473
        else {
 
474
            /*
 
475
              0   lo               hi               old_size
 
476
              |   |<----avail----->|<-----tomove------>|
 
477
              |   |<-bytes_len->|<-----tomove------>|
 
478
              0   lo         new_hi              new_size
 
479
            */
 
480
            memmove(buf + lo + bytes_len, buf + hi,
 
481
                    Py_SIZE(self) - hi);
 
482
        }
 
483
        if (PyByteArray_Resize((PyObject *)self,
 
484
                               Py_SIZE(self) + growth) < 0) {
 
485
            /* Issue #19578: Handling the memory allocation failure here is
 
486
               tricky here because the bytearray object has already been
 
487
               modified. Depending on growth and lo, the behaviour is
 
488
               different.
 
489
 
 
490
               If growth < 0 and lo != 0, the operation is completed, but a
 
491
               MemoryError is still raised and the memory block is not
 
492
               shrinked. Otherwise, the bytearray is restored in its previous
 
493
               state and a MemoryError is raised. */
 
494
            if (lo == 0) {
 
495
                self->ob_start += growth;
 
496
                return -1;
 
497
            }
 
498
            /* memmove() removed bytes, the bytearray object cannot be
 
499
               restored in its previous state. */
 
500
            Py_SIZE(self) += growth;
 
501
            res = -1;
 
502
        }
 
503
        buf = PyByteArray_AS_STRING(self);
 
504
    }
 
505
    else if (growth > 0) {
 
506
        if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
 
507
            PyErr_NoMemory();
 
508
            return -1;
 
509
        }
 
510
 
 
511
        if (PyByteArray_Resize((PyObject *)self,
 
512
                               Py_SIZE(self) + growth) < 0) {
 
513
            return -1;
 
514
        }
 
515
        buf = PyByteArray_AS_STRING(self);
 
516
        /* Make the place for the additional bytes */
 
517
        /*
 
518
          0   lo        hi               old_size
 
519
          |   |<-avail->|<-----tomove------>|
 
520
          |   |<---bytes_len-->|<-----tomove------>|
 
521
          0   lo            new_hi              new_size
 
522
         */
 
523
        memmove(buf + lo + bytes_len, buf + hi,
 
524
                Py_SIZE(self) - lo - bytes_len);
 
525
    }
 
526
 
 
527
    if (bytes_len > 0)
 
528
        memcpy(buf + lo, bytes, bytes_len);
 
529
    return res;
 
530
}
 
531
 
 
532
static int
 
533
bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
 
534
               PyObject *values)
 
535
{
 
536
    Py_ssize_t needed;
 
537
    void *bytes;
 
538
    Py_buffer vbytes;
 
539
    int res = 0;
 
540
 
 
541
    vbytes.len = -1;
 
542
    if (values == (PyObject *)self) {
 
543
        /* Make a copy and call this function recursively */
 
544
        int err;
 
545
        values = PyByteArray_FromObject(values);
 
546
        if (values == NULL)
 
547
            return -1;
 
548
        err = bytearray_setslice(self, lo, hi, values);
 
549
        Py_DECREF(values);
 
550
        return err;
 
551
    }
 
552
    if (values == NULL) {
 
553
        /* del b[lo:hi] */
 
554
        bytes = NULL;
 
555
        needed = 0;
 
556
    }
 
557
    else {
 
558
            if (_getbuffer(values, &vbytes) < 0) {
 
559
                    PyErr_Format(PyExc_TypeError,
 
560
                                 "can't set bytearray slice from %.100s",
 
561
                                 Py_TYPE(values)->tp_name);
 
562
                    return -1;
 
563
            }
 
564
            needed = vbytes.len;
 
565
            bytes = vbytes.buf;
 
566
    }
 
567
 
 
568
    if (lo < 0)
 
569
        lo = 0;
 
570
    if (hi < lo)
 
571
        hi = lo;
 
572
    if (hi > Py_SIZE(self))
 
573
        hi = Py_SIZE(self);
 
574
 
 
575
    res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
 
576
    if (vbytes.len != -1)
 
577
        PyBuffer_Release(&vbytes);
 
578
    return res;
 
579
}
 
580
 
 
581
static int
 
582
bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
 
583
{
 
584
    int ival;
 
585
 
 
586
    if (i < 0)
 
587
        i += Py_SIZE(self);
 
588
 
 
589
    if (i < 0 || i >= Py_SIZE(self)) {
 
590
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
 
591
        return -1;
 
592
    }
 
593
 
 
594
    if (value == NULL)
 
595
        return bytearray_setslice(self, i, i+1, NULL);
 
596
 
 
597
    if (!_getbytevalue(value, &ival))
 
598
        return -1;
 
599
 
 
600
    PyByteArray_AS_STRING(self)[i] = ival;
 
601
    return 0;
 
602
}
 
603
 
 
604
static int
 
605
bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
 
606
{
 
607
    Py_ssize_t start, stop, step, slicelen, needed;
 
608
    char *buf, *bytes;
 
609
    buf = PyByteArray_AS_STRING(self);
 
610
 
 
611
    if (PyIndex_Check(index)) {
 
612
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
 
613
 
 
614
        if (i == -1 && PyErr_Occurred())
 
615
            return -1;
 
616
 
 
617
        if (i < 0)
 
618
            i += PyByteArray_GET_SIZE(self);
 
619
 
 
620
        if (i < 0 || i >= Py_SIZE(self)) {
 
621
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
 
622
            return -1;
 
623
        }
 
624
 
 
625
        if (values == NULL) {
 
626
            /* Fall through to slice assignment */
 
627
            start = i;
 
628
            stop = i + 1;
 
629
            step = 1;
 
630
            slicelen = 1;
 
631
        }
 
632
        else {
 
633
            int ival;
 
634
            if (!_getbytevalue(values, &ival))
 
635
                return -1;
 
636
            buf[i] = (char)ival;
 
637
            return 0;
 
638
        }
 
639
    }
 
640
    else if (PySlice_Check(index)) {
 
641
        if (PySlice_GetIndicesEx(index,
 
642
                                 PyByteArray_GET_SIZE(self),
 
643
                                 &start, &stop, &step, &slicelen) < 0) {
 
644
            return -1;
 
645
        }
 
646
    }
 
647
    else {
 
648
        PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer");
 
649
        return -1;
 
650
    }
 
651
 
 
652
    if (values == NULL) {
 
653
        bytes = NULL;
 
654
        needed = 0;
 
655
    }
 
656
    else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
 
657
        int err;
 
658
        if (PyNumber_Check(values) || PyUnicode_Check(values)) {
 
659
            PyErr_SetString(PyExc_TypeError,
 
660
                            "can assign only bytes, buffers, or iterables "
 
661
                            "of ints in range(0, 256)");
 
662
            return -1;
 
663
        }
 
664
        /* Make a copy and call this function recursively */
 
665
        values = PyByteArray_FromObject(values);
 
666
        if (values == NULL)
 
667
            return -1;
 
668
        err = bytearray_ass_subscript(self, index, values);
 
669
        Py_DECREF(values);
 
670
        return err;
 
671
    }
 
672
    else {
 
673
        assert(PyByteArray_Check(values));
 
674
        bytes = PyByteArray_AS_STRING(values);
 
675
        needed = Py_SIZE(values);
 
676
    }
 
677
    /* Make sure b[5:2] = ... inserts before 5, not before 2. */
 
678
    if ((step < 0 && start < stop) ||
 
679
        (step > 0 && start > stop))
 
680
        stop = start;
 
681
    if (step == 1) {
 
682
        return bytearray_setslice_linear(self, start, stop, bytes, needed);
 
683
    }
 
684
    else {
 
685
        if (needed == 0) {
 
686
            /* Delete slice */
 
687
            size_t cur;
 
688
            Py_ssize_t i;
 
689
 
 
690
            if (!_canresize(self))
 
691
                return -1;
 
692
 
 
693
            if (slicelen == 0)
 
694
                /* Nothing to do here. */
 
695
                return 0;
 
696
 
 
697
            if (step < 0) {
 
698
                stop = start + 1;
 
699
                start = stop + step * (slicelen - 1) - 1;
 
700
                step = -step;
 
701
            }
 
702
            for (cur = start, i = 0;
 
703
                 i < slicelen; cur += step, i++) {
 
704
                Py_ssize_t lim = step - 1;
 
705
 
 
706
                if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
 
707
                    lim = PyByteArray_GET_SIZE(self) - cur - 1;
 
708
 
 
709
                memmove(buf + cur - i,
 
710
                        buf + cur + 1, lim);
 
711
            }
 
712
            /* Move the tail of the bytes, in one chunk */
 
713
            cur = start + (size_t)slicelen*step;
 
714
            if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
 
715
                memmove(buf + cur - slicelen,
 
716
                        buf + cur,
 
717
                        PyByteArray_GET_SIZE(self) - cur);
 
718
            }
 
719
            if (PyByteArray_Resize((PyObject *)self,
 
720
                               PyByteArray_GET_SIZE(self) - slicelen) < 0)
 
721
                return -1;
 
722
 
 
723
            return 0;
 
724
        }
 
725
        else {
 
726
            /* Assign slice */
 
727
            Py_ssize_t i;
 
728
            size_t cur;
 
729
 
 
730
            if (needed != slicelen) {
 
731
                PyErr_Format(PyExc_ValueError,
 
732
                             "attempt to assign bytes of size %zd "
 
733
                             "to extended slice of size %zd",
 
734
                             needed, slicelen);
 
735
                return -1;
 
736
            }
 
737
            for (cur = start, i = 0; i < slicelen; cur += step, i++)
 
738
                buf[cur] = bytes[i];
 
739
            return 0;
 
740
        }
 
741
    }
 
742
}
 
743
 
 
744
static int
 
745
bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
 
746
{
 
747
    static char *kwlist[] = {"source", "encoding", "errors", 0};
 
748
    PyObject *arg = NULL;
 
749
    const char *encoding = NULL;
 
750
    const char *errors = NULL;
 
751
    Py_ssize_t count;
 
752
    PyObject *it;
 
753
    PyObject *(*iternext)(PyObject *);
 
754
 
 
755
    if (Py_SIZE(self) != 0) {
 
756
        /* Empty previous contents (yes, do this first of all!) */
 
757
        if (PyByteArray_Resize((PyObject *)self, 0) < 0)
 
758
            return -1;
 
759
    }
 
760
 
 
761
    /* Parse arguments */
 
762
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytearray", kwlist,
 
763
                                     &arg, &encoding, &errors))
 
764
        return -1;
 
765
 
 
766
    /* Make a quick exit if no first argument */
 
767
    if (arg == NULL) {
 
768
        if (encoding != NULL || errors != NULL) {
 
769
            PyErr_SetString(PyExc_TypeError,
 
770
                            "encoding or errors without sequence argument");
 
771
            return -1;
 
772
        }
 
773
        return 0;
 
774
    }
 
775
 
 
776
    if (PyUnicode_Check(arg)) {
 
777
        /* Encode via the codec registry */
 
778
        PyObject *encoded, *new;
 
779
        if (encoding == NULL) {
 
780
            PyErr_SetString(PyExc_TypeError,
 
781
                            "string argument without an encoding");
 
782
            return -1;
 
783
        }
 
784
        encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
 
785
        if (encoded == NULL)
 
786
            return -1;
 
787
        assert(PyBytes_Check(encoded));
 
788
        new = bytearray_iconcat(self, encoded);
 
789
        Py_DECREF(encoded);
 
790
        if (new == NULL)
 
791
            return -1;
 
792
        Py_DECREF(new);
 
793
        return 0;
 
794
    }
 
795
 
 
796
    /* If it's not unicode, there can't be encoding or errors */
 
797
    if (encoding != NULL || errors != NULL) {
 
798
        PyErr_SetString(PyExc_TypeError,
 
799
                        "encoding or errors without a string argument");
 
800
        return -1;
 
801
    }
 
802
 
 
803
    /* Is it an int? */
 
804
    count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
 
805
    if (count == -1 && PyErr_Occurred()) {
 
806
        if (PyErr_ExceptionMatches(PyExc_OverflowError))
 
807
            return -1;
 
808
        PyErr_Clear();
 
809
    }
 
810
    else if (count < 0) {
 
811
        PyErr_SetString(PyExc_ValueError, "negative count");
 
812
        return -1;
 
813
    }
 
814
    else {
 
815
        if (count > 0) {
 
816
            if (PyByteArray_Resize((PyObject *)self, count))
 
817
                return -1;
 
818
            memset(PyByteArray_AS_STRING(self), 0, count);
 
819
        }
 
820
        return 0;
 
821
    }
 
822
 
 
823
    /* Use the buffer API */
 
824
    if (PyObject_CheckBuffer(arg)) {
 
825
        Py_ssize_t size;
 
826
        Py_buffer view;
 
827
        if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
 
828
            return -1;
 
829
        size = view.len;
 
830
        if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
 
831
        if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
 
832
            &view, size, 'C') < 0)
 
833
            goto fail;
 
834
        PyBuffer_Release(&view);
 
835
        return 0;
 
836
    fail:
 
837
        PyBuffer_Release(&view);
 
838
        return -1;
 
839
    }
 
840
 
 
841
    /* XXX Optimize this if the arguments is a list, tuple */
 
842
 
 
843
    /* Get the iterator */
 
844
    it = PyObject_GetIter(arg);
 
845
    if (it == NULL)
 
846
        return -1;
 
847
    iternext = *Py_TYPE(it)->tp_iternext;
 
848
 
 
849
    /* Run the iterator to exhaustion */
 
850
    for (;;) {
 
851
        PyObject *item;
 
852
        int rc, value;
 
853
 
 
854
        /* Get the next item */
 
855
        item = iternext(it);
 
856
        if (item == NULL) {
 
857
            if (PyErr_Occurred()) {
 
858
                if (!PyErr_ExceptionMatches(PyExc_StopIteration))
 
859
                    goto error;
 
860
                PyErr_Clear();
 
861
            }
 
862
            break;
 
863
        }
 
864
 
 
865
        /* Interpret it as an int (__index__) */
 
866
        rc = _getbytevalue(item, &value);
 
867
        Py_DECREF(item);
 
868
        if (!rc)
 
869
            goto error;
 
870
 
 
871
        /* Append the byte */
 
872
        if (Py_SIZE(self) < self->ob_alloc)
 
873
            Py_SIZE(self)++;
 
874
        else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
 
875
            goto error;
 
876
        PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
 
877
    }
 
878
 
 
879
    /* Clean up and return success */
 
880
    Py_DECREF(it);
 
881
    return 0;
 
882
 
 
883
 error:
 
884
    /* Error handling when it != NULL */
 
885
    Py_DECREF(it);
 
886
    return -1;
 
887
}
 
888
 
 
889
/* Mostly copied from string_repr, but without the
 
890
   "smart quote" functionality. */
 
891
static PyObject *
 
892
bytearray_repr(PyByteArrayObject *self)
 
893
{
 
894
    const char *quote_prefix = "bytearray(b";
 
895
    const char *quote_postfix = ")";
 
896
    Py_ssize_t length = Py_SIZE(self);
 
897
    /* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
 
898
    size_t newsize;
 
899
    PyObject *v;
 
900
    Py_ssize_t i;
 
901
    char *bytes;
 
902
    char c;
 
903
    char *p;
 
904
    int quote;
 
905
    char *test, *start;
 
906
    char *buffer;
 
907
 
 
908
    if (length > (PY_SSIZE_T_MAX - 15) / 4) {
 
909
        PyErr_SetString(PyExc_OverflowError,
 
910
            "bytearray object is too large to make repr");
 
911
        return NULL;
 
912
    }
 
913
 
 
914
    newsize = 15 + length * 4;
 
915
    buffer = PyObject_Malloc(newsize);
 
916
    if (buffer == NULL) {
 
917
        PyErr_NoMemory();
 
918
        return NULL;
 
919
    }
 
920
 
 
921
    /* Figure out which quote to use; single is preferred */
 
922
    quote = '\'';
 
923
    start = PyByteArray_AS_STRING(self);
 
924
    for (test = start; test < start+length; ++test) {
 
925
        if (*test == '"') {
 
926
            quote = '\''; /* back to single */
 
927
            break;
 
928
        }
 
929
        else if (*test == '\'')
 
930
            quote = '"';
 
931
    }
 
932
 
 
933
    p = buffer;
 
934
    while (*quote_prefix)
 
935
        *p++ = *quote_prefix++;
 
936
    *p++ = quote;
 
937
 
 
938
    bytes = PyByteArray_AS_STRING(self);
 
939
    for (i = 0; i < length; i++) {
 
940
        /* There's at least enough room for a hex escape
 
941
           and a closing quote. */
 
942
        assert(newsize - (p - buffer) >= 5);
 
943
        c = bytes[i];
 
944
        if (c == '\'' || c == '\\')
 
945
            *p++ = '\\', *p++ = c;
 
946
        else if (c == '\t')
 
947
            *p++ = '\\', *p++ = 't';
 
948
        else if (c == '\n')
 
949
            *p++ = '\\', *p++ = 'n';
 
950
        else if (c == '\r')
 
951
            *p++ = '\\', *p++ = 'r';
 
952
        else if (c == 0)
 
953
            *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
 
954
        else if (c < ' ' || c >= 0x7f) {
 
955
            *p++ = '\\';
 
956
            *p++ = 'x';
 
957
            *p++ = Py_hexdigits[(c & 0xf0) >> 4];
 
958
            *p++ = Py_hexdigits[c & 0xf];
 
959
        }
 
960
        else
 
961
            *p++ = c;
 
962
    }
 
963
    assert(newsize - (p - buffer) >= 1);
 
964
    *p++ = quote;
 
965
    while (*quote_postfix) {
 
966
       *p++ = *quote_postfix++;
 
967
    }
 
968
 
 
969
    v = PyUnicode_DecodeASCII(buffer, p - buffer, NULL);
 
970
    PyObject_Free(buffer);
 
971
    return v;
 
972
}
 
973
 
 
974
static PyObject *
 
975
bytearray_str(PyObject *op)
 
976
{
 
977
        if (Py_BytesWarningFlag) {
 
978
                if (PyErr_WarnEx(PyExc_BytesWarning,
 
979
                                 "str() on a bytearray instance", 1))
 
980
                        return NULL;
 
981
        }
 
982
        return bytearray_repr((PyByteArrayObject*)op);
 
983
}
 
984
 
 
985
static PyObject *
 
986
bytearray_richcompare(PyObject *self, PyObject *other, int op)
 
987
{
 
988
    Py_ssize_t self_size, other_size;
 
989
    Py_buffer self_bytes, other_bytes;
 
990
    PyObject *res;
 
991
    Py_ssize_t minsize;
 
992
    int cmp;
 
993
 
 
994
    /* Bytes can be compared to anything that supports the (binary)
 
995
       buffer API.  Except that a comparison with Unicode is always an
 
996
       error, even if the comparison is for equality. */
 
997
    if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) ||
 
998
        PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) {
 
999
        if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
 
1000
            if (PyErr_WarnEx(PyExc_BytesWarning,
 
1001
                            "Comparison between bytearray and string", 1))
 
1002
                return NULL;
 
1003
        }
 
1004
 
 
1005
        Py_RETURN_NOTIMPLEMENTED;
 
1006
    }
 
1007
 
 
1008
    self_size = _getbuffer(self, &self_bytes);
 
1009
    if (self_size < 0) {
 
1010
        PyErr_Clear();
 
1011
        Py_RETURN_NOTIMPLEMENTED;
 
1012
    }
 
1013
 
 
1014
    other_size = _getbuffer(other, &other_bytes);
 
1015
    if (other_size < 0) {
 
1016
        PyErr_Clear();
 
1017
        PyBuffer_Release(&self_bytes);
 
1018
        Py_RETURN_NOTIMPLEMENTED;
 
1019
    }
 
1020
 
 
1021
    if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
 
1022
        /* Shortcut: if the lengths differ, the objects differ */
 
1023
        cmp = (op == Py_NE);
 
1024
    }
 
1025
    else {
 
1026
        minsize = self_size;
 
1027
        if (other_size < minsize)
 
1028
            minsize = other_size;
 
1029
 
 
1030
        cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize);
 
1031
        /* In ISO C, memcmp() guarantees to use unsigned bytes! */
 
1032
 
 
1033
        if (cmp == 0) {
 
1034
            if (self_size < other_size)
 
1035
                cmp = -1;
 
1036
            else if (self_size > other_size)
 
1037
                cmp = 1;
 
1038
        }
 
1039
 
 
1040
        switch (op) {
 
1041
        case Py_LT: cmp = cmp <  0; break;
 
1042
        case Py_LE: cmp = cmp <= 0; break;
 
1043
        case Py_EQ: cmp = cmp == 0; break;
 
1044
        case Py_NE: cmp = cmp != 0; break;
 
1045
        case Py_GT: cmp = cmp >  0; break;
 
1046
        case Py_GE: cmp = cmp >= 0; break;
 
1047
        }
 
1048
    }
 
1049
 
 
1050
    res = cmp ? Py_True : Py_False;
 
1051
    PyBuffer_Release(&self_bytes);
 
1052
    PyBuffer_Release(&other_bytes);
 
1053
    Py_INCREF(res);
 
1054
    return res;
 
1055
}
 
1056
 
 
1057
static void
 
1058
bytearray_dealloc(PyByteArrayObject *self)
 
1059
{
 
1060
    if (self->ob_exports > 0) {
 
1061
        PyErr_SetString(PyExc_SystemError,
 
1062
                        "deallocated bytearray object has exported buffers");
 
1063
        PyErr_Print();
 
1064
    }
 
1065
    if (self->ob_bytes != 0) {
 
1066
        PyObject_Free(self->ob_bytes);
 
1067
    }
 
1068
    Py_TYPE(self)->tp_free((PyObject *)self);
 
1069
}
 
1070
 
 
1071
 
 
1072
/* -------------------------------------------------------------------- */
 
1073
/* Methods */
 
1074
 
 
1075
#define FASTSEARCH fastsearch
 
1076
#define STRINGLIB(F) stringlib_##F
 
1077
#define STRINGLIB_CHAR char
 
1078
#define STRINGLIB_SIZEOF_CHAR 1
 
1079
#define STRINGLIB_LEN PyByteArray_GET_SIZE
 
1080
#define STRINGLIB_STR PyByteArray_AS_STRING
 
1081
#define STRINGLIB_NEW PyByteArray_FromStringAndSize
 
1082
#define STRINGLIB_ISSPACE Py_ISSPACE
 
1083
#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
 
1084
#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
 
1085
#define STRINGLIB_MUTABLE 1
 
1086
 
 
1087
#include "stringlib/fastsearch.h"
 
1088
#include "stringlib/count.h"
 
1089
#include "stringlib/find.h"
 
1090
#include "stringlib/join.h"
 
1091
#include "stringlib/partition.h"
 
1092
#include "stringlib/split.h"
 
1093
#include "stringlib/ctype.h"
 
1094
#include "stringlib/transmogrify.h"
 
1095
 
 
1096
 
 
1097
/* The following Py_LOCAL_INLINE and Py_LOCAL functions
 
1098
were copied from the old char* style string object. */
 
1099
 
 
1100
/* helper macro to fixup start/end slice values */
 
1101
#define ADJUST_INDICES(start, end, len)         \
 
1102
    if (end > len)                              \
 
1103
        end = len;                              \
 
1104
    else if (end < 0) {                         \
 
1105
        end += len;                             \
 
1106
        if (end < 0)                            \
 
1107
            end = 0;                            \
 
1108
    }                                           \
 
1109
    if (start < 0) {                            \
 
1110
        start += len;                           \
 
1111
        if (start < 0)                          \
 
1112
            start = 0;                          \
 
1113
    }
 
1114
 
 
1115
Py_LOCAL_INLINE(Py_ssize_t)
 
1116
bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
 
1117
{
 
1118
    PyObject *subobj;
 
1119
    char byte;
 
1120
    Py_buffer subbuf;
 
1121
    const char *sub;
 
1122
    Py_ssize_t sub_len;
 
1123
    Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
 
1124
    Py_ssize_t res;
 
1125
 
 
1126
    if (!stringlib_parse_args_finds_byte("find/rfind/index/rindex",
 
1127
                                         args, &subobj, &byte, &start, &end))
 
1128
        return -2;
 
1129
 
 
1130
    if (subobj) {
 
1131
        if (_getbuffer(subobj, &subbuf) < 0)
 
1132
            return -2;
 
1133
 
 
1134
        sub = subbuf.buf;
 
1135
        sub_len = subbuf.len;
 
1136
    }
 
1137
    else {
 
1138
        sub = &byte;
 
1139
        sub_len = 1;
 
1140
    }
 
1141
 
 
1142
    if (dir > 0)
 
1143
        res = stringlib_find_slice(
 
1144
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
 
1145
            sub, sub_len, start, end);
 
1146
    else
 
1147
        res = stringlib_rfind_slice(
 
1148
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
 
1149
            sub, sub_len, start, end);
 
1150
 
 
1151
    if (subobj)
 
1152
        PyBuffer_Release(&subbuf);
 
1153
 
 
1154
    return res;
 
1155
}
 
1156
 
 
1157
PyDoc_STRVAR(find__doc__,
 
1158
"B.find(sub[, start[, end]]) -> int\n\
 
1159
\n\
 
1160
Return the lowest index in B where subsection sub is found,\n\
 
1161
such that sub is contained within B[start,end].  Optional\n\
 
1162
arguments start and end are interpreted as in slice notation.\n\
 
1163
\n\
 
1164
Return -1 on failure.");
 
1165
 
 
1166
static PyObject *
 
1167
bytearray_find(PyByteArrayObject *self, PyObject *args)
 
1168
{
 
1169
    Py_ssize_t result = bytearray_find_internal(self, args, +1);
 
1170
    if (result == -2)
 
1171
        return NULL;
 
1172
    return PyLong_FromSsize_t(result);
 
1173
}
 
1174
 
 
1175
PyDoc_STRVAR(count__doc__,
 
1176
"B.count(sub[, start[, end]]) -> int\n\
 
1177
\n\
 
1178
Return the number of non-overlapping occurrences of subsection sub in\n\
 
1179
bytes B[start:end].  Optional arguments start and end are interpreted\n\
 
1180
as in slice notation.");
 
1181
 
 
1182
static PyObject *
 
1183
bytearray_count(PyByteArrayObject *self, PyObject *args)
 
1184
{
 
1185
    PyObject *sub_obj;
 
1186
    const char *str = PyByteArray_AS_STRING(self), *sub;
 
1187
    Py_ssize_t sub_len;
 
1188
    char byte;
 
1189
    Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;
 
1190
 
 
1191
    Py_buffer vsub;
 
1192
    PyObject *count_obj;
 
1193
 
 
1194
    if (!stringlib_parse_args_finds_byte("count", args, &sub_obj, &byte,
 
1195
                                         &start, &end))
 
1196
        return NULL;
 
1197
 
 
1198
    if (sub_obj) {
 
1199
        if (_getbuffer(sub_obj, &vsub) < 0)
 
1200
            return NULL;
 
1201
 
 
1202
        sub = vsub.buf;
 
1203
        sub_len = vsub.len;
 
1204
    }
 
1205
    else {
 
1206
        sub = &byte;
 
1207
        sub_len = 1;
 
1208
    }
 
1209
 
 
1210
    ADJUST_INDICES(start, end, PyByteArray_GET_SIZE(self));
 
1211
 
 
1212
    count_obj = PyLong_FromSsize_t(
 
1213
        stringlib_count(str + start, end - start, sub, sub_len, PY_SSIZE_T_MAX)
 
1214
        );
 
1215
 
 
1216
    if (sub_obj)
 
1217
        PyBuffer_Release(&vsub);
 
1218
 
 
1219
    return count_obj;
 
1220
}
 
1221
 
 
1222
PyDoc_STRVAR(clear__doc__,
 
1223
"B.clear() -> None\n\
 
1224
\n\
 
1225
Remove all items from B.");
 
1226
 
 
1227
static PyObject *
 
1228
bytearray_clear(PyByteArrayObject *self)
 
1229
{
 
1230
    if (PyByteArray_Resize((PyObject *)self, 0) < 0)
 
1231
        return NULL;
 
1232
    Py_RETURN_NONE;
 
1233
}
 
1234
 
 
1235
PyDoc_STRVAR(copy__doc__,
 
1236
"B.copy() -> bytearray\n\
 
1237
\n\
 
1238
Return a copy of B.");
 
1239
 
 
1240
static PyObject *
 
1241
bytearray_copy(PyByteArrayObject *self)
 
1242
{
 
1243
    return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
 
1244
                                         PyByteArray_GET_SIZE(self));
 
1245
}
 
1246
 
 
1247
PyDoc_STRVAR(index__doc__,
 
1248
"B.index(sub[, start[, end]]) -> int\n\
 
1249
\n\
 
1250
Like B.find() but raise ValueError when the subsection is not found.");
 
1251
 
 
1252
static PyObject *
 
1253
bytearray_index(PyByteArrayObject *self, PyObject *args)
 
1254
{
 
1255
    Py_ssize_t result = bytearray_find_internal(self, args, +1);
 
1256
    if (result == -2)
 
1257
        return NULL;
 
1258
    if (result == -1) {
 
1259
        PyErr_SetString(PyExc_ValueError,
 
1260
                        "subsection not found");
 
1261
        return NULL;
 
1262
    }
 
1263
    return PyLong_FromSsize_t(result);
 
1264
}
 
1265
 
 
1266
 
 
1267
PyDoc_STRVAR(rfind__doc__,
 
1268
"B.rfind(sub[, start[, end]]) -> int\n\
 
1269
\n\
 
1270
Return the highest index in B where subsection sub is found,\n\
 
1271
such that sub is contained within B[start,end].  Optional\n\
 
1272
arguments start and end are interpreted as in slice notation.\n\
 
1273
\n\
 
1274
Return -1 on failure.");
 
1275
 
 
1276
static PyObject *
 
1277
bytearray_rfind(PyByteArrayObject *self, PyObject *args)
 
1278
{
 
1279
    Py_ssize_t result = bytearray_find_internal(self, args, -1);
 
1280
    if (result == -2)
 
1281
        return NULL;
 
1282
    return PyLong_FromSsize_t(result);
 
1283
}
 
1284
 
 
1285
 
 
1286
PyDoc_STRVAR(rindex__doc__,
 
1287
"B.rindex(sub[, start[, end]]) -> int\n\
 
1288
\n\
 
1289
Like B.rfind() but raise ValueError when the subsection is not found.");
 
1290
 
 
1291
static PyObject *
 
1292
bytearray_rindex(PyByteArrayObject *self, PyObject *args)
 
1293
{
 
1294
    Py_ssize_t result = bytearray_find_internal(self, args, -1);
 
1295
    if (result == -2)
 
1296
        return NULL;
 
1297
    if (result == -1) {
 
1298
        PyErr_SetString(PyExc_ValueError,
 
1299
                        "subsection not found");
 
1300
        return NULL;
 
1301
    }
 
1302
    return PyLong_FromSsize_t(result);
 
1303
}
 
1304
 
 
1305
 
 
1306
static int
 
1307
bytearray_contains(PyObject *self, PyObject *arg)
 
1308
{
 
1309
    Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
 
1310
    if (ival == -1 && PyErr_Occurred()) {
 
1311
        Py_buffer varg;
 
1312
        Py_ssize_t pos;
 
1313
        PyErr_Clear();
 
1314
        if (_getbuffer(arg, &varg) < 0)
 
1315
            return -1;
 
1316
        pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
 
1317
                             varg.buf, varg.len, 0);
 
1318
        PyBuffer_Release(&varg);
 
1319
        return pos >= 0;
 
1320
    }
 
1321
    if (ival < 0 || ival >= 256) {
 
1322
        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
 
1323
        return -1;
 
1324
    }
 
1325
 
 
1326
    return memchr(PyByteArray_AS_STRING(self), (int) ival, Py_SIZE(self)) != NULL;
 
1327
}
 
1328
 
 
1329
 
 
1330
/* Matches the end (direction >= 0) or start (direction < 0) of self
 
1331
 * against substr, using the start and end arguments. Returns
 
1332
 * -1 on error, 0 if not found and 1 if found.
 
1333
 */
 
1334
Py_LOCAL(int)
 
1335
_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
 
1336
                 Py_ssize_t end, int direction)
 
1337
{
 
1338
    Py_ssize_t len = PyByteArray_GET_SIZE(self);
 
1339
    const char* str;
 
1340
    Py_buffer vsubstr;
 
1341
    int rv = 0;
 
1342
 
 
1343
    str = PyByteArray_AS_STRING(self);
 
1344
 
 
1345
    if (_getbuffer(substr, &vsubstr) < 0)
 
1346
        return -1;
 
1347
 
 
1348
    ADJUST_INDICES(start, end, len);
 
1349
 
 
1350
    if (direction < 0) {
 
1351
        /* startswith */
 
1352
        if (start+vsubstr.len > len) {
 
1353
            goto done;
 
1354
        }
 
1355
    } else {
 
1356
        /* endswith */
 
1357
        if (end-start < vsubstr.len || start > len) {
 
1358
            goto done;
 
1359
        }
 
1360
 
 
1361
        if (end-vsubstr.len > start)
 
1362
            start = end - vsubstr.len;
 
1363
    }
 
1364
    if (end-start >= vsubstr.len)
 
1365
        rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
 
1366
 
 
1367
done:
 
1368
    PyBuffer_Release(&vsubstr);
 
1369
    return rv;
 
1370
}
 
1371
 
 
1372
 
 
1373
PyDoc_STRVAR(startswith__doc__,
 
1374
"B.startswith(prefix[, start[, end]]) -> bool\n\
 
1375
\n\
 
1376
Return True if B starts with the specified prefix, False otherwise.\n\
 
1377
With optional start, test B beginning at that position.\n\
 
1378
With optional end, stop comparing B at that position.\n\
 
1379
prefix can also be a tuple of bytes to try.");
 
1380
 
 
1381
static PyObject *
 
1382
bytearray_startswith(PyByteArrayObject *self, PyObject *args)
 
1383
{
 
1384
    Py_ssize_t start = 0;
 
1385
    Py_ssize_t end = PY_SSIZE_T_MAX;
 
1386
    PyObject *subobj;
 
1387
    int result;
 
1388
 
 
1389
    if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end))
 
1390
        return NULL;
 
1391
    if (PyTuple_Check(subobj)) {
 
1392
        Py_ssize_t i;
 
1393
        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
 
1394
            result = _bytearray_tailmatch(self,
 
1395
                                      PyTuple_GET_ITEM(subobj, i),
 
1396
                                      start, end, -1);
 
1397
            if (result == -1)
 
1398
                return NULL;
 
1399
            else if (result) {
 
1400
                Py_RETURN_TRUE;
 
1401
            }
 
1402
        }
 
1403
        Py_RETURN_FALSE;
 
1404
    }
 
1405
    result = _bytearray_tailmatch(self, subobj, start, end, -1);
 
1406
    if (result == -1) {
 
1407
        if (PyErr_ExceptionMatches(PyExc_TypeError))
 
1408
            PyErr_Format(PyExc_TypeError, "startswith first arg must be bytes "
 
1409
                         "or a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
 
1410
        return NULL;
 
1411
    }
 
1412
    else
 
1413
        return PyBool_FromLong(result);
 
1414
}
 
1415
 
 
1416
PyDoc_STRVAR(endswith__doc__,
 
1417
"B.endswith(suffix[, start[, end]]) -> bool\n\
 
1418
\n\
 
1419
Return True if B ends with the specified suffix, False otherwise.\n\
 
1420
With optional start, test B beginning at that position.\n\
 
1421
With optional end, stop comparing B at that position.\n\
 
1422
suffix can also be a tuple of bytes to try.");
 
1423
 
 
1424
static PyObject *
 
1425
bytearray_endswith(PyByteArrayObject *self, PyObject *args)
 
1426
{
 
1427
    Py_ssize_t start = 0;
 
1428
    Py_ssize_t end = PY_SSIZE_T_MAX;
 
1429
    PyObject *subobj;
 
1430
    int result;
 
1431
 
 
1432
    if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end))
 
1433
        return NULL;
 
1434
    if (PyTuple_Check(subobj)) {
 
1435
        Py_ssize_t i;
 
1436
        for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
 
1437
            result = _bytearray_tailmatch(self,
 
1438
                                      PyTuple_GET_ITEM(subobj, i),
 
1439
                                      start, end, +1);
 
1440
            if (result == -1)
 
1441
                return NULL;
 
1442
            else if (result) {
 
1443
                Py_RETURN_TRUE;
 
1444
            }
 
1445
        }
 
1446
        Py_RETURN_FALSE;
 
1447
    }
 
1448
    result = _bytearray_tailmatch(self, subobj, start, end, +1);
 
1449
    if (result == -1) {
 
1450
        if (PyErr_ExceptionMatches(PyExc_TypeError))
 
1451
            PyErr_Format(PyExc_TypeError, "endswith first arg must be bytes or "
 
1452
                         "a tuple of bytes, not %s", Py_TYPE(subobj)->tp_name);
 
1453
        return NULL;
 
1454
    }
 
1455
    else
 
1456
        return PyBool_FromLong(result);
 
1457
}
 
1458
 
 
1459
 
 
1460
PyDoc_STRVAR(translate__doc__,
 
1461
"B.translate(table[, deletechars]) -> bytearray\n\
 
1462
\n\
 
1463
Return a copy of B, where all characters occurring in the\n\
 
1464
optional argument deletechars are removed, and the remaining\n\
 
1465
characters have been mapped through the given translation\n\
 
1466
table, which must be a bytes object of length 256.");
 
1467
 
 
1468
static PyObject *
 
1469
bytearray_translate(PyByteArrayObject *self, PyObject *args)
 
1470
{
 
1471
    char *input, *output;
 
1472
    const char *table;
 
1473
    Py_ssize_t i, c;
 
1474
    PyObject *input_obj = (PyObject*)self;
 
1475
    const char *output_start;
 
1476
    Py_ssize_t inlen;
 
1477
    PyObject *result = NULL;
 
1478
    int trans_table[256];
 
1479
    PyObject *tableobj = NULL, *delobj = NULL;
 
1480
    Py_buffer vtable, vdel;
 
1481
 
 
1482
    if (!PyArg_UnpackTuple(args, "translate", 1, 2,
 
1483
                           &tableobj, &delobj))
 
1484
          return NULL;
 
1485
 
 
1486
    if (tableobj == Py_None) {
 
1487
        table = NULL;
 
1488
        tableobj = NULL;
 
1489
    } else if (_getbuffer(tableobj, &vtable) < 0) {
 
1490
        return NULL;
 
1491
    } else {
 
1492
        if (vtable.len != 256) {
 
1493
            PyErr_SetString(PyExc_ValueError,
 
1494
                            "translation table must be 256 characters long");
 
1495
            PyBuffer_Release(&vtable);
 
1496
            return NULL;
 
1497
        }
 
1498
        table = (const char*)vtable.buf;
 
1499
    }
 
1500
 
 
1501
    if (delobj != NULL) {
 
1502
        if (_getbuffer(delobj, &vdel) < 0) {
 
1503
            if (tableobj != NULL)
 
1504
                PyBuffer_Release(&vtable);
 
1505
            return NULL;
 
1506
        }
 
1507
    }
 
1508
    else {
 
1509
        vdel.buf = NULL;
 
1510
        vdel.len = 0;
 
1511
    }
 
1512
 
 
1513
    inlen = PyByteArray_GET_SIZE(input_obj);
 
1514
    result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
 
1515
    if (result == NULL)
 
1516
        goto done;
 
1517
    output_start = output = PyByteArray_AsString(result);
 
1518
    input = PyByteArray_AS_STRING(input_obj);
 
1519
 
 
1520
    if (vdel.len == 0 && table != NULL) {
 
1521
        /* If no deletions are required, use faster code */
 
1522
        for (i = inlen; --i >= 0; ) {
 
1523
            c = Py_CHARMASK(*input++);
 
1524
            *output++ = table[c];
 
1525
        }
 
1526
        goto done;
 
1527
    }
 
1528
 
 
1529
    if (table == NULL) {
 
1530
        for (i = 0; i < 256; i++)
 
1531
            trans_table[i] = Py_CHARMASK(i);
 
1532
    } else {
 
1533
        for (i = 0; i < 256; i++)
 
1534
            trans_table[i] = Py_CHARMASK(table[i]);
 
1535
    }
 
1536
 
 
1537
    for (i = 0; i < vdel.len; i++)
 
1538
        trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
 
1539
 
 
1540
    for (i = inlen; --i >= 0; ) {
 
1541
        c = Py_CHARMASK(*input++);
 
1542
        if (trans_table[c] != -1)
 
1543
            if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
 
1544
                    continue;
 
1545
    }
 
1546
    /* Fix the size of the resulting string */
 
1547
    if (inlen > 0)
 
1548
        if (PyByteArray_Resize(result, output - output_start) < 0) {
 
1549
            Py_CLEAR(result);
 
1550
            goto done;
 
1551
        }
 
1552
 
 
1553
done:
 
1554
    if (tableobj != NULL)
 
1555
        PyBuffer_Release(&vtable);
 
1556
    if (delobj != NULL)
 
1557
        PyBuffer_Release(&vdel);
 
1558
    return result;
 
1559
}
 
1560
 
 
1561
 
 
1562
static PyObject *
 
1563
bytearray_maketrans(PyObject *null, PyObject *args)
 
1564
{
 
1565
        return _Py_bytes_maketrans(args);
 
1566
}
 
1567
 
 
1568
 
 
1569
/* find and count characters and substrings */
 
1570
 
 
1571
#define findchar(target, target_len, c)                         \
 
1572
  ((char *)memchr((const void *)(target), c, target_len))
 
1573
 
 
1574
 
 
1575
/* Bytes ops must return a string, create a copy */
 
1576
Py_LOCAL(PyByteArrayObject *)
 
1577
return_self(PyByteArrayObject *self)
 
1578
{
 
1579
    /* always return a new bytearray */
 
1580
    return (PyByteArrayObject *)PyByteArray_FromStringAndSize(
 
1581
            PyByteArray_AS_STRING(self),
 
1582
            PyByteArray_GET_SIZE(self));
 
1583
}
 
1584
 
 
1585
Py_LOCAL_INLINE(Py_ssize_t)
 
1586
countchar(const char *target, Py_ssize_t target_len, char c, Py_ssize_t maxcount)
 
1587
{
 
1588
    Py_ssize_t count=0;
 
1589
    const char *start=target;
 
1590
    const char *end=target+target_len;
 
1591
 
 
1592
    while ( (start=findchar(start, end-start, c)) != NULL ) {
 
1593
        count++;
 
1594
        if (count >= maxcount)
 
1595
            break;
 
1596
        start += 1;
 
1597
    }
 
1598
    return count;
 
1599
}
 
1600
 
 
1601
 
 
1602
/* Algorithms for different cases of string replacement */
 
1603
 
 
1604
/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
 
1605
Py_LOCAL(PyByteArrayObject *)
 
1606
replace_interleave(PyByteArrayObject *self,
 
1607
                   const char *to_s, Py_ssize_t to_len,
 
1608
                   Py_ssize_t maxcount)
 
1609
{
 
1610
    char *self_s, *result_s;
 
1611
    Py_ssize_t self_len, result_len;
 
1612
    Py_ssize_t count, i;
 
1613
    PyByteArrayObject *result;
 
1614
 
 
1615
    self_len = PyByteArray_GET_SIZE(self);
 
1616
 
 
1617
    /* 1 at the end plus 1 after every character;
 
1618
       count = min(maxcount, self_len + 1) */
 
1619
    if (maxcount <= self_len)
 
1620
        count = maxcount;
 
1621
    else
 
1622
        /* Can't overflow: self_len + 1 <= maxcount <= PY_SSIZE_T_MAX. */
 
1623
        count = self_len + 1;
 
1624
 
 
1625
    /* Check for overflow */
 
1626
    /*   result_len = count * to_len + self_len; */
 
1627
    assert(count > 0);
 
1628
    if (to_len > (PY_SSIZE_T_MAX - self_len) / count) {
 
1629
        PyErr_SetString(PyExc_OverflowError,
 
1630
                        "replace string is too long");
 
1631
        return NULL;
 
1632
    }
 
1633
    result_len = count * to_len + self_len;
 
1634
 
 
1635
    if (! (result = (PyByteArrayObject *)
 
1636
                     PyByteArray_FromStringAndSize(NULL, result_len)) )
 
1637
        return NULL;
 
1638
 
 
1639
    self_s = PyByteArray_AS_STRING(self);
 
1640
    result_s = PyByteArray_AS_STRING(result);
 
1641
 
 
1642
    /* TODO: special case single character, which doesn't need memcpy */
 
1643
 
 
1644
    /* Lay the first one down (guaranteed this will occur) */
 
1645
    Py_MEMCPY(result_s, to_s, to_len);
 
1646
    result_s += to_len;
 
1647
    count -= 1;
 
1648
 
 
1649
    for (i=0; i<count; i++) {
 
1650
        *result_s++ = *self_s++;
 
1651
        Py_MEMCPY(result_s, to_s, to_len);
 
1652
        result_s += to_len;
 
1653
    }
 
1654
 
 
1655
    /* Copy the rest of the original string */
 
1656
    Py_MEMCPY(result_s, self_s, self_len-i);
 
1657
 
 
1658
    return result;
 
1659
}
 
1660
 
 
1661
/* Special case for deleting a single character */
 
1662
/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
 
1663
Py_LOCAL(PyByteArrayObject *)
 
1664
replace_delete_single_character(PyByteArrayObject *self,
 
1665
                                char from_c, Py_ssize_t maxcount)
 
1666
{
 
1667
    char *self_s, *result_s;
 
1668
    char *start, *next, *end;
 
1669
    Py_ssize_t self_len, result_len;
 
1670
    Py_ssize_t count;
 
1671
    PyByteArrayObject *result;
 
1672
 
 
1673
    self_len = PyByteArray_GET_SIZE(self);
 
1674
    self_s = PyByteArray_AS_STRING(self);
 
1675
 
 
1676
    count = countchar(self_s, self_len, from_c, maxcount);
 
1677
    if (count == 0) {
 
1678
        return return_self(self);
 
1679
    }
 
1680
 
 
1681
    result_len = self_len - count;  /* from_len == 1 */
 
1682
    assert(result_len>=0);
 
1683
 
 
1684
    if ( (result = (PyByteArrayObject *)
 
1685
                    PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
 
1686
        return NULL;
 
1687
    result_s = PyByteArray_AS_STRING(result);
 
1688
 
 
1689
    start = self_s;
 
1690
    end = self_s + self_len;
 
1691
    while (count-- > 0) {
 
1692
        next = findchar(start, end-start, from_c);
 
1693
        if (next == NULL)
 
1694
            break;
 
1695
        Py_MEMCPY(result_s, start, next-start);
 
1696
        result_s += (next-start);
 
1697
        start = next+1;
 
1698
    }
 
1699
    Py_MEMCPY(result_s, start, end-start);
 
1700
 
 
1701
    return result;
 
1702
}
 
1703
 
 
1704
/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */
 
1705
 
 
1706
Py_LOCAL(PyByteArrayObject *)
 
1707
replace_delete_substring(PyByteArrayObject *self,
 
1708
                         const char *from_s, Py_ssize_t from_len,
 
1709
                         Py_ssize_t maxcount)
 
1710
{
 
1711
    char *self_s, *result_s;
 
1712
    char *start, *next, *end;
 
1713
    Py_ssize_t self_len, result_len;
 
1714
    Py_ssize_t count, offset;
 
1715
    PyByteArrayObject *result;
 
1716
 
 
1717
    self_len = PyByteArray_GET_SIZE(self);
 
1718
    self_s = PyByteArray_AS_STRING(self);
 
1719
 
 
1720
    count = stringlib_count(self_s, self_len,
 
1721
                            from_s, from_len,
 
1722
                            maxcount);
 
1723
 
 
1724
    if (count == 0) {
 
1725
        /* no matches */
 
1726
        return return_self(self);
 
1727
    }
 
1728
 
 
1729
    result_len = self_len - (count * from_len);
 
1730
    assert (result_len>=0);
 
1731
 
 
1732
    if ( (result = (PyByteArrayObject *)
 
1733
        PyByteArray_FromStringAndSize(NULL, result_len)) == NULL )
 
1734
            return NULL;
 
1735
 
 
1736
    result_s = PyByteArray_AS_STRING(result);
 
1737
 
 
1738
    start = self_s;
 
1739
    end = self_s + self_len;
 
1740
    while (count-- > 0) {
 
1741
        offset = stringlib_find(start, end-start,
 
1742
                                from_s, from_len,
 
1743
                                0);
 
1744
        if (offset == -1)
 
1745
            break;
 
1746
        next = start + offset;
 
1747
 
 
1748
        Py_MEMCPY(result_s, start, next-start);
 
1749
 
 
1750
        result_s += (next-start);
 
1751
        start = next+from_len;
 
1752
    }
 
1753
    Py_MEMCPY(result_s, start, end-start);
 
1754
    return result;
 
1755
}
 
1756
 
 
1757
/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
 
1758
Py_LOCAL(PyByteArrayObject *)
 
1759
replace_single_character_in_place(PyByteArrayObject *self,
 
1760
                                  char from_c, char to_c,
 
1761
                                  Py_ssize_t maxcount)
 
1762
{
 
1763
    char *self_s, *result_s, *start, *end, *next;
 
1764
    Py_ssize_t self_len;
 
1765
    PyByteArrayObject *result;
 
1766
 
 
1767
    /* The result string will be the same size */
 
1768
    self_s = PyByteArray_AS_STRING(self);
 
1769
    self_len = PyByteArray_GET_SIZE(self);
 
1770
 
 
1771
    next = findchar(self_s, self_len, from_c);
 
1772
 
 
1773
    if (next == NULL) {
 
1774
        /* No matches; return the original bytes */
 
1775
        return return_self(self);
 
1776
    }
 
1777
 
 
1778
    /* Need to make a new bytes */
 
1779
    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
 
1780
    if (result == NULL)
 
1781
        return NULL;
 
1782
    result_s = PyByteArray_AS_STRING(result);
 
1783
    Py_MEMCPY(result_s, self_s, self_len);
 
1784
 
 
1785
    /* change everything in-place, starting with this one */
 
1786
    start =  result_s + (next-self_s);
 
1787
    *start = to_c;
 
1788
    start++;
 
1789
    end = result_s + self_len;
 
1790
 
 
1791
    while (--maxcount > 0) {
 
1792
        next = findchar(start, end-start, from_c);
 
1793
        if (next == NULL)
 
1794
            break;
 
1795
        *next = to_c;
 
1796
        start = next+1;
 
1797
    }
 
1798
 
 
1799
    return result;
 
1800
}
 
1801
 
 
1802
/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
 
1803
Py_LOCAL(PyByteArrayObject *)
 
1804
replace_substring_in_place(PyByteArrayObject *self,
 
1805
                           const char *from_s, Py_ssize_t from_len,
 
1806
                           const char *to_s, Py_ssize_t to_len,
 
1807
                           Py_ssize_t maxcount)
 
1808
{
 
1809
    char *result_s, *start, *end;
 
1810
    char *self_s;
 
1811
    Py_ssize_t self_len, offset;
 
1812
    PyByteArrayObject *result;
 
1813
 
 
1814
    /* The result bytes will be the same size */
 
1815
 
 
1816
    self_s = PyByteArray_AS_STRING(self);
 
1817
    self_len = PyByteArray_GET_SIZE(self);
 
1818
 
 
1819
    offset = stringlib_find(self_s, self_len,
 
1820
                            from_s, from_len,
 
1821
                            0);
 
1822
    if (offset == -1) {
 
1823
        /* No matches; return the original bytes */
 
1824
        return return_self(self);
 
1825
    }
 
1826
 
 
1827
    /* Need to make a new bytes */
 
1828
    result = (PyByteArrayObject *) PyByteArray_FromStringAndSize(NULL, self_len);
 
1829
    if (result == NULL)
 
1830
        return NULL;
 
1831
    result_s = PyByteArray_AS_STRING(result);
 
1832
    Py_MEMCPY(result_s, self_s, self_len);
 
1833
 
 
1834
    /* change everything in-place, starting with this one */
 
1835
    start =  result_s + offset;
 
1836
    Py_MEMCPY(start, to_s, from_len);
 
1837
    start += from_len;
 
1838
    end = result_s + self_len;
 
1839
 
 
1840
    while ( --maxcount > 0) {
 
1841
        offset = stringlib_find(start, end-start,
 
1842
                                from_s, from_len,
 
1843
                                0);
 
1844
        if (offset==-1)
 
1845
            break;
 
1846
        Py_MEMCPY(start+offset, to_s, from_len);
 
1847
        start += offset+from_len;
 
1848
    }
 
1849
 
 
1850
    return result;
 
1851
}
 
1852
 
 
1853
/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
 
1854
Py_LOCAL(PyByteArrayObject *)
 
1855
replace_single_character(PyByteArrayObject *self,
 
1856
                         char from_c,
 
1857
                         const char *to_s, Py_ssize_t to_len,
 
1858
                         Py_ssize_t maxcount)
 
1859
{
 
1860
    char *self_s, *result_s;
 
1861
    char *start, *next, *end;
 
1862
    Py_ssize_t self_len, result_len;
 
1863
    Py_ssize_t count;
 
1864
    PyByteArrayObject *result;
 
1865
 
 
1866
    self_s = PyByteArray_AS_STRING(self);
 
1867
    self_len = PyByteArray_GET_SIZE(self);
 
1868
 
 
1869
    count = countchar(self_s, self_len, from_c, maxcount);
 
1870
    if (count == 0) {
 
1871
        /* no matches, return unchanged */
 
1872
        return return_self(self);
 
1873
    }
 
1874
 
 
1875
    /* use the difference between current and new, hence the "-1" */
 
1876
    /*   result_len = self_len + count * (to_len-1)  */
 
1877
    assert(count > 0);
 
1878
    if (to_len - 1 > (PY_SSIZE_T_MAX - self_len) / count) {
 
1879
        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
 
1880
        return NULL;
 
1881
    }
 
1882
    result_len = self_len + count * (to_len - 1);
 
1883
 
 
1884
    if ( (result = (PyByteArrayObject *)
 
1885
          PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
 
1886
            return NULL;
 
1887
    result_s = PyByteArray_AS_STRING(result);
 
1888
 
 
1889
    start = self_s;
 
1890
    end = self_s + self_len;
 
1891
    while (count-- > 0) {
 
1892
        next = findchar(start, end-start, from_c);
 
1893
        if (next == NULL)
 
1894
            break;
 
1895
 
 
1896
        if (next == start) {
 
1897
            /* replace with the 'to' */
 
1898
            Py_MEMCPY(result_s, to_s, to_len);
 
1899
            result_s += to_len;
 
1900
            start += 1;
 
1901
        } else {
 
1902
            /* copy the unchanged old then the 'to' */
 
1903
            Py_MEMCPY(result_s, start, next-start);
 
1904
            result_s += (next-start);
 
1905
            Py_MEMCPY(result_s, to_s, to_len);
 
1906
            result_s += to_len;
 
1907
            start = next+1;
 
1908
        }
 
1909
    }
 
1910
    /* Copy the remainder of the remaining bytes */
 
1911
    Py_MEMCPY(result_s, start, end-start);
 
1912
 
 
1913
    return result;
 
1914
}
 
1915
 
 
1916
/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
 
1917
Py_LOCAL(PyByteArrayObject *)
 
1918
replace_substring(PyByteArrayObject *self,
 
1919
                  const char *from_s, Py_ssize_t from_len,
 
1920
                  const char *to_s, Py_ssize_t to_len,
 
1921
                  Py_ssize_t maxcount)
 
1922
{
 
1923
    char *self_s, *result_s;
 
1924
    char *start, *next, *end;
 
1925
    Py_ssize_t self_len, result_len;
 
1926
    Py_ssize_t count, offset;
 
1927
    PyByteArrayObject *result;
 
1928
 
 
1929
    self_s = PyByteArray_AS_STRING(self);
 
1930
    self_len = PyByteArray_GET_SIZE(self);
 
1931
 
 
1932
    count = stringlib_count(self_s, self_len,
 
1933
                            from_s, from_len,
 
1934
                            maxcount);
 
1935
 
 
1936
    if (count == 0) {
 
1937
        /* no matches, return unchanged */
 
1938
        return return_self(self);
 
1939
    }
 
1940
 
 
1941
    /* Check for overflow */
 
1942
    /*    result_len = self_len + count * (to_len-from_len) */
 
1943
    assert(count > 0);
 
1944
    if (to_len - from_len > (PY_SSIZE_T_MAX - self_len) / count) {
 
1945
        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
 
1946
        return NULL;
 
1947
    }
 
1948
    result_len = self_len + count * (to_len - from_len);
 
1949
 
 
1950
    if ( (result = (PyByteArrayObject *)
 
1951
          PyByteArray_FromStringAndSize(NULL, result_len)) == NULL)
 
1952
        return NULL;
 
1953
    result_s = PyByteArray_AS_STRING(result);
 
1954
 
 
1955
    start = self_s;
 
1956
    end = self_s + self_len;
 
1957
    while (count-- > 0) {
 
1958
        offset = stringlib_find(start, end-start,
 
1959
                                from_s, from_len,
 
1960
                                0);
 
1961
        if (offset == -1)
 
1962
            break;
 
1963
        next = start+offset;
 
1964
        if (next == start) {
 
1965
            /* replace with the 'to' */
 
1966
            Py_MEMCPY(result_s, to_s, to_len);
 
1967
            result_s += to_len;
 
1968
            start += from_len;
 
1969
        } else {
 
1970
            /* copy the unchanged old then the 'to' */
 
1971
            Py_MEMCPY(result_s, start, next-start);
 
1972
            result_s += (next-start);
 
1973
            Py_MEMCPY(result_s, to_s, to_len);
 
1974
            result_s += to_len;
 
1975
            start = next+from_len;
 
1976
        }
 
1977
    }
 
1978
    /* Copy the remainder of the remaining bytes */
 
1979
    Py_MEMCPY(result_s, start, end-start);
 
1980
 
 
1981
    return result;
 
1982
}
 
1983
 
 
1984
 
 
1985
Py_LOCAL(PyByteArrayObject *)
 
1986
replace(PyByteArrayObject *self,
 
1987
        const char *from_s, Py_ssize_t from_len,
 
1988
        const char *to_s, Py_ssize_t to_len,
 
1989
        Py_ssize_t maxcount)
 
1990
{
 
1991
    if (maxcount < 0) {
 
1992
        maxcount = PY_SSIZE_T_MAX;
 
1993
    } else if (maxcount == 0 || PyByteArray_GET_SIZE(self) == 0) {
 
1994
        /* nothing to do; return the original bytes */
 
1995
        return return_self(self);
 
1996
    }
 
1997
 
 
1998
    if (maxcount == 0 ||
 
1999
        (from_len == 0 && to_len == 0)) {
 
2000
        /* nothing to do; return the original bytes */
 
2001
        return return_self(self);
 
2002
    }
 
2003
 
 
2004
    /* Handle zero-length special cases */
 
2005
 
 
2006
    if (from_len == 0) {
 
2007
        /* insert the 'to' bytes everywhere.   */
 
2008
        /*    >>> "Python".replace("", ".")     */
 
2009
        /*    '.P.y.t.h.o.n.'                   */
 
2010
        return replace_interleave(self, to_s, to_len, maxcount);
 
2011
    }
 
2012
 
 
2013
    /* Except for "".replace("", "A") == "A" there is no way beyond this */
 
2014
    /* point for an empty self bytes to generate a non-empty bytes */
 
2015
    /* Special case so the remaining code always gets a non-empty bytes */
 
2016
    if (PyByteArray_GET_SIZE(self) == 0) {
 
2017
        return return_self(self);
 
2018
    }
 
2019
 
 
2020
    if (to_len == 0) {
 
2021
        /* delete all occurrences of 'from' bytes */
 
2022
        if (from_len == 1) {
 
2023
            return replace_delete_single_character(
 
2024
                    self, from_s[0], maxcount);
 
2025
        } else {
 
2026
            return replace_delete_substring(self, from_s, from_len, maxcount);
 
2027
        }
 
2028
    }
 
2029
 
 
2030
    /* Handle special case where both bytes have the same length */
 
2031
 
 
2032
    if (from_len == to_len) {
 
2033
        if (from_len == 1) {
 
2034
            return replace_single_character_in_place(
 
2035
                    self,
 
2036
                    from_s[0],
 
2037
                    to_s[0],
 
2038
                    maxcount);
 
2039
        } else {
 
2040
            return replace_substring_in_place(
 
2041
                self, from_s, from_len, to_s, to_len, maxcount);
 
2042
        }
 
2043
    }
 
2044
 
 
2045
    /* Otherwise use the more generic algorithms */
 
2046
    if (from_len == 1) {
 
2047
        return replace_single_character(self, from_s[0],
 
2048
                                        to_s, to_len, maxcount);
 
2049
    } else {
 
2050
        /* len('from')>=2, len('to')>=1 */
 
2051
        return replace_substring(self, from_s, from_len, to_s, to_len, maxcount);
 
2052
    }
 
2053
}
 
2054
 
 
2055
 
 
2056
PyDoc_STRVAR(replace__doc__,
 
2057
"B.replace(old, new[, count]) -> bytearray\n\
 
2058
\n\
 
2059
Return a copy of B with all occurrences of subsection\n\
 
2060
old replaced by new.  If the optional argument count is\n\
 
2061
given, only the first count occurrences are replaced.");
 
2062
 
 
2063
static PyObject *
 
2064
bytearray_replace(PyByteArrayObject *self, PyObject *args)
 
2065
{
 
2066
    Py_ssize_t count = -1;
 
2067
    PyObject *from, *to, *res;
 
2068
    Py_buffer vfrom, vto;
 
2069
 
 
2070
    if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
 
2071
        return NULL;
 
2072
 
 
2073
    if (_getbuffer(from, &vfrom) < 0)
 
2074
        return NULL;
 
2075
    if (_getbuffer(to, &vto) < 0) {
 
2076
        PyBuffer_Release(&vfrom);
 
2077
        return NULL;
 
2078
    }
 
2079
 
 
2080
    res = (PyObject *)replace((PyByteArrayObject *) self,
 
2081
                              vfrom.buf, vfrom.len,
 
2082
                              vto.buf, vto.len, count);
 
2083
 
 
2084
    PyBuffer_Release(&vfrom);
 
2085
    PyBuffer_Release(&vto);
 
2086
    return res;
 
2087
}
 
2088
 
 
2089
PyDoc_STRVAR(split__doc__,
 
2090
"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\
 
2091
\n\
 
2092
Return a list of the sections in B, using sep as the delimiter.\n\
 
2093
If sep is not given, B is split on ASCII whitespace characters\n\
 
2094
(space, tab, return, newline, formfeed, vertical tab).\n\
 
2095
If maxsplit is given, at most maxsplit splits are done.");
 
2096
 
 
2097
static PyObject *
 
2098
bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
 
2099
{
 
2100
    static char *kwlist[] = {"sep", "maxsplit", 0};
 
2101
    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
 
2102
    Py_ssize_t maxsplit = -1;
 
2103
    const char *s = PyByteArray_AS_STRING(self), *sub;
 
2104
    PyObject *list, *subobj = Py_None;
 
2105
    Py_buffer vsub;
 
2106
 
 
2107
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split",
 
2108
                                     kwlist, &subobj, &maxsplit))
 
2109
        return NULL;
 
2110
    if (maxsplit < 0)
 
2111
        maxsplit = PY_SSIZE_T_MAX;
 
2112
 
 
2113
    if (subobj == Py_None)
 
2114
        return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
 
2115
 
 
2116
    if (_getbuffer(subobj, &vsub) < 0)
 
2117
        return NULL;
 
2118
    sub = vsub.buf;
 
2119
    n = vsub.len;
 
2120
 
 
2121
    list = stringlib_split(
 
2122
        (PyObject*) self, s, len, sub, n, maxsplit
 
2123
        );
 
2124
    PyBuffer_Release(&vsub);
 
2125
    return list;
 
2126
}
 
2127
 
 
2128
PyDoc_STRVAR(partition__doc__,
 
2129
"B.partition(sep) -> (head, sep, tail)\n\
 
2130
\n\
 
2131
Search for the separator sep in B, and return the part before it,\n\
 
2132
the separator itself, and the part after it.  If the separator is not\n\
 
2133
found, returns B and two empty bytearray objects.");
 
2134
 
 
2135
static PyObject *
 
2136
bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj)
 
2137
{
 
2138
    PyObject *bytesep, *result;
 
2139
 
 
2140
    bytesep = PyByteArray_FromObject(sep_obj);
 
2141
    if (! bytesep)
 
2142
        return NULL;
 
2143
 
 
2144
    result = stringlib_partition(
 
2145
            (PyObject*) self,
 
2146
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
 
2147
            bytesep,
 
2148
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
 
2149
            );
 
2150
 
 
2151
    Py_DECREF(bytesep);
 
2152
    return result;
 
2153
}
 
2154
 
 
2155
PyDoc_STRVAR(rpartition__doc__,
 
2156
"B.rpartition(sep) -> (head, sep, tail)\n\
 
2157
\n\
 
2158
Search for the separator sep in B, starting at the end of B,\n\
 
2159
and return the part before it, the separator itself, and the\n\
 
2160
part after it.  If the separator is not found, returns two empty\n\
 
2161
bytearray objects and B.");
 
2162
 
 
2163
static PyObject *
 
2164
bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj)
 
2165
{
 
2166
    PyObject *bytesep, *result;
 
2167
 
 
2168
    bytesep = PyByteArray_FromObject(sep_obj);
 
2169
    if (! bytesep)
 
2170
        return NULL;
 
2171
 
 
2172
    result = stringlib_rpartition(
 
2173
            (PyObject*) self,
 
2174
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
 
2175
            bytesep,
 
2176
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
 
2177
            );
 
2178
 
 
2179
    Py_DECREF(bytesep);
 
2180
    return result;
 
2181
}
 
2182
 
 
2183
PyDoc_STRVAR(rsplit__doc__,
 
2184
"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\
 
2185
\n\
 
2186
Return a list of the sections in B, using sep as the delimiter,\n\
 
2187
starting at the end of B and working to the front.\n\
 
2188
If sep is not given, B is split on ASCII whitespace characters\n\
 
2189
(space, tab, return, newline, formfeed, vertical tab).\n\
 
2190
If maxsplit is given, at most maxsplit splits are done.");
 
2191
 
 
2192
static PyObject *
 
2193
bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
 
2194
{
 
2195
    static char *kwlist[] = {"sep", "maxsplit", 0};
 
2196
    Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
 
2197
    Py_ssize_t maxsplit = -1;
 
2198
    const char *s = PyByteArray_AS_STRING(self), *sub;
 
2199
    PyObject *list, *subobj = Py_None;
 
2200
    Py_buffer vsub;
 
2201
 
 
2202
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit",
 
2203
                                     kwlist, &subobj, &maxsplit))
 
2204
        return NULL;
 
2205
    if (maxsplit < 0)
 
2206
        maxsplit = PY_SSIZE_T_MAX;
 
2207
 
 
2208
    if (subobj == Py_None)
 
2209
        return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
 
2210
 
 
2211
    if (_getbuffer(subobj, &vsub) < 0)
 
2212
        return NULL;
 
2213
    sub = vsub.buf;
 
2214
    n = vsub.len;
 
2215
 
 
2216
    list = stringlib_rsplit(
 
2217
        (PyObject*) self, s, len, sub, n, maxsplit
 
2218
        );
 
2219
    PyBuffer_Release(&vsub);
 
2220
    return list;
 
2221
}
 
2222
 
 
2223
PyDoc_STRVAR(reverse__doc__,
 
2224
"B.reverse() -> None\n\
 
2225
\n\
 
2226
Reverse the order of the values in B in place.");
 
2227
static PyObject *
 
2228
bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
 
2229
{
 
2230
    char swap, *head, *tail;
 
2231
    Py_ssize_t i, j, n = Py_SIZE(self);
 
2232
 
 
2233
    j = n / 2;
 
2234
    head = PyByteArray_AS_STRING(self);
 
2235
    tail = head + n - 1;
 
2236
    for (i = 0; i < j; i++) {
 
2237
        swap = *head;
 
2238
        *head++ = *tail;
 
2239
        *tail-- = swap;
 
2240
    }
 
2241
 
 
2242
    Py_RETURN_NONE;
 
2243
}
 
2244
 
 
2245
PyDoc_STRVAR(insert__doc__,
 
2246
"B.insert(index, int) -> None\n\
 
2247
\n\
 
2248
Insert a single item into the bytearray before the given index.");
 
2249
static PyObject *
 
2250
bytearray_insert(PyByteArrayObject *self, PyObject *args)
 
2251
{
 
2252
    PyObject *value;
 
2253
    int ival;
 
2254
    Py_ssize_t where, n = Py_SIZE(self);
 
2255
    char *buf;
 
2256
 
 
2257
    if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
 
2258
        return NULL;
 
2259
 
 
2260
    if (n == PY_SSIZE_T_MAX) {
 
2261
        PyErr_SetString(PyExc_OverflowError,
 
2262
                        "cannot add more objects to bytearray");
 
2263
        return NULL;
 
2264
    }
 
2265
    if (!_getbytevalue(value, &ival))
 
2266
        return NULL;
 
2267
    if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
 
2268
        return NULL;
 
2269
    buf = PyByteArray_AS_STRING(self);
 
2270
 
 
2271
    if (where < 0) {
 
2272
        where += n;
 
2273
        if (where < 0)
 
2274
            where = 0;
 
2275
    }
 
2276
    if (where > n)
 
2277
        where = n;
 
2278
    memmove(buf + where + 1, buf + where, n - where);
 
2279
    buf[where] = ival;
 
2280
 
 
2281
    Py_RETURN_NONE;
 
2282
}
 
2283
 
 
2284
PyDoc_STRVAR(append__doc__,
 
2285
"B.append(int) -> None\n\
 
2286
\n\
 
2287
Append a single item to the end of B.");
 
2288
static PyObject *
 
2289
bytearray_append(PyByteArrayObject *self, PyObject *arg)
 
2290
{
 
2291
    int value;
 
2292
    Py_ssize_t n = Py_SIZE(self);
 
2293
 
 
2294
    if (! _getbytevalue(arg, &value))
 
2295
        return NULL;
 
2296
    if (n == PY_SSIZE_T_MAX) {
 
2297
        PyErr_SetString(PyExc_OverflowError,
 
2298
                        "cannot add more objects to bytearray");
 
2299
        return NULL;
 
2300
    }
 
2301
    if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
 
2302
        return NULL;
 
2303
 
 
2304
    PyByteArray_AS_STRING(self)[n] = value;
 
2305
 
 
2306
    Py_RETURN_NONE;
 
2307
}
 
2308
 
 
2309
PyDoc_STRVAR(extend__doc__,
 
2310
"B.extend(iterable_of_ints) -> None\n\
 
2311
\n\
 
2312
Append all the elements from the iterator or sequence to the\n\
 
2313
end of B.");
 
2314
static PyObject *
 
2315
bytearray_extend(PyByteArrayObject *self, PyObject *arg)
 
2316
{
 
2317
    PyObject *it, *item, *bytearray_obj;
 
2318
    Py_ssize_t buf_size = 0, len = 0;
 
2319
    int value;
 
2320
    char *buf;
 
2321
 
 
2322
    /* bytearray_setslice code only accepts something supporting PEP 3118. */
 
2323
    if (PyObject_CheckBuffer(arg)) {
 
2324
        if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1)
 
2325
            return NULL;
 
2326
 
 
2327
        Py_RETURN_NONE;
 
2328
    }
 
2329
 
 
2330
    it = PyObject_GetIter(arg);
 
2331
    if (it == NULL)
 
2332
        return NULL;
 
2333
 
 
2334
    /* Try to determine the length of the argument. 32 is arbitrary. */
 
2335
    buf_size = PyObject_LengthHint(arg, 32);
 
2336
    if (buf_size == -1) {
 
2337
        Py_DECREF(it);
 
2338
        return NULL;
 
2339
    }
 
2340
 
 
2341
    bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
 
2342
    if (bytearray_obj == NULL) {
 
2343
        Py_DECREF(it);
 
2344
        return NULL;
 
2345
    }
 
2346
    buf = PyByteArray_AS_STRING(bytearray_obj);
 
2347
 
 
2348
    while ((item = PyIter_Next(it)) != NULL) {
 
2349
        if (! _getbytevalue(item, &value)) {
 
2350
            Py_DECREF(item);
 
2351
            Py_DECREF(it);
 
2352
            Py_DECREF(bytearray_obj);
 
2353
            return NULL;
 
2354
        }
 
2355
        buf[len++] = value;
 
2356
        Py_DECREF(item);
 
2357
 
 
2358
        if (len >= buf_size) {
 
2359
            buf_size = len + (len >> 1) + 1;
 
2360
            if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
 
2361
                Py_DECREF(it);
 
2362
                Py_DECREF(bytearray_obj);
 
2363
                return NULL;
 
2364
            }
 
2365
            /* Recompute the `buf' pointer, since the resizing operation may
 
2366
               have invalidated it. */
 
2367
            buf = PyByteArray_AS_STRING(bytearray_obj);
 
2368
        }
 
2369
    }
 
2370
    Py_DECREF(it);
 
2371
 
 
2372
    /* Resize down to exact size. */
 
2373
    if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
 
2374
        Py_DECREF(bytearray_obj);
 
2375
        return NULL;
 
2376
    }
 
2377
 
 
2378
    if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
 
2379
        Py_DECREF(bytearray_obj);
 
2380
        return NULL;
 
2381
    }
 
2382
    Py_DECREF(bytearray_obj);
 
2383
 
 
2384
    Py_RETURN_NONE;
 
2385
}
 
2386
 
 
2387
PyDoc_STRVAR(pop__doc__,
 
2388
"B.pop([index]) -> int\n\
 
2389
\n\
 
2390
Remove and return a single item from B. If no index\n\
 
2391
argument is given, will pop the last value.");
 
2392
static PyObject *
 
2393
bytearray_pop(PyByteArrayObject *self, PyObject *args)
 
2394
{
 
2395
    int value;
 
2396
    Py_ssize_t where = -1, n = Py_SIZE(self);
 
2397
    char *buf;
 
2398
 
 
2399
    if (!PyArg_ParseTuple(args, "|n:pop", &where))
 
2400
        return NULL;
 
2401
 
 
2402
    if (n == 0) {
 
2403
        PyErr_SetString(PyExc_IndexError,
 
2404
                        "pop from empty bytearray");
 
2405
        return NULL;
 
2406
    }
 
2407
    if (where < 0)
 
2408
        where += Py_SIZE(self);
 
2409
    if (where < 0 || where >= Py_SIZE(self)) {
 
2410
        PyErr_SetString(PyExc_IndexError, "pop index out of range");
 
2411
        return NULL;
 
2412
    }
 
2413
    if (!_canresize(self))
 
2414
        return NULL;
 
2415
 
 
2416
    buf = PyByteArray_AS_STRING(self);
 
2417
    value = buf[where];
 
2418
    memmove(buf + where, buf + where + 1, n - where);
 
2419
    if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
 
2420
        return NULL;
 
2421
 
 
2422
    return PyLong_FromLong((unsigned char)value);
 
2423
}
 
2424
 
 
2425
PyDoc_STRVAR(remove__doc__,
 
2426
"B.remove(int) -> None\n\
 
2427
\n\
 
2428
Remove the first occurrence of a value in B.");
 
2429
static PyObject *
 
2430
bytearray_remove(PyByteArrayObject *self, PyObject *arg)
 
2431
{
 
2432
    int value;
 
2433
    Py_ssize_t where, n = Py_SIZE(self);
 
2434
    char *buf = PyByteArray_AS_STRING(self);
 
2435
 
 
2436
    if (! _getbytevalue(arg, &value))
 
2437
        return NULL;
 
2438
 
 
2439
    for (where = 0; where < n; where++) {
 
2440
        if (buf[where] == value)
 
2441
            break;
 
2442
    }
 
2443
    if (where == n) {
 
2444
        PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
 
2445
        return NULL;
 
2446
    }
 
2447
    if (!_canresize(self))
 
2448
        return NULL;
 
2449
 
 
2450
    memmove(buf + where, buf + where + 1, n - where);
 
2451
    if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
 
2452
        return NULL;
 
2453
 
 
2454
    Py_RETURN_NONE;
 
2455
}
 
2456
 
 
2457
/* XXX These two helpers could be optimized if argsize == 1 */
 
2458
 
 
2459
static Py_ssize_t
 
2460
lstrip_helper(char *myptr, Py_ssize_t mysize,
 
2461
              void *argptr, Py_ssize_t argsize)
 
2462
{
 
2463
    Py_ssize_t i = 0;
 
2464
    while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
 
2465
        i++;
 
2466
    return i;
 
2467
}
 
2468
 
 
2469
static Py_ssize_t
 
2470
rstrip_helper(char *myptr, Py_ssize_t mysize,
 
2471
              void *argptr, Py_ssize_t argsize)
 
2472
{
 
2473
    Py_ssize_t i = mysize - 1;
 
2474
    while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
 
2475
        i--;
 
2476
    return i + 1;
 
2477
}
 
2478
 
 
2479
PyDoc_STRVAR(strip__doc__,
 
2480
"B.strip([bytes]) -> bytearray\n\
 
2481
\n\
 
2482
Strip leading and trailing bytes contained in the argument\n\
 
2483
and return the result as a new bytearray.\n\
 
2484
If the argument is omitted, strip ASCII whitespace.");
 
2485
static PyObject *
 
2486
bytearray_strip(PyByteArrayObject *self, PyObject *args)
 
2487
{
 
2488
    Py_ssize_t left, right, mysize, argsize;
 
2489
    char *myptr, *argptr;
 
2490
    PyObject *arg = Py_None;
 
2491
    Py_buffer varg;
 
2492
    if (!PyArg_ParseTuple(args, "|O:strip", &arg))
 
2493
        return NULL;
 
2494
    if (arg == Py_None) {
 
2495
        argptr = "\t\n\r\f\v ";
 
2496
        argsize = 6;
 
2497
    }
 
2498
    else {
 
2499
        if (_getbuffer(arg, &varg) < 0)
 
2500
            return NULL;
 
2501
        argptr = (char *) varg.buf;
 
2502
        argsize = varg.len;
 
2503
    }
 
2504
    myptr = PyByteArray_AS_STRING(self);
 
2505
    mysize = Py_SIZE(self);
 
2506
    left = lstrip_helper(myptr, mysize, argptr, argsize);
 
2507
    if (left == mysize)
 
2508
        right = left;
 
2509
    else
 
2510
        right = rstrip_helper(myptr, mysize, argptr, argsize);
 
2511
    if (arg != Py_None)
 
2512
        PyBuffer_Release(&varg);
 
2513
    return PyByteArray_FromStringAndSize(myptr + left, right - left);
 
2514
}
 
2515
 
 
2516
PyDoc_STRVAR(lstrip__doc__,
 
2517
"B.lstrip([bytes]) -> bytearray\n\
 
2518
\n\
 
2519
Strip leading bytes contained in the argument\n\
 
2520
and return the result as a new bytearray.\n\
 
2521
If the argument is omitted, strip leading ASCII whitespace.");
 
2522
static PyObject *
 
2523
bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
 
2524
{
 
2525
    Py_ssize_t left, right, mysize, argsize;
 
2526
    char *myptr, *argptr;
 
2527
    PyObject *arg = Py_None;
 
2528
    Py_buffer varg;
 
2529
    if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
 
2530
        return NULL;
 
2531
    if (arg == Py_None) {
 
2532
        argptr = "\t\n\r\f\v ";
 
2533
        argsize = 6;
 
2534
    }
 
2535
    else {
 
2536
        if (_getbuffer(arg, &varg) < 0)
 
2537
            return NULL;
 
2538
        argptr = (char *) varg.buf;
 
2539
        argsize = varg.len;
 
2540
    }
 
2541
    myptr = PyByteArray_AS_STRING(self);
 
2542
    mysize = Py_SIZE(self);
 
2543
    left = lstrip_helper(myptr, mysize, argptr, argsize);
 
2544
    right = mysize;
 
2545
    if (arg != Py_None)
 
2546
        PyBuffer_Release(&varg);
 
2547
    return PyByteArray_FromStringAndSize(myptr + left, right - left);
 
2548
}
 
2549
 
 
2550
PyDoc_STRVAR(rstrip__doc__,
 
2551
"B.rstrip([bytes]) -> bytearray\n\
 
2552
\n\
 
2553
Strip trailing bytes contained in the argument\n\
 
2554
and return the result as a new bytearray.\n\
 
2555
If the argument is omitted, strip trailing ASCII whitespace.");
 
2556
static PyObject *
 
2557
bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
 
2558
{
 
2559
    Py_ssize_t right, mysize, argsize;
 
2560
    char *myptr, *argptr;
 
2561
    PyObject *arg = Py_None;
 
2562
    Py_buffer varg;
 
2563
    if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
 
2564
        return NULL;
 
2565
    if (arg == Py_None) {
 
2566
        argptr = "\t\n\r\f\v ";
 
2567
        argsize = 6;
 
2568
    }
 
2569
    else {
 
2570
        if (_getbuffer(arg, &varg) < 0)
 
2571
            return NULL;
 
2572
        argptr = (char *) varg.buf;
 
2573
        argsize = varg.len;
 
2574
    }
 
2575
    myptr = PyByteArray_AS_STRING(self);
 
2576
    mysize = Py_SIZE(self);
 
2577
    right = rstrip_helper(myptr, mysize, argptr, argsize);
 
2578
    if (arg != Py_None)
 
2579
        PyBuffer_Release(&varg);
 
2580
    return PyByteArray_FromStringAndSize(myptr, right);
 
2581
}
 
2582
 
 
2583
PyDoc_STRVAR(decode_doc,
 
2584
"B.decode(encoding='utf-8', errors='strict') -> str\n\
 
2585
\n\
 
2586
Decode B using the codec registered for encoding. Default encoding\n\
 
2587
is 'utf-8'. errors may be given to set a different error\n\
 
2588
handling scheme.  Default is 'strict' meaning that encoding errors raise\n\
 
2589
a UnicodeDecodeError.  Other possible values are 'ignore' and 'replace'\n\
 
2590
as well as any other name registered with codecs.register_error that is\n\
 
2591
able to handle UnicodeDecodeErrors.");
 
2592
 
 
2593
static PyObject *
 
2594
bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs)
 
2595
{
 
2596
    const char *encoding = NULL;
 
2597
    const char *errors = NULL;
 
2598
    static char *kwlist[] = {"encoding", "errors", 0};
 
2599
 
 
2600
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
 
2601
        return NULL;
 
2602
    if (encoding == NULL)
 
2603
        encoding = PyUnicode_GetDefaultEncoding();
 
2604
    return PyUnicode_FromEncodedObject(self, encoding, errors);
 
2605
}
 
2606
 
 
2607
PyDoc_STRVAR(alloc_doc,
 
2608
"B.__alloc__() -> int\n\
 
2609
\n\
 
2610
Return the number of bytes actually allocated.");
 
2611
 
 
2612
static PyObject *
 
2613
bytearray_alloc(PyByteArrayObject *self)
 
2614
{
 
2615
    return PyLong_FromSsize_t(self->ob_alloc);
 
2616
}
 
2617
 
 
2618
PyDoc_STRVAR(join_doc,
 
2619
"B.join(iterable_of_bytes) -> bytearray\n\
 
2620
\n\
 
2621
Concatenate any number of bytes/bytearray objects, with B\n\
 
2622
in between each pair, and return the result as a new bytearray.");
 
2623
 
 
2624
static PyObject *
 
2625
bytearray_join(PyObject *self, PyObject *iterable)
 
2626
{
 
2627
    return stringlib_bytes_join(self, iterable);
 
2628
}
 
2629
 
 
2630
PyDoc_STRVAR(splitlines__doc__,
 
2631
"B.splitlines([keepends]) -> list of lines\n\
 
2632
\n\
 
2633
Return a list of the lines in B, breaking at line boundaries.\n\
 
2634
Line breaks are not included in the resulting list unless keepends\n\
 
2635
is given and true.");
 
2636
 
 
2637
static PyObject*
 
2638
bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds)
 
2639
{
 
2640
    static char *kwlist[] = {"keepends", 0};
 
2641
    int keepends = 0;
 
2642
 
 
2643
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines",
 
2644
                                     kwlist, &keepends))
 
2645
        return NULL;
 
2646
 
 
2647
    return stringlib_splitlines(
 
2648
        (PyObject*) self, PyByteArray_AS_STRING(self),
 
2649
        PyByteArray_GET_SIZE(self), keepends
 
2650
        );
 
2651
}
 
2652
 
 
2653
PyDoc_STRVAR(fromhex_doc,
 
2654
"bytearray.fromhex(string) -> bytearray (static method)\n\
 
2655
\n\
 
2656
Create a bytearray object from a string of hexadecimal numbers.\n\
 
2657
Spaces between two numbers are accepted.\n\
 
2658
Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef').");
 
2659
 
 
2660
static int
 
2661
hex_digit_to_int(Py_UCS4 c)
 
2662
{
 
2663
    if (c >= 128)
 
2664
        return -1;
 
2665
    if (Py_ISDIGIT(c))
 
2666
        return c - '0';
 
2667
    else {
 
2668
        if (Py_ISUPPER(c))
 
2669
            c = Py_TOLOWER(c);
 
2670
        if (c >= 'a' && c <= 'f')
 
2671
            return c - 'a' + 10;
 
2672
    }
 
2673
    return -1;
 
2674
}
 
2675
 
 
2676
static PyObject *
 
2677
bytearray_fromhex(PyObject *cls, PyObject *args)
 
2678
{
 
2679
    PyObject *newbytes, *hexobj;
 
2680
    char *buf;
 
2681
    Py_ssize_t hexlen, byteslen, i, j;
 
2682
    int top, bot;
 
2683
    void *data;
 
2684
    unsigned int kind;
 
2685
 
 
2686
    if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
 
2687
        return NULL;
 
2688
    assert(PyUnicode_Check(hexobj));
 
2689
    if (PyUnicode_READY(hexobj))
 
2690
        return NULL;
 
2691
    kind = PyUnicode_KIND(hexobj);
 
2692
    data = PyUnicode_DATA(hexobj);
 
2693
    hexlen = PyUnicode_GET_LENGTH(hexobj);
 
2694
 
 
2695
    byteslen = hexlen/2; /* This overestimates if there are spaces */
 
2696
    newbytes = PyByteArray_FromStringAndSize(NULL, byteslen);
 
2697
    if (!newbytes)
 
2698
        return NULL;
 
2699
    buf = PyByteArray_AS_STRING(newbytes);
 
2700
    for (i = j = 0; i < hexlen; i += 2) {
 
2701
        /* skip over spaces in the input */
 
2702
        while (PyUnicode_READ(kind, data, i) == ' ')
 
2703
            i++;
 
2704
        if (i >= hexlen)
 
2705
            break;
 
2706
        top = hex_digit_to_int(PyUnicode_READ(kind, data, i));
 
2707
        bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1));
 
2708
        if (top == -1 || bot == -1) {
 
2709
            PyErr_Format(PyExc_ValueError,
 
2710
                         "non-hexadecimal number found in "
 
2711
                         "fromhex() arg at position %zd", i);
 
2712
            goto error;
 
2713
        }
 
2714
        buf[j++] = (top << 4) + bot;
 
2715
    }
 
2716
    if (PyByteArray_Resize(newbytes, j) < 0)
 
2717
        goto error;
 
2718
    return newbytes;
 
2719
 
 
2720
  error:
 
2721
    Py_DECREF(newbytes);
 
2722
    return NULL;
 
2723
}
 
2724
 
 
2725
 
 
2726
static PyObject *
 
2727
_common_reduce(PyByteArrayObject *self, int proto)
 
2728
{
 
2729
    PyObject *dict;
 
2730
    _Py_IDENTIFIER(__dict__);
 
2731
    char *buf;
 
2732
 
 
2733
    dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
 
2734
    if (dict == NULL) {
 
2735
        PyErr_Clear();
 
2736
        dict = Py_None;
 
2737
        Py_INCREF(dict);
 
2738
    }
 
2739
 
 
2740
    buf = PyByteArray_AS_STRING(self);
 
2741
    if (proto < 3) {
 
2742
        /* use str based reduction for backwards compatibility with Python 2.x */
 
2743
        PyObject *latin1;
 
2744
        if (Py_SIZE(self))
 
2745
            latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
 
2746
        else
 
2747
            latin1 = PyUnicode_FromString("");
 
2748
        return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
 
2749
    }
 
2750
    else {
 
2751
        /* use more efficient byte based reduction */
 
2752
        if (Py_SIZE(self)) {
 
2753
            return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
 
2754
        }
 
2755
        else {
 
2756
            return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
 
2757
        }
 
2758
    }
 
2759
}
 
2760
 
 
2761
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
 
2762
 
 
2763
static PyObject *
 
2764
bytearray_reduce(PyByteArrayObject *self)
 
2765
{
 
2766
    return _common_reduce(self, 2);
 
2767
}
 
2768
 
 
2769
PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling.");
 
2770
 
 
2771
static PyObject *
 
2772
bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args)
 
2773
{
 
2774
    int proto = 0;
 
2775
 
 
2776
    if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto))
 
2777
        return NULL;
 
2778
 
 
2779
    return _common_reduce(self, proto);
 
2780
}
 
2781
 
 
2782
PyDoc_STRVAR(sizeof_doc,
 
2783
"B.__sizeof__() -> int\n\
 
2784
 \n\
 
2785
Returns the size of B in memory, in bytes");
 
2786
static PyObject *
 
2787
bytearray_sizeof(PyByteArrayObject *self)
 
2788
{
 
2789
    Py_ssize_t res;
 
2790
 
 
2791
    res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char);
 
2792
    return PyLong_FromSsize_t(res);
 
2793
}
 
2794
 
 
2795
static PySequenceMethods bytearray_as_sequence = {
 
2796
    (lenfunc)bytearray_length,              /* sq_length */
 
2797
    (binaryfunc)PyByteArray_Concat,         /* sq_concat */
 
2798
    (ssizeargfunc)bytearray_repeat,         /* sq_repeat */
 
2799
    (ssizeargfunc)bytearray_getitem,        /* sq_item */
 
2800
    0,                                      /* sq_slice */
 
2801
    (ssizeobjargproc)bytearray_setitem,     /* sq_ass_item */
 
2802
    0,                                      /* sq_ass_slice */
 
2803
    (objobjproc)bytearray_contains,         /* sq_contains */
 
2804
    (binaryfunc)bytearray_iconcat,          /* sq_inplace_concat */
 
2805
    (ssizeargfunc)bytearray_irepeat,        /* sq_inplace_repeat */
 
2806
};
 
2807
 
 
2808
static PyMappingMethods bytearray_as_mapping = {
 
2809
    (lenfunc)bytearray_length,
 
2810
    (binaryfunc)bytearray_subscript,
 
2811
    (objobjargproc)bytearray_ass_subscript,
 
2812
};
 
2813
 
 
2814
static PyBufferProcs bytearray_as_buffer = {
 
2815
    (getbufferproc)bytearray_getbuffer,
 
2816
    (releasebufferproc)bytearray_releasebuffer,
 
2817
};
 
2818
 
 
2819
static PyMethodDef
 
2820
bytearray_methods[] = {
 
2821
    {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
 
2822
    {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc},
 
2823
    {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc},
 
2824
    {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc},
 
2825
    {"append", (PyCFunction)bytearray_append, METH_O, append__doc__},
 
2826
    {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
 
2827
     _Py_capitalize__doc__},
 
2828
    {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
 
2829
    {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__},
 
2830
    {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__},
 
2831
    {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
 
2832
    {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
 
2833
    {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
 
2834
    {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
 
2835
     expandtabs__doc__},
 
2836
    {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
 
2837
    {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
 
2838
    {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS,
 
2839
     fromhex_doc},
 
2840
    {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__},
 
2841
    {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__},
 
2842
    {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
 
2843
     _Py_isalnum__doc__},
 
2844
    {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
 
2845
     _Py_isalpha__doc__},
 
2846
    {"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
 
2847
     _Py_isdigit__doc__},
 
2848
    {"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
 
2849
     _Py_islower__doc__},
 
2850
    {"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
 
2851
     _Py_isspace__doc__},
 
2852
    {"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
 
2853
     _Py_istitle__doc__},
 
2854
    {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
 
2855
     _Py_isupper__doc__},
 
2856
    {"join", (PyCFunction)bytearray_join, METH_O, join_doc},
 
2857
    {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
 
2858
    {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
 
2859
    {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__},
 
2860
    {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC,
 
2861
     _Py_maketrans__doc__},
 
2862
    {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__},
 
2863
    {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__},
 
2864
    {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__},
 
2865
    {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__},
 
2866
    {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__},
 
2867
    {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__},
 
2868
    {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__},
 
2869
    {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
 
2870
    {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__},
 
2871
    {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__},
 
2872
    {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__},
 
2873
    {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
 
2874
    {"splitlines", (PyCFunction)bytearray_splitlines,
 
2875
     METH_VARARGS | METH_KEYWORDS, splitlines__doc__},
 
2876
    {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS ,
 
2877
     startswith__doc__},
 
2878
    {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__},
 
2879
    {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
 
2880
     _Py_swapcase__doc__},
 
2881
    {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
 
2882
    {"translate", (PyCFunction)bytearray_translate, METH_VARARGS,
 
2883
     translate__doc__},
 
2884
    {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
 
2885
    {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
 
2886
    {NULL}
 
2887
};
 
2888
 
 
2889
PyDoc_STRVAR(bytearray_doc,
 
2890
"bytearray(iterable_of_ints) -> bytearray\n\
 
2891
bytearray(string, encoding[, errors]) -> bytearray\n\
 
2892
bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
 
2893
bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
 
2894
bytearray() -> empty bytes array\n\
 
2895
\n\
 
2896
Construct an mutable bytearray object from:\n\
 
2897
  - an iterable yielding integers in range(256)\n\
 
2898
  - a text string encoded using the specified encoding\n\
 
2899
  - a bytes or a buffer object\n\
 
2900
  - any object implementing the buffer API.\n\
 
2901
  - an integer");
 
2902
 
 
2903
 
 
2904
static PyObject *bytearray_iter(PyObject *seq);
 
2905
 
 
2906
PyTypeObject PyByteArray_Type = {
 
2907
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 
2908
    "bytearray",
 
2909
    sizeof(PyByteArrayObject),
 
2910
    0,
 
2911
    (destructor)bytearray_dealloc,       /* tp_dealloc */
 
2912
    0,                                  /* tp_print */
 
2913
    0,                                  /* tp_getattr */
 
2914
    0,                                  /* tp_setattr */
 
2915
    0,                                  /* tp_reserved */
 
2916
    (reprfunc)bytearray_repr,           /* tp_repr */
 
2917
    0,                                  /* tp_as_number */
 
2918
    &bytearray_as_sequence,             /* tp_as_sequence */
 
2919
    &bytearray_as_mapping,              /* tp_as_mapping */
 
2920
    0,                                  /* tp_hash */
 
2921
    0,                                  /* tp_call */
 
2922
    bytearray_str,                      /* tp_str */
 
2923
    PyObject_GenericGetAttr,            /* tp_getattro */
 
2924
    0,                                  /* tp_setattro */
 
2925
    &bytearray_as_buffer,               /* tp_as_buffer */
 
2926
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
2927
    bytearray_doc,                      /* tp_doc */
 
2928
    0,                                  /* tp_traverse */
 
2929
    0,                                  /* tp_clear */
 
2930
    (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
 
2931
    0,                                  /* tp_weaklistoffset */
 
2932
    bytearray_iter,                     /* tp_iter */
 
2933
    0,                                  /* tp_iternext */
 
2934
    bytearray_methods,                  /* tp_methods */
 
2935
    0,                                  /* tp_members */
 
2936
    0,                                  /* tp_getset */
 
2937
    0,                                  /* tp_base */
 
2938
    0,                                  /* tp_dict */
 
2939
    0,                                  /* tp_descr_get */
 
2940
    0,                                  /* tp_descr_set */
 
2941
    0,                                  /* tp_dictoffset */
 
2942
    (initproc)bytearray_init,           /* tp_init */
 
2943
    PyType_GenericAlloc,                /* tp_alloc */
 
2944
    PyType_GenericNew,                  /* tp_new */
 
2945
    PyObject_Del,                       /* tp_free */
 
2946
};
 
2947
 
 
2948
/*********************** Bytes Iterator ****************************/
 
2949
 
 
2950
typedef struct {
 
2951
    PyObject_HEAD
 
2952
    Py_ssize_t it_index;
 
2953
    PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
 
2954
} bytesiterobject;
 
2955
 
 
2956
static void
 
2957
bytearrayiter_dealloc(bytesiterobject *it)
 
2958
{
 
2959
    _PyObject_GC_UNTRACK(it);
 
2960
    Py_XDECREF(it->it_seq);
 
2961
    PyObject_GC_Del(it);
 
2962
}
 
2963
 
 
2964
static int
 
2965
bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
 
2966
{
 
2967
    Py_VISIT(it->it_seq);
 
2968
    return 0;
 
2969
}
 
2970
 
 
2971
static PyObject *
 
2972
bytearrayiter_next(bytesiterobject *it)
 
2973
{
 
2974
    PyByteArrayObject *seq;
 
2975
    PyObject *item;
 
2976
 
 
2977
    assert(it != NULL);
 
2978
    seq = it->it_seq;
 
2979
    if (seq == NULL)
 
2980
        return NULL;
 
2981
    assert(PyByteArray_Check(seq));
 
2982
 
 
2983
    if (it->it_index < PyByteArray_GET_SIZE(seq)) {
 
2984
        item = PyLong_FromLong(
 
2985
            (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
 
2986
        if (item != NULL)
 
2987
            ++it->it_index;
 
2988
        return item;
 
2989
    }
 
2990
 
 
2991
    Py_DECREF(seq);
 
2992
    it->it_seq = NULL;
 
2993
    return NULL;
 
2994
}
 
2995
 
 
2996
static PyObject *
 
2997
bytearrayiter_length_hint(bytesiterobject *it)
 
2998
{
 
2999
    Py_ssize_t len = 0;
 
3000
    if (it->it_seq)
 
3001
        len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
 
3002
    return PyLong_FromSsize_t(len);
 
3003
}
 
3004
 
 
3005
PyDoc_STRVAR(length_hint_doc,
 
3006
    "Private method returning an estimate of len(list(it)).");
 
3007
 
 
3008
static PyObject *
 
3009
bytearrayiter_reduce(bytesiterobject *it)
 
3010
{
 
3011
    if (it->it_seq != NULL) {
 
3012
        return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
 
3013
                             it->it_seq, it->it_index);
 
3014
    } else {
 
3015
        PyObject *u = PyUnicode_FromUnicode(NULL, 0);
 
3016
        if (u == NULL)
 
3017
            return NULL;
 
3018
        return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
 
3019
    }
 
3020
}
 
3021
 
 
3022
static PyObject *
 
3023
bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
 
3024
{
 
3025
    Py_ssize_t index = PyLong_AsSsize_t(state);
 
3026
    if (index == -1 && PyErr_Occurred())
 
3027
        return NULL;
 
3028
    if (index < 0)
 
3029
        index = 0;
 
3030
    it->it_index = index;
 
3031
    Py_RETURN_NONE;
 
3032
}
 
3033
 
 
3034
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
 
3035
 
 
3036
static PyMethodDef bytearrayiter_methods[] = {
 
3037
    {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
 
3038
     length_hint_doc},
 
3039
     {"__reduce__",      (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
 
3040
     reduce_doc},
 
3041
    {"__setstate__",    (PyCFunction)bytearrayiter_setstate, METH_O,
 
3042
     setstate_doc},
 
3043
    {NULL, NULL} /* sentinel */
 
3044
};
 
3045
 
 
3046
PyTypeObject PyByteArrayIter_Type = {
 
3047
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
 
3048
    "bytearray_iterator",              /* tp_name */
 
3049
    sizeof(bytesiterobject),           /* tp_basicsize */
 
3050
    0,                                 /* tp_itemsize */
 
3051
    /* methods */
 
3052
    (destructor)bytearrayiter_dealloc, /* tp_dealloc */
 
3053
    0,                                 /* tp_print */
 
3054
    0,                                 /* tp_getattr */
 
3055
    0,                                 /* tp_setattr */
 
3056
    0,                                 /* tp_reserved */
 
3057
    0,                                 /* tp_repr */
 
3058
    0,                                 /* tp_as_number */
 
3059
    0,                                 /* tp_as_sequence */
 
3060
    0,                                 /* tp_as_mapping */
 
3061
    0,                                 /* tp_hash */
 
3062
    0,                                 /* tp_call */
 
3063
    0,                                 /* tp_str */
 
3064
    PyObject_GenericGetAttr,           /* tp_getattro */
 
3065
    0,                                 /* tp_setattro */
 
3066
    0,                                 /* tp_as_buffer */
 
3067
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
 
3068
    0,                                 /* tp_doc */
 
3069
    (traverseproc)bytearrayiter_traverse,  /* tp_traverse */
 
3070
    0,                                 /* tp_clear */
 
3071
    0,                                 /* tp_richcompare */
 
3072
    0,                                 /* tp_weaklistoffset */
 
3073
    PyObject_SelfIter,                 /* tp_iter */
 
3074
    (iternextfunc)bytearrayiter_next,  /* tp_iternext */
 
3075
    bytearrayiter_methods,             /* tp_methods */
 
3076
    0,
 
3077
};
 
3078
 
 
3079
static PyObject *
 
3080
bytearray_iter(PyObject *seq)
 
3081
{
 
3082
    bytesiterobject *it;
 
3083
 
 
3084
    if (!PyByteArray_Check(seq)) {
 
3085
        PyErr_BadInternalCall();
 
3086
        return NULL;
 
3087
    }
 
3088
    it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
 
3089
    if (it == NULL)
 
3090
        return NULL;
 
3091
    it->it_index = 0;
 
3092
    Py_INCREF(seq);
 
3093
    it->it_seq = (PyByteArrayObject *)seq;
 
3094
    _PyObject_GC_TRACK(it);
 
3095
    return (PyObject *)it;
 
3096
}