From 6240dd36e524ff2ec8ed6401baa9fa366c7392f7 Mon Sep 17 00:00:00 2001 From: ChillerDragon Date: Sun, 19 Mar 2023 11:40:15 +0100 Subject: [PATCH] Polish and test int packer --- tests/int_packer_test.py | 45 ++++++++++++++++++++++++++++++++++++++++ twnet_parser/packer.py | 27 +----------------------- 2 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 tests/int_packer_test.py diff --git a/tests/int_packer_test.py b/tests/int_packer_test.py new file mode 100644 index 0000000..5704b26 --- /dev/null +++ b/tests/int_packer_test.py @@ -0,0 +1,45 @@ +from twnet_parser.packer import * + +def test_pack_small_positive_ints(): + assert pack_int(1) == b'\x01' + assert pack_int(2) == b'\x02' + assert pack_int(3) == b'\x03' + + assert pack_int(44) == b'\x2C' + assert pack_int(45) == b'\x2D' + assert pack_int(46) == b'\x2E' + +def test_pack_multi_byte_positive_ints(): + assert pack_int(63) == b'\x3F' + assert pack_int(64) == b'\x80\x01' + assert pack_int(65) == b'\x81\x01' + +def test_pack_small_negative_ints(): + assert pack_int(-1) == b'\x40' + assert pack_int(-2) == b'\x41' + assert pack_int(-3) == b'\x42' + + assert pack_int(-44) == b'\x6B' + assert pack_int(-45) == b'\x6C' + assert pack_int(-46) == b'\x6D' + +def test_pack_multi_byte_negative_ints(): + assert pack_int(-63) == b'\x7E' + assert pack_int(-64) == b'\x7F' + assert pack_int(-65) == b'\xC0\x01' + +def test_pack_multi_byte_positive_and_negative(): + assert pack_int(-66663) == b'\xe6\x91\x08' + assert pack_int(66663) == b'\xa7\x91\x08' + + assert pack_int(-8866663) == b'\xe6\xad\xba\x08' + assert pack_int(8866663) == b'\xa7\xad\xba\x08' + +# TODO: should we just pack numbers bigger than 4 bytes? +# since the official tw client and server are written in C++ +# they do not support such big numbers +# we could also throw an error here instead +def test_pack_too_big_positive_and_negative(): + assert pack_int(-98866996963) == b'\xe2\x9b\xf5\xce\xe0\x05' + assert pack_int(98866996963) == b'\xa3\x9b\xf5\xce\xe0\x05' + diff --git a/twnet_parser/packer.py b/twnet_parser/packer.py index 45a30a8..91c2dea 100644 --- a/twnet_parser/packer.py +++ b/twnet_parser/packer.py @@ -1,45 +1,20 @@ #!/usr/bin/env python -from textwrap import wrap - -def dbg(raw: bytearray) -> None: - bits_str = '' - annotation_str = '' - for byte in raw: - bits_str += ' '.join(wrap(f"{byte:08b} ", 2)) - annotation_str += 'ES DD DD DD ' - print(f" {bits_str} {bytes(raw)!r}") - print(f" {annotation_str}") - +# TODO: optimize performance and benchmark in tests def pack_int(num: int) -> bytes: - print(f"packing {num}") res: bytearray = bytearray(b'\x00') if num < 0: res[0] |= 0x40 # set sign bit - print(f"num={num}") num = ~num - # print(f"num num={num}") - - # print("--- signed:") - # dbg(res) res[0] |= num & 0x3F # pack 6bit into res num >>= 6 # discard 6 bits - print("--- pack 6 bit:") - dbg(res) - i = 0 while num != 0: res[i] |= 0x80 # set extend bit i += 1 res.extend(bytes([num & 0x7F])) # pack 7 bit num >>= 7 # discard 7 bits - print(num) - return bytes(res) -print(pack_int(63)) -print(pack_int(64)) -print(pack_int(65)) -