Author: Ronan Lamy <[email protected]>
Branch: PyBuffer
Changeset: r91036:21e7a68c528e
Date: 2017-04-10 19:39 +0100
http://bitbucket.org/pypy/pypy/changeset/21e7a68c528e/
Log: Move W_MemoryObject.lookup_dimension() to Buffer.get_offset()
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -2,6 +2,8 @@
from rpython.rlib.signature import signature
from rpython.rlib import types
+from pypy.interpreter.error import oefmt
+
class Buffer(object):
"""Abstract base class for buffers."""
@@ -78,15 +80,30 @@
if copiedbytes >= bytesize:
break
+ def get_offset(self, space, dim, index):
+ "Convert index at dimension `dim` into a byte offset"
+ shape = self.getshape()
+ nitems = shape[dim]
+ if index < 0:
+ index += nitems
+ if index < 0 or index >= nitems:
+ raise oefmt(space.w_IndexError,
+ "index out of bounds on dimension %d", dim+1)
+ # TODO suboffsets?
+ strides = self.getstrides()
+ return strides[dim] * index
+
+
def w_getitem(self, space, idx):
+ offset = self.get_offset(space, 0, idx)
from pypy.module.struct.formatiterator import UnpackFormatIterator
itemsize = self.getitemsize()
if itemsize == 1:
- ch = self.as_binary()[idx]
+ ch = self.as_binary()[offset]
return space.newint(ord(ch))
else:
# TODO: this probably isn't very fast
- buf = SubBuffer(self.as_binary(), idx, itemsize)
+ buf = SubBuffer(self.as_binary(), offset, itemsize)
fmtiter = UnpackFormatIterator(space, buf)
fmtiter.length = buf.getlength()
fmtiter.interpret(self.getformat())
@@ -94,9 +111,10 @@
def setitem_w(self, space, idx, w_obj):
from pypy.module.struct.formatiterator import PackFormatIterator
+ offset = self.get_offset(space, 0, idx)
itemsize = self.getitemsize()
if itemsize == 1:
- self.as_binary()[idx] = space.byte_w(w_obj)
+ self.as_binary()[offset] = space.byte_w(w_obj)
else:
# TODO: this probably isn't very fast
fmtiter = PackFormatIterator(space, [w_obj], itemsize)
@@ -107,7 +125,7 @@
"memoryview: invalid type for format '%s'",
self.getformat())
byteval = fmtiter.result.build()
- self.setslice(idx, byteval)
+ self.setslice(offset, byteval)
class SimpleBuffer(Buffer):
@@ -145,11 +163,24 @@
def getstrides(self):
return [1]
+ def get_offset(self, space, dim, index):
+ "Convert index at dimension `dim` into a byte offset"
+ assert dim == 0
+ nitems = self.getlength()
+ if index < 0:
+ index += nitems
+ if index < 0 or index >= nitems:
+ raise oefmt(space.w_IndexError,
+ "index out of bounds on dimension %d", dim + 1)
+ return index
+
def w_getitem(self, space, idx):
+ idx = self.get_offset(space, 0, idx)
ch = self.data[idx]
return space.newint(ord(ch))
def setitem_w(self, space, idx, w_obj):
+ idx = self.get_offset(space, 0, idx)
self.data[idx] = space.byte_w(w_obj)
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
@@ -158,22 +158,10 @@
while dim < length:
w_obj = w_tuple.getitem(space, dim)
index = space.getindex_w(w_obj, space.w_IndexError)
- shape = self.buf.getshape()
- strides = self.buf.getstrides()
- start = self.lookup_dimension(space, shape, strides, start, dim,
index)
+ start += self.buf.get_offset(space, dim, index)
dim += 1
return start
- def lookup_dimension(self, space, shape, strides, start, dim, index):
- nitems = shape[dim]
- if index < 0:
- index += nitems
- if index < 0 or index >= nitems:
- raise oefmt(space.w_IndexError,
- "index out of bounds on dimension %d", dim+1)
- # TODO suboffsets?
- return start + strides[dim] * index
-
def _getitem_tuple_indexed(self, space, w_index):
view = self.buf
@@ -219,10 +207,7 @@
if dim == 0:
raise oefmt(space.w_TypeError, "invalid indexing of 0-dim
memory")
elif dim == 1:
- shape = self.getshape()
- strides = self.getstrides()
- idx = self.lookup_dimension(space, shape, strides, 0, 0, start)
- return self.buf.w_getitem(space, idx)
+ return self.buf.w_getitem(space, start)
else:
raise oefmt(space.w_NotImplementedError, "multi-dimensional
sub-views are not implemented")
elif is_slice:
@@ -263,10 +248,7 @@
start, stop, step, slicelength = self._decode_index(space, w_index,
is_slice)
itemsize = self.getitemsize()
if step == 0: # index only
- shape = self.getshape()
- strides = self.getstrides()
- idx = self.lookup_dimension(space, shape, strides, 0, 0, start)
- self.buf.setitem_w(space, idx, w_obj)
+ self.buf.setitem_w(space, start, w_obj)
elif step == 1:
value = space.buffer_w(w_obj, space.BUF_CONTIG_RO)
if value.getlength() != slicelength * itemsize:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit