QVariant десериализация дает недопустимое значение - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть следующий класс, который я хочу сериализовать и десериализовать:

#include <QObject>
#include <QDataStream>
#include <QVariant>

/**
 * @brief   The type used to store the \ref CComPacket::Cmd enum
 */
using CmdType = quint8;

/**
 * @brief   A smart container for the TCP packets
 */
class CComPacket : public QObject
{
    Q_OBJECT

public:

    /**
     * @brief   Provides the command information for the packet (tells how
     *          the data is supposed to be parsed).
     */
    enum class Cmd: CmdType
    {
        Invalid,
        ReadName,
        GiveName,
    };

    explicit CComPacket(QObject *parent = nullptr);

    /**
     * @brief   The ostream (<<) overloading
     * @param   out: The data stream to which the \p cpp class is going to
     *          be serialized.
     * @param   ccp: the class to be serialized into the \p out.
     * @return  reference to \p out.
     */
    friend QDataStream& operator<<(QDataStream& out, const CComPacket& ccp)
    {
        out << static_cast<CmdType>(ccp.m_cmd) << ccp.m_data;
        return out;
    }

    /**
     * @brief   The istream (>>) overloading
     * @param   in: The serialized data that will be deserialized to the \p cpp
     * @param   ccp: deserialized data goes here.
     * @return  The \p in reference.
     */
    friend QDataStream& operator>>(QDataStream& in, CComPacket& ccp)
    {
        CmdType tmp;
        in >> tmp >> ccp.m_data;
        ccp.m_cmd = static_cast<Cmd>(tmp);

        return in;
    }

    /**
     * @brief   The parsing command
     */
    Cmd m_cmd = Cmd::Invalid;

    /**
     * @brief   The data to be parsed
     */
    QVariant m_data;

};

Я пытаюсь проверить это с помощью этого кода:

CComPacket tmp;
tmp.m_cmd = CComPacket::Cmd::GiveName;
tmp.m_data = 5.112233;

QDataStream str;
str << tmp;

CComPacket tmp2;
str >> tmp2;

При отладке я вижу, что m_cmd член tmp2 десериализован правильно, но объект m_data все еще недействителен. Из документации я понимаю, что QVariant поддерживает сериализацию по умолчанию. Что мне здесь не хватает?

1 Ответ

0 голосов
/ 20 февраля 2020

Чтобы сделать эту работу, я должен был включить QByteArray, который должен был использоваться в качестве параметра для QDataStream, поскольку физический контейнер уже был необходим. Я планировал сериализовать данные в байты в любом случае на более позднем этапе, так что это просто все упростило. Я добавил следующие функции-члены:

QByteArray serialize();
static CComPacket deserialize(QByteArray& ba);

QByteArray CComPacket::serialize()
{
    QByteArray ba;
    QDataStream ds(&ba, QIODevice::WriteOnly);

    ds << *this;
    return ba;
}

CComPacket CComPacket::deserialize(QByteArray& ba)
{
    QDataStream ds(&ba, QIODevice::ReadOnly);
    CComPacket cp;

    ds >> cp;
    return cp;
}

И этот тестовый код теперь работает правильно (tmp совпадает с tmp2):

CComPacket tmp;
tmp.m_cmd = CComPacket::Cmd::GiveName;
tmp.m_data = 5.112233;

QByteArray ba = tmp.serialize();
CComPacket tmp2 = CComPacket::deserialize(ba);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...