summaryrefslogtreecommitdiff
path: root/src/serialport/qserialport_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialport/qserialport_win.cpp')
-rw-r--r--src/serialport/qserialport_win.cpp205
1 files changed, 118 insertions, 87 deletions
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index 7cbb81d..9ab4448 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -81,6 +81,94 @@
QT_BEGIN_NAMESPACE
+static inline void qt_set_common_props(DCB *dcb)
+{
+ dcb->fBinary = TRUE;
+ dcb->fAbortOnError = FALSE;
+ dcb->fNull = FALSE;
+ dcb->fErrorChar = FALSE;
+
+ if (dcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
+ dcb->fDtrControl = DTR_CONTROL_DISABLE;
+}
+
+static inline void qt_set_baudrate(DCB *dcb, qint32 baudrate)
+{
+ dcb->BaudRate = baudrate;
+}
+
+static inline void qt_set_databits(DCB *dcb, QSerialPort::DataBits databits)
+{
+ dcb->ByteSize = databits;
+}
+
+static inline void qt_set_parity(DCB *dcb, QSerialPort::Parity parity)
+{
+ dcb->fParity = TRUE;
+ switch (parity) {
+ case QSerialPort::NoParity:
+ dcb->Parity = NOPARITY;
+ dcb->fParity = FALSE;
+ break;
+ case QSerialPort::OddParity:
+ dcb->Parity = ODDPARITY;
+ break;
+ case QSerialPort::EvenParity:
+ dcb->Parity = EVENPARITY;
+ break;
+ case QSerialPort::MarkParity:
+ dcb->Parity = MARKPARITY;
+ break;
+ case QSerialPort::SpaceParity:
+ dcb->Parity = SPACEPARITY;
+ break;
+ default:
+ dcb->Parity = NOPARITY;
+ dcb->fParity = FALSE;
+ break;
+ }
+}
+
+static inline void qt_set_stopbits(DCB *dcb, QSerialPort::StopBits stopbits)
+{
+ switch (stopbits) {
+ case QSerialPort::OneStop:
+ dcb->StopBits = ONESTOPBIT;
+ break;
+ case QSerialPort::OneAndHalfStop:
+ dcb->StopBits = ONE5STOPBITS;
+ break;
+ case QSerialPort::TwoStop:
+ dcb->StopBits = TWOSTOPBITS;
+ break;
+ default:
+ dcb->StopBits = ONESTOPBIT;
+ break;
+ }
+}
+
+static inline void qt_set_flowcontrol(DCB *dcb, QSerialPort::FlowControl flowcontrol)
+{
+ dcb->fInX = FALSE;
+ dcb->fOutX = FALSE;
+ dcb->fOutxCtsFlow = FALSE;
+ dcb->fRtsControl = RTS_CONTROL_DISABLE;
+ switch (flowcontrol) {
+ case QSerialPort::NoFlowControl:
+ break;
+ case QSerialPort::SoftwareControl:
+ dcb->fInX = TRUE;
+ dcb->fOutX = TRUE;
+ break;
+ case QSerialPort::HardwareControl:
+ dcb->fOutxCtsFlow = TRUE;
+ dcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
+ break;
+ default:
+ break;
+ }
+}
+
bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{
DWORD desiredAccess = 0;
@@ -122,7 +210,6 @@ void QSerialPortPrivate::close()
readStarted = false;
writeStarted = false;
writeBuffer.clear();
- actualBytesToWrite = 0;
if (settingsRestoredOnClose) {
::SetCommState(handle, &restoredDcb);
@@ -204,10 +291,8 @@ bool QSerialPortPrivate::clear(QSerialPort::Directions directions)
DWORD flags = 0;
if (directions & QSerialPort::Input)
flags |= PURGE_RXABORT | PURGE_RXCLEAR;
- if (directions & QSerialPort::Output) {
+ if (directions & QSerialPort::Output)
flags |= PURGE_TXABORT | PURGE_TXCLEAR;
- actualBytesToWrite = 0;
- }
if (!::PurgeComm(handle, flags)) {
setError(getSystemError());
return false;
@@ -281,7 +366,7 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs)
bool QSerialPortPrivate::waitForBytesWritten(int msecs)
{
- if (writeBuffer.isEmpty())
+ if (writeBuffer.isEmpty() && writeChunkBuffer.isEmpty())
return false;
if (!writeStarted && !_q_startAsyncWrite())
@@ -319,7 +404,8 @@ bool QSerialPortPrivate::setBaudRate(qint32 baudRate, QSerialPort::Directions di
if (!getDcb(&dcb))
return false;
- dcb.BaudRate = baudRate;
+ qt_set_baudrate(&dcb, baudRate);
+
return setDcb(&dcb);
}
@@ -329,7 +415,8 @@ bool QSerialPortPrivate::setDataBits(QSerialPort::DataBits dataBits)
if (!getDcb(&dcb))
return false;
- dcb.ByteSize = dataBits;
+ qt_set_databits(&dcb, dataBits);
+
return setDcb(&dcb);
}
@@ -339,29 +426,8 @@ bool QSerialPortPrivate::setParity(QSerialPort::Parity parity)
if (!getDcb(&dcb))
return false;
- dcb.fParity = TRUE;
- switch (parity) {
- case QSerialPort::NoParity:
- dcb.Parity = NOPARITY;
- dcb.fParity = FALSE;
- break;
- case QSerialPort::OddParity:
- dcb.Parity = ODDPARITY;
- break;
- case QSerialPort::EvenParity:
- dcb.Parity = EVENPARITY;
- break;
- case QSerialPort::MarkParity:
- dcb.Parity = MARKPARITY;
- break;
- case QSerialPort::SpaceParity:
- dcb.Parity = SPACEPARITY;
- break;
- default:
- dcb.Parity = NOPARITY;
- dcb.fParity = FALSE;
- break;
- }
+ qt_set_parity(&dcb, parity);
+
return setDcb(&dcb);
}
@@ -371,20 +437,8 @@ bool QSerialPortPrivate::setStopBits(QSerialPort::StopBits stopBits)
if (!getDcb(&dcb))
return false;
- switch (stopBits) {
- case QSerialPort::OneStop:
- dcb.StopBits = ONESTOPBIT;
- break;
- case QSerialPort::OneAndHalfStop:
- dcb.StopBits = ONE5STOPBITS;
- break;
- case QSerialPort::TwoStop:
- dcb.StopBits = TWOSTOPBITS;
- break;
- default:
- dcb.StopBits = ONESTOPBIT;
- break;
- }
+ qt_set_stopbits(&dcb, stopBits);
+
return setDcb(&dcb);
}
@@ -394,24 +448,8 @@ bool QSerialPortPrivate::setFlowControl(QSerialPort::FlowControl flowControl)
if (!getDcb(&dcb))
return false;
- dcb.fInX = FALSE;
- dcb.fOutX = FALSE;
- dcb.fOutxCtsFlow = FALSE;
- dcb.fRtsControl = RTS_CONTROL_DISABLE;
- switch (flowControl) {
- case QSerialPort::NoFlowControl:
- break;
- case QSerialPort::SoftwareControl:
- dcb.fInX = TRUE;
- dcb.fOutX = TRUE;
- break;
- case QSerialPort::HardwareControl:
- dcb.fOutxCtsFlow = TRUE;
- dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
- break;
- default:
- break;
- }
+ qt_set_flowcontrol(&dcb, flowControl);
+
return setDcb(&dcb);
}
@@ -431,10 +469,8 @@ bool QSerialPortPrivate::completeAsyncRead(qint64 bytesTransferred)
readStarted = false;
return false;
}
- if (bytesTransferred > 0) {
- char *ptr = buffer.reserve(bytesTransferred);
- ::memcpy(ptr, readChunkBuffer.constData(), bytesTransferred);
- }
+ if (bytesTransferred > 0)
+ buffer.append(readChunkBuffer.constData(), bytesTransferred);
readStarted = false;
@@ -459,12 +495,13 @@ bool QSerialPortPrivate::completeAsyncWrite(qint64 bytesTransferred)
if (writeStarted) {
if (bytesTransferred == qint64(-1)) {
+ writeChunkBuffer.clear();
writeStarted = false;
return false;
- } else if (bytesTransferred > 0) {
- writeBuffer.free(bytesTransferred);
- emit q->bytesWritten(bytesTransferred);
}
+ Q_ASSERT(bytesTransferred == writeChunkBuffer.size());
+ writeChunkBuffer.clear();
+ emit q->bytesWritten(bytesTransferred);
writeStarted = false;
}
@@ -531,10 +568,10 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
if (writeBuffer.isEmpty() || writeStarted)
return true;
- const int writeBytes = writeBuffer.nextDataBlockSize();
+ writeChunkBuffer = writeBuffer.read();
::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped));
- if (!::WriteFile(handle, writeBuffer.readPointer(),
- writeBytes, nullptr, &writeCompletionOverlapped)) {
+ if (!::WriteFile(handle, writeChunkBuffer.constData(),
+ writeChunkBuffer.size(), nullptr, &writeCompletionOverlapped)) {
QSerialPortErrorInfo error = getSystemError();
if (error.errorCode != QSerialPort::NoError) {
@@ -545,7 +582,6 @@ bool QSerialPortPrivate::_q_startAsyncWrite()
}
}
- actualBytesToWrite -= writeBytes;
writeStarted = true;
return true;
}
@@ -579,8 +615,7 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
{
Q_Q(QSerialPort);
- ::memcpy(writeBuffer.reserve(maxSize), data, maxSize);
- actualBytesToWrite += maxSize;
+ writeBuffer.append(data, maxSize);
if (!writeBuffer.isEmpty() && !writeStarted) {
if (!startAsyncWriteTimer) {
@@ -588,7 +623,8 @@ qint64 QSerialPortPrivate::writeData(const char *data, qint64 maxSize)
QObjectPrivate::connect(startAsyncWriteTimer, &QTimer::timeout, this, &QSerialPortPrivate::_q_startAsyncWrite);
startAsyncWriteTimer->setSingleShot(true);
}
- startAsyncWriteTimer->start(0);
+ if (!startAsyncWriteTimer->isActive())
+ startAsyncWriteTimer->start();
}
return maxSize;
}
@@ -623,17 +659,12 @@ inline bool QSerialPortPrivate::initialize()
restoredDcb = dcb;
- dcb.fBinary = TRUE;
- dcb.fInX = FALSE;
- dcb.fOutX = FALSE;
- dcb.fAbortOnError = FALSE;
- dcb.fNull = FALSE;
- dcb.fErrorChar = FALSE;
-
- if (dcb.fDtrControl == DTR_CONTROL_HANDSHAKE)
- dcb.fDtrControl = DTR_CONTROL_DISABLE;
-
- dcb.BaudRate = inputBaudRate;
+ qt_set_common_props(&dcb);
+ qt_set_baudrate(&dcb, inputBaudRate);
+ qt_set_databits(&dcb, dataBits);
+ qt_set_parity(&dcb, parity);
+ qt_set_stopbits(&dcb, stopBits);
+ qt_set_flowcontrol(&dcb, flowControl);
if (!setDcb(&dcb))
return false;