Author: Richard Plangger <planri...@gmail.com>
Branch: py3.5-ssl
Changeset: r88815:2bb952fe0d93
Date: 2016-12-02 11:57 +0100
http://bitbucket.org/pypy/pypy/changeset/2bb952fe0d93/

Log:    passes the test for reverse iterating a memory view (flat memory
        views for bytes only tested)

diff --git a/pypy/module/struct/formatiterator.py 
b/pypy/module/struct/formatiterator.py
--- a/pypy/module/struct/formatiterator.py
+++ b/pypy/module/struct/formatiterator.py
@@ -109,6 +109,7 @@
         self.buf = buf
         self.length = buf.getlength()
         self.pos = 0
+        self.strides = None
         self.result_w = []     # list of wrapped objects
 
     # See above comment on operate.
@@ -126,11 +127,18 @@
         self.pos = (self.pos + mask) & ~mask
 
     def finished(self):
-        if self.pos != self.length:
-            raise StructError("unpack str size too long for format")
+        if self.strides:
+            # FIXME richard
+            pass
+        else:
+            if self.pos != self.length:
+                raise StructError("unpack str size too long for format")
 
     def read(self, count):
-        end = self.pos + count
+        if self.strides:
+            end = self.pos + count * self.strides[0]
+        else:
+            end = self.pos + count
         if end > self.length:
             raise StructError("unpack str size too short for format")
         s = self.buf.getslice(self.pos, end, 1, count)
@@ -151,5 +159,15 @@
         string, pos = self.buf.as_str_and_offset_maybe()
         return string, pos+self.pos
 
-    def skip(self, size):
-        self.read(size) # XXX, could avoid taking the slice
+    def skip(self, count):
+        # assumption: UnpackFormatIterator only iterates over
+        # flat structures (continous memory) either, forward (index
+        # is increasing) or reverse
+        if self.strides:
+            assert len(self.strides) == 1
+            end = self.pos + count * self.strides[0]
+        else:
+            end = self.pos + count
+        if end > self.length:
+            raise StructError("unpack str size too short for format")
+        self.pos = end
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
@@ -167,13 +167,18 @@
             raise NotImplementedError
         elif dim == 1:
             itemsize = self.getitemsize()
-            return self._tolist(space, buf, buf.getlength() // itemsize, fmt)
+            return self._tolist(space, buf, self.getlength() // itemsize, fmt)
         else:
             return self._tolist_rec(space, buf, 0, 0, fmt)
 
     def _tolist(self, space, buf, count, fmt):
         # TODO: this probably isn't very fast
         fmtiter = UnpackFormatIterator(space, buf)
+        # patch the length, necessary buffer might have offset
+        # which leads to wrong length calculation if e.g. the
+        # memoryview is reversed
+        fmtiter.length = self.getlength()
+        fmtiter.strides = self.getstrides()
         fmtiter.interpret(fmt * count)
         return space.newlist(fmtiter.result_w)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to