diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-01-17 17:25:58 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-01-17 17:25:58 +0100 |
commit | 05b3e3cf8678287a7d43a13e4ababe9a067f2dcf (patch) | |
tree | 50ca008ff71704f2530ab4556524023c53d34b56 | |
parent | 8e92374dc2cd48248be107ae48528a3c4330718e (diff) | |
parent | 2a83fbd6c70032d236bbdf0d87aaf51908cd5afd (diff) | |
download | qtserialport-05b3e3cf8678287a7d43a13e4ababe9a067f2dcf.tar.gz |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
.qmake.conf
Change-Id: Id8be0cbb66eabf59c47011e4605e71cf29c1f532
-rw-r--r-- | src/serialport/qserialport.cpp | 6 | ||||
-rw-r--r-- | src/serialport/qserialport.h | 6 | ||||
-rw-r--r-- | src/serialport/qserialport_symbian.cpp | 3 | ||||
-rw-r--r-- | src/serialport/qserialport_symbian_p.h | 2 | ||||
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 14 | ||||
-rw-r--r-- | src/serialport/qserialport_unix_p.h | 2 | ||||
-rw-r--r-- | src/serialport/qserialport_win.cpp | 181 | ||||
-rw-r--r-- | src/serialport/qserialport_win_p.h | 14 | ||||
-rw-r--r-- | src/serialport/qserialport_wince.cpp | 10 |
9 files changed, 107 insertions, 131 deletions
diff --git a/src/serialport/qserialport.cpp b/src/serialport/qserialport.cpp index 5d9442e..cd0c681 100644 --- a/src/serialport/qserialport.cpp +++ b/src/serialport/qserialport.cpp @@ -1375,7 +1375,11 @@ qint64 QSerialPort::readLineData(char *data, qint64 maxSize) qint64 QSerialPort::writeData(const char *data, qint64 maxSize) { Q_D(QSerialPort); - return d->writeToBuffer(data, maxSize); + + ::memcpy(d->writeBuffer.reserve(maxSize), data, maxSize); + if (!d->writeBuffer.isEmpty()) + d->startWriting(); + return maxSize; } void QSerialPort::setError(QSerialPort::SerialPortError serialPortError, const QString &errorString) diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h index c07af91..1689222 100644 --- a/src/serialport/qserialport.h +++ b/src/serialport/qserialport.h @@ -276,9 +276,9 @@ private: Q_DISABLE_COPY(QSerialPort) #if defined (Q_OS_WIN32) || defined(Q_OS_WIN64) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteCommunication()) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteRead()) - Q_PRIVATE_SLOT(d_func(), void _q_canCompleteWrite()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncCommunication()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncRead()) + Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncWrite()) #endif }; diff --git a/src/serialport/qserialport_symbian.cpp b/src/serialport/qserialport_symbian.cpp index 6047793..9318696 100644 --- a/src/serialport/qserialport_symbian.cpp +++ b/src/serialport/qserialport_symbian.cpp @@ -248,10 +248,9 @@ qint64 QSerialPortPrivate::systemOutputQueueSize () const return 0; } -qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +void QSerialPortPrivate::startWriting() { // TODO: Implement me - return -1; } bool QSerialPortPrivate::waitForReadyRead(int msec) diff --git a/src/serialport/qserialport_symbian_p.h b/src/serialport/qserialport_symbian_p.h index 253aa11..7c3d3ef 100644 --- a/src/serialport/qserialport_symbian_p.h +++ b/src/serialport/qserialport_symbian_p.h @@ -72,7 +72,7 @@ public: qint64 systemInputQueueSize () const; qint64 systemOutputQueueSize () const; - qint64 writeToBuffer(const char *data, qint64 maxSize); + void startWriting(); bool waitForReadyRead(int msec); bool waitForBytesWritten(int msec); diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 9571767..b994a0e 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -414,20 +414,10 @@ qint64 QSerialPortPrivate::systemOutputQueueSize () const return nbytes; } -qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +void QSerialPortPrivate::startWriting() { - char *ptr = writeBuffer.reserve(maxSize); - if (maxSize == 1) - *ptr = *data; - else - ::memcpy(ptr, data, maxSize); - - const qint64 written = maxSize; - - if (!writeBuffer.isEmpty() && !isWriteNotificationEnabled()) + if (!isWriteNotificationEnabled()) setWriteNotificationEnabled(true); - - return written; } bool QSerialPortPrivate::waitForReadyRead(int msecs) diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h index dba0ac5..7dbb760 100644 --- a/src/serialport/qserialport_unix_p.h +++ b/src/serialport/qserialport_unix_p.h @@ -111,7 +111,7 @@ public: qint64 systemInputQueueSize () const; qint64 systemOutputQueueSize () const; - qint64 writeToBuffer(const char *data, qint64 maxSize); + void startWriting(); bool waitForReadyRead(int msecs); bool waitForBytesWritten(int msecs); diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp index e460c78..f9e8a5e 100644 --- a/src/serialport/qserialport_win.cpp +++ b/src/serialport/qserialport_win.cpp @@ -115,7 +115,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { communicationNotifier->setHandle(communicationOverlapped.hEvent); - q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteCommunication())); + q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncCommunication())); } ::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped)); @@ -124,7 +124,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent); - q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteRead())); + q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncRead())); } ::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped)); @@ -133,7 +133,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) q->setError(decodeSystemError()); else { writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent); - q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteWrite())); + q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncWrite())); } } @@ -197,14 +197,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) return false; } - initializeOverlappedStructure(communicationOverlapped); - if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { - const QSerialPort::SerialPortError error = decodeSystemError(); - if (error != QSerialPort::NoError) { - q->setError(decodeSystemError()); - return false; - } - } + if (!startAsyncCommunication()) + return false; communicationNotifier->setEnabled(true); @@ -360,18 +354,10 @@ qint64 QSerialPortPrivate::systemOutputQueueSize () #ifndef Q_OS_WINCE -qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +void QSerialPortPrivate::startWriting() { - char *ptr = writeBuffer.reserve(maxSize); - if (maxSize == 1) - *ptr = *data; - else - ::memcpy(ptr, data, maxSize); - if (!writeSequenceStarted) startAsyncWrite(); - - return maxSize; } bool QSerialPortPrivate::waitForReadyRead(int msecs) @@ -393,14 +379,14 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) } if (triggeredEvent == communicationOverlapped.hEvent) { - _q_canCompleteCommunication(); + _q_completeAsyncCommunication(); if (error != QSerialPort::NoError) return false; } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); return error == QSerialPort::NoError; } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_canCompleteWrite(); + _q_completeAsyncWrite(); } else { return false; } @@ -431,11 +417,11 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) } if (triggeredEvent == communicationOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); } else if (triggeredEvent == readCompletionOverlapped.hEvent) { - _q_canCompleteRead(); + _q_completeAsyncRead(); } else if (triggeredEvent == writeCompletionOverlapped.hEvent) { - _q_canCompleteWrite(); + _q_completeAsyncWrite(); return error == QSerialPort::NoError; } else { return false; @@ -544,7 +530,7 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy) #ifndef Q_OS_WINCE -void QSerialPortPrivate::_q_canCompleteCommunication() +void QSerialPortPrivate::_q_completeAsyncCommunication() { Q_Q(QSerialPort); @@ -576,7 +562,7 @@ void QSerialPortPrivate::_q_canCompleteCommunication() startAsyncRead(); } -void QSerialPortPrivate::_q_canCompleteRead() +void QSerialPortPrivate::_q_completeAsyncRead() { Q_Q(QSerialPort); @@ -584,23 +570,22 @@ void QSerialPortPrivate::_q_canCompleteRead() if (!::GetOverlappedResult(descriptor, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE)) q->setError(decodeSystemError()); - completeAsyncRead(numberOfBytesTransferred); + if (numberOfBytesTransferred > 0) { + + readBuffer.append(readChunkBuffer.left(numberOfBytesTransferred)); + + if (!emulateErrorPolicy()) + emitReadyRead(); + } // start async read for possible remainder into driver queue - if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) { + if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) startAsyncRead(); - } else { // driver queue is emplty, so startup wait comm event - initializeOverlappedStructure(communicationOverlapped); - if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { - const QSerialPort::SerialPortError error = decodeSystemError(); - if (error != QSerialPort::NoError) { - q->setError(decodeSystemError()); - } - } - } + else // driver queue is emplty, so startup wait comm event + startAsyncCommunication(); } -void QSerialPortPrivate::_q_canCompleteWrite() +void QSerialPortPrivate::_q_completeAsyncWrite() { Q_Q(QSerialPort); @@ -610,7 +595,30 @@ void QSerialPortPrivate::_q_canCompleteWrite() q->setError(decodeSystemError()); } - completeAsyncWrite(numberOfBytesTransferred); + writeBuffer.free(numberOfBytesTransferred); + + if (numberOfBytesTransferred > 0) + emit q->bytesWritten(numberOfBytesTransferred); + + if (writeBuffer.isEmpty()) + writeSequenceStarted = false; + else + startAsyncWrite(); +} + +bool QSerialPortPrivate::startAsyncCommunication() +{ + Q_Q(QSerialPort); + + initializeOverlappedStructure(communicationOverlapped); + if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) { + const QSerialPort::SerialPortError error = decodeSystemError(); + if (error != QSerialPort::NoError) { + q->setError(decodeSystemError()); + return false; + } + } + return true; } bool QSerialPortPrivate::startAsyncRead() @@ -675,6 +683,42 @@ bool QSerialPortPrivate::startAsyncWrite() return true; } +bool QSerialPortPrivate::emulateErrorPolicy() +{ + if (!parityErrorOccurred) + return false; + + parityErrorOccurred = false; + + switch (policy) { + case QSerialPort::SkipPolicy: + readBuffer.getChar(); + break; + case QSerialPort::PassZeroPolicy: + readBuffer.getChar(); + readBuffer.putChar('\0'); + emitReadyRead(); + break; + case QSerialPort::IgnorePolicy: + return false; + case QSerialPort::StopReceivingPolicy: + emitReadyRead(); + break; + default: + return false; + } + + return true; +} + +void QSerialPortPrivate::emitReadyRead() +{ + Q_Q(QSerialPort); + + readyReadEmitted = true; + emit q->readyRead(); +} + #endif // #ifndef Q_OS_WINCE void QSerialPortPrivate::processIoErrors(bool error) @@ -706,61 +750,6 @@ void QSerialPortPrivate::processIoErrors(bool error) #ifndef Q_OS_WINCE -void QSerialPortPrivate::completeAsyncRead(DWORD numberOfBytes) -{ - Q_Q(QSerialPort); - - if (numberOfBytes > 0) { - - readBuffer.append(readChunkBuffer.left(numberOfBytes)); - - // Process emulate policy. - if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) { - - parityErrorOccurred = false; - - // Ignore received character, remove it from buffer - if (policy == QSerialPort::SkipPolicy) { - readBuffer.getChar(); - // Force returning without emitting a readyRead() signal - return; - } - - // Abort receiving - if (policy == QSerialPort::StopReceivingPolicy) { - readyReadEmitted = true; - emit q->readyRead(); - return; - } - - // Replace received character by zero - if (policy == QSerialPort::PassZeroPolicy) { - readBuffer.getChar(); - readBuffer.putChar('\0'); - } - - } - - readyReadEmitted = true; - emit q->readyRead(); - } -} - -void QSerialPortPrivate::completeAsyncWrite(DWORD numberOfBytes) -{ - Q_Q(QSerialPort); - - writeBuffer.free(numberOfBytes); - - if (numberOfBytes > 0) - emit q->bytesWritten(numberOfBytes); - - if (writeBuffer.isEmpty()) - writeSequenceStarted = false; - else - startAsyncWrite(); -} - bool QSerialPortPrivate::updateDcb() { Q_Q(QSerialPort); diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h index 61e6ce8..3ccdb56 100644 --- a/src/serialport/qserialport_win_p.h +++ b/src/serialport/qserialport_win_p.h @@ -81,7 +81,7 @@ public: qint64 systemInputQueueSize (); qint64 systemOutputQueueSize (); - qint64 writeToBuffer(const char *data, qint64 maxSize); + void startWriting(); bool waitForReadyRead(int msec); bool waitForBytesWritten(int msec); @@ -96,14 +96,16 @@ public: void processIoErrors(bool error); QSerialPort::SerialPortError decodeSystemError() const; #ifndef Q_OS_WINCE - void _q_canCompleteCommunication(); - void _q_canCompleteRead(); - void _q_canCompleteWrite(); + void _q_completeAsyncCommunication(); + void _q_completeAsyncRead(); + void _q_completeAsyncWrite(); + bool startAsyncCommunication(); bool startAsyncRead(); bool startAsyncWrite(); - void completeAsyncRead(DWORD numberOfBytes); - void completeAsyncWrite(DWORD numberOfBytes); + + bool emulateErrorPolicy(); + void emitReadyRead(); #else bool notifyRead(); bool notifyWrite(); diff --git a/src/serialport/qserialport_wince.cpp b/src/serialport/qserialport_wince.cpp index 26ebf64..bb76465 100644 --- a/src/serialport/qserialport_wince.cpp +++ b/src/serialport/qserialport_wince.cpp @@ -253,18 +253,10 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions) return ::PurgeComm(descriptor, flags); } -qint64 QSerialPortPrivate::writeToBuffer(const char *data, qint64 maxSize) +void QSerialPortPrivate::startWriting() { - char *ptr = writeBuffer.reserve(maxSize); - if (maxSize == 1) - *ptr = *data; - else - ::memcpy(ptr, data, maxSize); - // trigger write sequence notifyWrite(); - - return maxSize; } bool QSerialPortPrivate::waitForReadyRead(int msec) |