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