namespace packet {
/*!
|magic|type|length|data|checksum|
|4 |4 |4 | |2 |
*/
#pragma pack(push)
#pragma pack(1)
class IPacket
{
public:
virtual ~IPacket() = default;
protected:
virtual QByteArray sendData(const QByteArray &data) = 0;
virtual IPacket &receiveData(const QByteArray &data) = 0;
virtual quint32 type() const = 0;
virtual bool isVaild() = 0;
virtual bool isEqual(quint32 type) = 0;
};
constexpr quint32 magic = (quint32)0x49506B74;//IPkt asscii
class Packet : public IPacket
{
public:
enum Type:quint32 {
UserType = 1
};
QByteArray sendData(const QByteArray &data) override {
QByteArray byte;
QDataStream out(&byte, QIODevice::WriteOnly);
out << magic;
out << this->type();
out << (quint32)data.length();
out.writeRawData(data.data(), data.size());
out << qChecksum(data.data(), data.length());
return byte;
}
Packet &receiveData(const QByteArray &data) override {
QDataStream in(data);
in >> m_magic;
in >> m_type;
in >> m_length;
m_raw.resize(m_length);
in.readRawData(m_raw.data(),m_length);
in >> m_checksum;
return *this;
}
quint32 type() const override {
return UserType;
}
bool isVaild() override {
return m_checksum == qChecksum(m_raw.data(), m_raw.length()) ? true : false;
}
bool isEqual(quint32 type) override {
return type == m_type ? true : false;
}
quint32 m_magic;
quint32 m_type;
quint32 m_length;
QByteArray m_raw;
quint16 m_checksum;
};
struct alignas(alignof(quint32)) PacketHeader
{
void sequence(const QByteArray &data) {
QDataStream in(data);
in >> m_magic;
in >> m_type;
in >> m_length;
}
bool isValid() {
return (magic == magic && m_type > 0 && m_length > 0) ? true : false;
}
quint32 m_magic{ 0 };
quint32 m_type{ 0 };
quint32 m_length{ 0 };
};
#pragma pack(pop)
}