""" WhatsApp Poll decoder for iOS/macOS. Decodes poll messages (ZMESSAGETYPE = 46) stored as protobuf blobs in ZWAMESSAGEINFO.ZRECEIPTINFO. Uses raw varint/wire-type parsing with no external protobuf library dependency. """ import struct import logging def _decode_varint(data, pos): """Decode a protobuf varint starting at pos. Args: data (bytes): The protobuf data. pos (int): Starting position. Returns: tuple: (value, new_pos) Raises: ValueError: If the varint is truncated. """ result = 0 shift = 0 while pos < len(data): b = data[pos] pos += 1 result |= (b & 0x7F) << shift if not (b & 0x80): return result, pos shift += 7 raise ValueError("Truncated varint") def decode_protobuf_fields(data): """ Decode raw protobuf bytes into list of (field_number, wire_type_name, value). Handles: varint (0), fixed64 (1), length-delimited/bytes (2), fixed32 (5). Args: data (bytes): Raw protobuf data. Returns: list: List of (field_number, wire_type_name, value) tuples. """ fields = [] pos = 0 while pos < len(data): try: tag, pos = _decode_varint(data, pos) field_num = tag >> 3 wire_type = tag & 0x7 if wire_type == 0: # varint val, pos = _decode_varint(data, pos) fields.append((field_num, 'varint', val)) elif wire_type == 2: # length-delimited length, pos = _decode_varint(data, pos) val = data[pos:pos + length] pos += length fields.append((field_num, 'bytes', val)) elif wire_type == 5: # fixed32 val = struct.unpack('