Overte C++ Documentation
PacketList.h
1 //
2 // PacketList.h
3 //
4 //
5 // Created by Clement on 7/13/15.
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 #ifndef hifi_PacketList_h
14 #define hifi_PacketList_h
15 
16 #include <memory>
17 
18 #include "../ExtendedIODevice.h"
19 #include "Packet.h"
20 #include "PacketHeaders.h"
21 
22 class LimitedNodeList;
23 
24 namespace udt {
25 
26 class Packet;
27 
28 class PacketList : public ExtendedIODevice {
29  Q_OBJECT
30 public:
31  using MessageNumber = uint32_t;
32  using PacketPointer = std::unique_ptr<Packet>;
33 
34  static std::unique_ptr<PacketList> create(PacketType packetType, QByteArray extendedHeader = QByteArray(),
35  bool isReliable = false, bool isOrdered = false);
36  static std::unique_ptr<PacketList> fromReceivedPackets(std::list<std::unique_ptr<Packet>>&& packets);
37 
38  PacketType getType() const { return _packetType; }
39  bool isReliable() const { return _isReliable; }
40  bool isOrdered() const { return _isOrdered; }
41 
42  size_t getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); }
43  size_t getDataSize() const;
44  size_t getMessageSize() const;
45  QByteArray getMessage() const;
46 
47  QByteArray getExtendedHeader() const { return _extendedHeader; }
48 
49  void startSegment();
50  void endSegment();
51 
52  virtual qint64 getMaxSegmentSize() const { return Packet::maxPayloadSize(_isOrdered); }
53 
54  SockAddr getSenderSockAddr() const;
55 
56  void closeCurrentPacket(bool shouldSendEmpty = false);
57 
58  // QIODevice virtual functions
59  virtual bool isSequential() const override { return false; }
60  virtual qint64 size() const override { return getDataSize(); }
61 
62  qint64 writeString(const QString& string);
63 
64  p_high_resolution_clock::time_point getFirstPacketReceiveTime() const;
65 
66 
67 protected:
68  PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false);
69  PacketList(PacketList&& other);
70 
71  void preparePackets(MessageNumber messageNumber);
72 
73  virtual qint64 writeData(const char* data, qint64 maxSize) override;
74  // Not implemented, added an assert so that it doesn't get used by accident
75  virtual qint64 readData(char* data, qint64 maxSize) override { Q_ASSERT(false); return 0; }
76 
77  PacketType _packetType;
78  std::list<std::unique_ptr<Packet>> _packets;
79 
80  bool _isOrdered = false;
81 
82 private:
83  friend class ::LimitedNodeList;
84  friend class PacketQueue;
85  friend class SendQueue;
86  friend class Socket;
87 
88  Q_DISABLE_COPY(PacketList)
89 
90  // Takes the first packet of the list and returns it.
91  template<typename T> std::unique_ptr<T> takeFront();
92 
93  // Creates a new packet, can be overriden to change return underlying type
94  virtual std::unique_ptr<Packet> createPacket();
95  std::unique_ptr<Packet> createPacketWithExtendedHeader();
96 
97  Packet::MessageNumber _messageNumber;
98  bool _isReliable = false;
99 
100  std::unique_ptr<Packet> _currentPacket;
101 
102  int _segmentStartIndex = -1;
103 
104  QByteArray _extendedHeader;
105 };
106 
107 template<typename T> std::unique_ptr<T> PacketList::takeFront() {
108  static_assert(std::is_base_of<Packet, T>::value, "T must derive from Packet.");
109 
110  auto packet = std::move(_packets.front());
111  _packets.pop_front();
112  return std::unique_ptr<T>(dynamic_cast<T*>(packet.release()));
113 }
114 
115 }
116 
117 Q_DECLARE_METATYPE(udt::PacketList*);
118 
119 #endif // hifi_PacketList_h