C++ (Qt)bool WinSerialPortEngine::event(QEvent *e){ bool ret = false; if (e->type() == QEvent::WinEventAct) {... if (EV_RXCHAR & m_currentMask & m_setMask) { m_parent->canReadNotification(); ret = true; }...}
C++ (Qt)bool SerialPortPrivate::canReadNotification(){ Q_Q(SerialPort); #if defined (Q_OS_WINCE) m_engine->lockNotification(SerialPortEngine::CanReadLocker, true);#endif // Prevent recursive calls. if (m_readSerialNotifierCalled) { if (!m_readSerialNotifierStateSet) { m_readSerialNotifierStateSet = true; m_readSerialNotifierState = m_engine->isReadNotificationEnabled(); m_engine->setReadNotificationEnabled(false); } } m_readSerialNotifierCalled = true; //if (!m_isBuffered) // this->serialEngine->setReadNotificationEnabled(false); // If buffered, read data from the serial into the read buffer. qint64 newBytes = 0; if (m_isBuffered) { // Return if there is no space in the buffer. if (m_readBufferMaxSize && (m_readBuffer.size() >= m_readBufferMaxSize)) { m_readSerialNotifierCalled = false; return false; } // If reading from the serial fails after getting a read // notification, close the serial. newBytes = m_readBuffer.size(); if (!readFromPort()) { m_readSerialNotifierCalled = false; return false; } newBytes = m_readBuffer.size() - newBytes; // If read buffer is full, disable the read serial notifier. if (m_readBufferMaxSize && (m_readBuffer.size() == m_readBufferMaxSize)) { m_engine->setReadNotificationEnabled(false); } } // Only emit readyRead() when not recursing, and only if there is data available. bool hasData = (m_isBuffered) ? (newBytes > 0) : (bytesAvailable() > 0); if ((!m_emittedReadyRead) && hasData) { m_emittedReadyRead = true; emit q->readyRead(); m_emittedReadyRead = false; } if ((!hasData) && m_engine->isReadNotificationEnabled()) m_engine->setReadNotificationEnabled(true); // Reset the read serial notifier state if we reentered inside the // readyRead() connected slot. if (m_readSerialNotifierStateSet && (m_readSerialNotifierState != m_engine->isReadNotificationEnabled())) { m_engine->setReadNotificationEnabled(m_readSerialNotifierState); m_readSerialNotifierStateSet = false; } m_readSerialNotifierCalled = false; return true;}
C++ (Qt)bool SerialPortPrivate::readFromPort(){ qint64 bytesToRead = (m_policy == SerialPort::IgnorePolicy) ? bytesAvailable() : 1; if (bytesToRead <= 0) return false; if (m_readBufferMaxSize && (bytesToRead > (m_readBufferMaxSize - m_readBuffer.size()))) { bytesToRead = m_readBufferMaxSize - m_readBuffer.size(); } char *ptr = m_readBuffer.reserve(bytesToRead); qint64 readBytes = read(ptr, bytesToRead); if (readBytes <= 0) { m_readBuffer.chop(bytesToRead); return false; } m_readBuffer.chop(int(bytesToRead - ((readBytes < 0) ? qint64(0) : readBytes))); return true;}
C++ (Qt)qint64 WinSerialPortEngine::read(char *data, qint64 len){#if !defined (Q_OS_WINCE) clear_overlapped(&m_ovRead);#endif DWORD readBytes = 0; bool sucessResult = false; // FIXME: if (m_parent->m_policy != SerialPort::IgnorePolicy) len = 1; #if defined (Q_OS_WINCE) sucessResult = ::ReadFile(m_descriptor, data, len, &readBytes, 0);#else if (::ReadFile(m_descriptor, data, len, &readBytes, &m_ovRead)) sucessResult = true; else { if (::GetLastError() == ERROR_IO_PENDING) { // FIXME: Instead of an infinite wait I/O (not looped), we expect, for example 5 seconds. // Although, maybe there is a better solution. switch (::WaitForSingleObject(m_ovRead.hEvent, 5000)) { case WAIT_OBJECT_0: if (::GetOverlappedResult(m_descriptor, &m_ovRead, &readBytes, false)) sucessResult = true; break; default: ; } } }#endif if(!sucessResult) { m_parent->setError(SerialPort::IoError); return -1; } // FIXME: Process emulate policy. if (m_flagErrorFromCommEvent) { m_flagErrorFromCommEvent = false; switch (m_parent->m_policy) { case SerialPort::SkipPolicy: return 0; case SerialPort::PassZeroPolicy: *data = '\0'; break; case SerialPort::StopReceivingPolicy: break; default:; } } return qint64(readBytes);}
C++ (Qt) void connected();void disconnected();void error(QAbstractSocket::SocketError);
C++ (Qt) void opened();void closed();void error(SerialPort::SerialPortError);
C++ (Qt)bool WinSerialPortEngine::processIOErrors(){ DWORD err = 0; COMSTAT cs; bool ret = (::ClearCommError(m_descriptor, &err, &cs) != 0); if (ret && err) { if (err & CE_FRAME) m_parent->setError(SerialPort::FramingError); else if (err & CE_RXPARITY) m_parent->setError(SerialPort::ParityError); else if (err & CE_BREAK) m_parent->setError(SerialPort::BreakConditionError); else m_parent->setError(SerialPort::UnknownPortError); m_flagErrorFromCommEvent = true; } return ret;}
C++ (Qt)qint64 WinSerialPortEngine::read(char *data, qint64 len){...... // FIXME: Process emulate policy. if (m_flagErrorFromCommEvent) { m_flagErrorFromCommEvent = false; switch (m_parent->m_policy) { case SerialPort::SkipPolicy: return 0; case SerialPort::PassZeroPolicy: *data = '\0'; break; case SerialPort::StopReceivingPolicy: break; default:; } } return qint64(readBytes);}