Results 1 to 15 of 15

Thread: [ SOLVED (kinda) ]copy structure to QByteArray

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2008
    Posts
    107
    Thanks
    36
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Question Re: [ SOLVED (kinda) ]copy structure to QByteArray

    Well ... that almost worked ... except for QByteArray ...

    Given the following struct:

    Qt Code:
    1. //! \brief SERIAL PACKET FORMAT (Physical Layer - RS232)
    2.  
    3. typedef struct {
    4. quint8 DLE; // ASCII DLE character (16 decimal)
    5. quint8 packet_id; // packet ID
    6. // types:
    7. // 6 - ACK
    8. // 10 - Command
    9. // 14 - Date/Time Data
    10. // 21 - NAK
    11. // 38 - Unit ID/ESN
    12. // 51 - PVT (Position, Velocity, Time) Data
    13. // 135 - Legacy Stop message
    14. // 136 - Legacy text message
    15. // 161 - Fleet Management packet
    16. quint8 size_app_payload; // number of bytes of packet data (bytes 3 to n-4)
    17. QByteArray app_payload; // 0 to 255 bytes
    18. quint8 checksum; // 2's complement of the sum of all bytes from byte 1 to byte n-4 (end of the payload)
    19. quint8 DLE_end; // same as DLE
    20. quint8 ETX; // End of text - ASCII ETX character (3 decimal)
    21.  
    22. //! \note helper functions
    23. QByteArray serialize()
    24. {
    25. QByteArray byteArray;
    26.  
    27. QDataStream stream(&byteArray, QIODevice::WriteOnly);
    28.  
    29. stream << DLE
    30. << packet_id
    31. << size_app_payload
    32. << app_payload
    33. << checksum
    34. << DLE_end
    35. << ETX;
    36. return byteArray;
    37. }
    38.  
    39. void deserialize(const QByteArray& byteArray)
    40. {
    41. QDataStream stream(byteArray);
    42.  
    43. stream >> DLE
    44. >> packet_id
    45. >> size_app_payload
    46. >> app_payload
    47. >> checksum
    48. >> DLE_end
    49. >> ETX;
    50. }
    51. } serial_packet_format;
    To copy to clipboard, switch view to plain text mode 

    and the following code:

    Qt Code:
    1. serial_packet_format *sPacket = new serial_packet_format; // send fleet management packet wrapped in a serial packet format...
    2. sPacket->DLE=16;
    3. sPacket->packet_id= FLEET_MANAGEMENT; // fleet management packet
    4. // fill rest
    5. sPacket->size_app_payload=driver_id_receipt.size();
    6. sPacket->app_payload = QByteArray::QByteArray ( driver_id_receipt );
    7. // calculate 2's complement checksum
    8. sPacket->checksum = CalculateChecksum(driver_id_receipt.data(), driver_id_receipt.size() );
    9. sPacket->DLE_end=16;
    10. sPacket->ETX=3;
    11.  
    12. QByteArray serial_packet( sPacket->serialize() );
    To copy to clipboard, switch view to plain text mode 

    what happens is that upon
    Qt Code:
    1. stream << size_app_payload
    To copy to clipboard, switch view to plain text mode 

    a DWORD containing the QByteArray size is prepended to the original QByteArray...

    In other words:

    Upon execution of the above code here's what's inside sPacket:

    SERIAL PACKET CONTENTS (size=20):
    10
    FFFFFFA1
    0A

    00
    00
    00
    0A --> the 4 bytes in bold shouldn't be here!

    08
    12
    00
    00
    00
    01
    01
    00
    00
    00
    FFFFFFE4
    10
    03

    Please advise as this is the last thing to overcome my long standing problem...

    BR,
    Pedro Doria Meunier

  2. #2
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [ SOLVED (kinda) ]copy structure to QByteArray

    QDataStream is a class for serializing objects. But it can append its own info about serializing object. So don't expect it would be byte to byte what you want. It is made in such way that when you write something to QDataStream (with operator <<) and then you can read it from it on the other end (with operator >>) then you get the same. But who cares what is in the middle :] A little example : let's say you have a QString str("Hello"); then you write it to QDataStream object. In this stream the QDataStream can do whateveer it wants it can even append " World!" to your string :] but when you read string fron QDataStream it returns what you wrote: QString("Hello"). So if you want to have a QByteArray containing only your own data then put every byte of your data separately. For example, if you have an 32-bit integer you can do:
    Qt Code:
    1. int num = 158;
    2. for (int i = 0; i < 4; ++i) {
    3. ba += quint8((num >> i*8) & 0x000000ff);
    4. }
    To copy to clipboard, switch view to plain text mode 
    and now you have every byte of your int written to byte array. Then you have to construct one int from 4 bytes from byte array on the other side.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  3. #3
    Join Date
    Jan 2008
    Posts
    107
    Thanks
    36
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: [ SOLVED (kinda) ]copy structure to QByteArray

    Regarding the last post...
    (involving qdatastream << qbytearray )

    From Qt Assistant, "Format of the QDataStream Operators"

    QByteArray
    If the byte array is null: 0xFFFFFFFF (quint32)
    Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes


    So, from what I see, QDataStream doesn't do whatever "comes to its mind".
    It's simply doing what it's told...

    What I need to do is simply eliminate the use of QByteArray from the structure or find a fast, elegant, way to chop those array size bytes ...

    BR,
    Pedro Doria Meunier

  4. #4
    Join Date
    Oct 2009
    Posts
    8
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: [ SOLVED (kinda) ]copy structure to QByteArray

    Ok. By the looks of things you're sending this data to hardware for processing. I didn't realise that.

    In this case you could use a struct as you were planning to. It's quite common practice. You will probably have to tell the compiler not to pad out the struct, but I see in another thread you are already aware of that. If you are only targeting a single platform/compiler and don't have endianness worries, then you could do it this way. All you need to do is reinterpret_cast the struct into an unsigned char* (or whatever type your send function takes). eg:

    Qt Code:
    1. #pragma pack(push, 1)
    2. struct MyStruct
    3. {
    4. unsigned char c;
    5. unsigned int i;
    6. };
    7. #pragma pack(pop)
    8.  
    9. void send(unsigned char* buf, size_t length)
    10. {
    11. // send buf
    12. }
    13.  
    14. int main()
    15. {
    16. MyStruct myObj;
    17. myObj.c = 'A';
    18. myObj.i = 1;
    19.  
    20. send(reinterpret_cast<unsigned char*>(&myObj), sizeof(myObj));
    21.  
    22. return 0;
    23. }
    To copy to clipboard, switch view to plain text mode 

    My personal preference is to write portable code. So I would only do it this way if performance absolutely demanded it. Instead I would probably detect the endianness of the host at runtime, construct an unsigned char array of the correct size, reinterpret_cast the array at the appropriate offsets to copy in the appropriate values - applying endian conversions if necessary. But to each their own.

    Edit: I notice Qt provides qFromBigEndian to handle all the endian conversion stuff.
    Last edited by jord; 16th October 2009 at 14:27.

  5. The following user says thank you to jord for this useful post:

    pdoria (16th October 2009)

Similar Threads

  1. Replies: 1
    Last Post: 27th November 2014, 09:11
  2. How to copy sellected ellipse area from image
    By adamsakli in forum Newbie
    Replies: 2
    Last Post: 24th September 2009, 22:11
  3. How to copy selected ellipse area from image
    By adamsakli in forum Qt Programming
    Replies: 5
    Last Post: 24th September 2009, 19:54
  4. QByteArray problem
    By Misenko in forum Qt Programming
    Replies: 17
    Last Post: 4th October 2008, 21:53
  5. Replies: 1
    Last Post: 1st March 2006, 11:43

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.