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