Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/third_party/leb128/__init__.py
6162 views
1
"""
2
https://en.wikipedia.org/wiki/LEB128
3
4
LEB128 or Little Endian Base 128 is a form of variable-length code
5
compression used to store an arbitrarily large integer in a small number of
6
bytes. LEB128 is used in the DWARF debug file format and the WebAssembly
7
binary encoding for all integer literals.
8
"""
9
10
import typing
11
12
13
class _U:
14
@staticmethod
15
def encode(i: int) -> bytearray:
16
"""Encode the int i using unsigned leb128 and return the encoded bytearray."""
17
assert i >= 0
18
r = []
19
while True:
20
byte = i & 0x7f
21
i = i >> 7
22
if i == 0:
23
r.append(byte)
24
return bytearray(r)
25
r.append(0x80 | byte)
26
27
@staticmethod
28
def decode(b: bytearray) -> int:
29
"""Decode the unsigned leb128 encoded bytearray"""
30
r = 0
31
for i, e in enumerate(b):
32
r = r + ((e & 0x7f) << (i * 7))
33
return r
34
35
@staticmethod
36
def decode_reader(r: typing.BinaryIO) -> (int, int):
37
"""
38
Decode the unsigned leb128 encoded from a reader, it will return two values, the actual number and the number
39
of bytes read.
40
"""
41
a = bytearray()
42
while True:
43
b = ord(r.read(1))
44
a.append(b)
45
if (b & 0x80) == 0:
46
break
47
return _U.decode(a), len(a)
48
49
50
class _I:
51
@staticmethod
52
def encode(i: int) -> bytearray:
53
"""Encode the int i using signed leb128 and return the encoded bytearray."""
54
r = []
55
while True:
56
byte = i & 0x7f
57
i = i >> 7
58
if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0):
59
r.append(byte)
60
return bytearray(r)
61
r.append(0x80 | byte)
62
63
@staticmethod
64
def decode(b: bytearray) -> int:
65
"""Decode the signed leb128 encoded bytearray"""
66
r = 0
67
for i, e in enumerate(b):
68
r = r + ((e & 0x7f) << (i * 7))
69
if e & 0x40 != 0:
70
r |= - (1 << (i * 7) + 7)
71
return r
72
73
@staticmethod
74
def decode_reader(r: typing.BinaryIO) -> (int, int):
75
"""
76
Decode the signed leb128 encoded from a reader, it will return two values, the actual number and the number
77
of bytes read.
78
"""
79
a = bytearray()
80
while True:
81
b = ord(r.read(1))
82
a.append(b)
83
if (b & 0x80) == 0:
84
break
85
return _I.decode(a), len(a)
86
87
88
u = _U()
89
i = _I()
90
91