Skip to content

Commit

Permalink
Update leb128
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson committed Oct 16, 2024
1 parent 98996d8 commit 1eeda31
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions pywasm/leb128.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
# 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.
"""
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:
Expand All @@ -23,16 +26,24 @@ def encode(i: int) -> bytearray:

@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):
def decode_reader(r: typing.BinaryIO) -> typing.Tuple[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))
b = r.read(1)
if len(b) != 1:
raise EOFError
b = ord(b)
a.append(b)
if (b & 0x80) == 0:
break
Expand All @@ -42,6 +53,7 @@ def decode_reader(r: typing.BinaryIO) -> (int, int):
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
Expand All @@ -53,6 +65,7 @@ def encode(i: int) -> bytearray:

@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))
Expand All @@ -61,10 +74,17 @@ def decode(b: bytearray) -> int:
return r

@staticmethod
def decode_reader(r: typing.BinaryIO) -> (int, int):
def decode_reader(r: typing.BinaryIO) -> typing.Tuple[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))
b = r.read(1)
if len(b) != 1:
raise EOFError
b = ord(b)
a.append(b)
if (b & 0x80) == 0:
break
Expand Down

0 comments on commit 1eeda31

Please sign in to comment.