From 536358494053f8f808feab8ea2e32cf66dcfdbbe Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Sat, 7 Mar 2026 14:20:31 +0000 Subject: [PATCH] improve to_bytes efficiency with struct.pack --- vban_cmd/packet/headers.py | 58 ++++++++++++++++++++------------------ vban_cmd/packet/ping0.py | 50 ++++++++++++++++---------------- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/vban_cmd/packet/headers.py b/vban_cmd/packet/headers.py index c7107b6..692edfb 100644 --- a/vban_cmd/packet/headers.py +++ b/vban_cmd/packet/headers.py @@ -1,3 +1,4 @@ +import struct from dataclasses import dataclass from vban_cmd.enums import NBS @@ -34,15 +35,16 @@ class VbanPingHeader: """Creates the PING header bytes only.""" header = cls(framecounter=framecounter) - data = bytearray() - data.extend(header.vban) - data.extend(header.format_sr.to_bytes(1, 'little')) - data.extend(header.format_nbs.to_bytes(1, 'little')) - data.extend(header.format_nbc.to_bytes(1, 'little')) - data.extend(header.format_bit.to_bytes(1, 'little')) - data.extend(header.streamname) - data.extend(header.framecounter.to_bytes(4, 'little')) - return bytes(data) + return struct.pack( + '<4s4B16sI', + header.vban, + header.format_sr, + header.format_nbs, + header.format_nbc, + header.format_bit, + header.streamname, + header.framecounter, + ) @dataclass @@ -163,15 +165,16 @@ class VbanRTSubscribeHeader: def to_bytes(cls, nbs: NBS, framecounter: int) -> bytes: header = cls(nbs=nbs) - data = bytearray() - data.extend(header.vban) - data.extend(header.format_sr) - data.extend(header.format_nbs) - data.extend(header.format_nbc) - data.extend(header.format_bit) - data.extend(header.streamname) - data.extend(framecounter.to_bytes(4, 'little')) - return bytes(data) + return struct.pack( + '<4s4B16sI', + header.vban, + header.format_sr[0], + header.format_nbs[0], + header.format_nbc[0], + header.format_bit[0], + header.streamname, + framecounter, + ) @dataclass @@ -215,15 +218,16 @@ class VbanRTRequestHeader: name=name, bps_index=bps_index, channel=channel, framecounter=framecounter ) - data = bytearray() - data.extend(header.vban) - data.extend(header.sr) - data.extend(header.nbs) - data.extend(header.nbc) - data.extend(header.bit) - data.extend(header.streamname) - data.extend(header.framecounter.to_bytes(4, 'little')) - return bytes(data) + return struct.pack( + '<4s4B16sI', + header.vban, + header.sr[0], + header.nbs[0], + header.nbc[0], + header.bit[0], + header.streamname, + header.framecounter, + ) @classmethod def encode_with_payload( diff --git a/vban_cmd/packet/ping0.py b/vban_cmd/packet/ping0.py index 3c3c41b..52b08d3 100644 --- a/vban_cmd/packet/ping0.py +++ b/vban_cmd/packet/ping0.py @@ -1,3 +1,4 @@ +import struct from dataclasses import dataclass from enum import Enum @@ -65,30 +66,31 @@ class VbanPing0Payload: """Convert payload to bytes""" payload = cls() - data = bytearray() - data.extend(payload.bit_type.to_bytes(4, 'little')) - data.extend(payload.bit_feature.to_bytes(4, 'little')) - data.extend(payload.bit_feature_ex.to_bytes(4, 'little')) - data.extend(payload.preferred_rate.to_bytes(4, 'little')) - data.extend(payload.min_rate.to_bytes(4, 'little')) - data.extend(payload.max_rate.to_bytes(4, 'little')) - data.extend(payload.color_rgb.to_bytes(4, 'little')) - data.extend(payload.version) - data.extend(payload.gps_position) - data.extend(payload.user_position) - data.extend(payload.lang_code) - data.extend(payload.reserved) - data.extend(payload.reserved_ex) - data.extend(payload.distant_ip) - data.extend(payload.distant_port.to_bytes(2, 'little')) - data.extend(payload.distant_reserved.to_bytes(2, 'little')) - data.extend(payload.device_name) - data.extend(payload.manufacturer_name) - data.extend(payload.application_name) - data.extend(payload.host_name) - data.extend(payload.user_name) - data.extend(payload.user_comment) - return bytes(data) + return struct.pack( + '<7I4s8s8s8s8s64s32s2H64s64s64s64s128s128s', + payload.bit_type, + payload.bit_feature, + payload.bit_feature_ex, + payload.preferred_rate, + payload.min_rate, + payload.max_rate, + payload.color_rgb, + payload.version, + payload.gps_position, + payload.user_position, + payload.lang_code, + payload.reserved, + payload.reserved_ex, + payload.distant_ip, + payload.distant_port, + payload.distant_reserved, + payload.device_name, + payload.manufacturer_name, + payload.application_name, + payload.host_name, + payload.user_name, + payload.user_comment, + ) @classmethod def create_packet(cls, framecounter: int) -> bytes: