2023-10-22 16:25:32 -05:00
|
|
|
# https://en.wikipedia.org/wiki/LEB128
|
|
|
|
#
|
|
|
|
# LEB128 or Little Endian Base 128 is a form of variable-length code
|
|
|
|
# compression used to store an arbitrarily large integer in a small number of
|
|
|
|
# bytes. LEB128 is used in the DWARF debug file format and the WebAssembly
|
|
|
|
# binary encoding for all integer literals.
|
|
|
|
|
|
|
|
# Taken from https://github.com/mohanson/pywasm/blob/master/pywasm/leb128.py under the MIT license
|
|
|
|
|
|
|
|
import typing
|
|
|
|
|
|
|
|
|
|
|
|
class ULEB128:
|
|
|
|
@staticmethod
|
|
|
|
def encode(i: int) -> bytearray:
|
|
|
|
assert i >= 0
|
|
|
|
r = []
|
|
|
|
while True:
|
2023-10-22 16:27:11 -05:00
|
|
|
byte = i & 0x7F
|
2023-10-22 16:25:32 -05:00
|
|
|
i = i >> 7
|
|
|
|
if i == 0:
|
|
|
|
r.append(byte)
|
|
|
|
return bytearray(r)
|
|
|
|
r.append(0x80 | byte)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def decode(b: bytearray) -> int:
|
|
|
|
r = 0
|
|
|
|
for i, e in enumerate(b):
|
2023-10-22 16:27:11 -05:00
|
|
|
r = r + ((e & 0x7F) << (i * 7))
|
2023-10-22 16:25:32 -05:00
|
|
|
return r
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def decode_reader(r: typing.BinaryIO) -> (int, int):
|
|
|
|
a = bytearray()
|
|
|
|
while True:
|
|
|
|
b = ord(r.read(1))
|
|
|
|
a.append(b)
|
|
|
|
if (b & 0x80) == 0:
|
|
|
|
break
|
|
|
|
return ULEB128.decode(a), len(a)
|
|
|
|
|
|
|
|
|
|
|
|
class ILEB128:
|
|
|
|
@staticmethod
|
|
|
|
def encode(i: int) -> bytearray:
|
|
|
|
r = []
|
|
|
|
while True:
|
2023-10-22 16:27:11 -05:00
|
|
|
byte = i & 0x7F
|
2023-10-22 16:25:32 -05:00
|
|
|
i = i >> 7
|
|
|
|
if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0):
|
|
|
|
r.append(byte)
|
|
|
|
return bytearray(r)
|
|
|
|
r.append(0x80 | byte)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def decode(b: bytearray) -> int:
|
|
|
|
r = 0
|
|
|
|
for i, e in enumerate(b):
|
2023-10-22 16:27:11 -05:00
|
|
|
r = r + ((e & 0x7F) << (i * 7))
|
2023-10-22 16:25:32 -05:00
|
|
|
if e & 0x40 != 0:
|
2023-10-22 16:27:11 -05:00
|
|
|
r |= -(1 << (i * 7) + 7)
|
2023-10-22 16:25:32 -05:00
|
|
|
return r
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def decode_reader(r: typing.BinaryIO) -> (int, int):
|
|
|
|
a = bytearray()
|
|
|
|
while True:
|
|
|
|
b = ord(r.read(1))
|
|
|
|
a.append(b)
|
|
|
|
if (b & 0x80) == 0:
|
|
|
|
break
|
2023-10-22 16:27:11 -05:00
|
|
|
return ILEB128.decode(a), len(a)
|