Packet class polishing

This commit is contained in:
Atlante45 2015-07-06 17:02:55 -07:00
parent 0c7dc1e28f
commit 12edec7bea
2 changed files with 54 additions and 72 deletions

View file

@ -1,6 +1,6 @@
// //
// Packet.cpp // Packet.cpp
// // libraries/networking/src
// //
// Created by Clement on 7/2/15. // Created by Clement on 7/2/15.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -11,60 +11,66 @@
#include "Packet.h" #include "Packet.h"
int64_t Packet::headerSize() { #include "LimitedNodeList.h"
return sizeof(Packet::Header);
int64_t Packet::headerSize(PacketType::Value type) {
int64_t size = numBytesForArithmeticCodedPacketType(type) + sizeof(PacketVersion) +
((SEQUENCE_NUMBERED_PACKETS.contains(type)) ? sizeof(SequenceNumber) : 0);
return size;
} }
int64_t Packet::maxPayloadSize() { int64_t Packet::maxPayloadSize(PacketType::Value type) {
return MAX_PACKET_SIZE - Packet::headerSize(); return MAX_PACKET_SIZE - headerSize(type);
} }
std::unique_ptr<Packet> Packet::create(PacketType::Value type, int64_t size) { std::unique_ptr<Packet> Packet::create(PacketType::Value type, int64_t size) {
auto maxPayload = maxPayloadSize(type);
if (size == -1) { if (size == -1) {
size = maxPayloadSize(); // default size of -1, means biggest packet possible
size = maxPayload;
} }
if (size <= 0 || size > maxPayloadSize()) { if (size <= 0 || size > maxPayload) {
// Invalid size, return null pointer
return std::unique_ptr<Packet>(); return std::unique_ptr<Packet>();
} }
// allocate memory
return std::unique_ptr<Packet>(new Packet(type, size)); return std::unique_ptr<Packet>(new Packet(type, size));
} }
Packet::Packet(PacketType::Value type, int64_t size) { Packet::Packet(PacketType::Value type, int64_t size) :
_packetSize = headerSize() + size; _packetSize(headerSize(type) + size),
_packet = std::unique_ptr<char>(new char(_packetSize)); _packet(new char(_packetSize)),
_payloadStart = _packet.get() + headerSize(); _payload(_packet.get() + headerSize(type), size) {
Q_ASSERT(size <= maxPayloadSize(type));
} }
const Packet::Header& Packet::getHeader() const { PacketType::Value Packet::getPacketType() const {
return *reinterpret_cast<const Header*>(_packet.get()); return *reinterpret_cast<PacketType::Value*>(_packet.get());
} }
Packet::Header& Packet::getHeader() { PacketVersion Packet::getPacketTypeVersion() const {
return *reinterpret_cast<Header*>(_packet.get()); return *reinterpret_cast<PacketVersion*>(_packet.get() + numBytesForArithmeticCodedPacketType(getPacketType()));
} }
char* Packet::getPayload() { Packet::SequenceNumber Packet::getSequenceNumber() const {
return _payloadStart; PacketType::Value type{ getPacketType() };
} if (SEQUENCE_NUMBERED_PACKETS.contains(type)) {
SequenceNumber seqNum = *reinterpret_cast<SequenceNumber*>(_packet.get() + numBytesForArithmeticCodedPacketType(type) +
sizeof(PacketVersion));
int64_t NodeListPacket::headerSize() {
return sizeof(NodeListPacket::Header); return seqNum & ~(1 << 15); // remove control bit
}
int64_t NodeListPacket::maxPayloadSize() {
return Packet::maxPayloadSize() - NodeListPacket::headerSize();
}
std::unique_ptr<NodeListPacket> NodeListPacket::create(PacketType::Value type, int64_t size) {
if (size > maxPayloadSize()) {
return std::unique_ptr<NodeListPacket>();
} }
return -1;
return std::unique_ptr<NodeListPacket>(new NodeListPacket(type, size));
} }
NodeListPacket::NodeListPacket(PacketType::Value type, int64_t size) : Packet(type, headerSize() + size) { bool Packet::isControlPacket() const {
PacketType::Value type{ getPacketType() };
} if (SEQUENCE_NUMBERED_PACKETS.contains(type)) {
SequenceNumber seqNum = *reinterpret_cast<SequenceNumber*>(_packet.get() + numBytesForArithmeticCodedPacketType(type) +
sizeof(PacketVersion));
return seqNum & (1 << 15); // Only keep control bit
}
return false;
}

View file

@ -1,6 +1,6 @@
// //
// Packet.h // Packet.h
// // libraries/networking/src
// //
// Created by Clement on 7/2/15. // Created by Clement on 7/2/15.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -14,30 +14,24 @@
#include <memory> #include <memory>
#include "LimitedNodeList.h"
#include "PacketHeaders.h" #include "PacketHeaders.h"
#include "PacketPayload.h"
class Packet { class Packet {
public: public:
struct Header { using SequenceNumber = uint16_t;
// Required
uint8_t _type;
uint8_t _version;
// Optionnal
uint16_t _messageNumber;
// 1st bit is the data/control bit, rest is the sequence number
uint32_t _controlBitAndSequenceNumber;
};
// TODO sanity check Header struct size
static int64_t headerSize(); static int64_t headerSize(PacketType::Value type);
static int64_t maxPayloadSize(); static int64_t maxPayloadSize(PacketType::Value type);
static std::unique_ptr<Packet> create(PacketType::Value type, int64_t size = -1); static std::unique_ptr<Packet> create(PacketType::Value type, int64_t size = -1);
virtual const Header& getHeader() const; PacketType::Value getPacketType() const;
virtual char* getPayload(); PacketVersion getPacketTypeVersion() const;
SequenceNumber getSequenceNumber() const;
bool isControlPacket() const;
PacketPayload& payload() { return _payload; }
protected: protected:
Packet(PacketType::Value type, int64_t size); Packet(PacketType::Value type, int64_t size);
@ -46,29 +40,11 @@ protected:
Packet& operator=(Packet&&) = delete; Packet& operator=(Packet&&) = delete;
Packet& operator=(const Packet&) = delete; Packet& operator=(const Packet&) = delete;
Header& getHeader();
private: private:
int64_t _packetSize; int64_t _packetSize;
std::unique_ptr<char> _packet; std::unique_ptr<char> _packet;
char* _payloadStart; PacketPayload _payload;
};
class NodeListPacket : public Packet {
public:
struct Header {
// Required
char _sourceUuid[NUM_BYTES_RFC4122_UUID];
char _connectionUuid[NUM_BYTES_RFC4122_UUID];
};
static int64_t headerSize();
static int64_t maxPayloadSize();
static std::unique_ptr<NodeListPacket> create(PacketType::Value type, int64_t size = -1);
protected:
NodeListPacket(PacketType::Value type, int64_t size);
}; };
#endif // hifi_Packet_h #endif // hifi_Packet_h