2017-08-15 3 views
1

J'ai des données provenant de tcp socket en tant que données brutes (j'ai un format spécifié), puis je crée un objet basé sur ces données. Le format est comme suit: 24 octets d'en-tête [taille des données et quelques autres informations], puis la quantité de données spécifiée dans l'en-tête. Je voudrais juste le lire comme un objet (l'objet a un tampon pour les données à l'intérieur avec la taille dynamique où les données sont mises). Est-il possible d'outrepasser QDataStream ou de le faire d'une autre manière pour l'emballer élégamment? Je voudrais profiter des méthodes de transactions pour lire des paquets entiers de données et ne pas prendre soin de les assembler si elles viennent en morceaux (demi-en-tête, ou tout simplement pas la quantité complète de données).Désérialisation des données brutes à l'aide de QDataStream

Donc, fondamentalement, je voudrais faire qqch comme ceci:

Event event;   // my custom class 
QDataStream dataStream(tcpSocket); 

dataStream >> event; 
dataStream.commit(); 

Répondre

0

Je suis crois qu'il est le cas pour la surcharge de l'opérateur. J'ai fait un petit exemple démonstratif:

class Test 
{ 
public: 
    int i; 
    float f; 
    double d; 

    char empty[4]; 
    int ii[3]; 

    QString s; 

public: 
    friend QDataStream& operator>>(QDataStream& in, Test& test); 
    friend QDataStream& operator<<(QDataStream& out, const Test& test); 
}; 

QDataStream& operator>>(QDataStream& in, Test& test) 
{ 
    in >> test.i; 

    in.setFloatingPointPrecision(QDataStream::SinglePrecision); 
    in >> test.f; 

    in.setFloatingPointPrecision(QDataStream::DoublePrecision); 
    in >> test.d; 

    in.skipRawData(sizeof test.empty); 
    in.readRawData(reinterpret_cast<char*>(test.ii), sizeof test.ii); 

    in >> test.s; 

    return in; 
} 

QDataStream& operator<<(QDataStream& out, const Test& test) 
{ 
    out << test.i; 

    out.setFloatingPointPrecision(QDataStream::SinglePrecision); 
    out << test.f; 

    out.setFloatingPointPrecision(QDataStream::DoublePrecision); 
    out << test.d; 

    out.writeRawData(reinterpret_cast<const char*>(test.empty), sizeof test.empty); 
    out.writeRawData(reinterpret_cast<const char*>(test.ii), sizeof test.ii); 
    out << test.s; 

    return out; 
} 

Ensuite, vous pouvez faire:

outputStream 
     << test1 
     << test2 
     << test3; 

// ... 

inputStream.startTransaction(); 
inputStream 
     >> test11 
     >> test22 
     >> test33; 
inputStream.commitTransaction(); 

ces opérateurs sont prédéfinis pour les conteneurs fondamentaux Qt (QVector, QList, QSet etc.)