1.1 --- a/iixr.py Sat Sep 12 01:52:23 2009 +0200
1.2 +++ b/iixr.py Sat Sep 12 18:48:23 2009 +0200
1.3 @@ -199,8 +199,12 @@
1.4
1.5 def __init__(self, f):
1.6 File.__init__(self, f)
1.7 + self.reset_cache()
1.8 +
1.9 + def reset_cache(self):
1.10 self.cache = ""
1.11 self.cache_length = 0
1.12 + self.cache_start = 0
1.13
1.14 def read_number(self):
1.15
1.16 @@ -255,30 +259,56 @@
1.17 # Cache-affected methods.
1.18
1.19 def read(self, n):
1.20 - needed = n - self.cache_length
1.21 + needed = n - (self.cache_length - self.cache_start)
1.22 +
1.23 + # Read the needed number of characters, if possible.
1.24 +
1.25 if needed > 0:
1.26 s = self.f.read(max(needed, 1000))
1.27 self.cache += s
1.28 self.cache_length += len(s)
1.29
1.30 - s = self.cache[:n]
1.31 - self.cache = self.cache[n:]
1.32 - self.cache_length = len(self.cache)
1.33 + # Get the end of the requested block.
1.34 +
1.35 + next_start = self.cache_start + n
1.36 + s = self.cache[self.cache_start:next_start]
1.37 +
1.38 + # Reposition the pointer to the cache.
1.39 +
1.40 + self._seek_cache(len(s))
1.41 return s
1.42
1.43 def tell(self):
1.44 - return self.f.tell() - self.cache_length
1.45 + return self.f.tell() - self.cache_length + self.cache_start
1.46
1.47 def seek(self, offset):
1.48 current = self.tell()
1.49 self.f.seek(offset)
1.50 +
1.51 + # If seeking forward, attempt to navigate the cache.
1.52 +
1.53 if offset >= current:
1.54 - discarded = offset - current
1.55 - self.cache = self.cache[discarded:]
1.56 + self._seek_cache(offset - current)
1.57 + else:
1.58 + self.reset_cache()
1.59 +
1.60 + def _seek_cache(self, delta):
1.61 + next_start = self.cache_start + delta
1.62 +
1.63 + if next_start >= len(self.cache):
1.64 + self.reset_cache()
1.65 +
1.66 + # If the cache is too big, resize it.
1.67 +
1.68 + elif next_start > 1000:
1.69 + self.cache = self.cache[next_start:]
1.70 self.cache_length = len(self.cache)
1.71 + self.cache_start = 0
1.72 +
1.73 + # Otherwise, just reference the next part of the cache.
1.74 +
1.75 else:
1.76 - self.cache = ""
1.77 - self.cache_length = 0
1.78 + self.cache_start = next_start
1.79
1.80 class FileOpener:
1.81