[Qt-interest] How to deal with pointers for a QDataStream?

Oliver Heins heins at sopos.org
Tue Apr 20 22:24:55 CEST 2010


Hi André,

thank you again for your help.

Andre Somers <andre at familiesomers.nl> writes:

> On 20-4-2010 12:14, Oliver Heins wrote:
>
>> This is how I go: I write my MagicNumber and the highest unique id to
>> the file.  Then I traverse my QLinkedList<Token*>, writing the tokens:
>>
>>      while (i.hasNext())
>>          out<<  *(i.next());
>>
>> On reading, MagicNumber and the max id are set properly.  Then I try to
>> read the data into a QVector<Token>  tokenVec:
>>
>>      in>>  tokenVec;
>>    
> Huh? You are writing the data away with a loop, but expect to be able
> to read them back in one go into a QVector? That seems a bit
> optimistic... QVector itself has a structure, as documentented in the
> page "Format of the QDataStream Operators" in the documentation. It
> first writes out a 32 bits unsigned integer with the number of
> elements, and then the elements themselves. If you don't have that
> number of elements writen out, how do you expect QVector to be able to
> properly stream in the data?

I thought it would be something like: »read as much Token as possible
from stream and put them in the vector«.  Obviously, that was a wrong
assumption :)

> Is token.unique actually a quint32? You stream it out as one, but I
> can not see if is streamed in properly based on this code. 

No, it is an ordinary int, and it seems to cause problems.  (I thought
there would be an implicit cast from quint32 to int, but I seem to be
wrong again.)  Unfortunately, I can't get it work, even if I do an
explicit cast.  Here's what class Token now looks like and how the
operators are defined:

class Token
{
public:
    enum Type { Space, Paragraph, Kern, Char, Format, Note, End };
    enum SubType { Null = 0,
                   Bold, Italic,
                   Header1, Header2, Header3, Header4, Header5, Header6,
                   Itemize, Enumerate, Description, Item,
                   Note1, Note2, Note3, Note4, Note5 };

    [...]

    Type type;
    SubType subType;
    QChar chr;
    int unique;

    Token *parent;
    Token *partner;

    [...]
};

QDataStream &operator<<(QDataStream &out, const Token &token)
{
    quint32 partner = token.partner ? token.partner->unique : 0;
    quint32 parent = token.parent ? token.parent->unique : 0;

    out << qint16(token.type) << qint16(token.subType) << token.chr
            << quint32(token.unique) << parent << partner;
    return out;
}

QDataStream &operator>>(QDataStream &in, Token &token)
{
    quint32 partner, parent, unique;
    qint16 type, subType;

    token.parent = 0; // to be handled later
    token.partner = 0;
    in >> type >> subType >> token.chr >> unique >> parent >> partner;
    token.type = static_cast<Token::Type>(type);
    token.subType = static_cast<Token::SubType>(subType);
    token.unique = static_cast<int>(unique);

    return in;
}

> And what is token.chr exactly?

A QChar.

> By the way: don't forget to handle the version of your QDataStream
> properly! It changes between Qt releases. If you leave it implicit,
> you may end up not being able to read back your old files with a new
> release of your software... See QDataStream::setVersion.

Yes, I already do that.

Thanks again, 
 olli



More information about the Qt-interest-old mailing list