def read_exact(self, bytes, extended=None): """read_exact(self, bytes, extended=None) -> data Read exactly <bytes> number of bytes off the channel. May return less than <bytes> bytes if EOF is reached. <bytes>: Number of bytes to read. Blocks until enough data is available. <extended>: data_type_code of extended data type to read. Set to None to read normal data. """ if extended is not None: if extended not in self.extended_recv_buffer: self.extended_recv_buffer[extended] = Buffer() b = self.extended_recv_buffer[extended] else: b = self.recv_buffer result = [] bytes_left = bytes while bytes_left > 0: data = b.read_at_most(bytes_left) if not data: if result: return ''.join(result) else: raise EOFError result.append(data) bytes_left -= len(data) # Only adjust the window when the buffer is clear. if not b: self._check_window_adjust() return ''.join(result)
def __init__(self, connection_service): self.connection_service = connection_service # Local reference for convenience. self.transport = connection_service.transport self.recv_buffer = Buffer() self.extended_recv_buffer = {} self.remote_channel = Remote_Channel() self.window_data_added_cv = coro.condition_variable() self.channel_request_cv = coro.condition_variable() self.channel_open_cv = coro.condition_variable()
def append_extended_data_received(self, data_type_code, data): """append_extended_data_received(self, data_type_code, data) -> None Indicates that the given extended data was received. """ if data: if self.treat_extended_data_as_regular: self.append_data_received(data) else: if data_type_code in self.extended_recv_buffer: self.extended_recv_buffer[data_type_code].write(data) else: b = Buffer() b.write(data) self.extended_recv_buffer[data_type_code] = b
def read(self, bytes, extended=None): """read(self, bytes, extended=None) -> data Read data off the channel. Reads at most <bytes> bytes. It may return less than <bytes> even if there is more data in the buffer. <bytes>: Number of bytes to read. <extended>: data_type_code of extended data type to read. Set to None to read normal data. """ if extended is not None: if extended not in self.extended_recv_buffer: self.extended_recv_buffer[extended] = Buffer() b = self.extended_recv_buffer[extended] else: b = self.recv_buffer result = b.read_at_most(bytes) # Only adjust the window when the buffer is clear. if not b: self._check_window_adjust() return result