Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:21

0001 // Copyright (C) 2021 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 
0004 #ifndef QDATASTREAM_H
0005 #define QDATASTREAM_H
0006 
0007 #include <QtCore/qscopedpointer.h>
0008 #include <QtCore/qiodevicebase.h>
0009 #include <QtCore/qcontainerfwd.h>
0010 #include <QtCore/qnamespace.h>
0011 
0012 #include <iterator>         // std::distance(), std::next()
0013 
0014 #ifdef Status
0015 #error qdatastream.h must be included before any header file that defines Status
0016 #endif
0017 
0018 QT_BEGIN_NAMESPACE
0019 
0020 #if QT_CORE_REMOVED_SINCE(6, 3)
0021 class qfloat16;
0022 #endif
0023 class QByteArray;
0024 class QDataStream;
0025 class QIODevice;
0026 class QString;
0027 
0028 #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
0029 class QDataStreamPrivate;
0030 namespace QtPrivate {
0031 class StreamStateSaver;
0032 template <typename Container>
0033 QDataStream &readArrayBasedContainer(QDataStream &s, Container &c);
0034 template <typename Container>
0035 QDataStream &readListBasedContainer(QDataStream &s, Container &c);
0036 template <typename Container>
0037 QDataStream &readAssociativeContainer(QDataStream &s, Container &c);
0038 template <typename Container>
0039 QDataStream &writeSequentialContainer(QDataStream &s, const Container &c);
0040 template <typename Container>
0041 QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c);
0042 template <typename Container>
0043 QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c);
0044 }
0045 class Q_CORE_EXPORT QDataStream : public QIODeviceBase
0046 {
0047 public:
0048     enum Version {
0049         Qt_1_0 = 1,
0050         Qt_2_0 = 2,
0051         Qt_2_1 = 3,
0052         Qt_3_0 = 4,
0053         Qt_3_1 = 5,
0054         Qt_3_3 = 6,
0055         Qt_4_0 = 7,
0056         Qt_4_1 = Qt_4_0,
0057         Qt_4_2 = 8,
0058         Qt_4_3 = 9,
0059         Qt_4_4 = 10,
0060         Qt_4_5 = 11,
0061         Qt_4_6 = 12,
0062         Qt_4_7 = Qt_4_6,
0063         Qt_4_8 = Qt_4_7,
0064         Qt_4_9 = Qt_4_8,
0065         Qt_5_0 = 13,
0066         Qt_5_1 = 14,
0067         Qt_5_2 = 15,
0068         Qt_5_3 = Qt_5_2,
0069         Qt_5_4 = 16,
0070         Qt_5_5 = Qt_5_4,
0071         Qt_5_6 = 17,
0072         Qt_5_7 = Qt_5_6,
0073         Qt_5_8 = Qt_5_7,
0074         Qt_5_9 = Qt_5_8,
0075         Qt_5_10 = Qt_5_9,
0076         Qt_5_11 = Qt_5_10,
0077         Qt_5_12 = 18,
0078         Qt_5_13 = 19,
0079         Qt_5_14 = Qt_5_13,
0080         Qt_5_15 = Qt_5_14,
0081         Qt_6_0 = 20,
0082         Qt_6_1 = Qt_6_0,
0083         Qt_6_2 = Qt_6_0,
0084         Qt_6_3 = Qt_6_0,
0085         Qt_6_4 = Qt_6_0,
0086         Qt_6_5 = Qt_6_0,
0087         Qt_6_6 = 21,
0088         Qt_6_7 = 22,
0089         Qt_DefaultCompiledVersion = Qt_6_7
0090 #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
0091 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
0092 #endif
0093     };
0094 
0095     enum ByteOrder {
0096         BigEndian = QSysInfo::BigEndian,
0097         LittleEndian = QSysInfo::LittleEndian
0098     };
0099 
0100     enum Status {
0101         Ok,
0102         ReadPastEnd,
0103         ReadCorruptData,
0104         WriteFailed,
0105         SizeLimitExceeded,
0106     };
0107 
0108     enum FloatingPointPrecision {
0109         SinglePrecision,
0110         DoublePrecision
0111     };
0112 
0113     QDataStream();
0114     explicit QDataStream(QIODevice *);
0115     QDataStream(QByteArray *, OpenMode flags);
0116     QDataStream(const QByteArray &);
0117     ~QDataStream();
0118 
0119     QIODevice *device() const;
0120     void setDevice(QIODevice *);
0121 
0122     bool atEnd() const;
0123 
0124     Status status() const;
0125     void setStatus(Status status);
0126     void resetStatus();
0127 
0128     FloatingPointPrecision floatingPointPrecision() const;
0129     void setFloatingPointPrecision(FloatingPointPrecision precision);
0130 
0131     ByteOrder byteOrder() const;
0132     void setByteOrder(ByteOrder);
0133 
0134     int version() const;
0135     void setVersion(int);
0136 
0137     QDataStream &operator>>(char &i);
0138     QDataStream &operator>>(qint8 &i);
0139     QDataStream &operator>>(quint8 &i);
0140     QDataStream &operator>>(qint16 &i);
0141     QDataStream &operator>>(quint16 &i);
0142     QDataStream &operator>>(qint32 &i);
0143     inline QDataStream &operator>>(quint32 &i);
0144     QDataStream &operator>>(qint64 &i);
0145     QDataStream &operator>>(quint64 &i);
0146     QDataStream &operator>>(std::nullptr_t &ptr) { ptr = nullptr; return *this; }
0147 
0148     QDataStream &operator>>(bool &i);
0149 #if QT_CORE_REMOVED_SINCE(6, 3)
0150     QDataStream &operator>>(qfloat16 &f);
0151 #endif
0152     QDataStream &operator>>(float &f);
0153     QDataStream &operator>>(double &f);
0154     QDataStream &operator>>(char *&str);
0155     QDataStream &operator>>(char16_t &c);
0156     QDataStream &operator>>(char32_t &c);
0157 
0158     QDataStream &operator<<(char i);
0159     QDataStream &operator<<(qint8 i);
0160     QDataStream &operator<<(quint8 i);
0161     QDataStream &operator<<(qint16 i);
0162     QDataStream &operator<<(quint16 i);
0163     QDataStream &operator<<(qint32 i);
0164     inline QDataStream &operator<<(quint32 i);
0165     QDataStream &operator<<(qint64 i);
0166     QDataStream &operator<<(quint64 i);
0167     QDataStream &operator<<(std::nullptr_t) { return *this; }
0168     QDataStream &operator<<(bool i);
0169 #if QT_CORE_REMOVED_SINCE(6, 3)
0170     QDataStream &operator<<(qfloat16 f);
0171 #endif
0172     QDataStream &operator<<(float f);
0173     QDataStream &operator<<(double f);
0174     QDataStream &operator<<(const char *str);
0175     QDataStream &operator<<(char16_t c);
0176     QDataStream &operator<<(char32_t c);
0177     QDataStream &operator<<(const volatile void *) = delete;
0178 
0179 #if QT_DEPRECATED_SINCE(6, 11)
0180     QT_DEPRECATED_VERSION_X_6_11("Use an overload that takes qint64 length.")
0181     QDataStream &readBytes(char *&, uint &len);
0182 #endif
0183 #if QT_CORE_REMOVED_SINCE(6, 7)
0184     QDataStream &writeBytes(const char *, uint len);
0185     int skipRawData(int len);
0186     int readRawData(char *, int len);
0187     int writeRawData(const char *, int len);
0188 #endif
0189     QDataStream &readBytes(char *&, qint64 &len);
0190     qint64 readRawData(char *, qint64 len);
0191     QDataStream &writeBytes(const char *, qint64 len);
0192     qint64 writeRawData(const char *, qint64 len);
0193     qint64 skipRawData(qint64 len);
0194 
0195     void startTransaction();
0196     bool commitTransaction();
0197     void rollbackTransaction();
0198     void abortTransaction();
0199 
0200     bool isDeviceTransactionStarted() const;
0201 private:
0202     Q_DISABLE_COPY(QDataStream)
0203 
0204     QScopedPointer<QDataStreamPrivate> d;
0205 
0206     QIODevice *dev;
0207     bool owndev;
0208     bool noswap;
0209     ByteOrder byteorder;
0210     int ver;
0211     Status q_status;
0212 #if QT_CORE_REMOVED_SINCE(6, 7)
0213     int readBlock(char *data, int len);
0214 #endif
0215     qint64 readBlock(char *data, qint64 len);
0216     static inline qint64 readQSizeType(QDataStream &s);
0217     static inline bool writeQSizeType(QDataStream &s, qint64 value);
0218     static constexpr quint32 NullCode = 0xffffffffu;
0219     static constexpr quint32 ExtendedSize = 0xfffffffeu;
0220 
0221     friend class QtPrivate::StreamStateSaver;
0222     Q_CORE_EXPORT friend QDataStream &operator<<(QDataStream &out, const QString &str);
0223     Q_CORE_EXPORT friend QDataStream &operator>>(QDataStream &in, QString &str);
0224     Q_CORE_EXPORT friend QDataStream &operator<<(QDataStream &out, const QByteArray &ba);
0225     Q_CORE_EXPORT friend QDataStream &operator>>(QDataStream &in, QByteArray &ba);
0226     template <typename Container>
0227     friend QDataStream &QtPrivate::readArrayBasedContainer(QDataStream &s, Container &c);
0228     template <typename Container>
0229     friend QDataStream &QtPrivate::readListBasedContainer(QDataStream &s, Container &c);
0230     template <typename Container>
0231     friend QDataStream &QtPrivate::readAssociativeContainer(QDataStream &s, Container &c);
0232     template <typename Container>
0233     friend QDataStream &QtPrivate::writeSequentialContainer(QDataStream &s, const Container &c);
0234     template <typename Container>
0235     friend QDataStream &QtPrivate::writeAssociativeContainer(QDataStream &s, const Container &c);
0236     template <typename Container>
0237     friend QDataStream &QtPrivate::writeAssociativeMultiContainer(QDataStream &s,
0238                                                                   const Container &c);
0239 };
0240 
0241 namespace QtPrivate {
0242 
0243 class StreamStateSaver
0244 {
0245     Q_DISABLE_COPY_MOVE(StreamStateSaver)
0246 public:
0247     inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status())
0248     {
0249         if (!stream->isDeviceTransactionStarted())
0250             stream->resetStatus();
0251     }
0252     inline ~StreamStateSaver()
0253     {
0254         if (oldStatus != QDataStream::Ok) {
0255             stream->resetStatus();
0256             stream->setStatus(oldStatus);
0257         }
0258     }
0259 
0260 private:
0261     QDataStream *stream;
0262     QDataStream::Status oldStatus;
0263 };
0264 
0265 template <typename Container>
0266 QDataStream &readArrayBasedContainer(QDataStream &s, Container &c)
0267 {
0268     StreamStateSaver stateSaver(&s);
0269 
0270     c.clear();
0271     qint64 size = QDataStream::readQSizeType(s);
0272     qsizetype n = size;
0273     if (size != n || size < 0) {
0274         s.setStatus(QDataStream::SizeLimitExceeded);
0275         return s;
0276     }
0277     c.reserve(n);
0278     for (qsizetype i = 0; i < n; ++i) {
0279         typename Container::value_type t;
0280         s >> t;
0281         if (s.status() != QDataStream::Ok) {
0282             c.clear();
0283             break;
0284         }
0285         c.append(t);
0286     }
0287 
0288     return s;
0289 }
0290 
0291 template <typename Container>
0292 QDataStream &readListBasedContainer(QDataStream &s, Container &c)
0293 {
0294     StreamStateSaver stateSaver(&s);
0295 
0296     c.clear();
0297     qint64 size = QDataStream::readQSizeType(s);
0298     qsizetype n = size;
0299     if (size != n || size < 0) {
0300         s.setStatus(QDataStream::SizeLimitExceeded);
0301         return s;
0302     }
0303     for (qsizetype i = 0; i < n; ++i) {
0304         typename Container::value_type t;
0305         s >> t;
0306         if (s.status() != QDataStream::Ok) {
0307             c.clear();
0308             break;
0309         }
0310         c << t;
0311     }
0312 
0313     return s;
0314 }
0315 
0316 template <typename Container>
0317 QDataStream &readAssociativeContainer(QDataStream &s, Container &c)
0318 {
0319     StreamStateSaver stateSaver(&s);
0320 
0321     c.clear();
0322     qint64 size = QDataStream::readQSizeType(s);
0323     qsizetype n = size;
0324     if (size != n || size < 0) {
0325         s.setStatus(QDataStream::SizeLimitExceeded);
0326         return s;
0327     }
0328     for (qsizetype i = 0; i < n; ++i) {
0329         typename Container::key_type k;
0330         typename Container::mapped_type t;
0331         s >> k >> t;
0332         if (s.status() != QDataStream::Ok) {
0333             c.clear();
0334             break;
0335         }
0336         c.insert(k, t);
0337     }
0338 
0339     return s;
0340 }
0341 
0342 template <typename Container>
0343 QDataStream &writeSequentialContainer(QDataStream &s, const Container &c)
0344 {
0345     if (!QDataStream::writeQSizeType(s, c.size()))
0346         return s;
0347     for (const typename Container::value_type &t : c)
0348         s << t;
0349 
0350     return s;
0351 }
0352 
0353 template <typename Container>
0354 QDataStream &writeAssociativeContainer(QDataStream &s, const Container &c)
0355 {
0356     if (!QDataStream::writeQSizeType(s, c.size()))
0357         return s;
0358     auto it = c.constBegin();
0359     auto end = c.constEnd();
0360     while (it != end) {
0361         s << it.key() << it.value();
0362         ++it;
0363     }
0364 
0365     return s;
0366 }
0367 
0368 template <typename Container>
0369 QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c)
0370 {
0371     if (!QDataStream::writeQSizeType(s, c.size()))
0372         return s;
0373     auto it = c.constBegin();
0374     auto end = c.constEnd();
0375     while (it != end) {
0376         const auto rangeStart = it++;
0377         while (it != end && rangeStart.key() == it.key())
0378             ++it;
0379         const qint64 last = std::distance(rangeStart, it) - 1;
0380         for (qint64 i = last; i >= 0; --i) {
0381             auto next = std::next(rangeStart, i);
0382             s << next.key() << next.value();
0383         }
0384     }
0385 
0386     return s;
0387 }
0388 
0389 } // QtPrivate namespace
0390 
0391 template<typename ...T>
0392 using QDataStreamIfHasOStreamOperators =
0393     std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator<QDataStream, T>...>, QDataStream &>;
0394 template<typename Container, typename ...T>
0395 using QDataStreamIfHasOStreamOperatorsContainer =
0396     std::enable_if_t<std::conjunction_v<QTypeTraits::has_ostream_operator_container<QDataStream, Container, T>...>, QDataStream &>;
0397 
0398 template<typename ...T>
0399 using QDataStreamIfHasIStreamOperators =
0400     std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator<QDataStream, T>...>, QDataStream &>;
0401 template<typename Container, typename ...T>
0402 using QDataStreamIfHasIStreamOperatorsContainer =
0403     std::enable_if_t<std::conjunction_v<QTypeTraits::has_istream_operator_container<QDataStream, Container, T>...>, QDataStream &>;
0404 
0405 /*****************************************************************************
0406   QDataStream inline functions
0407  *****************************************************************************/
0408 
0409 inline QIODevice *QDataStream::device() const
0410 { return dev; }
0411 
0412 inline QDataStream::ByteOrder QDataStream::byteOrder() const
0413 { return byteorder; }
0414 
0415 inline int QDataStream::version() const
0416 { return ver; }
0417 
0418 inline void QDataStream::setVersion(int v)
0419 { ver = v; }
0420 
0421 qint64 QDataStream::readQSizeType(QDataStream &s)
0422 {
0423     quint32 first;
0424     s >> first;
0425     if (first == NullCode)
0426         return -1;
0427     if (first < ExtendedSize || s.version() < QDataStream::Qt_6_7)
0428         return qint64(first);
0429     qint64 extendedLen;
0430     s >> extendedLen;
0431     return extendedLen;
0432 }
0433 
0434 bool QDataStream::writeQSizeType(QDataStream &s, qint64 value)
0435 {
0436     if (value < qint64(ExtendedSize)) {
0437         s << quint32(value);
0438     } else if (s.version() >= QDataStream::Qt_6_7) {
0439         s << ExtendedSize << value;
0440     } else if (value == qint64(ExtendedSize)) {
0441         s << ExtendedSize;
0442     } else {
0443         s.setStatus(QDataStream::SizeLimitExceeded); // value is too big for old format
0444         return false;
0445     }
0446     return true;
0447 }
0448 
0449 inline QDataStream &QDataStream::operator>>(char &i)
0450 { return *this >> reinterpret_cast<qint8&>(i); }
0451 
0452 inline QDataStream &QDataStream::operator>>(quint8 &i)
0453 { return *this >> reinterpret_cast<qint8&>(i); }
0454 
0455 inline QDataStream &QDataStream::operator>>(quint16 &i)
0456 { return *this >> reinterpret_cast<qint16&>(i); }
0457 
0458 inline QDataStream &QDataStream::operator>>(quint32 &i)
0459 { return *this >> reinterpret_cast<qint32&>(i); }
0460 
0461 inline QDataStream &QDataStream::operator>>(quint64 &i)
0462 { return *this >> reinterpret_cast<qint64&>(i); }
0463 
0464 inline QDataStream &QDataStream::operator<<(char i)
0465 { return *this << qint8(i); }
0466 
0467 inline QDataStream &QDataStream::operator<<(quint8 i)
0468 { return *this << qint8(i); }
0469 
0470 inline QDataStream &QDataStream::operator<<(quint16 i)
0471 { return *this << qint16(i); }
0472 
0473 inline QDataStream &QDataStream::operator<<(quint32 i)
0474 { return *this << qint32(i); }
0475 
0476 inline QDataStream &QDataStream::operator<<(quint64 i)
0477 { return *this << qint64(i); }
0478 
0479 template <typename Enum>
0480 inline QDataStream &operator<<(QDataStream &s, QFlags<Enum> e)
0481 { return s << typename QFlags<Enum>::Int(e); }
0482 
0483 template <typename Enum>
0484 inline QDataStream &operator>>(QDataStream &s, QFlags<Enum> &e)
0485 {
0486     typename QFlags<Enum>::Int i;
0487     s >> i;
0488     e = QFlag(i);
0489     return s;
0490 }
0491 
0492 template <typename T>
0493 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
0494 operator<<(QDataStream &s, const T &t)
0495 { return s << static_cast<typename std::underlying_type<T>::type>(t); }
0496 
0497 template <typename T>
0498 typename std::enable_if_t<std::is_enum<T>::value, QDataStream &>
0499 operator>>(QDataStream &s, T &t)
0500 { return s >> reinterpret_cast<typename std::underlying_type<T>::type &>(t); }
0501 
0502 #ifndef Q_QDOC
0503 
0504 template<typename T>
0505 inline QDataStreamIfHasIStreamOperatorsContainer<QList<T>, T> operator>>(QDataStream &s, QList<T> &v)
0506 {
0507     return QtPrivate::readArrayBasedContainer(s, v);
0508 }
0509 
0510 template<typename T>
0511 inline QDataStreamIfHasOStreamOperatorsContainer<QList<T>, T> operator<<(QDataStream &s, const QList<T> &v)
0512 {
0513     return QtPrivate::writeSequentialContainer(s, v);
0514 }
0515 
0516 template <typename T>
0517 inline QDataStreamIfHasIStreamOperatorsContainer<QSet<T>, T> operator>>(QDataStream &s, QSet<T> &set)
0518 {
0519     return QtPrivate::readListBasedContainer(s, set);
0520 }
0521 
0522 template <typename T>
0523 inline QDataStreamIfHasOStreamOperatorsContainer<QSet<T>, T> operator<<(QDataStream &s, const QSet<T> &set)
0524 {
0525     return QtPrivate::writeSequentialContainer(s, set);
0526 }
0527 
0528 template <class Key, class T>
0529 inline QDataStreamIfHasIStreamOperatorsContainer<QHash<Key, T>, Key, T> operator>>(QDataStream &s, QHash<Key, T> &hash)
0530 {
0531     return QtPrivate::readAssociativeContainer(s, hash);
0532 }
0533 
0534 template <class Key, class T>
0535 
0536 inline QDataStreamIfHasOStreamOperatorsContainer<QHash<Key, T>, Key, T> operator<<(QDataStream &s, const QHash<Key, T> &hash)
0537 {
0538     return QtPrivate::writeAssociativeContainer(s, hash);
0539 }
0540 
0541 template <class Key, class T>
0542 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator>>(QDataStream &s, QMultiHash<Key, T> &hash)
0543 {
0544     return QtPrivate::readAssociativeContainer(s, hash);
0545 }
0546 
0547 template <class Key, class T>
0548 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiHash<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiHash<Key, T> &hash)
0549 {
0550     return QtPrivate::writeAssociativeMultiContainer(s, hash);
0551 }
0552 
0553 template <class Key, class T>
0554 inline QDataStreamIfHasIStreamOperatorsContainer<QMap<Key, T>, Key, T> operator>>(QDataStream &s, QMap<Key, T> &map)
0555 {
0556     return QtPrivate::readAssociativeContainer(s, map);
0557 }
0558 
0559 template <class Key, class T>
0560 inline QDataStreamIfHasOStreamOperatorsContainer<QMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMap<Key, T> &map)
0561 {
0562     return QtPrivate::writeAssociativeContainer(s, map);
0563 }
0564 
0565 template <class Key, class T>
0566 inline QDataStreamIfHasIStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator>>(QDataStream &s, QMultiMap<Key, T> &map)
0567 {
0568     return QtPrivate::readAssociativeContainer(s, map);
0569 }
0570 
0571 template <class Key, class T>
0572 inline QDataStreamIfHasOStreamOperatorsContainer<QMultiMap<Key, T>, Key, T> operator<<(QDataStream &s, const QMultiMap<Key, T> &map)
0573 {
0574     return QtPrivate::writeAssociativeMultiContainer(s, map);
0575 }
0576 
0577 template <class T1, class T2>
0578 inline QDataStreamIfHasIStreamOperators<T1, T2> operator>>(QDataStream& s, std::pair<T1, T2> &p)
0579 {
0580     s >> p.first >> p.second;
0581     return s;
0582 }
0583 
0584 template <class T1, class T2>
0585 inline QDataStreamIfHasOStreamOperators<T1, T2> operator<<(QDataStream& s, const std::pair<T1, T2> &p)
0586 {
0587     s << p.first << p.second;
0588     return s;
0589 }
0590 
0591 #else
0592 
0593 template <class T>
0594 QDataStream &operator>>(QDataStream &s, QList<T> &l);
0595 
0596 template <class T>
0597 QDataStream &operator<<(QDataStream &s, const QList<T> &l);
0598 
0599 template <class T>
0600 QDataStream &operator>>(QDataStream &s, QSet<T> &set);
0601 
0602 template <class T>
0603 QDataStream &operator<<(QDataStream &s, const QSet<T> &set);
0604 
0605 template <class Key, class T>
0606 QDataStream &operator>>(QDataStream &s, QHash<Key, T> &hash);
0607 
0608 template <class Key, class T>
0609 QDataStream &operator<<(QDataStream &s, const QHash<Key, T> &hash);
0610 
0611 template <class Key, class T>
0612 QDataStream &operator>>(QDataStream &s, QMultiHash<Key, T> &hash);
0613 
0614 template <class Key, class T>
0615 QDataStream &operator<<(QDataStream &s, const QMultiHash<Key, T> &hash);
0616 
0617 template <class Key, class T>
0618 QDataStream &operator>>(QDataStream &s, QMap<Key, T> &map);
0619 
0620 template <class Key, class T>
0621 QDataStream &operator<<(QDataStream &s, const QMap<Key, T> &map);
0622 
0623 template <class Key, class T>
0624 QDataStream &operator>>(QDataStream &s, QMultiMap<Key, T> &map);
0625 
0626 template <class Key, class T>
0627 QDataStream &operator<<(QDataStream &s, const QMultiMap<Key, T> &map);
0628 
0629 template <class T1, class T2>
0630 QDataStream &operator>>(QDataStream& s, std::pair<T1, T2> &p);
0631 
0632 template <class T1, class T2>
0633 QDataStream &operator<<(QDataStream& s, const std::pair<T1, T2> &p);
0634 
0635 #endif // Q_QDOC
0636 
0637 inline QDataStream &operator>>(QDataStream &s, QKeyCombination &combination)
0638 {
0639     int combined;
0640     s >> combined;
0641     combination = QKeyCombination::fromCombined(combined);
0642     return s;
0643 }
0644 
0645 inline QDataStream &operator<<(QDataStream &s, QKeyCombination combination)
0646 {
0647     return s << combination.toCombined();
0648 }
0649 
0650 #endif // QT_NO_DATASTREAM
0651 
0652 QT_END_NAMESPACE
0653 
0654 #endif // QDATASTREAM_H