Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to encode/decode and write and read binary data?
Forum Updated to NodeBB v4.3 + New Features

How to encode/decode and write and read binary data?

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 1.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Curtwagner1984
    wrote on 18 Apr 2018, 16:53 last edited by
    #1

    Hello!

    I'm writing a server and part of the messages I receive are headers. The Header is constructed in the following way:

    • First byte: binary operation code (Size 1 Byte)

    • Bytes 1-3: Header Checksum:(Size 2 Bytes)

    • Bytes 4-8 Payload index (Size 4 Bytes)

    • Bytes 9 - 10 Payload Checksum (Size 2 Bytes)

    Altogether 9 Bytes.

    I want to use binary encoding for things such as the operation code and the payload index rather than ASCII encoding because 1-byte ASCII encoding would give me at most 0-9 (10 options), while one byte in binary will give me 00000000 - 11111111 (256 options)

    However, I'm unsure how to parse this information on the receiving end. I've looked at QBuffer and QDataStream which seems to be most suitable for the task. But couldn't figure out exactly how to perform the task I need.

    For example, when I get a new message from a client that is stored in a QTcpesocket's buffer, I read the first 9 bytes.

    QByteArray ba;
     
    ba.append(this->socket->read(this->HEADER_SIZE)) ; //HEADER_SIZE = 9
    
    

    So now I have my whole header in the ba ByteArray. Now I want to separate it into chunks and parse them individually. I thought of doing something like this:

    
        QBuffer buffer(&receivedHeaderByteArray);
        buffer.open(QIODevice::ReadOnly);
    
        QByteArray opCodeByteArray = buffer.read(1);
    
        QByteArray headerCheckSumByteArray = buffer.read(2);
    
        QByteArray payloadIndex = buffer.read(4) ;
    
        QByteArray payloadChecksum = buffer.read(2);
    
    

    Presumably, now I have my header info separated into chunks but how do I convert the bytes in opCodeByteArray from a binary representation into an int?

    Would something like this be correct:

    QByteArray opCodeByteArray = buffer.read(1);
    QBuffer buffer(&opCodeByteArray );
    buffer.open(QIODevice::ReadOnly);
    qint8 opCodeInt;
    in >> opCodeInt;
    

    Also, How would I encode an int into a binary value? For example, if I want to write '7'it would be '111' in binary. But sending '111' in ASCII would take 3 Bytes while encoded to binary it will be only one byte '00000111'

    V 1 Reply Last reply 18 Apr 2018, 17:21
    0
    • C Curtwagner1984
      18 Apr 2018, 16:53

      Hello!

      I'm writing a server and part of the messages I receive are headers. The Header is constructed in the following way:

      • First byte: binary operation code (Size 1 Byte)

      • Bytes 1-3: Header Checksum:(Size 2 Bytes)

      • Bytes 4-8 Payload index (Size 4 Bytes)

      • Bytes 9 - 10 Payload Checksum (Size 2 Bytes)

      Altogether 9 Bytes.

      I want to use binary encoding for things such as the operation code and the payload index rather than ASCII encoding because 1-byte ASCII encoding would give me at most 0-9 (10 options), while one byte in binary will give me 00000000 - 11111111 (256 options)

      However, I'm unsure how to parse this information on the receiving end. I've looked at QBuffer and QDataStream which seems to be most suitable for the task. But couldn't figure out exactly how to perform the task I need.

      For example, when I get a new message from a client that is stored in a QTcpesocket's buffer, I read the first 9 bytes.

      QByteArray ba;
       
      ba.append(this->socket->read(this->HEADER_SIZE)) ; //HEADER_SIZE = 9
      
      

      So now I have my whole header in the ba ByteArray. Now I want to separate it into chunks and parse them individually. I thought of doing something like this:

      
          QBuffer buffer(&receivedHeaderByteArray);
          buffer.open(QIODevice::ReadOnly);
      
          QByteArray opCodeByteArray = buffer.read(1);
      
          QByteArray headerCheckSumByteArray = buffer.read(2);
      
          QByteArray payloadIndex = buffer.read(4) ;
      
          QByteArray payloadChecksum = buffer.read(2);
      
      

      Presumably, now I have my header info separated into chunks but how do I convert the bytes in opCodeByteArray from a binary representation into an int?

      Would something like this be correct:

      QByteArray opCodeByteArray = buffer.read(1);
      QBuffer buffer(&opCodeByteArray );
      buffer.open(QIODevice::ReadOnly);
      qint8 opCodeInt;
      in >> opCodeInt;
      

      Also, How would I encode an int into a binary value? For example, if I want to write '7'it would be '111' in binary. But sending '111' in ASCII would take 3 Bytes while encoded to binary it will be only one byte '00000111'

      V Offline
      V Offline
      VRonin
      wrote on 18 Apr 2018, 17:21 last edited by VRonin
      #2

      Edit

      Bytes 1-3 [...] Size 2 Bytes

      does not hold mathematically but nevermind

      @Curtwagner1984 said in How to encode/decode and write and read binary data?:

      Now I want to separate it into chunks and parse them individually

      First byte: ba.front();
      Bytes 1-3: ba.mid(1,2);
      Bytes 4-8: ba.mid(4,4);
      Bytes 9 - 10: ba.mid(9,2);

      How would I encode an int into a binary value? For example, if I want to write '7'

      QDataStream baStream(&ba,QIODevice::WriteOnly);
      baStream << static_cast<quint8>(7);
      

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      C 1 Reply Last reply 18 Apr 2018, 17:44
      6
      • V VRonin
        18 Apr 2018, 17:21

        Edit

        Bytes 1-3 [...] Size 2 Bytes

        does not hold mathematically but nevermind

        @Curtwagner1984 said in How to encode/decode and write and read binary data?:

        Now I want to separate it into chunks and parse them individually

        First byte: ba.front();
        Bytes 1-3: ba.mid(1,2);
        Bytes 4-8: ba.mid(4,4);
        Bytes 9 - 10: ba.mid(9,2);

        How would I encode an int into a binary value? For example, if I want to write '7'

        QDataStream baStream(&ba,QIODevice::WriteOnly);
        baStream << static_cast<quint8>(7);
        
        C Offline
        C Offline
        Curtwagner1984
        wrote on 18 Apr 2018, 17:44 last edited by
        #3

        @VRonin said in How to encode/decode and write and read binary data?:

        First byte: ba.front();
        Bytes 1-3: ba.mid(1,2);
        Bytes 4-8: ba.mid(4,4);
        Bytes 9 - 10: ba.mid(9,2);

        Thanks! What did you mean 'does not hold mathematically?'
        And converting this to ints would be done like this:?

        QByteArray opCode = ba.front();
        QDataStream baStream(&opCode,QIODevice::ReadOnly);
        qint8 opCodeInt;
        baStream >> opCodeInt;
        
        V 1 Reply Last reply 18 Apr 2018, 17:50
        0
        • C Curtwagner1984
          18 Apr 2018, 17:44

          @VRonin said in How to encode/decode and write and read binary data?:

          First byte: ba.front();
          Bytes 1-3: ba.mid(1,2);
          Bytes 4-8: ba.mid(4,4);
          Bytes 9 - 10: ba.mid(9,2);

          Thanks! What did you mean 'does not hold mathematically?'
          And converting this to ints would be done like this:?

          QByteArray opCode = ba.front();
          QDataStream baStream(&opCode,QIODevice::ReadOnly);
          qint8 opCodeInt;
          baStream >> opCodeInt;
          
          V Offline
          V Offline
          VRonin
          wrote on 18 Apr 2018, 17:50 last edited by
          #4

          @Curtwagner1984 said in How to encode/decode and write and read binary data?:

          What did you mean 'does not hold mathematically?'

          Bytes 1-3 is 3 Bytes (1,2 and 3), not 2

          And converting this to ints

          please be very careful with terminology here. Qt requires int to be 4 bytes in size, with that comes the problem of endianness.
          If you just mean the numeric value in each byte you can just iterate over the internal buffer using .cbegin()/cend() or by using ba.data()[i]

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          C 1 Reply Last reply 18 Apr 2018, 18:05
          1
          • V VRonin
            18 Apr 2018, 17:50

            @Curtwagner1984 said in How to encode/decode and write and read binary data?:

            What did you mean 'does not hold mathematically?'

            Bytes 1-3 is 3 Bytes (1,2 and 3), not 2

            And converting this to ints

            please be very careful with terminology here. Qt requires int to be 4 bytes in size, with that comes the problem of endianness.
            If you just mean the numeric value in each byte you can just iterate over the internal buffer using .cbegin()/cend() or by using ba.data()[i]

            C Offline
            C Offline
            Curtwagner1984
            wrote on 18 Apr 2018, 18:05 last edited by
            #5

            @VRonin said in How to encode/decode and write and read binary data?:

            @Curtwagner1984 said in How to encode/decode and write and read binary data?:

            What did you mean 'does not hold mathematically?'

            Bytes 1-3 is 3 Bytes (1,2 and 3), not 2

            Oh, my bad...
            I thought you meant the whole concept doesn't hold mathematically...

            And converting this to ints

            please be very careful with terminology here. Qt requires int to be 4 bytes in size, with that comes the problem of endianness.

            Could you please elaborate on this? Isn't this what qint8 and qint16 are for?

            1 Reply Last reply
            0
            • V Offline
              V Offline
              VRonin
              wrote on 18 Apr 2018, 18:19 last edited by VRonin
              #6

              Take the "Header Checksum" for example they are already stored as qint8 numerals inside QByteArray, if you want to convert those 2 bytes in a 4 bytes int then it becomes a problem. If you just want to access the values you can use constData().operator[]

              const QByteArray checksum= ba.mid(1,2);
              qDebug() << "First Byte in decimal" << static_cast<qint16>(checksum.constData()[0]); //the cast is necessary otherwise qDebug() will try to print an ascii value
              qDebug() << "Full Values in hexadecimal" << checksum.toHex();
              

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              2

              1/6

              18 Apr 2018, 16:53

              • Login

              • Login or register to search.
              1 out of 6
              • First post
                1/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved