Add vints_pack

This commit is contained in:
Alan Boudreault
2017-01-15 17:03:39 -05:00
parent aa11b5720b
commit 6f30ba392b

View File

@@ -86,6 +86,10 @@ def varint_pack(big):
return six.binary_type(revbytes)
def encode_zig_zag(n):
return (n << 1) ^ (n >> 63)
def decode_zig_zag(n):
return (n >> 1) ^ -(n & 1)
@@ -111,3 +115,30 @@ def vints_unpack(term): # noqa
values.append(decode_zig_zag(val))
return tuple(values)
def vints_pack(values):
revbytes = bytearray()
values.reverse()
for v in values:
v = encode_zig_zag(v)
if v < 128:
revbytes.append(v)
else:
num_extra_bytes = 0
num_bits = v.bit_length()
# We need to reserve (num_extra_bytes+1) bits in the first byte
# ie. with 1 extra byte, the first byte needs to be something like '10XXXXXX'
while num_bits > (8-(num_extra_bytes+1)):
num_extra_bytes += 1
num_bits -= 8
revbytes.append(v & 0xff)
v >>= 8
# We can now store the last bits in the first byte
n = 8 - num_extra_bytes
v |= (0xff >> n << n)
revbytes.append(abs(v))
revbytes.reverse()
return six.binary_type(revbytes)