7#include <QtCore/QElapsedTimer>
8#include <QtCore/QtEndian>
10#include <private/qiodevice_p.h>
11#include <private/qobject_p.h>
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
66
70 Q_DECLARE_PUBLIC(QPacketProtocol)
86
87
88
90 : QObject(*(
new QPacketProtocolPrivate(dev)), parent)
92 Q_ASSERT(4 ==
sizeof(qint32));
95 QObject::connect(dev, &QIODevice::readyRead,
this, &QPacketProtocol::readyToRead);
96 QObject::connect(dev, &QIODevice::bytesWritten,
this, &QPacketProtocol::bytesWritten);
100
101
102
103
106 Q_D(QPacketProtocol);
107 static const qint32 maxSize = std::numeric_limits<qint32>::max() -
sizeof(qint32);
112 if (data.size() > maxSize) {
117 const qint32 sendSize = data.size() +
static_cast<qint32>(
sizeof(qint32));
118 d->sendingPackets.append(sendSize);
120 qint32 sendSizeLE = qToLittleEndian(sendSize);
121 if (!d->writeToDevice((
const char *)&sendSizeLE,
sizeof(qint32))
122 || !d->writeToDevice(data.data(), data.size())) {
128
129
132 Q_D(
const QPacketProtocol);
133 return d->packets.size();
137
138
139
142 Q_D(QPacketProtocol);
143 return d->packets.isEmpty() ? QByteArray() : d->packets.takeFirst();
147
148
149
150
151
152
153
154
155
159 Q_D(QPacketProtocol);
160 if (!d->packets.isEmpty())
163 QElapsedTimer stopWatch;
166 d->waitingForPacket =
true;
168 if (!d->dev->waitForReadyRead(msecs))
170 if (!d->waitingForPacket)
172 msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
178 Q_D(QPacketProtocol);
179 Q_ASSERT(!d->sendingPackets.isEmpty());
182 if (d->sendingPackets.at(0) > bytes) {
183 d->sendingPackets[0] -= bytes;
186 bytes -= d->sendingPackets.at(0);
187 d->sendingPackets.removeFirst();
194 Q_D(QPacketProtocol);
197 if (-1 == d->inProgressSize) {
199 if (
static_cast<qint64>(
sizeof(qint32)) > d->dev->bytesAvailable())
203 qint32 inProgressSizeLE;
204 if (!d->readFromDevice((
char *)&inProgressSizeLE,
sizeof(qint32))) {
208 d->inProgressSize = qFromLittleEndian(inProgressSizeLE);
211 if (d->inProgressSize < qint32(
sizeof(qint32))) {
212 disconnect(d->dev, &QIODevice::readyRead,
this, &QPacketProtocol::readyToRead);
213 disconnect(d->dev, &QIODevice::bytesWritten,
this, &QPacketProtocol::bytesWritten);
219 d->inProgressSize -=
sizeof(qint32);
222 const int bytesToRead =
static_cast<
int>(
223 qMin(d->dev->bytesAvailable(),
224 static_cast<qint64>(d->inProgressSize - d->inProgress.size())));
226 QByteArray toRead(bytesToRead, Qt::Uninitialized);
227 if (!d->readFromDevice(toRead.data(), toRead.size())) {
232 d->inProgress.append(toRead);
233 if (d->inProgressSize == d->inProgress.size()) {
235 d->packets.append(d->inProgress);
236 d->inProgressSize = -1;
237 d->inProgress.clear();
239 d->waitingForPacket =
false;
254 qint64 totalWritten = 0;
255 while (totalWritten < size) {
256 const qint64 chunkSize =
dev->write(bytes + totalWritten, size - totalWritten);
259 totalWritten += chunkSize;
261 return totalWritten == size;
266 qint64 totalRead = 0;
267 while (totalRead < size) {
268 const qint64 chunkSize =
dev->read(buffer + totalRead, size - totalRead);
271 totalRead += chunkSize;
273 return totalRead == size;
277
278
279
280
281
284
285
286
287
288
289
293#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.
Combined button and popup list for selecting options.