1 """Binary encodings for bup."""
3 # Copyright (C) 2010 Rob Browning
5 # This code is covered under the terms of the GNU Library General
6 # Public License as described in the bup LICENSE file.
8 from cStringIO import StringIO
10 # Variable length integers are encoded as vints -- see jakarta lucene.
12 def write_vuint(port, x):
14 raise Exception("vuints must not be negative")
22 port.write(chr(0x80 | seven_bits))
24 port.write(chr(seven_bits))
30 raise EOFError('encountered EOF while reading vuint');
36 result |= ((b & 0x7f) << offset)
40 result |= (b << offset)
45 def write_vint(port, x):
46 # Sign is handled with the second bit of the first byte. All else
53 sign_and_six_bits = (x & 0x3f) | 0x40
55 sign_and_six_bits = x & 0x3f
58 port.write(chr(0x80 | sign_and_six_bits))
61 port.write(chr(sign_and_six_bits))
67 raise EOFError('encountered EOF while reading vint');
71 # Handle first byte with sign bit specially.
81 return -result if negative else result
85 result |= ((b & 0x7f) << offset)
89 result |= (b << offset)
91 return -result if negative else result
94 def write_bvec(port, x):
95 write_vuint(port, len(x))
105 port.read(read_vuint(port))
108 def pack(types, *args):
109 if len(types) != len(args):
110 raise Exception('number of arguments does not match format string')
112 for (type, value) in zip(types, args):
114 write_vuint(port, value)
116 write_vint(port, value)
118 write_bvec(port, value)
120 raise Exception('unknown xpack format string item "' + type + '"')
121 return port.getvalue()
124 def unpack(types, data):
126 port = StringIO(data)
129 result.append(read_vuint(port))
131 result.append(read_vint(port))
133 result.append(read_bvec(port))
135 raise Exception('unknown xunpack format string item "' + type + '"')