mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-27 06:38:44 -05:00
b74788ea89
The MessageClient and MessageServer classes now agree a maximum common schema number for the protocol described in NetworkMessage.hpp. this is achieved by the client sending a Heartbeat message specifying the highest schema number supported, the server responds with messages using the minimum of its highest supported schema number and the highest schema number sent by the client in its initial Heartbeat message. This mechanism enables clients and servers built with different generations of the message schema to interoperate with minimum loss of functionality. It should be noted that messages may be extended with new fields on the end of the current definition so long as the meaning of the original fields are unchanged. Such an extension does not need the schema number to be incremented. On the other hand, using a newer version of the underlying Qt QDataStream::Version should always increment the schema number since the NetworkMessage::Builder and NetworkMessage::Reader classes need to know which QDataStream::Version to use. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5991 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
132 lines
2.7 KiB
C++
132 lines
2.7 KiB
C++
#include "NetworkMessage.hpp"
|
|
|
|
#include <exception>
|
|
|
|
#include <QString>
|
|
#include <QByteArray>
|
|
|
|
#include "pimpl_impl.hpp"
|
|
|
|
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
|
|
}
|
|
#if QT_VERSION >= 0x050200
|
|
else if (schema <= 2)
|
|
{
|
|
setVersion (QDataStream::Qt_5_2); // Qt schema version
|
|
}
|
|
#endif
|
|
#if QT_VERSION >= 0x050400
|
|
else if (schema <= 3)
|
|
{
|
|
setVersion (QDataStream::Qt_5_4); // Qt schema version
|
|
}
|
|
#endif
|
|
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);
|
|
}
|
|
#if QT_VERSION >= 0x050200
|
|
else if (schema_ <= 2)
|
|
{
|
|
parent->setVersion (QDataStream::Qt_5_2);
|
|
}
|
|
#endif
|
|
#if QT_VERSION >= 0x050400
|
|
else if (schema_ <= 3)
|
|
{
|
|
parent->setVersion (QDataStream::Qt_5_4);
|
|
}
|
|
#endif
|
|
quint32 type;
|
|
*parent >> type >> id_;
|
|
if (type >= maximum_message_type_)
|
|
{
|
|
throw std::runtime_error {"Unrecognized message type"};
|
|
}
|
|
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_);
|
|
}
|
|
}
|