/* Copyright (C) 2014 * swift project community / contributors * * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, * including this file, may be copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE file. */ #ifndef BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H #define BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H #include "fs9.h" #include #include #include #include #include //! \file namespace BlackSimPlugin { namespace Fs9 { namespace Private { // Inhibit doxygen warnings about missing documentation //! \cond PRIVATE // overload the following two for types that need special treatment template QByteArray readValue(const QByteArray &data, Value &val) { static_assert(std::is_arithmetic::value || std::is_same::value, "Unsupported type"); val = *reinterpret_cast(data.constData()); return data.mid(sizeof(Value)); } template QByteArray writeValue(QByteArray data, const Value &value) { static_assert(std::is_arithmetic::value || std::is_same::value, "Unsupported type"); data.append(reinterpret_cast(&value), sizeof(Value)); return data; } QByteArray readValue(const QByteArray &data, QString &val); QByteArray writeValue(QByteArray data, const QString &value); template< typename MessageTuple, quint32 Size = std::tuple_size::value > struct Serializer; template< typename MsgTuple > struct Serializer { static const QByteArray &read(const QByteArray &data, MsgTuple &) { return data; } static QByteArray write(QByteArray &data, const MsgTuple &) { return data; } }; template< typename MessageTuple, quint32 Size > struct Serializer { static QByteArray read(const QByteArray &data, MessageTuple &messageTuple) { return readValue(Serializer < MessageTuple, Size - 1 >::read(data, messageTuple), std::get < Size - 1 > (messageTuple)); } static QByteArray write(QByteArray &data, const MessageTuple &messageTuple) { return writeValue(Serializer < MessageTuple, Size - 1 >::write(data, messageTuple), std::get < Size - 1 > (messageTuple)); } }; template< class MessageTuple > inline QByteArray doReadMessage(const QByteArray &data, MessageTuple messageTuple) { return Serializer::read(data, messageTuple); } template< class MessageTuple > inline QByteArray doWriteMessage(QByteArray &data, const MessageTuple &messageTuple) { return Serializer::write(data, messageTuple); } //! \endcond } // namespace Private //! FS9 multiplayer protocol packet parser class MultiPlayerPacketParser { public: //! Read message from byte stream template< class Message > static QByteArray readMessage(const QByteArray &data, Message &message) { return Private::doReadMessage(data.mid(2 * sizeof(qint32)), message.getTuple()); } //! Write message to byte stream template< class Message > static QByteArray writeMessage(QByteArray &data, const Message &message) { return Private::doWriteMessage(data, message.getTuple()); } //! Read the multiplayer packet type static CFs9Sdk::MULTIPLAYER_PACKET_ID readType(const QByteArray &data) { QByteArray type = data.left(sizeof(CFs9Sdk::MULTIPLAYER_PACKET_ID)); const quint32 *val = reinterpret_cast(type.constData()); return static_cast(*val); } //! Read the multiplayer packet size static qint32 readSize(const QByteArray &data) { return *reinterpret_cast(data.mid(sizeof(qint32), sizeof(qint32)).constData()); } //! Write the multiplayer packet type static void writeType(QByteArray &data, CFs9Sdk::MULTIPLAYER_PACKET_ID type) { data.append(reinterpret_cast(&type), sizeof(CFs9Sdk::MULTIPLAYER_PACKET_ID)); } //! Write the multiplayer packet size static void writeSize(QByteArray &data, qint32 size) { data.append(reinterpret_cast(&size), sizeof(qint32)); } }; } } #endif //BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H