Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-07 09:21:49

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