1.1 --- a/iixr/files.py Wed Sep 16 21:12:17 2009 +0200
1.2 +++ b/iixr/files.py Thu Sep 17 20:10:31 2009 +0200
1.3 @@ -19,18 +19,10 @@
1.4 """
1.5
1.6 from iixr.data import vint
1.7 -from cStringIO import StringIO
1.8 -import bz2, zlib
1.9 +import zlib
1.10
1.11 # Constants.
1.12
1.13 -WRITE_CACHE_SIZE = 100000
1.14 -READ_CACHE_SIZE = 10000
1.15 -READ_CACHE_RESIZE = 5000
1.16 -
1.17 -compressors = [("b", bz2.compress), ("z", zlib.compress)]
1.18 -decompressors = {"b" : bz2.decompress, "z" : zlib.decompress}
1.19 -
1.20 class File:
1.21
1.22 "A basic file abstraction."
1.23 @@ -73,8 +65,6 @@
1.24
1.25 def __init__(self, f):
1.26 File.__init__(self, f)
1.27 - self.cache = StringIO()
1.28 - self.cache_length = 0
1.29
1.30 def write_number(self, number):
1.31
1.32 @@ -97,14 +87,13 @@
1.33 # Compress the string if requested.
1.34
1.35 if compress:
1.36 - for flag, fn in compressors:
1.37 - cs = fn(s)
1.38 + cs = zlib.compress(s)
1.39 +
1.40 + # Take any shorter than the original.
1.41
1.42 - # Take the first string shorter than the original.
1.43 -
1.44 - if len(cs) < len(s):
1.45 - s = cs
1.46 - break
1.47 + if len(cs) < len(s):
1.48 + flag = "z"
1.49 + s = cs
1.50 else:
1.51 flag = "-"
1.52
1.53 @@ -119,17 +108,10 @@
1.54 # Cache-affected methods.
1.55
1.56 def write(self, s):
1.57 - self.cache.write(s)
1.58 - if self.cache.tell() >= WRITE_CACHE_SIZE:
1.59 - self.flush()
1.60 + self.f.write(s)
1.61
1.62 def tell(self):
1.63 - return self.f.tell() + self.cache.tell()
1.64 -
1.65 - def flush(self):
1.66 - self.cache.seek(0)
1.67 - self.f.write(self.cache.read())
1.68 - self.cache = StringIO()
1.69 + return self.f.tell()
1.70
1.71 class FileReader(File):
1.72
1.73 @@ -137,20 +119,6 @@
1.74
1.75 def __init__(self, f):
1.76 File.__init__(self, f)
1.77 - self.reset_cache(0)
1.78 -
1.79 - def reset_cache(self, offset):
1.80 - self.cache = ""
1.81 - self.cache_length = 0
1.82 - self.cache_start = 0
1.83 - self.cache_offset = offset
1.84 - self.f.seek(offset)
1.85 -
1.86 - def resize_cache(self, next_start):
1.87 - self.cache = self.cache[next_start:]
1.88 - self.cache_length = len(self.cache)
1.89 - self.cache_start = 0
1.90 - self.cache_offset += next_start
1.91
1.92 def read_number(self):
1.93
1.94 @@ -194,9 +162,8 @@
1.95
1.96 # Perform decompression if applicable.
1.97
1.98 - if flag != "-":
1.99 - fn = decompressors[flag]
1.100 - s = fn(s)
1.101 + if flag == "z":
1.102 + s = zlib.decompress(s)
1.103
1.104 # Convert strings to Unicode objects.
1.105
1.106 @@ -205,53 +172,13 @@
1.107 # Cache-affected methods.
1.108
1.109 def read(self, n):
1.110 - needed = n - (self.cache_length - self.cache_start)
1.111 -
1.112 - # Read the needed number of characters, if possible.
1.113 -
1.114 - if needed > 0:
1.115 - s = self.f.read(max(needed, READ_CACHE_SIZE))
1.116 - self.cache += s
1.117 - self.cache_length += len(s)
1.118 -
1.119 - # Get the end of the requested block.
1.120 -
1.121 - next_start = self.cache_start + n
1.122 - s = self.cache[self.cache_start:next_start]
1.123 -
1.124 - # Reposition the pointer to the cache.
1.125 -
1.126 - self._seek_cache(len(s))
1.127 - return s
1.128 + return self.f.read(n)
1.129
1.130 def tell(self):
1.131 - return self.cache_offset + self.cache_start
1.132 + return self.f.tell()
1.133
1.134 def seek(self, offset):
1.135 - current = self.tell()
1.136 -
1.137 - # If seeking forward, attempt to navigate the cache.
1.138 -
1.139 - if offset >= current:
1.140 - self._seek_cache(offset - current)
1.141 - else:
1.142 - self.reset_cache(offset)
1.143 -
1.144 - def _seek_cache(self, delta):
1.145 - next_start = self.cache_start + delta
1.146 -
1.147 - if next_start > 0 and next_start >= len(self.cache):
1.148 - self.reset_cache(self.cache_offset + next_start)
1.149 -
1.150 - # If the cache is too big, resize it.
1.151 -
1.152 - elif next_start > READ_CACHE_RESIZE:
1.153 - self.resize_cache(next_start)
1.154 -
1.155 - # Otherwise, just reference the next part of the cache.
1.156 -
1.157 - else:
1.158 - self.cache_start = next_start
1.159 + self.f.seek(offset)
1.160
1.161 class FileOpener:
1.162