Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct-2
Changeset: r91181:474ad89b70a8
Date: 2017-05-04 18:46 +0200
http://bitbucket.org/pypy/pypy/changeset/474ad89b70a8/

Log:    refactor rstruct.runpack to use the new Buffer.typed_read
        functionality, instead of deprecated strstorage. This breaks
        pypy/module/struct, whstruct, which will be fixed later

diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py
--- a/rpython/rlib/rstruct/runpack.py
+++ b/rpython/rlib/rstruct/runpack.py
@@ -8,17 +8,20 @@
 from rpython.rlib.rstruct.formatiterator import FormatIterator
 from rpython.rlib.rstruct.error import StructError
 from rpython.rlib.objectmodel import specialize
+from rpython.rlib.buffer import StringBuffer
 
 class MasterReader(object):
     def __init__(self, s):
-        self.input = s
+        self.inputbuf = StringBuffer(s)
+        self.length = len(s)
         self.inputpos = 0
 
     def read(self, count):
         end = self.inputpos + count
-        if end > len(self.input):
+        if end > self.length:
             raise StructError("unpack str size too short for format")
-        s = self.input[self.inputpos : end]
+        size = end - self.inputpos
+        s = self.inputbuf.getslice(self.inputpos, end, 1, size)
         self.inputpos = end
         return s
 
@@ -40,8 +43,8 @@
         def appendobj(self, value):
             self.value = value
 
-        def get_buffer_as_string_maybe(self):
-            return self.mr.input, self.mr.inputpos
+        def get_buffer_and_pos(self):
+            return self.mr.inputbuf, self.mr.inputpos
 
         def skip(self, size):
             self.read(size) # XXX, could avoid taking the slice
diff --git a/rpython/rlib/rstruct/standardfmttable.py 
b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -14,6 +14,7 @@
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.strstorage import str_storage_getitem
 from rpython.rlib import rarithmetic
+from rpython.rlib.buffer import CannotRead
 from rpython.rtyper.lltypesystem import rffi
 
 native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
@@ -134,19 +135,22 @@
 USE_FASTPATH = True    # set to False by some tests
 ALLOW_SLOWPATH = True  # set to False by some tests
 
-class CannotUnpack(Exception):
-    pass
 
 @specialize.memo()
 def unpack_fastpath(TYPE):
     @specialize.argtype(0)
     def do_unpack_fastpath(fmtiter):
         size = rffi.sizeof(TYPE)
-        strbuf, pos = fmtiter.get_buffer_as_string_maybe()
-        if strbuf is None or pos % size != 0 or not USE_FASTPATH:
-            raise CannotUnpack
+        buf, pos = fmtiter.get_buffer_and_pos()
+        if pos % size != 0 or not USE_FASTPATH:
+            # XXX: maybe we are too conservative here? On most architectures,
+            # it is possible to read the data even if pos is not
+            # aligned. Also, probably it should responsibility of
+            # buf.typed_read to raise CannotRead in case it is not aligned
+            # *and* it is not supported.
+            raise CannotRead
         fmtiter.skip(size)
-        return str_storage_getitem(TYPE, strbuf, pos)
+        return buf.typed_read(TYPE, pos)
     return do_unpack_fastpath
 
 @specialize.argtype(0)
@@ -196,7 +200,7 @@
         try:
             # fast path
             val = unpack_fastpath(TYPE)(fmtiter)
-        except CannotUnpack:
+        except CannotRead:
             # slow path, take the slice
             input = fmtiter.read(size)
             val = str_storage_getitem(TYPE, input, 0)
@@ -251,7 +255,7 @@
             return False
         try:
             intvalue = unpack_fastpath(TYPE)(fmtiter)
-        except CannotUnpack:
+        except CannotRead:
             return False
         if not signed and size < native_int_size:
             intvalue = rarithmetic.intmask(intvalue)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to