X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=bup.git;a=blobdiff_plain;f=lib%2Fbup%2Fvint.py;h=086cb302087d8edae343631c04c68a87440c35f8;hp=378234c62d2a2a5ec1f2ed9b62598a132e8dd07d;hb=bf67f94dd4f4096de4eee07a7dc377d6c889a016;hpb=453fcdac8595cf93c65c7deebf1f6557c0e410db diff --git a/lib/bup/vint.py b/lib/bup/vint.py index 378234c..086cb30 100644 --- a/lib/bup/vint.py +++ b/lib/bup/vint.py @@ -5,37 +5,50 @@ # This code is covered under the terms of the GNU Library General # Public License as described in the bup LICENSE file. +# Variable length integers are encoded as vints -- see lucene. + +from __future__ import absolute_import from io import BytesIO +import sys + +from bup import compat -# Variable length integers are encoded as vints -- see jakarta lucene. def write_vuint(port, x): + write = port.write + bytes_from_uint = compat.bytes_from_uint if x < 0: raise Exception("vuints must not be negative") elif x == 0: - port.write('\0') + write(bytes_from_uint(0)) else: - while x: + while True: seven_bits = x & 0x7f x >>= 7 if x: - port.write(chr(0x80 | seven_bits)) + write(bytes_from_uint(0x80 | seven_bits)) else: - port.write(chr(seven_bits)) + write(bytes_from_uint(seven_bits)) + break def read_vuint(port): c = port.read(1) - if c == '': - raise EOFError('encountered EOF while reading vuint'); + if not c: + raise EOFError('encountered EOF while reading vuint') + assert isinstance(c, bytes) + if ord(c) == 0: + return 0 result = 0 offset = 0 - while c: + while True: b = ord(c) if b & 0x80: result |= ((b & 0x7f) << offset) offset += 7 c = port.read(1) + if not c: + raise EOFError('encountered EOF while reading vuint') else: result |= (b << offset) break @@ -45,8 +58,10 @@ def read_vuint(port): def write_vint(port, x): # Sign is handled with the second bit of the first byte. All else # matches vuint. + write = port.write + bytes_from_uint = compat.bytes_from_uint if x == 0: - port.write('\0') + write(bytes_from_uint(0)) else: if x < 0: x = -x @@ -55,38 +70,40 @@ def write_vint(port, x): sign_and_six_bits = x & 0x3f x >>= 6 if x: - port.write(chr(0x80 | sign_and_six_bits)) + write(bytes_from_uint(0x80 | sign_and_six_bits)) write_vuint(port, x) else: - port.write(chr(sign_and_six_bits)) + write(bytes_from_uint(sign_and_six_bits)) def read_vint(port): c = port.read(1) - if c == '': - raise EOFError('encountered EOF while reading vint'); + if not c: + raise EOFError('encountered EOF while reading vint') + assert isinstance(c, bytes) negative = False result = 0 offset = 0 # Handle first byte with sign bit specially. - if c: - b = ord(c) - if b & 0x40: - negative = True - result |= (b & 0x3f) - if b & 0x80: - offset += 6 - c = port.read(1) - elif negative: - return -result - else: - return result - while c: + b = ord(c) + if b & 0x40: + negative = True + result |= (b & 0x3f) + if b & 0x80: + offset += 6 + c = port.read(1) + elif negative: + return -result + else: + return result + while True: b = ord(c) if b & 0x80: result |= ((b & 0x7f) << offset) offset += 7 c = port.read(1) + if not c: + raise EOFError('encountered EOF while reading vint') else: result |= (b << offset) break @@ -109,11 +126,9 @@ def read_bvec(port): def skip_bvec(port): port.read(read_vuint(port)) - -def pack(types, *args): +def send(port, types, *args): if len(types) != len(args): raise Exception('number of arguments does not match format string') - port = BytesIO() for (type, value) in zip(types, args): if type == 'V': write_vuint(port, value) @@ -123,12 +138,9 @@ def pack(types, *args): write_bvec(port, value) else: raise Exception('unknown xpack format string item "' + type + '"') - return port.getvalue() - -def unpack(types, data): +def recv(port, types): result = [] - port = BytesIO(data) for type in types: if type == 'V': result.append(read_vuint(port)) @@ -139,3 +151,12 @@ def unpack(types, data): else: raise Exception('unknown xunpack format string item "' + type + '"') return result + +def pack(types, *args): + port = BytesIO() + send(port, types, *args) + return port.getvalue() + +def unpack(types, data): + port = BytesIO(data) + return recv(port, types)