Python-2.7.3/Objects/bytearrayobject.c

No issues found

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