Results 1 to 9 of 9

Thread: Serialization custom type

  1. #1
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Serialization custom type

    Hello,
    I'm trying write to binary file my custom type, so I have:

    Qt Code:
    1. typedef enum t_timeloopsStatus
    2. {
    3. NOTHING = 0,
    4. UPDATED,
    5. } t_timeloopsStatus;
    6.  
    7. typedef struct t_timeloops
    8. {
    9. QString key;
    10. t_timeloopsStatus status;
    11. } t_timeloops;
    12.  
    13. QMap<QString, t_timeloops> _timeLoops;
    To copy to clipboard, switch view to plain text mode 
    I know, that I have to overload << and >> operators
    Qt Code:
    1. QDataStream &operator<<(QDataStream &out, const QMap<QString, t_timeloops> &timeloops);
    2. QDataStream &operator>>(QDataStream &in, QMap<QString, t_timeloops> &timeloops);
    To copy to clipboard, switch view to plain text mode 
    but I have no idea how will looks function for that.

    I found an original function for QMap and tried to rewrite it, but without success.
    Qt Code:
    1. QDataStream &operator<<(QDataStream &out, const QMap<QString, t_timeloops> &timeloops)
    2. {
    3. out << quint32(timeloops.size());
    4. typename QMap<QString, t_timeloops>::ConstIterator it = timeloops.end();
    5. typename QMap<QString, t_timeloops>::ConstIterator begin = timeloops.begin();
    6. while (it != begin) {
    7. --it;
    8. out << it.key() << it.value();
    9. }
    10. return out;
    11. }
    12.  
    13. QDataStream &operator>>(QDataStream &in, QMap<QString, t_timeloops> &timeloops)
    14. {
    15. QDataStream::Status oldStatus = in.status();
    16. in.resetStatus();
    17. timeloops.clear();
    18.  
    19. quint32 n;
    20. in >> n;
    21.  
    22. timeloops.detach();
    23. for (quint32 i = 0; i < n; ++i) {
    24. if (in.status() != QDataStream::Ok)
    25. break;
    26.  
    27. QString key;
    28. t_timeloops value;
    29. in >> key >> value.key >> value.pad >> value.cylinder >> value.status;
    30. timeloops.insertMulti(key, value);
    31. }
    32. if (in.status() != QDataStream::Ok)
    33. timeloops.clear();
    34. if (oldStatus != QDataStream::Ok)
    35. in.setStatus(oldStatus);
    36. return in;
    37. }
    To copy to clipboard, switch view to plain text mode 

    Thanks for any help!
    Last edited by ado130; 3rd February 2017 at 19:11.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    The reason this doesn't work is because you are not writing the same thing you are trying to read in. For each map entry, you write out two things, namely the QMap's key and value, but then on input you try to read 5 things for each entry and only the first one (key) corresponds to something you have written out. I have no idea where you think value.pad and value.cylinder are going to come from - they aren't even members of your struct.

    You are probably going to have to write operator >> and << for your t_timeloops struct unless Qt is able to create one on its own. You probably don't need to write these operators for QMap<>; these already exist in Qt and do the right thing. However, the QMap operators need to know how to write out the values in the map, and for that you need to supply the operators for t_timeloops.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    Thanks for reply. Yeah, sorry the structure is not whole, just a part of it, there's missing a few QString and one enum.
    So as you said, I need operators just for t_timeloops? Can you show me any pseudocode?

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    It is no different in principle from what you wrote for QMap; you need to replace the calling arguments with "& t_timeloops", and then replace the guts of the routine with code to write or read each element in your struct. Operators already exist for QString, so you don't need to reimplement those, and you can static_cast your enums to int or vice versa on write or read, respectively.

    Once you have that, then you can simply serialize your QMap using the built-in QMap operators for QDataStream:

    Related Non-Members

    QDataStream &operator<<(QDataStream &out, const QMap<Key, T> &map)

    Writes the map map to stream out.
    This function requires the key and value types to implement operator<<().
    See also Format of the QDataStream operators.

    QDataStream &operator>>(QDataStream &in, QMap<Key, T> &map)

    Reads a map from stream in into map.
    This function requires the key and value types to implement operator>>().
    See also Format of the QDataStream operators.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    I had to slightly change the structure:
    Qt Code:
    1. typedef enum t_timeloopsStatus
    2. {
    3. NOTHING = 0,
    4. UPDATED,
    5. UPLOADED,
    6. CHANGED
    7. } t_timeloopsStatus;
    8.  
    9. typedef enum t_timeloopsTime
    10. {
    11. KEY = 0,
    12. PAD
    13. } t_timeloopsTime;
    14.  
    15. typedef struct t_keyParam
    16. {
    17. QString keyTime;
    18. QString padTime;
    19. QString cylinderTime;
    20. t_timeloopsStatus status;
    21. t_timeloopsTime select;
    22. } t_keyParam;
    23.  
    24. typedef struct t_timeloops
    25. {
    26. QMap<QString, t_keyParam> key;
    27. } t_timeloops;
    28.  
    29. QMap<QString, t_timeloops> _timeLoops;
    To copy to clipboard, switch view to plain text mode 

    Or maybe, do you have some idea how to save data? My situation is:
    Qt Code:
    1. Pad#1 - Key#1- key (qstring)
    2. - pad (qstring)
    3. - selected (enum)
    4. ...
    5. - Key#2- key (qstring)
    6. - pad (qstring)
    7. - selected (enum)
    8. ...
    9. ...
    10. Pad#2 - Key#2- key (qstring)
    11. - pad (qstring)
    12. - selected (enum)
    13. ...
    14. - Key#3- key (qstring)
    15. - pad (qstring)
    16. - selected (enum)
    17. ...
    18. ...
    19. ...
    To copy to clipboard, switch view to plain text mode 

    And back to the main probolem. Probably it's not good solution at all, but:
    Qt Code:
    1. QDataStream &operator<<(QDataStream &out, const t_keyParam &keyParam);
    2. QDataStream &operator<<(QDataStream &out, const t_timeloops &timeLoops);
    3. QDataStream &operator>>(QDataStream &in, const t_keyParam &keyParam);
    4. QDataStream &operator>>(QDataStream &in, const t_timeloops &timeLoops);
    5.  
    6. QDataStream &operator<<(QDataStream &out, const t_keyParam &keyParam)
    7. {
    8. out << static_cast<quint8>(keyParam.select) << static_cast<quint8>(keyParam.status);
    9. return out;
    10. }
    11.  
    12. QDataStream &operator<<(QDataStream &out, const t_timeloops &timeLoops)
    13. {
    14. out << timeLoops.key;
    15. return out;
    16. }
    17.  
    18.  
    19. QDataStream &operator>>(QDataStream &in, const t_keyParam &keyParam)
    20. {
    21. in >> static_cast<quint8>(keyParam.select) >> static_cast<quint8>(keyParam.status);
    22. return in;
    23. }
    24.  
    25.  
    26. QDataStream &operator>>(QDataStream &in, const t_timeloops &timeLoops)
    27. {
    28. in >> timeLoops.key;
    29. return in;
    30. }
    To copy to clipboard, switch view to plain text mode 

    So I'm trying write a function just for my typedef and enum.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    Or maybe, do you have some idea how to save data? My situation is:
    I have no idea what you are trying to accomplish. Maybe if you described (in words) the user problem you are trying to solve with "pads", "keys" and so forth, it will make more sense.

    If you have a custom class or struct that you wish to serialize using the QDataStream operators, your operator methods have to serialize -all- of the members of that class or struct if you want to be able read in and restore exactly what you have written. You don't just serialize one member unless you can somehow create the values of the other members from that one member's value.

    I don't understand why you are defining a t_timeloops struct that contains another QMap as a member. If that's all it is, typedef it:

    Qt Code:
    1. typedef QMap< QString, t_keyParam > t_timeloops;
    To copy to clipboard, switch view to plain text mode 

    You still end up with a QMap< QString, QMap< QString, t_keyParam > > as your top-level data container without the extra class as a nuisance, if that is indeed what you want.

    You do not need to write any other QDataStream operators -except- the pair for t_keyParam, and you need to read / write -all- the members of that struct. The QMap operators will take care of the jigher levels for you.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    Ok thanks, so this could be a final struct
    Qt Code:
    1. typedef enum t_timeloopsStatus
    2. {
    3. NOTHING = 0,
    4. UPDATED,
    5. UPLOADED,
    6. CHANGED
    7. } t_timeloopsStatus;
    8.  
    9. typedef enum t_timeloopsTime
    10. {
    11. KEY = 0,
    12. PAD
    13. } t_timeloopsTime;
    14.  
    15. typedef struct t_timeloops
    16. {
    17. QString keyTime;
    18. QString padTime;
    19. QString cylinderTime;
    20. t_timeloopsStatus status;
    21. t_timeloopsTime select;
    22. } t_timeloops;
    23.  
    24. QMap<QString, QMap<QString, t_timeloops>> _timeLoops;
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. QDataStream &operator<<(QDataStream &out, const t_timeloops &timeLoops)
    2. {
    3. out << static_cast<QString>(timeLoops.keyTime) << static_cast<QString>(timeLoops.padTime) << static_cast<QString>(timeLoops.cylinderTime) << static_cast<quint16>(timeLoops.select) << static_cast<quint16>(timeLoops.status);
    4. return out;
    5. }
    6.  
    7.  
    8. QDataStream &operator>>(QDataStream &in, const t_timeloops &timeLoops)
    9. {
    10. in >> static_cast<QString>(timeLoops.keyTime) >> static_cast<QString>(timeLoops.padTime) >> static_cast<QString>(timeLoops.cylinderTime) >> (quint16&)timeLoops.select >> (quint16&)timeLoops.status;
    11. return in;
    12. }
    To copy to clipboard, switch view to plain text mode 
    It seems that the writing works, but still problem with reading and enums.

    Thanks again!, it's really helpful.
    Last edited by ado130; 6th February 2017 at 20:46.

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    The static_cast< QString > is completely unnecessary. QDataStream knows how to serialize QString types, just write out << timeloops.keyTime, etc.

    Enums are no different from int or unsigned int as far as serialization goes. Your methods should look like this (note the removal of "const" from operator>> - you can't write to a const variable):

    Qt Code:
    1. QDataStream & operator<<(QDataStream & out, const t_timeloops & timeLoops)
    2. {
    3. out << timeLoops.keyTime << timeLoops.padTime << timeLoops.cylinderTime << static_cast<quint16>(timeLoops.select) << static_cast<quint16>(timeLoops.status);
    4. return out;
    5. }
    6.  
    7. QDataStream & operator>>(QDataStream & in, t_timeloops & timeLoops)
    8. {
    9. in >> timeLoops.keyTime >> timeLoops.padTime >> timeLoops.cylinderTime;
    10. quint16 inVal;
    11. in >> inVal;
    12. timeLoops.select = static_cast< t_timeloopsTime >( inVal );
    13. in >> inVal;
    14. timeLoops.status = static_cast< t_timeloopsStatus >( inVal );
    15. return in;
    16. }
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. The following user says thank you to d_stranz for this useful post:

    ado130 (7th February 2017)

  10. #9
    Join Date
    Jan 2017
    Posts
    58
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Serialization custom type

    Thanks a lot d_tranz, you're great, it was really helpful.

Similar Threads

  1. Custom Type Sending
    By iprion in forum Qt Programming
    Replies: 1
    Last Post: 21st June 2013, 12:19
  2. QVariant with Custom Type
    By kasmanit in forum Qt Programming
    Replies: 4
    Last Post: 2nd September 2012, 18:02
  3. QSettings custom class serialization problem
    By sakya in forum Qt Programming
    Replies: 1
    Last Post: 19th December 2011, 12:00
  4. QTreeView with custom type
    By jajdoo in forum Newbie
    Replies: 1
    Last Post: 25th September 2011, 21:27
  5. QVariant custom type.
    By hickscorp in forum Qt Programming
    Replies: 0
    Last Post: 3rd May 2010, 15:23

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.