plestylib.traffic.utils
=======================

.. py:module:: plestylib.traffic.utils

.. autoapi-nested-parse::

   Socket read helpers for mixed protocol payloads.

   This module provides robust read utilities that support:
   - SCPI definite-length binary blocks (``#<n><len><payload>``)
   - JSON-style messages starting with ``{``
   - Line-style messages terminated by a caller-provided delimiter



Functions
---------

.. autoapisummary::

   plestylib.traffic.utils._recv_exact
   plestylib.traffic.utils.sock_smart_read


Module Contents
---------------

.. py:function:: _recv_exact(sock: socket.socket, n: int) -> bytes

   Receive exactly n bytes or raise error.


.. py:function:: sock_smart_read(sock: socket.socket, terminator: bytes, max_size: int = 10000000) -> bytes

   Read one message from a socket using protocol-aware framing.

   The function inspects the first byte and chooses a read strategy:
   - ``b'#'``: parse SCPI definite-length binary block and return payload only
   - ``b'{'``: read a JSON-like message until trailing ``b'}'``
   - otherwise: read line-style data until ``terminator`` is observed

   :param sock: Connected socket object.
   :param terminator: Byte delimiter used for line-style messages.
   :param max_size: Maximum allowed message/payload size in bytes.

   :returns: Bytes read from the socket according to detected framing.

   :raises ValueError: If framing is malformed or payload exceeds ``max_size``.
   :raises TimeoutError: If the socket times out while reading.
   :raises RuntimeError: If a non-blocking socket has no data.
   :raises ConnectionError: If the connection closes unexpectedly or OS socket
       errors occur.


