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

Reply via email to