6#include <QtCore/QElapsedTimer>
7#include <QtCore/QtEndian>
9#include <private/qiodevice_p.h>
10#include <private/qobject_p.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
69 Q_DECLARE_PUBLIC(QPacketProtocol)
85
86
87
89 : QObject(*(
new QPacketProtocolPrivate(dev)), parent)
91 Q_ASSERT(4 ==
sizeof(qint32));
94 QObject::connect(dev, &QIODevice::readyRead,
this, &QPacketProtocol::readyToRead);
95 QObject::connect(dev, &QIODevice::bytesWritten,
this, &QPacketProtocol::bytesWritten);
99
100
101
102
105 Q_D(QPacketProtocol);
106 static const qint32 maxSize = std::numeric_limits<qint32>::max() -
sizeof(qint32);
111 if (data.size() > maxSize) {
116 const qint32 sendSize = data.size() +
static_cast<qint32>(
sizeof(qint32));
117 d->sendingPackets.append(sendSize);
119 qint32 sendSizeLE = qToLittleEndian(sendSize);
120 if (!d->writeToDevice((
const char *)&sendSizeLE,
sizeof(qint32))
121 || !d->writeToDevice(data.data(), data.size())) {
127
128
131 Q_D(
const QPacketProtocol);
132 return d->packets.size();
136
137
138
141 Q_D(QPacketProtocol);
142 return d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst();
146
147
148
149
150
151
152
153
154
158 Q_D(QPacketProtocol);
159 if (!d->packets.isEmpty())
162 QElapsedTimer stopWatch;
165 d->waitingForPacket =
true;
167 if (!d->dev->waitForReadyRead(msecs))
169 if (!d->waitingForPacket)
171 msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
177 Q_D(QPacketProtocol);
178 Q_ASSERT(!d->sendingPackets.isEmpty());
181 if (d->sendingPackets.at(0) > bytes) {
182 d->sendingPackets[0] -= bytes;
185 bytes -= d->sendingPackets.at(0);
186 d->sendingPackets.removeFirst();
193 Q_D(QPacketProtocol);
196 if (-1 == d->inProgressSize) {
198 if (
static_cast<qint64>(
sizeof(qint32)) > d->dev->bytesAvailable())
202 qint32 inProgressSizeLE;
203 if (!d->readFromDevice((
char *)&inProgressSizeLE,
sizeof(qint32))) {
207 d->inProgressSize = qFromLittleEndian(inProgressSizeLE);
210 if (d->inProgressSize < qint32(
sizeof(qint32))) {
211 disconnect(d->dev, &QIODevice::readyRead,
this, &QPacketProtocol::readyToRead);
212 disconnect(d->dev, &QIODevice::bytesWritten,
this, &QPacketProtocol::bytesWritten);
218 d->inProgressSize -=
sizeof(qint32);
221 const int bytesToRead =
static_cast<
int>(
222 qMin(d->dev->bytesAvailable(),
223 static_cast<qint64>(d->inProgressSize - d->inProgress.size())));
225 QByteArray toRead(bytesToRead, Qt::Uninitialized);
226 if (!d->readFromDevice(toRead.data(), toRead.size())) {
231 d->inProgress.append(toRead);
232 if (d->inProgressSize == d->inProgress.size()) {
234 d->packets.append(d->inProgress);
235 d->inProgressSize = -1;
236 d->inProgress.clear();
238 d->waitingForPacket =
false;
253 qint64 totalWritten = 0;
254 while (totalWritten < size) {
255 const qint64 chunkSize =
dev->write(bytes + totalWritten, size - totalWritten);
258 totalWritten += chunkSize;
260 return totalWritten == size;
265 qint64 totalRead = 0;
266 while (totalRead < size) {
267 const qint64 chunkSize =
dev->read(buffer + totalRead, size - totalRead);
270 totalRead += chunkSize;
272 return totalRead == size;
276
277
278
279
280
283
284
285
286
287
288
292#include "moc_qpacketprotocol_p.cpp"
ImageReaderError error() const
Returns the type of error that occurred last.
QList< QByteArray > packets
bool writeToDevice(const char *bytes, qint64 size)
QList< qint32 > sendingPackets
bool readFromDevice(char *buffer, qint64 size)
The QPacketProtocol class encapsulates communicating discrete packets across fragmented IO channels,...
void send(const QByteArray &data)
Transmit the packet.
bool waitForReadyRead(int msecs=3000)
This function locks until a new packet is available for reading and the \l{QIODevice::}...
qint64 packetsAvailable() const
Returns the number of received packets yet to be read.
QByteArray read()
Return the next unread packet, or an empty QByteArray if no packets are available.