IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Discussion :

QDataStream et ordre des octets

  1. #1
    Membre actif Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Points : 230
    Points
    230
    Par défaut QDataStream et ordre des octets
    Bonjour,

    Je ne trouve pas de solution au problème suivant, posé par mon chef.

    Voici le contexte.

    Ce que j'ai : une structure de données (typedef struct) contenant des uint8, des uint32, des char *, des int16 provenant d'une bibliothèque en C.

    Ce que je veux : sérialiser une instance de cette structure en format Little Endian OU Big Endian, dans un fichier binaire avec 1) la taille requise de l'instance toujours en BigEndian 2) suivie de la valeur en LittleEndian ou BigEndian.

    Actuellement j'y arrive presque via
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    dataStream.setDevice(m_binFile);
    dataStream.setByteOrder(QDataStream::BigEndian /* ou LittleEndian*/);
     
    /* length */
    dataStream << quint32(7);
     
    /* data (example for digital data without char * data) */
    dataStream << qint16( QString(readBytesList.value(0)).toInt()) 
               << quint32(QString(readBytesList.value(1)).toUInt())
               << quint8( QString(readBytesList.value(2)).toUInt());
    Le problème est le suivant :
    La fonction setByteOrder() change tous les octets, or je voudrais toujours avoir le champs "taille" en BigEndian.

    Comment faire ?

    Merci pour les pistes que vous pourriez m'apporter !

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Peut être tester pour forcer l'écriture (avec flush ? ça existe ?) après la taille et changer ensuite l'endian
    Mais je crois pas que QDataStream soit fait pour ça

    Sinon, le plus simple est probablement d'inverser les bits de la taille lorsque tu es en littleendian, ce qui reviendra à l'écrire en bigendian... mais j'ai du mal à comprendre l'intérêt d'une telle modification d'endian pendant la lecture/écriture

    Une petite fonction pour inverser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #ifdef OPENMS_BIG_ENDIAN
    template <typename T>
    T ByteReverse(const T in)
    {
      T out;
      const char * pin = (const char *) &in;
      char * pout = (char *) (&out + 1) - 1;
     
      int i;
      for (i = sizeof(T); i > 0; --i)
      {
        *pout-- = *pin++;
      }
      return out;
    }
     
    #endif

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 951
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 951
    Points : 5 671
    Points
    5 671
    Par défaut
    Joa,

    Je trouve bizarre d'envisager un mélange de big et little endian dans le même fichier, bonjour le mélange pour s'y retrouver.

    À dire vrai, c'est même carrément une très mauvaise idée.

  4. #4
    Membre actif Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Points : 230
    Points
    230
    Par défaut
    Bonjour,

    J'ai trouvé ma réponse en fouillant les fonctions proposées par Qt.

    Voici la solution de mon problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <QCoreApplication>
    #include <QDataStream>
    #include <QDebug>
    #include <QFile>
    #include <QtEndian>
     
    int main(int argc, char *argv[])
    {
        QCoreApplication application(argc, argv);
     
        /* Create binary output file */
        QFile * binFile = new QFile("D:/workspace/output.bin");
     
        if (!binFile->open(QIODevice::WriteOnly))
            return EXIT_FAILURE;
     
        QDataStream dataStream(binFile);
     
        /* switch according to target */
        dataStream.setByteOrder(QDataStream::LittleEndian);
        //dataStream.setByteOrder(QDataStream::BigEndian);
     
        /* an example with simple data */
     
        int length = 7; // = 1 (for uint8) + 2 (for uint16) + 4 (for uint32) 
     
        /* Item length */
        QByteArray lLengthBytesArray;
        lLengthBytesArray.resize(4);
        qToBigEndian(quint32(length), (uchar*) lLengthBytesArray.data());
        dataStream.writeRawData(lLengthBytesArray, 4);
     
        /* data */
        dataStream << quint8(5)
                   << qint16(23)
                   << qint32(4830);
     
        if (binFile) {
            binFile->close();
            delete binFile;
            binFile = 0;
        }
     
        //return application.exec();
        return EXIT_SUCCESS;
    }
    En switchant l'ordre des octets via dataStream.setByteOrder(xxxx), j'obtiens (en lisant avec l'éditeur de texte hexa WinHex) :

    00 00 00 07 (length) 05 17 00 DE 12 00 00 en Little Endian (format Windows)

    00 00 00 07 (length) 05 00 17 00 00 12 DE en Big Endian (format d'un machine cible type unix)

    Je vous remercie pour les réponses qui m'ont permis d'avoir des pistes à explorer.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Modifier l'ordre des Fields d'un dataset
    Par teska dans le forum Bases de données
    Réponses: 3
    Dernier message: 22/03/2004, 17h38
  2. Modifier l'ordre des cartes son
    Par YéTeeh dans le forum Matériel
    Réponses: 3
    Dernier message: 19/08/2003, 02h13
  3. Ordre des champs dans une table
    Par patapetz dans le forum Outils
    Réponses: 5
    Dernier message: 30/07/2003, 07h53
  4. Question : ordre des bits ?
    Par Choupi dans le forum C
    Réponses: 3
    Dernier message: 11/02/2003, 07h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo