js8call/JS8_UDP/NetworkMessage.cpp

105 lines
2.8 KiB
C++
Raw Permalink Normal View History

2026-01-09 12:48:09 -05:00
/**
* @file NetworkMessage.cpp
2026-01-18 12:53:55 -06:00
* @brief Implementation of NetworkMessage::Builder and NetworkMessage::Reader
* classes
2026-01-09 12:48:09 -05:00
*/
2026-01-18 12:53:55 -06:00
#include "NetworkMessage.h"
#include "JS8_Include/pimpl_impl.h"
#include <QByteArray>
#include <QDebug>
#include <QIODevice>
#include <QString>
2026-01-18 12:53:55 -06:00
#include <exception>
namespace NetworkMessage {
Builder::Builder(QIODevice *device, Type type, QString const &id,
quint32 schema)
: QDataStream{device} {
common_initialization(type, id, schema);
}
Builder::Builder(QByteArray *a, Type type, QString const &id, quint32 schema)
: QDataStream{a, QIODevice::WriteOnly} {
common_initialization(type, id, schema);
}
void Builder::common_initialization(Type type, QString const &id,
quint32 schema) {
if (schema <= 1) {
setVersion(QDataStream::Qt_5_0); // Qt schema version
}
else if (schema <= 2) {
setVersion(QDataStream::Qt_5_2); // Qt schema version
}
else if (schema <= 3) {
setVersion(QDataStream::Qt_5_4); // Qt schema version
}
else {
throw std::runtime_error{"Unrecognized message schema"};
}
// the following two items assume that the quint32 encoding is
// unchanged over QDataStream versions
*this << magic;
*this << schema;
*this << static_cast<quint32>(type) << id.toUtf8();
}
class Reader::impl {
public:
void common_initialization(Reader *parent) {
quint32 magic;
*parent >> magic;
if (magic != Builder::magic) {
throw std::runtime_error{"Invalid message format"};
}
*parent >> schema_;
if (schema_ > Builder::schema_number) {
throw std::runtime_error{"Unrecognized message schema"};
}
if (schema_ <= 1) {
parent->setVersion(QDataStream::Qt_5_0);
}
else if (schema_ <= 2) {
parent->setVersion(QDataStream::Qt_5_2);
}
else if (schema_ <= 3) {
parent->setVersion(QDataStream::Qt_5_4);
}
quint32 type;
*parent >> type >> id_;
if (type >= maximum_message_type_) {
qDebug() << "Unrecognized message type:" << type
<< "from id:" << id_;
type_ = maximum_message_type_;
} else {
type_ = static_cast<Type>(type);
}
}
quint32 schema_;
Type type_;
QByteArray id_;
};
Reader::Reader(QIODevice *device) : QDataStream{device} {
m_->common_initialization(this);
}
Reader::Reader(QByteArray const &a) : QDataStream{a} {
m_->common_initialization(this);
}
Reader::~Reader() {}
quint32 Reader::schema() const { return m_->schema_; }
Type Reader::type() const { return static_cast<Type>(m_->type_); }
QString Reader::id() const { return QString::fromUtf8(m_->id_); }
} // namespace NetworkMessage