Add message part to Packet

This commit is contained in:
Atlante45 2015-09-23 17:32:12 +02:00
parent 8cecb95bf2
commit c3fc6f4f79
5 changed files with 51 additions and 40 deletions

View file

@ -15,7 +15,7 @@ using namespace udt;
int Packet::localHeaderSize(bool isPartOfMessage) {
return sizeof(Packet::SequenceNumberAndBitField) +
(isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) : 0);
(isPartOfMessage ? sizeof(Packet::MessageNumberAndBitField) + sizeof(MessagePart) : 0);
}
int Packet::totalHeaderSize(bool isPartOfMessage) {
@ -109,9 +109,11 @@ Packet& Packet::operator=(Packet&& other) {
return *this;
}
void Packet::writeMessageNumber(MessageNumber messageNumber) {
void Packet::writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart) {
_isPartOfMessage = true;
_messageNumber = messageNumber;
_packetPosition = position;
_messagePart = messagePart;
writeHeader();
}
@ -141,6 +143,9 @@ void Packet::readHeader() const {
MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1;
_messageNumber = *messageNumberAndBitField & MESSAGE_NUMBER_MASK;
_packetPosition = static_cast<PacketPosition>(*messageNumberAndBitField >> PACKET_POSITION_OFFSET);
MessagePart* messagePart = messageNumberAndBitField + 1;
_messagePart = *messagePart;
}
}
@ -166,5 +171,8 @@ void Packet::writeHeader() const {
MessageNumberAndBitField* messageNumberAndBitField = seqNumBitField + 1;
*messageNumberAndBitField = _messageNumber;
*messageNumberAndBitField |= _packetPosition << PACKET_POSITION_OFFSET;
MessagePart* messagePart = messageNumberAndBitField + 1;
*messagePart = _messagePart;
}
}

View file

@ -31,6 +31,7 @@ public:
// NOTE: The MessageNumber is only actually 30 bits to leave room for a bit field
using MessageNumber = uint32_t;
using MessageNumberAndBitField = uint32_t;
using MessagePart = uint32_t;
// Use same size as MessageNumberAndBitField so we can use the enum with bitwise operations
enum PacketPosition : MessageNumberAndBitField {
@ -55,14 +56,13 @@ public:
bool isPartOfMessage() const { return _isPartOfMessage; }
bool isReliable() const { return _isReliable; }
SequenceNumber getSequenceNumber() const { return _sequenceNumber; }
MessageNumber getMessageNumber() const { return _messageNumber; }
void setPacketPosition(PacketPosition position) { _packetPosition = position; }
PacketPosition getPacketPosition() const { return _packetPosition; }
void writeMessageNumber(MessageNumber messageNumber);
SequenceNumber getSequenceNumber() const { return _sequenceNumber; }
MessageNumber getMessageNumber() const { return _messageNumber; }
PacketPosition getPacketPosition() const { return _packetPosition; }
MessagePart getMessagePart() const { return _messagePart; }
void writeMessageNumber(MessageNumber messageNumber, PacketPosition position, MessagePart messagePart);
void writeSequenceNumber(SequenceNumber sequenceNumber) const;
protected:
@ -84,8 +84,9 @@ private:
mutable bool _isReliable { false };
mutable bool _isPartOfMessage { false };
mutable SequenceNumber _sequenceNumber { 0 };
mutable PacketPosition _packetPosition { PacketPosition::ONLY };
mutable MessageNumber _messageNumber { 0 };
mutable PacketPosition _packetPosition { PacketPosition::ONLY };
mutable MessagePart _messagePart { 0 };
};
} // namespace udt

View file

@ -132,6 +132,24 @@ QByteArray PacketList::getMessage() {
return data;
}
void PacketList::preparePackets(MessageNumber messageNumber) {
Q_ASSERT(_packets.size() > 0);
if (_packets.size() == 1) {
_packets.front()->writeMessageNumber(messageNumber, Packet::PacketPosition::ONLY, 0);
} else {
const auto second = ++_packets.begin();
const auto last = --_packets.end();
Packet::MessagePart messagePart = 0;
std::for_each(second, last, [&](const PacketPointer& packet) {
packet->writeMessageNumber(messageNumber, Packet::PacketPosition::MIDDLE, ++messagePart);
});
_packets.front()->writeMessageNumber(messageNumber, Packet::PacketPosition::FIRST, 0);
_packets.back()->writeMessageNumber(messageNumber, Packet::PacketPosition::LAST, ++messagePart);
}
}
qint64 PacketList::writeData(const char* data, qint64 maxSize) {
auto sizeRemaining = maxSize;

View file

@ -28,28 +28,29 @@ class Packet;
class PacketList : public QIODevice {
Q_OBJECT
public:
using MessageNumber = uint32_t;
using PacketPointer = std::unique_ptr<Packet>;
static std::unique_ptr<PacketList> create(PacketType packetType, QByteArray extendedHeader = QByteArray(),
bool isReliable = false, bool isOrdered = false);
static std::unique_ptr<PacketList> fromReceivedPackets(std::list<std::unique_ptr<Packet>>&& packets);
PacketType getType() const { return _packetType; }
bool isReliable() const { return _isReliable; }
bool isOrdered() const { return _isOrdered; }
int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); }
size_t getDataSize() const;
size_t getMessageSize() const;
QByteArray getMessage();
QByteArray getExtendedHeader() const { return _extendedHeader; }
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;
size_t getMessageSize() const;
void closeCurrentPacket(bool shouldSendEmpty = false);
QByteArray getMessage();
// QIODevice virtual functions
virtual bool isSequential() const { return false; }
virtual qint64 size() const { return getDataSize(); }
@ -60,6 +61,8 @@ public:
protected:
PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false);
PacketList(PacketList&& other);
void preparePackets(MessageNumber messageNumber);
virtual qint64 writeData(const char* data, qint64 maxSize);
// Not implemented, added an assert so that it doesn't get used by accident

View file

@ -45,26 +45,7 @@ void PacketQueue::queuePacket(PacketPointer packet) {
}
void PacketQueue::queuePacketList(PacketListPointer packetList) {
Q_ASSERT(packetList->_packets.size() > 0);
auto messageNumber = getNextMessageNumber();
auto markPacket = [&messageNumber](const PacketPointer& packet, Packet::PacketPosition position) {
packet->setPacketPosition(position);
packet->writeMessageNumber(messageNumber);
};
if (packetList->_packets.size() == 1) {
markPacket(packetList->_packets.front(), Packet::PacketPosition::ONLY);
} else {
const auto second = ++packetList->_packets.begin();
const auto last = --packetList->_packets.end();
std::for_each(second, last, [&](const PacketPointer& packet) {
markPacket(packet, Packet::PacketPosition::MIDDLE);
});
markPacket(packetList->_packets.front(), Packet::PacketPosition::FIRST);
markPacket(packetList->_packets.back(), Packet::PacketPosition::LAST);
}
packetList->preparePackets(getNextMessageNumber());
LockGuard locker(_packetsLock);
_packets.splice(_packets.end(), packetList->_packets);