···66from . import BlockStore
7788# should be equivalent to multiformats.varint.decode(), but not extremely slow for no reason.
99-def parse_varint(stream: BinaryIO):
99+def decode_varint(stream: BinaryIO):
1010 n = 0
1111- shift = 0
1212- while True:
1111+ for shift in range(0, 63, 7):
1312 val = stream.read(1)
1413 if not val:
1515- raise ValueError("eof") # match varint.decode()
1414+ raise ValueError("unexpected end of varint input")
1615 val = val[0]
1716 n |= (val & 0x7f) << shift
1817 if not val & 0x80:
1818+ if shift and not val:
1919+ raise ValueError("varint not minimally encoded")
1920 return n
2021 shift += 7
2222+ raise ValueError("varint too long")
21232224def encode_varint(n: int) -> bytes:
2525+ if not 0 <= n < 2**63:
2626+ raise ValueError("integer out of encodable varint range")
2327 res = []
2428 while n > 0x7f:
2529 res.append(0x80 | (n & 0x7f))
···4751 file.seek(0)
48524953 # parse out CAR header
5050- header_len = parse_varint(file)
5454+ header_len = decode_varint(file)
5155 header = file.read(header_len)
5256 if len(header) != header_len:
5357 raise EOFError("not enough CAR header bytes")
···6266 self.block_offsets = {}
6367 while True:
6468 try:
6565- length = parse_varint(file)
6969+ length = decode_varint(file)
6670 except ValueError:
6771 break # EOF
6872 start = file.tell()