Search code examples
qtserializationdeserializationcbor

CBOR serialization and deserialization on different platforms


I write a client-server application where the server is a Linux machine, and the client is a Windows machine. I serialize data using CBOR before sending them over a network.

I serialized data on the server and obtained "\x83\x01\x00\xf4". However, when trying to deserialize it on Windows, I get ASSERT: "recursed->type == CborInvalidType" in file C:\Users\qt\qtbase\src\3rdparty\tinycbor\src\cborparser.c, line 633 error. When I tested it in a Linux-to-Linux setup, it worked fine.

Here is a very simple application that demonstrates the error (runs or Linux, crashes on Windows):

#include <QCoreApplication>
#include <QCborStreamReader>
#include <QCborStreamWriter>

enum PacketType
{
    packet,
    sharedVar,
    sigcom
};

enum TypeName
{
    whatever
};

// this is how I serialize data on Linux
QByteArray serializeBOOL(bool t, TypeName typeName)
{
    QByteArray arr;
    QCborStreamWriter writer(&arr);

    writer.startArray(3);
    writer.append(PacketType::sharedVar);
    writer.append(typeName);
    writer.append(t);
    writer.endArray();

    return arr;
}

PacketType getPacketType(const QByteArray &arr)
{
    QCborStreamReader reader(arr);

    reader.enterContainer();
    PacketType type = static_cast<PacketType>(reader.toInteger());
    reader.leaveContainer();

    return type;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QByteArray arr = serializeBOOL(false, whatever);

    getPacketType(arr);

    return a.exec();
}

I thought CBOR could be used across platforms similarly to JSON. Is that not the case?


Solution

  • The problem was that you could not leave the container if you were not at the end.

    The solution was adding 3x reader.next() into PacketType getPacketType(const QByteArray &arr). Another option would be not to leave a container.

    PacketType getPacketType(const QByteArray &arr)
    {
        QCborStreamReader reader(arr);
    
        reader.enterContainer();
        PacketType type = static_cast<PacketType>(reader.toInteger());
        reader.next();
        reader.next();
        reader.next();
        reader.leaveContainer();
    
        return type;
    }