Spaces:
Running
Running
File size: 3,366 Bytes
e11e4fe |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
from typing import List
import struct
class IncomingMessage:
"""
Utility class for reading the message written to a SideChannel.
Values must be read in the order they were written.
"""
def __init__(self, buffer: bytes, offset: int = 0):
"""
Create a new IncomingMessage from the bytes.
"""
self.buffer = buffer
self.offset = offset
def read_bool(self, default_value: bool = False) -> bool:
"""
Read a boolean value from the message buffer.
:param default_value: Default value to use if the end of the message is reached.
:return: The value read from the message, or the default value if the end was reached.
"""
if self._at_end_of_buffer():
return default_value
val = struct.unpack_from("<?", self.buffer, self.offset)[0]
self.offset += 1
return val
def read_int32(self, default_value: int = 0) -> int:
"""
Read an integer value from the message buffer.
:param default_value: Default value to use if the end of the message is reached.
:return: The value read from the message, or the default value if the end was reached.
"""
if self._at_end_of_buffer():
return default_value
val = struct.unpack_from("<i", self.buffer, self.offset)[0]
self.offset += 4
return val
def read_float32(self, default_value: float = 0.0) -> float:
"""
Read a float value from the message buffer.
:param default_value: Default value to use if the end of the message is reached.
:return: The value read from the message, or the default value if the end was reached.
"""
if self._at_end_of_buffer():
return default_value
val = struct.unpack_from("<f", self.buffer, self.offset)[0]
self.offset += 4
return val
def read_float32_list(self, default_value: List[float] = None) -> List[float]:
"""
Read a list of float values from the message buffer.
:param default_value: Default value to use if the end of the message is reached.
:return: The value read from the message, or the default value if the end was reached.
"""
if self._at_end_of_buffer():
return [] if default_value is None else default_value
list_len = self.read_int32()
output = []
for _ in range(list_len):
output.append(self.read_float32())
return output
def read_string(self, default_value: str = "") -> str:
"""
Read a string value from the message buffer.
:param default_value: Default value to use if the end of the message is reached.
:return: The value read from the message, or the default value if the end was reached.
"""
if self._at_end_of_buffer():
return default_value
encoded_str_len = self.read_int32()
val = self.buffer[self.offset : self.offset + encoded_str_len].decode("ascii")
self.offset += encoded_str_len
return val
def get_raw_bytes(self) -> bytes:
"""
Get a copy of the internal bytes used by the message.
"""
return bytearray(self.buffer)
def _at_end_of_buffer(self) -> bool:
return self.offset >= len(self.buffer)
|