'Read size bytes from the serial port. If a timeout is set it may
return less characters as requested. With no timeout it will block
until the requested number of bytes is read.'

def read(self, size=1):

    if (not self.is_open):
        raise portNotOpenError
    if (size > 0):
        win32.ResetEvent(self._overlapped_read.hEvent)
        flags = win32.DWORD()
        comstat = win32.COMSTAT()
        if (not win32.ClearCommError(self._port_handle, ctypes.byref(flags), ctypes.byref(comstat))):
            raise SerialException('ClearCommError    failed    ({!r})'.format(ctypes.WinError()))
        n = (min(comstat.cbInQue, size) if (self.timeout == 0) else size)
        if (n > 0):
            buf = ctypes.create_string_buffer(n)
            rc = win32.DWORD()
            read_ok = win32.ReadFile(self._port_handle, buf, n, ctypes.byref(rc), ctypes.byref(self._overlapped_read))
            if ((not read_ok) and (win32.GetLastError() not in (win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING))):
                raise SerialException('ReadFile    failed    ({!r})'.format(ctypes.WinError()))
            result_ok = win32.GetOverlappedResult(self._port_handle, ctypes.byref(self._overlapped_read), ctypes.byref(rc), True)
            if (not result_ok):
                if (win32.GetLastError() != win32.ERROR_OPERATION_ABORTED):
                    raise SerialException('GetOverlappedResult    failed    ({!r})'.format(ctypes.WinError()))
            read = buf.raw[:rc.value]
        else:
            read = bytes()
    else:
        read = bytes()
    return bytes(read)
