From 7eddcf383c229cd4ff627f2258722f7fb49aec05 Mon Sep 17 00:00:00 2001 From: Atlante45 <clement.brisset@gmail.com> Date: Tue, 7 Jul 2015 11:33:33 -0700 Subject: [PATCH] Merge Packet and PacketPayload --- libraries/networking/src/Packet.cpp | 53 ++++++++++++++++- libraries/networking/src/Packet.h | 36 ++++++++++-- libraries/networking/src/PacketHeaders.h | 1 + libraries/networking/src/PacketPayload.cpp | 66 ---------------------- libraries/networking/src/PacketPayload.h | 40 ------------- 5 files changed, 83 insertions(+), 113 deletions(-) delete mode 100644 libraries/networking/src/PacketPayload.cpp delete mode 100644 libraries/networking/src/PacketPayload.h diff --git a/libraries/networking/src/Packet.cpp b/libraries/networking/src/Packet.cpp index 717a79f2ff..fb1a3dabe3 100644 --- a/libraries/networking/src/Packet.cpp +++ b/libraries/networking/src/Packet.cpp @@ -41,7 +41,8 @@ std::unique_ptr<Packet> Packet::create(PacketType::Value type, int64_t size) { Packet::Packet(PacketType::Value type, int64_t size) : _packetSize(headerSize(type) + size), _packet(new char(_packetSize)), - _payload(_packet.get() + headerSize(type), size) { + _payloadStart(_packet.get() + headerSize(type)), + _capacity(size) { // Sanity check Q_ASSERT(size <= maxPayloadSize(type)); @@ -87,7 +88,7 @@ bool Packet::isControlPacket() const { void Packet::setPacketTypeAndVersion(PacketType::Value type) { // Pack the packet type - auto offset = packArithmeticallyCodedValue((int)type, _packet.get()); + auto offset = packArithmeticallyCodedValue(type, _packet.get()); // Pack the packet version auto version { versionForPacketType(type) }; @@ -102,3 +103,51 @@ void Packet::setSequenceNumber(SequenceNumber seqNum) { memcpy(_packet.get() + numBytesForArithmeticCodedPacketType(type) + sizeof(PacketVersion), &seqNum, sizeof(seqNum)); } + +bool Packet::seek(qint64 pos) { + bool valid = (pos >= 0) && (pos < size()); + if (valid) { + _position = pos; + } + return valid; +} + +static const qint64 PACKET_WRITE_ERROR = -1; +qint64 Packet::writeData(const char* data, qint64 maxSize) { + // make sure we have the space required to write this block + if (maxSize <= bytesAvailable()) { + qint64 currentPos = pos(); + + // good to go - write the data + memcpy(_payloadStart + currentPos, data, maxSize); + + // seek to the new position based on where our write just finished + seek(currentPos + maxSize); + + // keep track of _sizeUsed so we can just write the actual data when packet is about to be sent + _sizeUsed = std::max(pos() + 1, _sizeUsed); + + // return the number of bytes written + return maxSize; + } else { + // not enough space left for this write - return an error + return PACKET_WRITE_ERROR; + } +} + +qint64 Packet::readData(char* dest, qint64 maxSize) { + // we're either reading what is left from the current position or what was asked to be read + qint64 numBytesToRead = std::min(bytesAvailable(), maxSize); + + if (numBytesToRead > 0) { + int currentPosition = pos(); + + // read out the data + memcpy(dest, _payloadStart + currentPosition, numBytesToRead); + + // seek to the end of the read + seek(currentPosition + numBytesToRead); + } + + return numBytesToRead; +} diff --git a/libraries/networking/src/Packet.h b/libraries/networking/src/Packet.h index dd275aeb15..a2c3c83e50 100644 --- a/libraries/networking/src/Packet.h +++ b/libraries/networking/src/Packet.h @@ -17,7 +17,7 @@ #include "PacketHeaders.h" #include "PacketPayload.h" -class Packet { +class Packet : public QIODevice { public: using SequenceNumber = uint16_t; @@ -26,12 +26,29 @@ public: static std::unique_ptr<Packet> create(PacketType::Value type, int64_t size = -1); + + qint64 getSizeWithHeader() const { return getSizeUsed(); } + qint64 getSizeUsed() const { return _sizeUsed; } + void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; } + + const char* constData() const { return _payloadStart; } + PacketType::Value getPacketType() const; PacketVersion getPacketTypeVersion() const; SequenceNumber getSequenceNumber() const; bool isControlPacket() const; - PacketPayload& payload() { return _payload; } + // QIODevice virtual functions + // + // WARNING: Those methods all refer to the paylaod only and not the entire packet + virtual bool atEnd() const { return _position == _capacity; } + virtual qint64 bytesAvailable() const { return size() - pos(); } + virtual bool canReadLine() const { return false; } + virtual bool isSequential() const { return false; } + virtual qint64 pos() const { return _position; } + virtual bool reset() { return seek(0); } + virtual bool seek(qint64 pos); + virtual qint64 size() const { return _capacity; } protected: Packet(PacketType::Value type, int64_t size); @@ -39,14 +56,23 @@ protected: Packet(const Packet&) = delete; Packet& operator=(Packet&&) = delete; Packet& operator=(const Packet&) = delete; + + // QIODevice virtual functions + virtual qint64 writeData(const char* data, qint64 maxSize); + virtual qint64 readData(char* data, qint64 maxSize); void setPacketTypeAndVersion(PacketType::Value type); void setSequenceNumber(SequenceNumber seqNum); - int64_t _packetSize; - std::unique_ptr<char> _packet; + std::unique_ptr<char> _packet; // Allocated memory + int64_t _packetSize = 0; // Total size of the allocated memory + + char* _payloadStart = nullptr; // Start of the payload + qint64 _position = 0; // Current position in the payload + qint64 _capacity = 0; // Total capacity of the payload + + qint64 _sizeUsed = 0; // How much of the payload is actually used - PacketPayload _payload; }; #endif // hifi_Packet_h \ No newline at end of file diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 298a0f7246..b164081d0d 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -118,6 +118,7 @@ int numBytesForPacketHeader(const QByteArray& packet); int numBytesForPacketHeader(const char* packet); int numBytesForArithmeticCodedPacketType(PacketType::Value packetType); int numBytesForPacketHeaderGivenPacketType(PacketType::Value packetType); +int packArithmeticallyCodedValue(int value, char* destination); QUuid uuidFromPacketHeader(const QByteArray& packet); diff --git a/libraries/networking/src/PacketPayload.cpp b/libraries/networking/src/PacketPayload.cpp deleted file mode 100644 index 5f0bc9b557..0000000000 --- a/libraries/networking/src/PacketPayload.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// PacketPayload.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 07/06/15. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "PacketPayload.h" - -PacketPayload::PacketPayload(char* data, qint64 capacity) : - _data(data) - _capacity(capacity) -{ - -} - -const int PACKET_READ_ERROR = -1; - -qint64 PacketPayload::writeData(const char* data, qint64 maxSize) { - - qint64 currentPos = pos(); - - // make sure we have the space required to write this block - qint64 bytesAvailable = _capacity - currentPos; - - if (bytesAvailable < srcBytes) { - // good to go - write the data - memcpy(_data + currentPos, src, srcBytes); - - // seek to the new position based on where our write just finished - seek(currentPos + srcBytes); - - // keep track of _maxWritten so we can just write the actual data when packet is about to be sent - _size = std::max(pos() + 1, _maxWritten); - - // return the number of bytes written - return srcBytes; - } else { - // not enough space left for this write - return an error - return PACKET_WRITE_ERROR; - } -} - -const qint64 PACKET_READ_ERROR = -1; - -qint64 PacketPayload::readData(char* dest, qint64 maxSize) { - - int currentPosition = pos(); - - // we're either reading what is left from the current position or what was asked to be read - qint64 numBytesToRead = std::min(_maxSize - currentPosition, maxSize); - - if (numBytesToRead > 0) { - // read out the data - memcpy(dest, _data + currentPosition, numBytesToRead); - - // seek to the end of the read - seek(_data + currentPosition + numBytesToRead); - } - - return numBytesToRead; -} diff --git a/libraries/networking/src/PacketPayload.h b/libraries/networking/src/PacketPayload.h deleted file mode 100644 index a9e3811767..0000000000 --- a/libraries/networking/src/PacketPayload.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// PacketPayload.h -// libraries/networking/src -// -// Created by Stephen Birarda on 07/06/15. -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_PacketPayload_h -#define hifi_PacketPayload_h - -#pragma once - -#include <QtCore/QIODevice> - -class PacketPayload : public QIODevice { -public: - PacketPayload(char* data, qint64 capacity); - - qint64 getSizeUsed() const { return _sizeUsed; } - void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; } - - virtual qint64 size() const { return _capacity; } - virtual bool isSequential() const { return false; } - - const char* constData() const { return _data; } -protected: - qint64 writeData(const char* data, qint64 maxSize); - qint64 readData(char* data, qint64 maxSize); - -private: - char* _data; - qint64 _sizeUsed = 0; - qint64 _capacity = 0; -}; - -#endif // hifi_PacketPayload_h