Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions pythonosc/parsing/framing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from pythonosc.parsing.slip import (
END,
END_END,
decode as slip_decode,
encode as slip_encode,
)
Expand Down Expand Up @@ -55,15 +54,16 @@ def decode_stream(
pos = start
messages = []

while (end := buf.find(END_END, pos)) >= 0:
if end > pos:
messages.append(slip_decode(bytes(buf[pos:end])))
scan = start
while (end := buf.find(END, scan)) >= 0:
if end > scan:
messages.append(slip_decode(bytes(buf[scan:end])))
pos = end + len(END)
scan = end + len(END)

pos = end + len(END)

if buf.endswith(END):
messages.append(slip_decode(bytes(buf[pos:end])))
pos = len(buf)
# Consume trailing delimiters, but retain an incomplete packet.
if scan == len(buf):
pos = scan

return messages, pos - start

Expand Down
36 changes: 36 additions & 0 deletions pythonosc/test/parsing/test_framing.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,42 @@ def framing(self) -> Framing:
def test_encode(self, framing: Framing) -> None:
assert framing.encode(b"te\xc0st") == b"\xc0te\xdb\xdcst\xc0"

@mark.parametrize("prefix", [b"", b"\xc0"])
def test_single_end_separates_packets(
self, framing: Framing, prefix: bytes
) -> None:
data = prefix + b"one\xc0two\xc0"
assert framing.decode_stream(data) == ([b"one", b"two"], len(data))

@mark.parametrize("count", [1, 2, 3, 5])
def test_end_markers_do_not_emit_empty_packets(
self, framing: Framing, count: int
) -> None:
data = b"\xc0" * count
assert framing.decode_stream(data) == ([], len(data))

@mark.parametrize("leading_end", [False, True])
def test_every_stream_split_preserves_packets(
self, framing: Framing, leading_end: bool
) -> None:
expected = [b"one", b"two\xc0\xdb", b"three"]
data = b"".join(framing.encode(value)[not leading_end :] for value in expected)
for split in range(len(data) + 1):
parser = FramingParser(framing)
actual = parser.feed(data[:split]) + parser.feed(data[split:])
assert actual == expected, split
assert parser.remaining == b""

def test_bytewise_stream_preserves_packets(self, framing: Framing) -> None:
parser = FramingParser(framing)
expected = [b"one", b"two\xc0\xdb"]
data = b"".join(framing.encode(value) for value in expected)
actual = []
for byte in data:
actual.extend(parser.feed(bytes([byte])))
assert actual == expected
assert parser.remaining == b""


class TestBinaryLengthFraming(CommonFramingTest):
@fixture
Expand Down
Loading