def __init__(self): self._read_buffer = ReadBuffer(self.MAX_BUFFER_SIZE) self._write_buffer = [] self._connected = False self._closed = False
class BaseStream(object): error_class = StreamError MAX_BUFFER_SIZE = 100*1024*1024 READ_CHUNK_SIZE = 4*1024 def __init__(self): self._read_buffer = ReadBuffer(self.MAX_BUFFER_SIZE) self._write_buffer = [] self._connected = False self._closed = False def read_bytes(self, nbytes): assert isinstance(nbytes, six.integer_types) assert nbytes > 0 return self._do_read(nbytes=nbytes) def read_until(self, delimiter): return self._do_read(delimiter=delimiter) def read_until_regex(self, regex): return self._do_read(regex=re.compile(regex)) def write(self, data): self._check_closed() if not self._connected: self._write_buffer.append(data) else: self._write(data) def close(self): if self._closed: return self._read_buffer.clear() self._write_buffer = [] self._close() self._closed = True @property def closed(self): return self._closed def _set_connected(self): self._connected = True buf, self._write_buffer = self._write_buffer, [] if buf: self._write(b''.join(buf)) # internal def _do_read(self, delimiter=None, nbytes=None, regex=None): # See if we've already got the data from a previous read data = self._read_from_buffer(delimiter, nbytes, regex) if data is not None: return data self._check_closed() while not self.closed: self._read(self.READ_CHUNK_SIZE) data = self._read_from_buffer(delimiter, nbytes, regex) if data is not None: return data return b'' def _read_from_buffer(self, delimiter=None, nbytes=None, regex=None): if nbytes is not None: return self._read_buffer.read(nbytes) elif delimiter is not None: return self._read_buffer.read_until(delimiter) elif regex is not None: return self._read_buffer.read_until_regex(regex) def _check_closed(self): if self._closed: raise self.error_class('stream is closed') # internal, to be implemented by subclasses def _read(self, n): raise NotImplementedError def _write(self, data): raise NotImplementedError def _close(self): raise NotImplementedError
class BaseStream(object): error_class = StreamError MAX_BUFFER_SIZE = 100 * 1024 * 1024 READ_CHUNK_SIZE = 4 * 1024 def __init__(self): self._read_buffer = ReadBuffer(self.MAX_BUFFER_SIZE) self._write_buffer = [] self._connected = False self._closed = False def read_bytes(self, nbytes): assert isinstance(nbytes, six.integer_types) assert nbytes > 0 return self._do_read(nbytes=nbytes) def read_until(self, delimiter): return self._do_read(delimiter=delimiter) def read_until_regex(self, regex): return self._do_read(regex=re.compile(regex)) def write(self, data): self._check_closed() if not self._connected: self._write_buffer.append(data) else: self._write(data) def close(self): if self._closed: return # Read buffer is not closed because it may still contain buffered data self._write_buffer = [] self._close() self._closed = True @property def readable(self): raise NotImplementedError @property def writable(self): raise NotImplementedError @property def closed(self): return self._closed def _set_connected(self): self._connected = True buf, self._write_buffer = self._write_buffer, [] if buf: self._write(b''.join(buf)) # internal def _do_read(self, delimiter=None, nbytes=None, regex=None): # See if we've already got the data from a previous read data = self._read_from_buffer(delimiter, nbytes, regex) if data is not None: return data self._check_closed() while not self.closed: self._read(self.READ_CHUNK_SIZE) data = self._read_from_buffer(delimiter, nbytes, regex) if data is not None: return data return b'' def _read_from_buffer(self, delimiter=None, nbytes=None, regex=None): if nbytes is not None: return self._read_buffer.read(nbytes) elif delimiter is not None: return self._read_buffer.read_until(delimiter) elif regex is not None: return self._read_buffer.read_until_regex(regex) def _check_closed(self): if self._closed: raise self.error_class('stream is closed') # internal, to be implemented by subclasses def _read(self, n): raise NotImplementedError def _write(self, data): raise NotImplementedError def _close(self): raise NotImplementedError