def _read_frame(self): if self._frame_size == -1: if self.length < SIZE_OF_FRAME_LENGTH_AND_FLAGS: # we don't have even the frame length and flags ready return False self._read_frame_size_and_flags() if self.length < self._frame_size: return False self._buf.seek(self._bytes_read) size = self._frame_size data = self._buf.read(size) self._bytes_read += size self._frame_size = -1 # No need to reset flags since it will be overwritten on the next read_frame_size_and_flags call frame = Frame(data, self._frame_flags) if not self._message: self._message = InboundMessage(frame) else: self._message.add_frame(frame) return True
class _Reader(object): def __init__(self, builder): self._buf = io.BytesIO() self._builder = builder self._bytes_read = 0 self._bytes_written = 0 self._frame_size = 0 self._frame_flags = 0 self._message = None def read(self, data): self._buf.seek(self._bytes_written) self._buf.write(data) self._bytes_written += len(data) def process(self): message = self._read_message() while message: self._builder.on_message(message) message = self._read_message() def _read_message(self): while True: if self._read_frame(): if self._message.end_frame.is_final_frame(): msg = self._message self._reset() return msg else: return None def _read_frame(self): n = self.length if n < SIZE_OF_FRAME_LENGTH_AND_FLAGS: # we don't have even the frame length and flags ready return False if self._frame_size == 0: self._read_frame_size_and_flags() if n < self._frame_size: return False self._buf.seek(self._bytes_read) size = self._frame_size - SIZE_OF_FRAME_LENGTH_AND_FLAGS data = self._buf.read(size) self._bytes_read += size self._frame_size = 0 # No need to reset flags since it will be overwritten on the next read_frame_size_and_flags call frame = Frame(data, self._frame_flags) if not self._message: self._message = InboundMessage(frame) else: self._message.add_frame(frame) return True def _read_frame_size_and_flags(self): self._buf.seek(self._bytes_read) header_data = self._buf.read(SIZE_OF_FRAME_LENGTH_AND_FLAGS) self._frame_size, self._frame_flags = _frame_header.unpack_from( header_data, 0) self._bytes_read += SIZE_OF_FRAME_LENGTH_AND_FLAGS def _reset(self): if self._bytes_written == self._bytes_read: self._buf.seek(0) self._buf.truncate() self._bytes_written = 0 self._bytes_read = 0 self._message = None @property def length(self): return self._bytes_written - self._bytes_read