1.1 --- a/iixr.py Tue Aug 25 23:53:20 2009 +0200
1.2 +++ b/iixr.py Wed Aug 26 22:51:29 2009 +0200
1.3 @@ -53,38 +53,23 @@
1.4 # Special case: one byte containing zero.
1.5
1.6 elif number == 0:
1.7 - self.f.write(chr(1) + chr(0))
1.8 + self.f.write(chr(0))
1.9 return
1.10
1.11 # Write the number from least to most significant digits.
1.12
1.13 - nbytes = 0
1.14 bytes = []
1.15
1.16 while number != 0:
1.17 - lsd = number & 255
1.18 + lsd = number & 127
1.19 + number = number >> 7
1.20 + if number != 0:
1.21 + lsd |= 128
1.22 bytes.append(chr(lsd))
1.23 - number = number >> 8
1.24 - nbytes += 1
1.25
1.26 - # Too large numbers are not supported.
1.27 -
1.28 - if nbytes > 255:
1.29 - raise ValueError, "Number %r is too large." % number
1.30 -
1.31 - bytes.insert(0, chr(nbytes))
1.32 record = "".join(bytes)
1.33 self.f.write(record)
1.34
1.35 - def write_unsigned_byte(self, number):
1.36 -
1.37 - "Write 'number' to the file using a single byte."
1.38 -
1.39 - if not (0 <= number <= 255):
1.40 - raise ValueError, "Number %r is out of range." % number
1.41 -
1.42 - self.f.write(chr(number))
1.43 -
1.44 def write_string(self, s):
1.45
1.46 "Write 's' to the file, recording its length."
1.47 @@ -94,7 +79,7 @@
1.48 if not (0 <= length <= 255):
1.49 raise ValueError, "String %r is too long." % s
1.50
1.51 - self.write_unsigned_byte(length)
1.52 + self.write_number(length)
1.53 self.f.write(s)
1.54
1.55 class FileReader(File):
1.56 @@ -105,39 +90,31 @@
1.57
1.58 "Read a number from the file."
1.59
1.60 - nbytes = self.read_unsigned_byte()
1.61 -
1.62 # Read each byte, adding it to the number.
1.63
1.64 - bytes = self.f.read(nbytes)
1.65 -
1.66 - i = 0
1.67 shift = 0
1.68 number = 0
1.69 + more = 1
1.70
1.71 - while i < nbytes:
1.72 - csd = ord(bytes[i])
1.73 + while more:
1.74 + byte = self.f.read(1)
1.75 + if not byte:
1.76 + raise EOFError
1.77 +
1.78 + csd = ord(byte)
1.79 + more = csd & 128 != 0
1.80 + if more:
1.81 + csd &= 127
1.82 number += (csd << shift)
1.83 - shift += 8
1.84 - i += 1
1.85 + shift += 7
1.86
1.87 return number
1.88
1.89 - def read_unsigned_byte(self):
1.90 -
1.91 - "Read a number from the file, consuming a single byte."
1.92 -
1.93 - s = self.f.read(1)
1.94 - if not s:
1.95 - raise EOFError
1.96 -
1.97 - return ord(s)
1.98 -
1.99 def read_string(self):
1.100
1.101 "Read a string from the file."
1.102
1.103 - length = self.read_unsigned_byte()
1.104 + length = self.read_number()
1.105 return self.f.read(length)
1.106
1.107 # Specific classes.
1.108 @@ -282,7 +259,7 @@
1.109 common = len(commonprefix([self.last_term, term]))
1.110 suffix = term[common:]
1.111
1.112 - self.write_unsigned_byte(common)
1.113 + self.write_number(common)
1.114 self.write_string(suffix)
1.115
1.116 # Write the offset delta.
1.117 @@ -310,7 +287,7 @@
1.118
1.119 # Read the prefix length and term suffix.
1.120
1.121 - common = self.read_unsigned_byte()
1.122 + common = self.read_number()
1.123 suffix = self.read_string()
1.124
1.125 self.last_term = self.last_term[:common] + suffix