From 8032f05ed6666b5878d94464ff5200b33b7772c1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 18 Aug 2015 23:06:30 -0700 Subject: [PATCH] Add support for generating PacketList from received data --- libraries/networking/src/udt/PacketList.cpp | 54 +++++++++++++++++++-- libraries/networking/src/udt/PacketList.h | 27 +++++++++-- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/udt/PacketList.cpp b/libraries/networking/src/udt/PacketList.cpp index 494587971b..e5386a4cc9 100644 --- a/libraries/networking/src/udt/PacketList.cpp +++ b/libraries/networking/src/udt/PacketList.cpp @@ -13,17 +13,26 @@ #include -#include "Packet.h" +#include "../NLPacket.h" using namespace udt; -PacketList::PacketList(PacketType packetType, QByteArray extendedHeader) : +PacketList::PacketList(PacketType packetType, QByteArray extendedHeader, bool isReliable, bool isOrdered) : _packetType(packetType), + _isReliable(isReliable), + _isOrdered(isOrdered), _extendedHeader(extendedHeader) { + Q_ASSERT_X(!(!_isReliable && _isOrdered), "PacketList", "Unreliable ordered PacketLists are not currently supported"); QIODevice::open(WriteOnly); } +PacketList::PacketList(PacketList&& other) : + _packetType(other._packetType), + _packets(std::move(other._packets)) +{ +} + void PacketList::startSegment() { _segmentStartIndex = _currentPacket ? _currentPacket->pos() : _extendedHeader.size(); } @@ -32,10 +41,30 @@ void PacketList::endSegment() { _segmentStartIndex = -1; } +size_t PacketList::getDataSize() const { + size_t totalBytes = 0; + for (const auto& packet : _packets) { + totalBytes += packet->getDataSize(); + } + + if (_currentPacket) { + totalBytes += _currentPacket->getDataSize(); + } + + return totalBytes; +} + +std::unique_ptr PacketList::fromReceivedPackets(std::list>&& packets) { + auto packetList = std::unique_ptr(new PacketList(PacketType::Unknown, QByteArray(), true, true)); + packetList->_packets = std::move(packets); + return packetList; +} + std::unique_ptr PacketList::createPacket() { // use the static create method to create a new packet - // TODO: create a packet with correct reliability and messaging - return Packet::create(); + // If this packet list is supposed to be ordered then we consider this to be part of a message + bool isPartOfMessage = _isOrdered; + return Packet::create(-1, _isReliable, isPartOfMessage); } std::unique_ptr PacketList::createPacketWithExtendedHeader() { @@ -53,6 +82,23 @@ std::unique_ptr PacketList::createPacketWithExtendedHeader() { return packet; } +QByteArray PacketList::getAllData() { + size_t sizeBytes = 0; + + for (const auto& packet : _packets) { + sizeBytes += packet->size(); + } + + QByteArray data; + data.reserve(sizeBytes); + + for (auto& packet : _packets) { + data.append(packet->getPayload(), packet->getPayloadSize()); + } + + return data; +} + qint64 PacketList::writeData(const char* data, qint64 maxSize) { if (!_currentPacket) { // we don't have a current packet, time to set one up diff --git a/libraries/networking/src/udt/PacketList.h b/libraries/networking/src/udt/PacketList.h index 18acb7fa17..5596253a6c 100644 --- a/libraries/networking/src/udt/PacketList.h +++ b/libraries/networking/src/udt/PacketList.h @@ -16,6 +16,7 @@ #include +#include "Packet.h" #include "PacketHeaders.h" class LimitedNodeList; @@ -27,26 +28,44 @@ class Packet; class PacketList : public QIODevice { Q_OBJECT public: - PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray()); + PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false); + PacketList(PacketList&& other); + + static std::unique_ptr fromReceivedPackets(std::list>&& packets); virtual bool isSequential() const { return true; } + + bool isReliable() const { return _isReliable; } + bool isOrdered() const { return _isOrdered; } void startSegment(); void endSegment(); PacketType getType() const { return _packetType; } int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); } + + QByteArray getExtendedHeader() const { return _extendedHeader; } + + size_t getDataSize() const; void closeCurrentPacket(bool shouldSendEmpty = false); - + + QByteArray getAllData(); + template qint64 readPrimitive(T* data); template qint64 writePrimitive(const T& data); + std::list> _packets; protected: virtual qint64 writeData(const char* data, qint64 maxSize); virtual qint64 readData(char* data, qint64 maxSize) { return 0; } + PacketType _packetType; + private: friend class ::LimitedNodeList; + friend class Socket; + friend class SendQueue; + friend class NLPacketList; PacketList(const PacketList& other) = delete; PacketList& operator=(const PacketList& other) = delete; @@ -58,11 +77,11 @@ private: virtual std::unique_ptr createPacket(); std::unique_ptr createPacketWithExtendedHeader(); - PacketType _packetType; + Packet::MessageNumber _messageNumber; + bool _isReliable = false; bool _isOrdered = false; std::unique_ptr _currentPacket; - std::list> _packets; int _segmentStartIndex = -1;