1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qpacket_p.h" |
5 | |
6 | QT_BEGIN_NAMESPACE |
7 | |
8 | /*! |
9 | \class QPacket |
10 | \internal |
11 | |
12 | \brief The QPacket class encapsulates an unfragmentable packet of data to be |
13 | transmitted by QPacketProtocol. |
14 | |
15 | The QPacket class works together with QPacketProtocol to make it simple to |
16 | send arbitrary sized data "packets" across fragmented transports such as TCP |
17 | and UDP. |
18 | |
19 | QPacket provides a QDataStream interface to an unfragmentable packet. |
20 | Applications should construct a QPacket, propagate it with data and then |
21 | transmit it over a QPacketProtocol instance. For example: |
22 | \code |
23 | int version = QDataStream::Qt_DefaultCompiledVersion; |
24 | QPacketProtocol protocol(...); |
25 | |
26 | QPacket myPacket(version); |
27 | myPacket << "Hello world!" << 123; |
28 | protocol.send(myPacket.data()); |
29 | \endcode |
30 | |
31 | As long as both ends of the connection are using the QPacketProtocol class |
32 | and the same data stream version, the data within this packet will be |
33 | delivered unfragmented at the other end, ready for extraction. |
34 | |
35 | \code |
36 | QByteArray greeting; |
37 | int count; |
38 | |
39 | QPacket myPacket(version, protocol.read()); |
40 | |
41 | myPacket >> greeting >> count; |
42 | \endcode |
43 | |
44 | Only packets constructed from raw byte arrays may be read from. Empty QPacket |
45 | instances are for transmission only and are considered "write only". Attempting |
46 | to read data from them will result in undefined behavior. |
47 | |
48 | \ingroup io |
49 | \sa QPacketProtocol |
50 | */ |
51 | |
52 | |
53 | /*! |
54 | Constructs an empty write-only packet. |
55 | */ |
56 | QPacket::QPacket(int version) |
57 | { |
58 | buf.open(openMode: QIODevice::WriteOnly); |
59 | setDevice(&buf); |
60 | setVersion(version); |
61 | } |
62 | |
63 | /*! |
64 | Constructs a read-only packet. |
65 | */ |
66 | QPacket::QPacket(int version, const QByteArray &data) |
67 | { |
68 | buf.setData(data); |
69 | buf.open(openMode: QIODevice::ReadOnly); |
70 | setDevice(&buf); |
71 | setVersion(version); |
72 | } |
73 | |
74 | /*! |
75 | Returns a reference to the raw packet data. |
76 | */ |
77 | const QByteArray &QPacket::data() const |
78 | { |
79 | return buf.data(); |
80 | } |
81 | |
82 | /*! |
83 | Returns a copy of the raw packet data, with extra reserved space removed. |
84 | Mind that this triggers a deep copy. Use it if you anticipate the data to be detached soon anyway. |
85 | */ |
86 | QByteArray QPacket::squeezedData() const |
87 | { |
88 | QByteArray ret = buf.data(); |
89 | ret.squeeze(); |
90 | return ret; |
91 | } |
92 | |
93 | /*! |
94 | Clears the packet, discarding any data. |
95 | */ |
96 | void QPacket::clear() |
97 | { |
98 | buf.reset(); |
99 | QByteArray &buffer = buf.buffer(); |
100 | // Keep the old size to prevent unnecessary allocations |
101 | buffer.reserve(asize: buffer.capacity()); |
102 | buffer.truncate(pos: 0); |
103 | } |
104 | |
105 | QT_END_NAMESPACE |
106 | |