def read(self, max_length):
if not isinstance(max_length, int_types):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(max_length)<EOL>))<EOL><DEDENT>buffered_length = len(self._decrypted_bytes)<EOL>if buffered_length >= max_length:<EOL><INDENT>output = self._decrypted_bytes[<NUM_LIT:0>:max_length]<EOL>self._decrypted_bytes = self._decrypted_bytes[max_length:]<EOL>return output<EOL><DEDENT>if self._ssl is None:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>if buffered_length > <NUM_LIT:0> and not self.select_read(<NUM_LIT:0>):<EOL><INDENT>output = self._decrypted_bytes<EOL>self._decrypted_bytes = b'<STR_LIT>'<EOL>return output<EOL><DEDENT>to_read = min(self._buffer_size, max_length - buffered_length)<EOL>output = self._decrypted_bytes<EOL>again = True<EOL>while again:<EOL><INDENT>again = False<EOL>result = libssl.SSL_read(self._ssl, self._read_buffer, to_read)<EOL>self._raw_write()<EOL>if result <= <NUM_LIT:0>:<EOL><INDENT>error = libssl.SSL_get_error(self._ssl, result)<EOL>if error == LibsslConst.SSL_ERROR_WANT_READ:<EOL><INDENT>if self._raw_read() != b'<STR_LIT>':<EOL><INDENT>again = True<EOL>continue<EOL><DEDENT>raise_disconnection()<EOL><DEDENT>elif error == LibsslConst.SSL_ERROR_WANT_WRITE:<EOL><INDENT>self._raw_write()<EOL>again = True<EOL>continue<EOL><DEDENT>elif error == LibsslConst.SSL_ERROR_ZERO_RETURN:<EOL><INDENT>self._gracefully_closed = True<EOL>self._shutdown(False)<EOL>break<EOL><DEDENT>else:<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>, TLSError)<EOL><DEDENT><DEDENT>output += bytes_from_buffer(self._read_buffer, result)<EOL><DEDENT>if self._gracefully_closed and len(output) == <NUM_LIT:0>:<EOL><INDENT>self._raise_closed()<EOL><DEDENT>self._decrypted_bytes = output[max_length:]<EOL>return output[<NUM_LIT:0>:max_length]<EOL>
Reads data from the TLS-wrapped socket

:param max_length:
    The number of bytes to read - output may be less than this

:raises:
    socket.socket - when a non-TLS socket error occurs
    oscrypto.errors.TLSError - when a TLS-related error occurs
    ValueError - when any of the parameters contain an invalid value
    TypeError - when any of the parameters are of the wrong type
    OSError - when an error is returned by the OS crypto library

:return:
    A byte string of the data read