Overte C++ Documentation
BasePacket.h
1 //
2 // BasePacket.h
3 // libraries/networking/src/udt
4 //
5 // Created by Stephen Birarda on 2015-07-23.
6 // Copyright 2015 High Fidelity, Inc.
7 // Copyright 2021 Vircadia contributors.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #pragma once
14 
15 #ifndef hifi_BasePacket_h
16 #define hifi_BasePacket_h
17 
18 #include <memory>
19 
20 #include <PortableHighResolutionClock.h>
21 
22 #include "../SockAddr.h"
23 #include "Constants.h"
24 #include "../ExtendedIODevice.h"
25 
26 namespace udt {
27 
28 class BasePacket : public ExtendedIODevice {
29  Q_OBJECT
30 public:
31  static const qint64 PACKET_WRITE_ERROR;
32 
33  static std::unique_ptr<BasePacket> create(qint64 size = -1);
34  static std::unique_ptr<BasePacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
35  const SockAddr& senderSockAddr);
36 
37  // Current level's header size
38  static int localHeaderSize();
39  // Cumulated size of all the headers
40  static int totalHeaderSize();
41  // The maximum payload size this packet can use to fit in MTU
42  static int maxPayloadSize();
43 
44  // Payload direct access to the payload, use responsibly!
45  char* getPayload() { return _payloadStart; }
46  const char* getPayload() const { return _payloadStart; }
47 
48  // Return direct access to the entire packet, use responsibly!
49  char* getData() { return _packet.get(); }
50  const char* getData() const { return _packet.get(); }
51 
52  // Returns the size of the packet, including the header
53  qint64 getDataSize() const { return (_payloadStart - _packet.get()) + _payloadSize; }
54 
55  // Returns the size of the packet, including the header AND the UDP/IP header
56  qint64 getWireSize() const { return getDataSize() + UDP_IPV4_HEADER_SIZE; }
57 
58  // Returns the size of the payload only
59  qint64 getPayloadSize() const { return _payloadSize; }
60 
61  // Allows a writer to change the size of the payload used when writing directly
62  void setPayloadSize(qint64 payloadSize);
63 
64  // Returns the number of bytes allocated for the payload
65  qint64 getPayloadCapacity() const { return _payloadCapacity; }
66 
67  qint64 bytesLeftToRead() const { return _payloadSize - pos(); }
68  qint64 bytesAvailableForWrite() const { return _payloadCapacity - pos(); }
69 
70  SockAddr& getSenderSockAddr() { return _senderSockAddr; }
71  const SockAddr& getSenderSockAddr() const { return _senderSockAddr; }
72 
73  // QIODevice virtual functions
74  // WARNING: Those methods all refer to the payload ONLY and NOT the entire packet
75  virtual bool isSequential() const override { return false; }
76  virtual bool reset() override;
77  virtual qint64 size() const override { return _payloadCapacity; }
78 
79  using QIODevice::read; // Bring QIODevice::read methods to scope, otherwise they are hidden by folling method
80  QByteArray read(qint64 maxSize);
81  QByteArray readWithoutCopy(qint64 maxSize); // this can only be used if packet will stay in scope
82 
83  qint64 writeString(const QString& string);
84  QString readString();
85 
86  void setReceiveTime(p_high_resolution_clock::time_point receiveTime) { _receiveTime = receiveTime; }
87  p_high_resolution_clock::time_point getReceiveTime() const { return _receiveTime; }
88 
89 protected:
90  BasePacket(qint64 size);
91  BasePacket(std::unique_ptr<char[]> data, qint64 size, const SockAddr& senderSockAddr);
92  BasePacket(const BasePacket& other) : ExtendedIODevice() { *this = other; }
93  BasePacket& operator=(const BasePacket& other);
94  BasePacket(BasePacket&& other);
95  BasePacket& operator=(BasePacket&& other);
96 
97  // QIODevice virtual functions
98  virtual qint64 writeData(const char* data, qint64 maxSize) override;
99  virtual qint64 readData(char* data, qint64 maxSize) override;
100 
101  void adjustPayloadStartAndCapacity(qint64 headerSize, bool shouldDecreasePayloadSize = false);
102 
103  qint64 _packetSize = 0; // Total size of the allocated memory
104  std::unique_ptr<char[]> _packet; // Allocated memory
105 
106  char* _payloadStart = nullptr; // Start of the payload
107  qint64 _payloadCapacity = 0; // Total capacity of the payload
108 
109  qint64 _payloadSize = 0; // How much of the payload is actually used
110 
111  SockAddr _senderSockAddr; // sender address for packet (only used on receiving end)
112 
113  p_high_resolution_clock::time_point _receiveTime; // captures the time the packet received (only used on receiving end)
114 };
115 
116 } // namespace udt
117 
118 
119 #endif // hifi_BasePacket_h