From 1eeda314beadd89b5308a7d8068cf1adec6575b6 Mon Sep 17 00:00:00 2001 From: mohanson Date: Wed, 16 Oct 2024 19:35:10 +0800 Subject: [PATCH] Update leb128 --- pywasm/leb128.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pywasm/leb128.py b/pywasm/leb128.py index 91d4fd63..5938bc34 100644 --- a/pywasm/leb128.py +++ b/pywasm/leb128.py @@ -1,9 +1,11 @@ -# 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 @@ -11,6 +13,7 @@ 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: @@ -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 @@ -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 @@ -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)) @@ -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