forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
89 lines (77 loc) · 2.45 KB
/
__init__.py
File metadata and controls
89 lines (77 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""
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.
"""
import typing
class _U:
@staticmethod
def encode(i: int) -> bytearray:
"""Encode the int i using unsigned leb128 and return the encoded bytearray."""
assert i >= 0
r = []
while True:
byte = i & 0x7f
i = i >> 7
if i == 0:
r.append(byte)
return bytearray(r)
r.append(0x80 | byte)
@staticmethod
def decode(b: bytearray) -> int:
"""Decode the unsigned leb128 encoded bytearray"""
r = 0
for i, e in enumerate(b):
r = r + ((e & 0x7f) << (i * 7))
return r
@staticmethod
def decode_reader(r: typing.BinaryIO) -> (int, int):
"""
Decode the unsigned leb128 encoded from a reader, it will return two values, the actual number and the number
of bytes read.
"""
a = bytearray()
while True:
b = ord(r.read(1))
a.append(b)
if (b & 0x80) == 0:
break
return _U.decode(a), len(a)
class _I:
@staticmethod
def encode(i: int) -> bytearray:
"""Encode the int i using signed leb128 and return the encoded bytearray."""
r = []
while True:
byte = i & 0x7f
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:
"""Decode the signed leb128 encoded bytearray"""
r = 0
for i, e in enumerate(b):
r = r + ((e & 0x7f) << (i * 7))
if e & 0x40 != 0:
r |= - (1 << (i * 7) + 7)
return r
@staticmethod
def decode_reader(r: typing.BinaryIO) -> (int, int):
"""
Decode the signed leb128 encoded from a reader, it will return two values, the actual number and the number
of bytes read.
"""
a = bytearray()
while True:
b = ord(r.read(1))
a.append(b)
if (b & 0x80) == 0:
break
return _I.decode(a), len(a)
u = _U()
i = _I()