Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:26:25

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