pypy / pypy / objspace / std / bytearrayobject.py

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.rlib.rarithmetic import intmask
from pypy.rlib.rstring import StringBuilder
from pypy.rlib.debug import check_annotation
from pypy.objspace.std import stringobject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.listobject import get_positive_index
from pypy.objspace.std.listtype import get_list_index
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.strutil import ParseStringError
from pypy.objspace.std.strutil import string_to_float
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
from pypy.objspace.std import slicetype
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.buffer import RWBuffer
from pypy.objspace.std.bytearraytype import (
    makebytearraydata_w, getbytevalue,
    new_bytearray
)
from pypy.tool.sourcetools import func_with_new_name


class W_BytearrayObject(W_Object):
    from pypy.objspace.std.bytearraytype import bytearray_typedef as typedef

    def __init__(w_self, data):
        w_self.data = data

    def __repr__(w_self):
        """ representation for debugging purposes """
        return "%s(%s)" % (w_self.__class__.__name__, ''.join(w_self.data))

registerimplementation(W_BytearrayObject)

init_signature = Signature(['source', 'encoding', 'errors'], None, None)
init_defaults = [None, None, None]

def init__Bytearray(space, w_bytearray, __args__):
    # this is on the silly side
    w_source, w_encoding, w_errors = __args__.parse_obj(
            None, 'bytearray', init_signature, init_defaults)

    if w_source is None:
        w_source = space.wrap('')
    if w_encoding is None:
        w_encoding = space.w_None
    if w_errors is None:
        w_errors = space.w_None

    # Unicode argument
    if not space.is_w(w_encoding, space.w_None):
        from pypy.objspace.std.unicodetype import (
            _get_encoding_and_errors, encode_object
        )
        encoding, errors = _get_encoding_and_errors(space, w_encoding, w_errors)

        # if w_source is an integer this correctly raises a TypeError
        # the CPython error message is: "encoding or errors without a string argument"
        # ours is: "expected unicode, got int object"
        w_source = encode_object(space, w_source, encoding, errors)

    # Is it an int?
    try:
        count = space.int_w(w_source)
    except OperationError, e:
        if not e.match(space, space.w_TypeError):
            raise
    else:
        if count < 0:
            raise OperationError(space.w_ValueError,
                                 space.wrap("bytearray negative count"))
        w_bytearray.data = ['\0'] * count
        return

    data = makebytearraydata_w(space, w_source)
    w_bytearray.data = data

def len__Bytearray(space, w_bytearray):
    result = len(w_bytearray.data)
    return wrapint(space, result)

def ord__Bytearray(space, w_bytearray):
    if len(w_bytearray.data) != 1:
        raise OperationError(space.w_TypeError,
                             space.wrap("expected a character, but string"
                            "of length %s found" % len(w_bytearray.data)))
    return space.wrap(ord(w_bytearray.data[0]))

def getitem__Bytearray_ANY(space, w_bytearray, w_index):
    # getindex_w should get a second argument space.w_IndexError,
    # but that doesn't exist the first time this is called.
    try:
        w_IndexError = space.w_IndexError
    except AttributeError:
        w_IndexError = None
    index = space.getindex_w(w_index, w_IndexError, "bytearray index")
    try:
        return space.newint(ord(w_bytearray.data[index]))
    except IndexError:
        raise OperationError(space.w_IndexError,
                             space.wrap("bytearray index out of range"))

def getitem__Bytearray_Slice(space, w_bytearray, w_slice):
    data = w_bytearray.data
    length = len(data)
    start, stop, step, slicelength = w_slice.indices4(space, length)
    assert slicelength >= 0
    if step == 1 and 0 <= start <= stop:
        newdata = data[start:stop]
    else:
        newdata = _getitem_slice_multistep(data, start, step, slicelength)
    return W_BytearrayObject(newdata)

def _getitem_slice_multistep(data, start, step, slicelength):
    return [data[start + i*step] for i in range(slicelength)]

def contains__Bytearray_Int(space, w_bytearray, w_char):
    char = space.int_w(w_char)
    if not 0 <= char < 256:
        raise OperationError(space.w_ValueError,
                             space.wrap("byte must be in range(0, 256)"))
    for c in w_bytearray.data:
        if ord(c) == char:
            return space.w_True
    return space.w_False

def contains__Bytearray_String(space, w_bytearray, w_str):
    # XXX slow - copies, needs rewriting
    w_str2 = str__Bytearray(space, w_bytearray)
    return stringobject.contains__String_String(space, w_str2, w_str)

def contains__Bytearray_ANY(space, w_bytearray, w_sub):
    # XXX slow - copies, needs rewriting
    w_str = space.wrap(space.bufferstr_new_w(w_sub))
    w_str2 = str__Bytearray(space, w_bytearray)
    return stringobject.contains__String_String(space, w_str2, w_str)

def add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
    data1 = w_bytearray1.data
    data2 = w_bytearray2.data
    return W_BytearrayObject(data1 + data2)

def add__Bytearray_ANY(space, w_bytearray1, w_other):
    data1 = w_bytearray1.data
    data2 = [c for c in space.bufferstr_new_w(w_other)]
    return W_BytearrayObject(data1 + data2)

def add__String_Bytearray(space, w_str, w_bytearray):
    data2 = w_bytearray.data
    data1 = [c for c in space.str_w(w_str)]
    return W_BytearrayObject(data1 + data2)

def mul_bytearray_times(space, w_bytearray, w_times):
    try:
        times = space.getindex_w(w_times, space.w_OverflowError)
    except OperationError, e:
        if e.match(space, space.w_TypeError):
            raise FailedToImplement
        raise
    data = w_bytearray.data
    return W_BytearrayObject(data * times)

def mul__Bytearray_ANY(space, w_bytearray, w_times):
    return mul_bytearray_times(space, w_bytearray, w_times)

def mul__ANY_Bytearray(space, w_times, w_bytearray):
    return mul_bytearray_times(space, w_bytearray, w_times)

def inplace_mul__Bytearray_ANY(space, w_bytearray, w_times):
    try:
        times = space.getindex_w(w_times, space.w_OverflowError)
    except OperationError, e:
        if e.match(space, space.w_TypeError):
            raise FailedToImplement
        raise
    w_bytearray.data *= times
    return w_bytearray

def eq__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
    data1 = w_bytearray1.data
    data2 = w_bytearray2.data
    if len(data1) != len(data2):
        return space.w_False
    for i in range(len(data1)):
        if data1[i] != data2[i]:
            return space.w_False
    return space.w_True

def String2Bytearray(space, w_str):
    data = [c for c in space.str_w(w_str)]
    return W_BytearrayObject(data)

def eq__Bytearray_String(space, w_bytearray, w_other):
    return space.eq(str__Bytearray(space, w_bytearray), w_other)

def eq__Bytearray_Unicode(space, w_bytearray, w_other):
    return space.w_False

def eq__Unicode_Bytearray(space, w_other, w_bytearray):
    return space.w_False

def ne__Bytearray_String(space, w_bytearray, w_other):
    return space.ne(str__Bytearray(space, w_bytearray), w_other)

def ne__Bytearray_Unicode(space, w_bytearray, w_other):
    return space.w_True

def ne__Unicode_Bytearray(space, w_other, w_bytearray):
    return space.w_True

def _min(a, b):
    if a < b:
        return a
    return b

def lt__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
    data1 = w_bytearray1.data
    data2 = w_bytearray2.data
    ncmp = _min(len(data1), len(data2))
    # Search for the first index where items are different
    for p in range(ncmp):
        if data1[p] != data2[p]:
            return space.newbool(data1[p] < data2[p])
    # No more items to compare -- compare sizes
    return space.newbool(len(data1) < len(data2))

def gt__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
    data1 = w_bytearray1.data
    data2 = w_bytearray2.data
    ncmp = _min(len(data1), len(data2))
    # Search for the first index where items are different
    for p in range(ncmp):
        if data1[p] != data2[p]:
            return space.newbool(data1[p] > data2[p])
    # No more items to compare -- compare sizes
    return space.newbool(len(data1) > len(data2))

def str_translate__Bytearray_ANY_ANY(space, w_bytearray1, w_table, w_deletechars):
    # XXX slow, copies *twice* needs proper implementation
    w_str_copy = str__Bytearray(space, w_bytearray1)
    w_res = stringobject.str_translate__String_ANY_ANY(space, w_str_copy,
                                                       w_table, w_deletechars)
    return String2Bytearray(space, w_res)

# Mostly copied from repr__String, but without the "smart quote"
# functionality.
def repr__Bytearray(space, w_bytearray):
    s = w_bytearray.data

    # Good default if there are no replacements.
    buf = StringBuilder(len("bytearray(b'')") + len(s))

    buf.append("bytearray(b'")

    for i in range(len(s)):
        c = s[i]

        if c == '\\' or c == "'":
            buf.append('\\')
            buf.append(c)
        elif c == '\t':
            buf.append('\\t')
        elif c == '\r':
            buf.append('\\r')
        elif c == '\n':
            buf.append('\\n')
        elif not '\x20' <= c < '\x7f':
            n = ord(c)
            buf.append('\\x')
            buf.append("0123456789abcdef"[n>>4])
            buf.append("0123456789abcdef"[n&0xF])
        else:
            buf.append(c)

    buf.append("')")

    return space.wrap(buf.build())

def str__Bytearray(space, w_bytearray):
    return space.wrap(''.join(w_bytearray.data))

def str_count__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
    w_char = space.wrap(space.bufferstr_new_w(w_char))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_count__String_String_ANY_ANY(space, w_str, w_char,
                                                         w_start, w_stop)

def str_index__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
    w_char = space.wrap(space.bufferstr_new_w(w_char))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_index__String_String_ANY_ANY(space, w_str, w_char,
                                                         w_start, w_stop)

def str_rindex__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
    w_char = space.wrap(space.bufferstr_new_w(w_char))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_rindex__String_String_ANY_ANY(space, w_str, w_char,
                                                         w_start, w_stop)

def str_find__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
    w_char = space.wrap(space.bufferstr_new_w(w_char))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_find__String_String_ANY_ANY(space, w_str, w_char,
                                                         w_start, w_stop)

def str_rfind__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
    w_char = space.wrap(space.bufferstr_new_w(w_char))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_rfind__String_String_ANY_ANY(space, w_str, w_char,
                                                         w_start, w_stop)

def str_startswith__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_prefix, w_start, w_stop):
    w_prefix = space.wrap(space.bufferstr_new_w(w_prefix))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_startswith__String_String_ANY_ANY(space, w_str, w_prefix,
                                                              w_start, w_stop)

def str_startswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_prefix, w_start, w_stop):
    w_str = str__Bytearray(space, w_bytearray)
    w_prefix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
                               space.unpackiterable(w_prefix)])
    return stringobject.str_startswith__String_Tuple_ANY_ANY(space, w_str, w_prefix,
                                                              w_start, w_stop)

def str_endswith__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_suffix, w_start, w_stop):
    w_suffix = space.wrap(space.bufferstr_new_w(w_suffix))
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_endswith__String_String_ANY_ANY(space, w_str, w_suffix,
                                                              w_start, w_stop)

def str_endswith__Bytearray_Tuple_ANY_ANY(space, w_bytearray, w_suffix, w_start, w_stop):
    w_str = str__Bytearray(space, w_bytearray)
    w_suffix = space.newtuple([space.wrap(space.bufferstr_new_w(w_entry)) for w_entry in
                               space.unpackiterable(w_suffix)])
    return stringobject.str_endswith__String_Tuple_ANY_ANY(space, w_str, w_suffix,
                                                              w_start, w_stop)

def str_join__Bytearray_ANY(space, w_self, w_list):
    list_w = space.listview(w_list)
    if not list_w:
        return W_BytearrayObject([])
    data = w_self.data
    newdata = []
    for i in range(len(list_w)):
        w_s = list_w[i]
        if not (space.isinstance_w(w_s, space.w_str) or
                space.isinstance_w(w_s, space.w_bytearray)):
            raise operationerrfmt(
                space.w_TypeError,
                "sequence item %d: expected string, %s "
                "found", i, space.type(w_s).getname(space))

        if data and i != 0:
            newdata.extend(data)
        newdata.extend([c for c in space.bufferstr_new_w(w_s)])
    return W_BytearrayObject(newdata)

def str_decode__Bytearray_ANY_ANY(space, w_bytearray, w_encoding, w_errors):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_decode__String_ANY_ANY(space, w_str, w_encoding, w_errors)

def str_islower__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_islower__String(space, w_str)

def str_isupper__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_isupper__String(space, w_str)

def str_isalpha__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_isalpha__String(space, w_str)

def str_isalnum__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_isalnum__String(space, w_str)

def str_isdigit__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_isdigit__String(space, w_str)

def str_istitle__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_istitle__String(space, w_str)

def str_isspace__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    return stringobject.str_isspace__String(space, w_str)

def bytearray_insert__Bytearray_Int_ANY(space, w_bytearray, w_idx, w_other):
    where = space.int_w(w_idx)
    length = len(w_bytearray.data)
    index = get_positive_index(where, length)
    val = getbytevalue(space, w_other)
    w_bytearray.data.insert(index, val)
    return space.w_None

def bytearray_pop__Bytearray_Int(space, w_bytearray, w_idx):
    index = space.int_w(w_idx)
    try:
        result = w_bytearray.data.pop(index)
    except IndexError:
        if not w_bytearray.data:
            raise OperationError(space.w_IndexError, space.wrap(
                "pop from empty bytearray"))
        raise OperationError(space.w_IndexError, space.wrap(
            "pop index out of range"))
    return space.wrap(ord(result))

def bytearray_remove__Bytearray_ANY(space, w_bytearray, w_char):
    char = space.int_w(space.index(w_char))
    try:
        result = w_bytearray.data.remove(chr(char))
    except ValueError:
        raise OperationError(space.w_ValueError, space.wrap(
            "value not found in bytearray"))

def bytearray_reverse__Bytearray(space, w_bytearray):
    w_bytearray.data.reverse()
    return space.w_None

_space_chars = ''.join([chr(c) for c in [9, 10, 11, 12, 13, 32]])

def bytearray_strip__Bytearray_None(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, _space_chars, 1, 1)

def bytearray_strip__Bytearray_ANY(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 1, 1)

def bytearray_lstrip__Bytearray_None(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, _space_chars, 1, 0)

def bytearray_lstrip__Bytearray_ANY(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 1, 0)

def bytearray_rstrip__Bytearray_None(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, _space_chars, 0, 1)

def bytearray_rstrip__Bytearray_ANY(space, w_bytearray, w_chars):
    return _strip(space, w_bytearray, space.bufferstr_new_w(w_chars), 0, 1)

# These methods could just delegate to the string implementation,
# but they have to return a bytearray.
def str_replace__Bytearray_ANY_ANY_ANY(space, w_bytearray, w_str1, w_str2, w_max):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_replace__String_ANY_ANY_ANY(space, w_str, w_str1,
                                                         w_str2, w_max)
    return String2Bytearray(space, w_res)

def str_upper__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_upper__String(space, w_str)
    return String2Bytearray(space, w_res)

def str_lower__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_lower__String(space, w_str)
    return String2Bytearray(space, w_res)

def str_title__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_title__String(space, w_str)
    return String2Bytearray(space, w_res)

def str_swapcase__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_swapcase__String(space, w_str)
    return String2Bytearray(space, w_res)

def str_capitalize__Bytearray(space, w_bytearray):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_capitalize__String(space, w_str)
    return String2Bytearray(space, w_res)

def str_ljust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_ljust__String_ANY_ANY(space, w_str, w_width,
                                                   w_fillchar)
    return String2Bytearray(space, w_res)

def str_rjust__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_rjust__String_ANY_ANY(space, w_str, w_width,
                                                   w_fillchar)
    return String2Bytearray(space, w_res)

def str_center__Bytearray_ANY_ANY(space, w_bytearray, w_width, w_fillchar):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_center__String_ANY_ANY(space, w_str, w_width,
                                                    w_fillchar)
    return String2Bytearray(space, w_res)

def str_zfill__Bytearray_ANY(space, w_bytearray, w_width):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_zfill__String_ANY(space, w_str, w_width)
    return String2Bytearray(space, w_res)

def str_expandtabs__Bytearray_ANY(space, w_bytearray, w_tabsize):
    w_str = str__Bytearray(space, w_bytearray)
    w_res = stringobject.str_expandtabs__String_ANY(space, w_str, w_tabsize)
    return String2Bytearray(space, w_res)

def str_splitlines__Bytearray_ANY(space, w_bytearray, w_keepends):
    w_str = str__Bytearray(space, w_bytearray)
    w_result = stringobject.str_splitlines__String_ANY(space, w_str, w_keepends)
    return space.newlist([
        new_bytearray(space, space.w_bytearray, makebytearraydata_w(space, w_entry))
                        for w_entry in space.unpackiterable(w_result)
    ])

def str_split__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
    w_str = str__Bytearray(space, w_bytearray)
    if not space.is_w(w_by, space.w_None):
        w_by = space.wrap(space.bufferstr_new_w(w_by))
    w_list = space.call_method(w_str, "split", w_by, w_maxsplit)
    length = space.int_w(space.len(w_list))
    for i in range(length):
        w_i = space.wrap(i)
        space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
    return w_list

def str_rsplit__Bytearray_ANY_ANY(space, w_bytearray, w_by, w_maxsplit=-1):
    w_str = str__Bytearray(space, w_bytearray)
    if not space.is_w(w_by, space.w_None):
        w_by = space.wrap(space.bufferstr_new_w(w_by))
    w_list = space.call_method(w_str, "rsplit", w_by, w_maxsplit)
    length = space.int_w(space.len(w_list))
    for i in range(length):
        w_i = space.wrap(i)
        space.setitem(w_list, w_i, String2Bytearray(space, space.getitem(w_list, w_i)))
    return w_list

def str_partition__Bytearray_ANY(space, w_bytearray, w_sub):
    w_str = str__Bytearray(space, w_bytearray)
    w_sub = space.wrap(space.bufferstr_new_w(w_sub))
    w_tuple = stringobject.str_partition__String_String(space, w_str, w_sub)
    w_a, w_b, w_c = space.fixedview(w_tuple, 3)
    return space.newtuple([
        String2Bytearray(space, w_a),
        String2Bytearray(space, w_b),
        String2Bytearray(space, w_c)])

def str_rpartition__Bytearray_ANY(space, w_bytearray, w_sub):
    w_str = str__Bytearray(space, w_bytearray)
    w_sub = space.wrap(space.bufferstr_new_w(w_sub))
    w_tuple = stringobject.str_rpartition__String_String(space, w_str, w_sub)
    w_a, w_b, w_c = space.fixedview(w_tuple, 3)
    return space.newtuple([
        String2Bytearray(space, w_a),
        String2Bytearray(space, w_b),
        String2Bytearray(space, w_c)])

# __________________________________________________________
# Mutability methods

def list_append__Bytearray_ANY(space, w_bytearray, w_item):
    from pypy.objspace.std.bytearraytype import getbytevalue
    w_bytearray.data.append(getbytevalue(space, w_item))

def list_extend__Bytearray_Bytearray(space, w_bytearray, w_other):
    w_bytearray.data += w_other.data

def list_extend__Bytearray_ANY(space, w_bytearray, w_other):
    w_bytearray.data += makebytearraydata_w(space, w_other)

def inplace_add__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2):
    list_extend__Bytearray_Bytearray(space, w_bytearray1, w_bytearray2)
    return w_bytearray1

def inplace_add__Bytearray_ANY(space, w_bytearray1, w_iterable2):
    w_bytearray1.data += space.bufferstr_new_w(w_iterable2)
    return w_bytearray1

def setitem__Bytearray_ANY_ANY(space, w_bytearray, w_index, w_item):
    from pypy.objspace.std.bytearraytype import getbytevalue
    idx = space.getindex_w(w_index, space.w_IndexError, "bytearray index")
    try:
        w_bytearray.data[idx] = getbytevalue(space, w_item)
    except IndexError:
        raise OperationError(space.w_IndexError,
                             space.wrap("bytearray index out of range"))

def setitem__Bytearray_Slice_ANY(space, w_bytearray, w_slice, w_other):
    oldsize = len(w_bytearray.data)
    start, stop, step, slicelength = w_slice.indices4(space, oldsize)
    sequence2 = makebytearraydata_w(space, w_other)
    _setitem_slice_helper(space, w_bytearray.data, start, step, slicelength, sequence2, empty_elem='\x00')

def delitem__Bytearray_ANY(space, w_bytearray, w_idx):
    idx = get_list_index(space, w_idx)
    try:
        del w_bytearray.data[idx]
    except IndexError:
        raise OperationError(space.w_IndexError,
                             space.wrap("bytearray deletion index out of range"))
    return space.w_None

def delitem__Bytearray_Slice(space, w_bytearray, w_slice):
    start, stop, step, slicelength = w_slice.indices4(space,
                                                      len(w_bytearray.data))
    _delitem_slice_helper(space, w_bytearray.data, start, step, slicelength)

#XXX share the code again with the stuff in listobject.py
def _delitem_slice_helper(space, items, start, step, slicelength):
    if slicelength==0:
        return

    if step < 0:
        start = start + step * (slicelength-1)
        step = -step

    if step == 1:
        assert start >= 0
        if slicelength > 0:
            del items[start:start+slicelength]
    else:
        n = len(items)
        i = start

        for discard in range(1, slicelength):
            j = i+1
            i += step
            while j < i:
                items[j-discard] = items[j]
                j += 1

        j = i+1
        while j < n:
            items[j-slicelength] = items[j]
            j += 1
        start = n - slicelength
        assert start >= 0 # annotator hint
        del items[start:]

def _setitem_slice_helper(space, items, start, step, slicelength, sequence2,
                          empty_elem):
    assert slicelength >= 0
    oldsize = len(items)
    len2 = len(sequence2)
    if step == 1:  # Support list resizing for non-extended slices
        delta = slicelength - len2
        if delta < 0:
            delta = -delta
            newsize = oldsize + delta
            # XXX support this in rlist!
            items += [empty_elem] * delta
            lim = start+len2
            i = newsize - 1
            while i >= lim:
                items[i] = items[i-delta]
                i -= 1
        elif delta == 0:
            pass
        else:
            assert start >= 0   # start<0 is only possible with slicelength==0
            del items[start:start+delta]
    elif len2 != slicelength:  # No resize for extended slices
        raise operationerrfmt(space.w_ValueError, "attempt to "
              "assign sequence of size %d to extended slice of size %d",
              len2, slicelength)

    if sequence2 is items:
        if step > 0:
            # Always copy starting from the right to avoid
            # having to make a shallow copy in the case where
            # the source and destination lists are the same list.
            i = len2 - 1
            start += i*step
            while i >= 0:
                items[start] = sequence2[i]
                start -= step
                i -= 1
            return
        else:
            # Make a shallow copy to more easily handle the reversal case
            sequence2 = list(sequence2)
    for i in range(len2):
        items[start] = sequence2[i]
        start += step

def _strip(space, w_bytearray, u_chars, left, right):
    # note: mostly copied from stringobject._strip
    # should really be shared
    u_self = w_bytearray.data

    lpos = 0
    rpos = len(u_self)

    if left:
        while lpos < rpos and u_self[lpos] in u_chars:
            lpos += 1

    if right:
        while rpos > lpos and u_self[rpos - 1] in u_chars:
            rpos -= 1
        assert rpos >= 0

    return new_bytearray(space, space.w_bytearray, u_self[lpos:rpos])

# __________________________________________________________
# Buffer interface

class BytearrayBuffer(RWBuffer):
    def __init__(self, data):
        self.data = data

    def getlength(self):
        return len(self.data)

    def getitem(self, index):
        return self.data[index]

    def setitem(self, index, char):
        self.data[index] = char

def buffer__Bytearray(space, self):
    b = BytearrayBuffer(self.data)
    return space.wrap(b)

from pypy.objspace.std import bytearraytype
register_all(vars(), bytearraytype)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.