2015-04-15 12:40:49 -04:00
|
|
|
#include "NetworkMessage.hpp"
|
|
|
|
|
|
|
|
#include <exception>
|
|
|
|
|
|
|
|
#include <QString>
|
|
|
|
#include <QByteArray>
|
|
|
|
|
|
|
|
#include "pimpl_impl.hpp"
|
|
|
|
|
|
|
|
namespace NetworkMessage
|
|
|
|
{
|
2015-10-21 14:56:29 -04:00
|
|
|
Builder::Builder (QIODevice * device, Type type, QString const& id, quint32 schema)
|
2015-04-15 12:40:49 -04:00
|
|
|
: QDataStream {device}
|
|
|
|
{
|
2015-10-21 14:56:29 -04:00
|
|
|
common_initialization (type, id, schema);
|
2015-04-15 12:40:49 -04:00
|
|
|
}
|
|
|
|
|
2015-10-21 14:56:29 -04:00
|
|
|
Builder::Builder (QByteArray * a, Type type, QString const& id, quint32 schema)
|
2015-04-15 12:40:49 -04:00
|
|
|
: QDataStream {a, QIODevice::WriteOnly}
|
|
|
|
{
|
2015-10-21 14:56:29 -04:00
|
|
|
common_initialization (type, id, schema);
|
2015-04-15 12:40:49 -04:00
|
|
|
}
|
|
|
|
|
2015-10-21 14:56:29 -04:00
|
|
|
void Builder::common_initialization (Type type, QString const& id, quint32 schema)
|
2015-04-15 12:40:49 -04:00
|
|
|
{
|
2015-10-21 14:56:29 -04:00
|
|
|
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
|
2015-04-15 12:40:49 -04:00
|
|
|
*this << magic;
|
2015-10-21 14:56:29 -04:00
|
|
|
*this << schema;
|
|
|
|
|
2015-04-15 12:40:49 -04:00
|
|
|
*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);
|
|
|
|
}
|
2015-10-21 14:56:29 -04:00
|
|
|
#if QT_VERSION >= 0x050200
|
2015-04-16 18:17:14 -04:00
|
|
|
else if (schema_ <= 2)
|
|
|
|
{
|
|
|
|
parent->setVersion (QDataStream::Qt_5_2);
|
|
|
|
}
|
2015-10-21 14:56:29 -04:00
|
|
|
#endif
|
|
|
|
#if QT_VERSION >= 0x050400
|
|
|
|
else if (schema_ <= 3)
|
|
|
|
{
|
|
|
|
parent->setVersion (QDataStream::Qt_5_4);
|
|
|
|
}
|
|
|
|
#endif
|
2015-04-15 12:40:49 -04:00
|
|
|
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_);
|
|
|
|
}
|
|
|
|
}
|