Author: Ronan Lamy <ronan.l...@gmail.com> Branch: PyBuffer Changeset: r90840:55b0a70b52e1 Date: 2017-03-28 14:14 +0100 http://bitbucket.org/pypy/pypy/changeset/55b0a70b52e1/
Log: Stop abusing SubBuffer to represent memoryview slices diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py --- a/pypy/objspace/std/memoryobject.py +++ b/pypy/objspace/std/memoryobject.py @@ -302,24 +302,14 @@ else: raise oefmt(space.w_NotImplementedError, "multi-dimensional sub-views are not implemented") elif is_slice: - mv = W_MemoryView.copy(self) - mv.init_slice(start, stop, step, slicelength, 0) - mv.init_len() - mv._init_flags() - return mv + return self.new_slice(start, stop, step, slicelength, 0) # multi index is handled at the top of this function else: raise TypeError("memoryview: invalid slice key") - def init_slice(self, start, stop, step, slicelength, dim): - # modifies the buffer, shape and stride to allow step to be > 1 - self.strides = strides = self.getstrides()[:] - self.shape = shape = self.getshape()[:] - bytesize = self.getitemsize() * slicelength - self.buf = SubBuffer(self.buf, strides[dim] * start, bytesize) - shape[dim] = slicelength - strides[dim] = strides[dim] * step - # TODO subbuffer + def new_slice(self, start, stop, step, slicelength, dim): + sliced = BufferSlice(self.buf, start, step, slicelength) + return W_MemoryView(sliced, sliced.getformat(), sliced.getitemsize()) def init_len(self): self.length = self.bytecount_from_shape() @@ -678,7 +668,7 @@ def descr_hex(self, space): from pypy.objspace.std.bytearrayobject import _array_to_hexstring self._check_released(space) - return _array_to_hexstring(space, self.buf, 0, 1, self.getlength()) + return _array_to_hexstring(space, self.buf.as_binary(), 0, 1, self.getlength()) def is_byte_format(char): return char == 'b' or char == 'B' or char == 'c' @@ -765,3 +755,65 @@ _IsFortranContiguous(ndim, shape, strides, itemsize)) return 0 +class BufferSlice(Buffer): + def __init__(self, buf, start, step, length): + self.buf = buf + self.readonly = self.buf.readonly + self.strides = buf.getstrides()[:] + itemsize = buf.getitemsize() + self.offset = start * itemsize + self.step = step + self.strides[0] *= step + self.shape = buf.getshape()[:] + self.shape[0] = length + + def getlength(self): + return self.shape[0] * self.getitemsize() + + def as_str(self): + return self.getslice(0, self.getlength(), 1, self.getlength()) + + def as_str_and_offset_maybe(self): + string, offset = self.buf.as_str_and_offset_maybe() + if string is not None: + return string, offset + self.offset + return None, 0 + + def getitem(self, index): + return self.buf.getitem(self.offset + index) + + def setitem(self, index, char): + self.buf.setitem(self.offset + index, char) + + def getslice(self, start, stop, step, size): + if start == stop: + return '' # otherwise, adding self.offset might make them + # out of bounds + return self.buf.getslice(self.offset + start, self.offset + stop, + step, size) + + def setslice(self, start, string): + if len(string) == 0: + return # otherwise, adding self.offset might make 'start' + # out of bounds + self.buf.setslice(self.offset + start, string) + + def get_raw_address(self): + from rpython.rtyper.lltypesystem import rffi + ptr = self.buf.get_raw_address() + return rffi.ptradd(ptr, self.offset) + + def getformat(self): + return self.buf.getformat() + + def getitemsize(self): + return self.buf.getitemsize() + + def getndim(self): + return self.buf.getndim() + + def getshape(self): + return self.shape + + def getstrides(self): + return self.strides _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit