[pypy-svn] pypy default: Support in rmmap find(reverse=True).
arigo
commits-noreply at bitbucket.org
Thu Feb 10 16:48:11 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r41786:8f6d23bc36ce
Date: 2011-02-10 16:43 +0100
http://bitbucket.org/pypy/pypy/changeset/8f6d23bc36ce/
Log: Support in rmmap find(reverse=True).
diff --git a/pypy/rlib/test/test_rmmap.py b/pypy/rlib/test/test_rmmap.py
--- a/pypy/rlib/test/test_rmmap.py
+++ b/pypy/rlib/test/test_rmmap.py
@@ -137,22 +137,31 @@
interpret(func, [f.fileno()])
f.close()
+ def test_find_rfind(self):
+ f = open(self.tmpname + "g", "w+")
+ f.write("foobarfoobar\0")
+ f.flush()
+ m = mmap.mmap(f.fileno(), 13)
+
+ for s1 in range(-20, 20):
+ for e1 in range(-20, 20):
+ expected = "foobarfoobar\0".find("ob", s1, e1)
+ assert m.find("ob", s1, e1, False) == expected
+ expected = "foobarfoobar\0".rfind("ob", s1, e1)
+ assert m.find("ob", s1, e1, True) == expected
+
+ m.close()
+ f.close()
+
def test_find(self):
f = open(self.tmpname + "g", "w+")
-
f.write("foobarfoobar\0")
f.flush()
- # prebuilt a table of expected search results
- expected = {}
- for s1 in range(-20, 20):
- for e1 in range(-20, 20):
- res = "foobarfoobar\0".find("ob", s1, e1)
- expected.setdefault(s1, {})[e1] = res
-
def func(no):
m = mmap.mmap(no, 12)
assert m.find("\0", 0, 13) == -1 # no searching past the stop
+ assert m.find("\0", 0, 13, True) == -1
m.close()
#
m = mmap.mmap(no, 13)
@@ -165,9 +174,6 @@
assert m.find("o", 2, 4) == 2
assert m.find("o", 2, -4) == 2
assert m.find("o", 8, -5) == -1
- for s1 in range(-20, 20):
- for e1 in range(-20, 20):
- assert m.find("ob", s1, e1) == expected[s1][e1]
m.close()
func(f.fileno())
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -361,7 +361,7 @@
self.pos += len(res)
return res
- def find(self, tofind, start, end):
+ def find(self, tofind, start, end, reverse=False):
self.check_valid()
# XXX naive! how can we reuse the rstr algorithm?
@@ -375,16 +375,33 @@
end = 0
elif end > self.size:
end = self.size
+ #
+ upto = end - len(tofind)
+ if not reverse:
+ step = 1
+ p = start
+ if p > upto:
+ return -1 # failure (empty range to search)
+ else:
+ step = -1
+ p = upto
+ upto = start
+ if p < upto:
+ return -1 # failure (empty range to search)
+ #
data = self.data
- for p in xrange(start, end - len(tofind) + 1):
+ while True:
+ assert p >= 0
for q in range(len(tofind)):
if data[p+q] != tofind[q]:
break # position 'p' is not a match
else:
# full match
return p
- # failure
- return -1
+ #
+ if p == upto:
+ return -1 # failure
+ p += step
def seek(self, pos, whence=0):
self.check_valid()
More information about the Pypy-commit
mailing list