Path: blob/main/third_party/leb128/__init__.py
6162 views
"""1https://en.wikipedia.org/wiki/LEB12823LEB128 or Little Endian Base 128 is a form of variable-length code4compression used to store an arbitrarily large integer in a small number of5bytes. LEB128 is used in the DWARF debug file format and the WebAssembly6binary encoding for all integer literals.7"""89import typing101112class _U:13@staticmethod14def encode(i: int) -> bytearray:15"""Encode the int i using unsigned leb128 and return the encoded bytearray."""16assert i >= 017r = []18while True:19byte = i & 0x7f20i = i >> 721if i == 0:22r.append(byte)23return bytearray(r)24r.append(0x80 | byte)2526@staticmethod27def decode(b: bytearray) -> int:28"""Decode the unsigned leb128 encoded bytearray"""29r = 030for i, e in enumerate(b):31r = r + ((e & 0x7f) << (i * 7))32return r3334@staticmethod35def decode_reader(r: typing.BinaryIO) -> (int, int):36"""37Decode the unsigned leb128 encoded from a reader, it will return two values, the actual number and the number38of bytes read.39"""40a = bytearray()41while True:42b = ord(r.read(1))43a.append(b)44if (b & 0x80) == 0:45break46return _U.decode(a), len(a)474849class _I:50@staticmethod51def encode(i: int) -> bytearray:52"""Encode the int i using signed leb128 and return the encoded bytearray."""53r = []54while True:55byte = i & 0x7f56i = i >> 757if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0):58r.append(byte)59return bytearray(r)60r.append(0x80 | byte)6162@staticmethod63def decode(b: bytearray) -> int:64"""Decode the signed leb128 encoded bytearray"""65r = 066for i, e in enumerate(b):67r = r + ((e & 0x7f) << (i * 7))68if e & 0x40 != 0:69r |= - (1 << (i * 7) + 7)70return r7172@staticmethod73def decode_reader(r: typing.BinaryIO) -> (int, int):74"""75Decode the signed leb128 encoded from a reader, it will return two values, the actual number and the number76of bytes read.77"""78a = bytearray()79while True:80b = ord(r.read(1))81a.append(b)82if (b & 0x80) == 0:83break84return _I.decode(a), len(a)858687u = _U()88i = _I()899091