summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shachnev <mitya57@gmail.com>2022-05-15 23:58:48 +0300
committerDmitry Shachnev <mitya57@gmail.com>2022-06-27 14:46:23 +0300
commite7ce9ac18b5a1ef33e2343d85a01bb7947d1668d (patch)
tree64b207d05d39a4e7b488cb10f967ea83f03322d2
parentdc58581ad469b63d443153cae54397bc00f5dc72 (diff)
Make pduFromStream work on big endian (again)
reinterpret_cast<char *>(&code) works on little endian, but not on big endian, because code is an int (4 bytes value). I fixed this bug earlier in afb7f76efafcb04e430168416d9d74113bde13bc, but it was added back in 2c0bb738e988d84f36169e0103d051745b678479. [ChangeLog][QModbusPdu] Fix reading from stream on big endian systems Pick-to: 6.4 6.3 6.2 5.15 Change-Id: Ic432d5c86aac40ec2acdc07b4c4881967a023966 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
-rw-r--r--src/serialbus/qmodbuspdu.cpp21
-rw-r--r--src/serialbus/qmodbuspdu.h1
2 files changed, 20 insertions, 2 deletions
diff --git a/src/serialbus/qmodbuspdu.cpp b/src/serialbus/qmodbuspdu.cpp
index c008bf7..d06e75f 100644
--- a/src/serialbus/qmodbuspdu.cpp
+++ b/src/serialbus/qmodbuspdu.cpp
@@ -95,11 +95,12 @@ static QDataStream &pduFromStream(QDataStream &stream, Type type, QModbusPdu *pd
} raii = { pdu };
QModbusPdu::FunctionCode code = QModbusPdu::FunctionCode::Invalid;
- if (stream.readRawData(reinterpret_cast<char *>(&code), sizeof(quint8)) != sizeof(quint8))
+ stream >> code;
+ if (stream.status() == QDataStream::ReadPastEnd)
return stream;
pdu->setFunctionCode(code);
- if (code == QModbusPdu::Invalid || code == QModbusPdu::UndefinedFunctionCode) // shortcut
+ if (code == QModbusPdu::Invalid) // shortcut
return stream;
constexpr const int MaxPduDataSize = 252; // in bytes
@@ -598,6 +599,22 @@ void QModbusRequest::registerDataSizeCalculator(FunctionCode fc, CalcFuncPtr cal
}
/*!
+ \internal
+
+ Reads a FunctionCode from a \a stream.
+ In stream we serialize FunctionCode as one byte, so we use a temporary char
+ variable to make the code work on both little endian and big endian systems.
+ If reading from stream fails, code will retain original value.
+*/
+QDataStream &operator>>(QDataStream &stream, QModbusPdu::FunctionCode &code)
+{
+ char buffer;
+ if (stream.readRawData(&buffer, 1) == 1)
+ code = static_cast<QModbusPdu::FunctionCode>(buffer);
+ return stream;
+}
+
+/*!
\relates QModbusRequest
Reads a \a pdu from the \a stream and returns a reference to the stream.
diff --git a/src/serialbus/qmodbuspdu.h b/src/serialbus/qmodbuspdu.h
index 60aa6ed..a54e05b 100644
--- a/src/serialbus/qmodbuspdu.h
+++ b/src/serialbus/qmodbuspdu.h
@@ -157,6 +157,7 @@ private:
};
Q_SERIALBUS_EXPORT QDebug operator<<(QDebug debug, const QModbusPdu &pdu);
Q_SERIALBUS_EXPORT QDataStream &operator<<(QDataStream &stream, const QModbusPdu &pdu);
+Q_SERIALBUS_EXPORT QDataStream &operator>>(QDataStream &stream, QModbusPdu::FunctionCode &code);
class Q_SERIALBUS_EXPORT QModbusRequest : public QModbusPdu
{