/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdatastream.h"
#include "qdatastream_p.h"

#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
#include "qbuffer.h"
#include "qfloat16.h"
#include "qstring.h"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "qendian.h"

QT_BEGIN_NAMESPACE

/*!
    \class QDataStream
    \inmodule QtCore
    \reentrant
    \brief The QDataStream class provides serialization of binary data
    to a QIODevice.

    \ingroup io


    A data stream is a binary stream of encoded information which is
    100% independent of the host computer's operating system, CPU or
    byte order. For example, a data stream that is written by a PC
    under Windows can be read by a Sun SPARC running Solaris.

    You can also use a data stream to read/write \l{raw}{raw
    unencoded binary data}. If you want a "parsing" input stream, see
    QTextStream.

    The QDataStream class implements the serialization of C++'s basic
    data types, like \c char, \c short, \c int, \c{char *}, etc.
    Serialization of more complex data is accomplished by breaking up
    the data into primitive units.

    A data stream cooperates closely with a QIODevice. A QIODevice
    represents an input/output medium one can read data from and write
    data to. The QFile class is an example of an I/O device.

    Example (write binary data to a stream):

    \snippet code/src_corelib_io_qdatastream.cpp 0

    Example (read binary data from a stream):

    \snippet code/src_corelib_io_qdatastream.cpp 1

    Each item written to the stream is written in a predefined binary
    format that varies depending on the item's type. Supported Qt
    types include QBrush, QColor, QDateTime, QFont, QPixmap, QString,
    QVariant and many others. For the complete list of all Qt types
    supporting data streaming see \l{Serializing Qt Data Types}.

    For integers it is best to always cast to a Qt integer type for
    writing, and to read back into the same Qt integer type. This
    ensures that you get integers of the size you want and insulates
    you from compiler and platform differences.

    Enumerations can be serialized through QDataStream without the
    need of manually defining streaming operators. Enum classes are
    serialized using the declared size.

    To take one example, a \c{char *} string is written as a 32-bit
    integer equal to the length of the string including the '\\0' byte,
    followed by all the characters of the string including the
    '\\0' byte. When reading a \c{char *} string, 4 bytes are read to
    create the 32-bit length value, then that many characters for the
    \c {char *} string including the '\\0' terminator are read.

    The initial I/O device is usually set in the constructor, but can be
    changed with setDevice(). If you've reached the end of the data
    (or if there is no I/O device set) atEnd() will return true.

    \section1 Versioning

    QDataStream's binary format has evolved since Qt 1.0, and is
    likely to continue evolving to reflect changes done in Qt. When
    inputting or outputting complex types, it's very important to
    make sure that the same version of the stream (version()) is used
    for reading and writing. If you need both forward and backward
    compatibility, you can hardcode the version number in the
    application:

    \snippet code/src_corelib_io_qdatastream.cpp 2

    If you are producing a new binary data format, such as a file
    format for documents created by your application, you could use a
    QDataStream to write the data in a portable format. Typically, you
    would write a brief header containing a magic string and a version
    number to give yourself room for future expansion. For example:

    \snippet code/src_corelib_io_qdatastream.cpp 3

    Then read it in with:

    \snippet code/src_corelib_io_qdatastream.cpp 4

    You can select which byte order to use when serializing data. The
    default setting is big endian (MSB first). Changing it to little
    endian breaks the portability (unless the reader also changes to
    little endian). We recommend keeping this setting unless you have
    special requirements.

    \target raw
    \section1 Reading and Writing Raw Binary Data

    You may wish to read/write your own raw binary data to/from the
    data stream directly. Data may be read from the stream into a
    preallocated \c{char *} using readRawData(). Similarly data can be
    written to the stream using writeRawData(). Note that any
    encoding/decoding of the data must be done by you.

    A similar pair of functions is readBytes() and writeBytes(). These
    differ from their \e raw counterparts as follows: readBytes()
    reads a quint32 which is taken to be the length of the data to be
    read, then that number of bytes is read into the preallocated
    \c{char *}; writeBytes() writes a quint32 containing the length of the
    data, followed by the data. Note that any encoding/decoding of
    the data (apart from the length quint32) must be done by you.

    \section1 Reading and Writing Qt Collection Classes

    The Qt container classes can also be serialized to a QDataStream.
    These include QList, QLinkedList, QVector, QSet, QHash, and QMap.
    The stream operators are declared as non-members of the classes.

    \target Serializing Qt Classes
    \section1 Reading and Writing Other Qt Classes

    In addition to the overloaded stream operators documented here,
    any Qt classes that you might want to serialize to a QDataStream
    will have appropriate stream operators declared as non-member of
    the class:

    \snippet code/src_corelib_serialization_qdatastream.cpp 0

    For example, here are the stream operators declared as non-members
    of the QImage class:

    \snippet code/src_corelib_serialization_qdatastream.cpp 1

    To see if your favorite Qt class has similar stream operators
    defined, check the \b {Related Non-Members} section of the
    class's documentation page.

    \section1 Using Read Transactions

    When a data stream operates on an asynchronous device, the chunks of data
    can arrive at arbitrary points in time. The QDataStream class implements
    a transaction mechanism that provides the ability to read the data
    atomically with a series of stream operators. As an example, you can
    handle incomplete reads from a socket by using a transaction in a slot
    connected to the readyRead() signal:

    \snippet code/src_corelib_io_qdatastream.cpp 6

    If no full packet is received, this code restores the stream to the
    initial position, after which you need to wait for more data to arrive.

    \sa QTextStream, QVariant
*/

/*!
    \enum QDataStream::ByteOrder

    The byte order used for reading/writing the data.

    \value BigEndian Most significant byte first (the default)
    \value LittleEndian Least significant byte first
*/

/*!
  \enum QDataStream::FloatingPointPrecision

  The precision of floating point numbers used for reading/writing the data. This will only have
  an effect if the version of the data stream is Qt_4_6 or higher.

  \warning The floating point precision must be set to the same value on the object that writes
  and the object that reads the data stream.

  \value SinglePrecision All floating point numbers in the data stream have 32-bit precision.
  \value DoublePrecision All floating point numbers in the data stream have 64-bit precision.

  \sa setFloatingPointPrecision(), floatingPointPrecision()
*/

/*!
    \enum QDataStream::Status

    This enum describes the current status of the data stream.

    \value Ok               The data stream is operating normally.
    \value ReadPastEnd      The data stream has read past the end of the
                            data in the underlying device.
    \value ReadCorruptData  The data stream has read corrupt data.
    \value WriteFailed      The data stream cannot write to the underlying device.
*/

/*****************************************************************************
  QDataStream member functions
 *****************************************************************************/

#define Q_VOID

#undef  CHECK_STREAM_PRECOND
#ifndef QT_NO_DEBUG
#define CHECK_STREAM_PRECOND(retVal) \
    if (!dev) { \
        qWarning("QDataStream: No device"); \
        return retVal; \
    }
#else
#define CHECK_STREAM_PRECOND(retVal) \
    if (!dev) { \
        return retVal; \
    }
#endif

#define CHECK_STREAM_WRITE_PRECOND(retVal) \
    CHECK_STREAM_PRECOND(retVal) \
    if (q_status != Ok) \
        return retVal;

#define CHECK_STREAM_TRANSACTION_PRECOND(retVal) \
    if (!d || d->transactionDepth == 0) { \
        qWarning("QDataStream: No transaction in progress"); \
        return retVal; \
    }

/*!
    Constructs a data stream that has no I/O device.

    \sa setDevice()
*/

QDataStream::QDataStream()
{
    dev = nullptr;
    owndev = false;
    byteorder = BigEndian;
    ver = Qt_DefaultCompiledVersion;
    noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
    q_status = Ok;
}

/*!
    Constructs a data stream that uses the I/O device \a d.

    \sa setDevice(), device()
*/

QDataStream::QDataStream(QIODevice *d)
{
    dev = d;                                // set device
    owndev = false;
    byteorder = BigEndian;                        // default byte order
    ver = Qt_DefaultCompiledVersion;
    noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
    q_status = Ok;
}

/*!
    \fn QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode mode)

    Constructs a data stream that operates on a byte array, \a a. The
    \a mode describes how the device is to be used.

    Alternatively, you can use QDataStream(const QByteArray &) if you
    just want to read from a byte array.

    Since QByteArray is not a QIODevice subclass, internally a QBuffer
    is created to wrap the byte array.
*/

QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode flags)
{
    QBuffer *buf = new QBuffer(a);
#ifndef QT_NO_QOBJECT
    buf->blockSignals(true);
#endif
    buf->open(flags);
    dev = buf;
    owndev = true;
    byteorder = BigEndian;
    ver = Qt_DefaultCompiledVersion;
    noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
    q_status = Ok;
}

/*!
    Constructs a read-only data stream that operates on byte array \a a.
    Use QDataStream(QByteArray*, int) if you want to write to a byte
    array.

    Since QByteArray is not a QIODevice subclass, internally a QBuffer
    is created to wrap the byte array.
*/
QDataStream::QDataStream(const QByteArray &a)
{
    QBuffer *buf = new QBuffer;
#ifndef QT_NO_QOBJECT
    buf->blockSignals(true);
#endif
    buf->setData(a);
    buf->open(QIODevice::ReadOnly);
    dev = buf;
    owndev = true;
    byteorder = BigEndian;
    ver = Qt_DefaultCompiledVersion;
    noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
    q_status = Ok;
}

/*!
    Destroys the data stream.

    The destructor will not affect the current I/O device, unless it is
    an internal I/O device (e.g. a QBuffer) processing a QByteArray
    passed in the \e constructor, in which case the internal I/O device
    is destroyed.
*/

QDataStream::~QDataStream()
{
    if (owndev)
        delete dev;
}


/*!
    \fn QIODevice *QDataStream::device() const

    Returns the I/O device currently set, or \nullptr if no
    device is currently set.

    \sa setDevice()
*/

/*!
    void QDataStream::setDevice(QIODevice *d)

    Sets the I/O device to \a d, which can be \nullptr
    to unset to current I/O device.

    \sa device()
*/

void QDataStream::setDevice(QIODevice *d)
{
    if (owndev) {
        delete dev;
        owndev = false;
    }
    dev = d;
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete
    Unsets the I/O device.
    Use setDevice(nullptr) instead.
*/

void QDataStream::unsetDevice()
{
    setDevice(nullptr);
}
#endif

/*!
    \fn bool QDataStream::atEnd() const

    Returns \c true if the I/O device has reached the end position (end of
    the stream or file) or if there is no I/O device set; otherwise
    returns \c false.

    \sa QIODevice::atEnd()
*/

bool QDataStream::atEnd() const
{
    return dev ? dev->atEnd() : true;
}

/*!
    Returns the floating point precision of the data stream.

    \since 4.6

    \sa FloatingPointPrecision, setFloatingPointPrecision()
*/
QDataStream::FloatingPointPrecision QDataStream::floatingPointPrecision() const
{
    return d ? d->floatingPointPrecision : QDataStream::DoublePrecision;
}

/*!
    Sets the floating point precision of the data stream to \a precision. If the floating point precision is
    DoublePrecision and the version of the data stream is Qt_4_6 or higher, all floating point
    numbers will be written and read with 64-bit precision. If the floating point precision is
    SinglePrecision and the version is Qt_4_6 or higher, all floating point numbers will be written
    and read with 32-bit precision.

    For versions prior to Qt_4_6, the precision of floating point numbers in the data stream depends
    on the stream operator called.

    The default is DoublePrecision.

    Note that this property does not affect the serialization or deserialization of \c qfloat16
    instances.

    \warning This property must be set to the same value on the object that writes and the object
    that reads the data stream.

    \since 4.6
*/
void QDataStream::setFloatingPointPrecision(QDataStream::FloatingPointPrecision precision)
{
    if (!d)
        d.reset(new QDataStreamPrivate());
    d->floatingPointPrecision = precision;
}

/*!
    Returns the status of the data stream.

    \sa Status, setStatus(), resetStatus()
*/

QDataStream::Status QDataStream::status() const
{
    return q_status;
}

/*!
    Resets the status of the data stream.

    \sa Status, status(), setStatus()
*/
void QDataStream::resetStatus()
{
    q_status = Ok;
}

/*!
    Sets the status of the data stream to the \a status given.

    Subsequent calls to setStatus() are ignored until resetStatus()
    is called.

    \sa Status, status(), resetStatus()
*/
void QDataStream::setStatus(Status status)
{
    if (q_status == Ok)
        q_status = status;
}

/*!
    \fn int QDataStream::byteOrder() const

    Returns the current byte order setting -- either BigEndian or
    LittleEndian.

    \sa setByteOrder()
*/

/*!
    Sets the serialization byte order to \a bo.

    The \a bo parameter can be QDataStream::BigEndian or
    QDataStream::LittleEndian.

    The default setting is big endian. We recommend leaving this
    setting unless you have special requirements.

    \sa byteOrder()
*/

void QDataStream::setByteOrder(ByteOrder bo)
{
    byteorder = bo;
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
        noswap = (byteorder == BigEndian);
    else
        noswap = (byteorder == LittleEndian);
}


/*!
    \enum QDataStream::Version

    This enum provides symbolic synonyms for the data serialization
    format version numbers.

    \value Qt_1_0 Version 1 (Qt 1.x)
    \value Qt_2_0 Version 2 (Qt 2.0)
    \value Qt_2_1 Version 3 (Qt 2.1, 2.2, 2.3)
    \value Qt_3_0 Version 4 (Qt 3.0)
    \value Qt_3_1 Version 5 (Qt 3.1, 3.2)
    \value Qt_3_3 Version 6 (Qt 3.3)
    \value Qt_4_0 Version 7 (Qt 4.0, Qt 4.1)
    \value Qt_4_1 Version 7 (Qt 4.0, Qt 4.1)
    \value Qt_4_2 Version 8 (Qt 4.2)
    \value Qt_4_3 Version 9 (Qt 4.3)
    \value Qt_4_4 Version 10 (Qt 4.4)
    \value Qt_4_5 Version 11 (Qt 4.5)
    \value Qt_4_6 Version 12 (Qt 4.6, Qt 4.7, Qt 4.8)
    \value Qt_4_7 Same as Qt_4_6.
    \value Qt_4_8 Same as Qt_4_6.
    \value Qt_4_9 Same as Qt_4_6.
    \value Qt_5_0 Version 13 (Qt 5.0)
    \value Qt_5_1 Version 14 (Qt 5.1)
    \value Qt_5_2 Version 15 (Qt 5.2)
    \value Qt_5_3 Same as Qt_5_2
    \value Qt_5_4 Version 16 (Qt 5.4)
    \value Qt_5_5 Same as Qt_5_4
    \value Qt_5_6 Version 17 (Qt 5.6)
    \value Qt_5_7 Same as Qt_5_6
    \value Qt_5_8 Same as Qt_5_6
    \value Qt_5_9 Same as Qt_5_6
    \value Qt_5_10 Same as Qt_5_6
    \value Qt_5_11 Same as Qt_5_6
    \value Qt_5_12 Version 18 (Qt 5.12)
    \value Qt_5_13 Version 19 (Qt 5.13)
    \value Qt_5_14 Same as Qt_5_13
    \omitvalue Qt_DefaultCompiledVersion

    \sa setVersion(), version()
*/

/*!
    \fn int QDataStream::version() const

    Returns the version number of the data serialization format.

    \sa setVersion(), Version
*/

/*!
    \fn void QDataStream::setVersion(int v)

    Sets the version number of the data serialization format to \a v,
    a value of the \l Version enum.

    You don't \e have to set a version if you are using the current
    version of Qt, but for your own custom binary formats we
    recommend that you do; see \l{Versioning} in the Detailed
    Description.

    To accommodate new functionality, the datastream serialization
    format of some Qt classes has changed in some versions of Qt. If
    you want to read data that was created by an earlier version of
    Qt, or write data that can be read by a program that was compiled
    with an earlier version of Qt, use this function to modify the
    serialization format used by QDataStream.

    The \l Version enum provides symbolic constants for the different
    versions of Qt. For example:

    \snippet code/src_corelib_io_qdatastream.cpp 5

    \sa version(), Version
*/

/*!
    \since 5.7

    Starts a new read transaction on the stream.

    Defines a restorable point within the sequence of read operations. For
    sequential devices, read data will be duplicated internally to allow
    recovery in case of incomplete reads. For random-access devices,
    this function saves the current position of the stream. Call
    commitTransaction(), rollbackTransaction(), or abortTransaction() to
    finish the current transaction.

    Once a transaction is started, subsequent calls to this function will make
    the transaction recursive. Inner transactions act as agents of the
    outermost transaction (i.e., report the status of read operations to the
    outermost transaction, which can restore the position of the stream).

    \note Restoring to the point of the nested startTransaction() call is not
    supported.

    When an error occurs during a transaction (including an inner transaction
    failing), reading from the data stream is suspended (all subsequent read
    operations return empty/zero values) and subsequent inner transactions are
    forced to fail. Starting a new outermost transaction recovers from this
    state. This behavior makes it unnecessary to error-check every read
    operation separately.

    \sa commitTransaction(), rollbackTransaction(), abortTransaction()
*/

void QDataStream::startTransaction()
{
    CHECK_STREAM_PRECOND(Q_VOID)

    if (!d)
        d.reset(new QDataStreamPrivate());

    if (++d->transactionDepth == 1) {
        dev->startTransaction();
        resetStatus();
    }
}

/*!
    \since 5.7

    Completes a read transaction. Returns \c true if no read errors have
    occurred during the transaction; otherwise returns \c false.

    If called on an inner transaction, committing will be postponed until
    the outermost commitTransaction(), rollbackTransaction(), or
    abortTransaction() call occurs.

    Otherwise, if the stream status indicates reading past the end of the
    data, this function restores the stream data to the point of the
    startTransaction() call. When this situation occurs, you need to wait for
    more data to arrive, after which you start a new transaction. If the data
    stream has read corrupt data or any of the inner transactions was aborted,
    this function aborts the transaction.

    \sa startTransaction(), rollbackTransaction(), abortTransaction()
*/

bool QDataStream::commitTransaction()
{
    CHECK_STREAM_TRANSACTION_PRECOND(false)
    if (--d->transactionDepth == 0) {
        CHECK_STREAM_PRECOND(false)

        if (q_status == ReadPastEnd) {
            dev->rollbackTransaction();
            return false;
        }
        dev->commitTransaction();
    }
    return q_status == Ok;
}

/*!
    \since 5.7

    Reverts a read transaction.

    This function is commonly used to rollback the transaction when an
    incomplete read was detected prior to committing the transaction.

    If called on an inner transaction, reverting is delegated to the outermost
    transaction, and subsequently started inner transactions are forced to
    fail.

    For the outermost transaction, restores the stream data to the point of
    the startTransaction() call. If the data stream has read corrupt data or
    any of the inner transactions was aborted, this function aborts the
    transaction.

    If the preceding stream operations were successful, sets the status of the
    data stream to \value ReadPastEnd.

    \sa startTransaction(), commitTransaction(), abortTransaction()
*/

void QDataStream::rollbackTransaction()
{
    setStatus(ReadPastEnd);

    CHECK_STREAM_TRANSACTION_PRECOND(Q_VOID)
    if (--d->transactionDepth != 0)
        return;

    CHECK_STREAM_PRECOND(Q_VOID)
    if (q_status == ReadPastEnd)
        dev->rollbackTransaction();
    else
        dev->commitTransaction();
}

/*!
    \since 5.7

    Aborts a read transaction.

    This function is commonly used to discard the transaction after
    higher-level protocol errors or loss of stream synchronization.

    If called on an inner transaction, aborting is delegated to the outermost
    transaction, and subsequently started inner transactions are forced to
    fail.

    For the outermost transaction, discards the restoration point and any
    internally duplicated data of the stream. Will not affect the current
    read position of the stream.

    Sets the status of the data stream to \value ReadCorruptData.

    \sa startTransaction(), commitTransaction(), rollbackTransaction()
*/

void QDataStream::abortTransaction()
{
    q_status = ReadCorruptData;

    CHECK_STREAM_TRANSACTION_PRECOND(Q_VOID)
    if (--d->transactionDepth != 0)
        return;

    CHECK_STREAM_PRECOND(Q_VOID)
    dev->commitTransaction();
}

/*****************************************************************************
  QDataStream read functions
 *****************************************************************************/

/*!
    \internal
*/

int QDataStream::readBlock(char *data, int len)
{
    // Disable reads on failure in transacted stream
    if (q_status != Ok && dev->isTransactionStarted())
        return -1;

    const int readResult = dev->read(data, len);
    if (readResult != len)
        setStatus(ReadPastEnd);
    return readResult;
}

/*!
    \fn QDataStream &QDataStream::operator>>(std::nullptr_t &ptr)
    \since 5.9
    \overload

    Simulates reading a \c{std::nullptr_t} from the stream into \a ptr and
    returns a reference to the stream. This function does not actually read
    anything from the stream, as \c{std::nullptr_t} values are stored as 0
    bytes.
*/

/*!
    \fn QDataStream &QDataStream::operator>>(quint8 &i)
    \overload

    Reads an unsigned byte from the stream into \a i, and returns a
    reference to the stream.
*/

/*!
    Reads a signed byte from the stream into \a i, and returns a
    reference to the stream.
*/

QDataStream &QDataStream::operator>>(qint8 &i)
{
    i = 0;
    CHECK_STREAM_PRECOND(*this)
    char c;
    if (readBlock(&c, 1) == 1)
        i = qint8(c);
    return *this;
}


/*!
    \fn QDataStream &QDataStream::operator>>(quint16 &i)
    \overload

    Reads an unsigned 16-bit integer from the stream into \a i, and
    returns a reference to the stream.
*/

/*!
    \overload

    Reads a signed 16-bit integer from the stream into \a i, and
    returns a reference to the stream.
*/

QDataStream &QDataStream::operator>>(qint16 &i)
{
    i = 0;
    CHECK_STREAM_PRECOND(*this)
    if (readBlock(reinterpret_cast<char *>(&i), 2) != 2) {
        i = 0;
    } else {
        if (!noswap) {
            i = qbswap(i);
        }
    }
    return *this;
}


/*!
    \fn QDataStream &QDataStream::operator>>(quint32 &i)
    \overload

    Reads an unsigned 32-bit integer from the stream into \a i, and
    returns a reference to the stream.
*/

/*!
    \overload

    Reads a signed 32-bit integer from the stream into \a i, and
    returns a reference to the stream.
*/

QDataStream &QDataStream::operator>>(qint32 &i)
{
    i = 0;
    CHECK_STREAM_PRECOND(*this)
    if (readBlock(reinterpret_cast<char *>(&i), 4) != 4) {
        i = 0;
    } else {
        if (!noswap) {
            i = qbswap(i);
        }
    }
    return *this;
}

/*!
    \fn QDataStream &QDataStream::operator>>(quint64 &i)
    \overload

    Reads an unsigned 64-bit integer from the stream, into \a i, and
    returns a reference to the stream.
*/

/*!
    \overload

    Reads a signed 64-bit integer from the stream into \a i, and
    returns a reference to the stream.
*/

QDataStream &QDataStream::operator>>(qint64 &i)
{
    i = qint64(0);
    CHECK_STREAM_PRECOND(*this)
    if (version() < 6) {
        quint32 i1, i2;
        *this >> i2 >> i1;
        i = ((quint64)i1 << 32) + i2;
    } else {
        if (readBlock(reinterpret_cast<char *>(&i), 8) != 8) {
            i = qint64(0);
        } else {
            if (!noswap) {
                i = qbswap(i);
            }
        }
    }
    return *this;
}

/*!
    Reads a boolean value from the stream into \a i. Returns a
    reference to the stream.
*/
QDataStream &QDataStream::operator>>(bool &i)
{
    qint8 v;
    *this >> v;
    i = !!v;
    return *this;
}

/*!
    \overload

    Reads a floating point number from the stream into \a f,
    using the standard IEEE 754 format. Returns a reference to the
    stream.

    \sa setFloatingPointPrecision()
*/

QDataStream &QDataStream::operator>>(float &f)
{
    if (version() >= QDataStream::Qt_4_6
        && floatingPointPrecision() == QDataStream::DoublePrecision) {
        double d;
        *this >> d;
        f = d;
        return *this;
    }

    f = 0.0f;
    CHECK_STREAM_PRECOND(*this)
    if (readBlock(reinterpret_cast<char *>(&f), 4) != 4) {
        f = 0.0f;
    } else {
        if (!noswap) {
            union {
                float val1;
                quint32 val2;
            } x;
            x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f));
            f = x.val1;
        }
    }
    return *this;
}

/*!
    \overload

    Reads a floating point number from the stream into \a f,
    using the standard IEEE 754 format. Returns a reference to the
    stream.

    \sa setFloatingPointPrecision()
*/

QDataStream &QDataStream::operator>>(double &f)
{
    if (version() >= QDataStream::Qt_4_6
        && floatingPointPrecision() == QDataStream::SinglePrecision) {
        float d;
        *this >> d;
        f = d;
        return *this;
    }

    f = 0.0;
    CHECK_STREAM_PRECOND(*this)
    if (readBlock(reinterpret_cast<char *>(&f), 8) != 8) {
        f = 0.0;
    } else {
        if (!noswap) {
            union {
                double val1;
                quint64 val2;
            } x;
            x.val2 = qbswap(*reinterpret_cast<quint64 *>(&f));
            f = x.val1;
        }
    }
    return *this;
}


/*!
    \overload
    \since 5.9

    Reads a floating point number from the stream into \a f,
    using the standard IEEE 754 format. Returns a reference to the
    stream.
*/
QDataStream &QDataStream::operator>>(qfloat16 &f)
{
    return *this >> reinterpret_cast<qint16&>(f);
}


/*!
    \overload

    Reads the '\\0'-terminated string \a s from the stream and returns
    a reference to the stream.

    The string is deserialized using \c{readBytes()}.

    Space for the string is allocated using \c{new []} -- the caller must
    destroy it with \c{delete []}.

    \sa readBytes(), readRawData()
*/

QDataStream &QDataStream::operator>>(char *&s)
{
    uint len = 0;
    return readBytes(s, len);
}


/*!
    Reads the buffer \a s from the stream and returns a reference to
    the stream.

    The buffer \a s is allocated using \c{new []}. Destroy it with the
    \c{delete []} operator.

    The \a l parameter is set to the length of the buffer. If the
    string read is empty, \a l is set to 0 and \a s is set to \nullptr.

    The serialization format is a quint32 length specifier first,
    then \a l bytes of data.

    \sa readRawData(), writeBytes()
*/

QDataStream &QDataStream::readBytes(char *&s, uint &l)
{
    s = nullptr;
    l = 0;
    CHECK_STREAM_PRECOND(*this)

    quint32 len;
    *this >> len;
    if (len == 0)
        return *this;

    const quint32 Step = 1024 * 1024;
    quint32 allocated = 0;
    char *prevBuf = nullptr;
    char *curBuf = nullptr;

    do {
        int blockSize = qMin(Step, len - allocated);
        prevBuf = curBuf;
        curBuf = new char[allocated + blockSize + 1];
        if (prevBuf) {
            memcpy(curBuf, prevBuf, allocated);
            delete [] prevBuf;
        }
        if (readBlock(curBuf + allocated, blockSize) != blockSize) {
            delete [] curBuf;
            return *this;
        }
        allocated += blockSize;
    } while (allocated < len);

    s = curBuf;
    s[len] = '\0';
    l = (uint)len;
    return *this;
}

/*!
    Reads at most \a len bytes from the stream into \a s and returns the number of
    bytes read. If an error occurs, this function returns -1.

    The buffer \a s must be preallocated. The data is \e not decoded.

    \sa readBytes(), QIODevice::read(), writeRawData()
*/

int QDataStream::readRawData(char *s, int len)
{
    CHECK_STREAM_PRECOND(-1)
    return readBlock(s, len);
}


/*****************************************************************************
  QDataStream write functions
 *****************************************************************************/

/*!
    \fn QDataStream &QDataStream::operator<<(std::nullptr_t ptr)
    \since 5.9
    \overload

    Simulates writing a \c{std::nullptr_t}, \a ptr, to the stream and returns a
    reference to the stream. This function does not actually write anything to
    the stream, as \c{std::nullptr_t} values are stored as 0 bytes.
*/

/*!
    \fn QDataStream &QDataStream::operator<<(quint8 i)
    \overload

    Writes an unsigned byte, \a i, to the stream and returns a
    reference to the stream.
*/

/*!
    Writes a signed byte, \a i, to the stream and returns a reference
    to the stream.
*/

QDataStream &QDataStream::operator<<(qint8 i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (!dev->putChar(i))
        q_status = WriteFailed;
    return *this;
}


/*!
    \fn QDataStream &QDataStream::operator<<(quint16 i)
    \overload

    Writes an unsigned 16-bit integer, \a i, to the stream and returns
    a reference to the stream.
*/

/*!
    \overload

    Writes a signed 16-bit integer, \a i, to the stream and returns a
    reference to the stream.
*/

QDataStream &QDataStream::operator<<(qint16 i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (!noswap) {
        i = qbswap(i);
    }
    if (dev->write((char *)&i, sizeof(qint16)) != sizeof(qint16))
        q_status = WriteFailed;
    return *this;
}

/*!
    \overload

    Writes a signed 32-bit integer, \a i, to the stream and returns a
    reference to the stream.
*/

QDataStream &QDataStream::operator<<(qint32 i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (!noswap) {
        i = qbswap(i);
    }
    if (dev->write((char *)&i, sizeof(qint32)) != sizeof(qint32))
        q_status = WriteFailed;
    return *this;
}

/*!
    \fn QDataStream &QDataStream::operator<<(quint64 i)
    \overload

    Writes an unsigned 64-bit integer, \a i, to the stream and returns a
    reference to the stream.
*/

/*!
    \overload

    Writes a signed 64-bit integer, \a i, to the stream and returns a
    reference to the stream.
*/

QDataStream &QDataStream::operator<<(qint64 i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (version() < 6) {
        quint32 i1 = i & 0xffffffff;
        quint32 i2 = i >> 32;
        *this << i2 << i1;
    } else {
        if (!noswap) {
            i = qbswap(i);
        }
        if (dev->write((char *)&i, sizeof(qint64)) != sizeof(qint64))
            q_status = WriteFailed;
    }
    return *this;
}

/*!
    \fn QDataStream &QDataStream::operator<<(quint32 i)
    \overload

    Writes an unsigned integer, \a i, to the stream as a 32-bit
    unsigned integer (quint32). Returns a reference to the stream.
*/

/*!
    Writes a boolean value, \a i, to the stream. Returns a reference
    to the stream.
*/

QDataStream &QDataStream::operator<<(bool i)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    if (!dev->putChar(qint8(i)))
        q_status = WriteFailed;
    return *this;
}

/*!
    \overload

    Writes a floating point number, \a f, to the stream using
    the standard IEEE 754 format. Returns a reference to the stream.

    \sa setFloatingPointPrecision()
*/

QDataStream &QDataStream::operator<<(float f)
{
    if (version() >= QDataStream::Qt_4_6
        && floatingPointPrecision() == QDataStream::DoublePrecision) {
        *this << double(f);
        return *this;
    }

    CHECK_STREAM_WRITE_PRECOND(*this)
    float g = f;                                // fixes float-on-stack problem
    if (!noswap) {
        union {
            float val1;
            quint32 val2;
        } x;
        x.val1 = g;
        x.val2 = qbswap(x.val2);

        if (dev->write((char *)&x.val2, sizeof(float)) != sizeof(float))
            q_status = WriteFailed;
        return *this;
    }

    if (dev->write((char *)&g, sizeof(float)) != sizeof(float))
        q_status = WriteFailed;
    return *this;
}


/*!
    \overload

    Writes a floating point number, \a f, to the stream using
    the standard IEEE 754 format. Returns a reference to the stream.

    \sa setFloatingPointPrecision()
*/

QDataStream &QDataStream::operator<<(double f)
{
    if (version() >= QDataStream::Qt_4_6
        && floatingPointPrecision() == QDataStream::SinglePrecision) {
        *this << float(f);
        return *this;
    }

    CHECK_STREAM_WRITE_PRECOND(*this)
    if (noswap) {
        if (dev->write((char *)&f, sizeof(double)) != sizeof(double))
            q_status = WriteFailed;
    } else {
        union {
            double val1;
            quint64 val2;
        } x;
        x.val1 = f;
        x.val2 = qbswap(x.val2);
        if (dev->write((char *)&x.val2, sizeof(double)) != sizeof(double))
            q_status = WriteFailed;
    }
    return *this;
}


/*!
    \fn QDataStream &QDataStream::operator<<(qfloat16 f)
    \overload
    \since 5.9

    Writes a floating point number, \a f, to the stream using
    the standard IEEE 754 format. Returns a reference to the stream.
*/
QDataStream &QDataStream::operator<<(qfloat16 f)
{
    return *this << reinterpret_cast<qint16&>(f);
}

/*!
    \overload

    Writes the '\\0'-terminated string \a s to the stream and returns a
    reference to the stream.

    The string is serialized using \c{writeBytes()}.

    \sa writeBytes(), writeRawData()
*/

QDataStream &QDataStream::operator<<(const char *s)
{
    if (!s) {
        *this << (quint32)0;
        return *this;
    }
    uint len = qstrlen(s) + 1;                        // also write null terminator
    *this << (quint32)len;                        // write length specifier
    writeRawData(s, len);
    return *this;
}

/*!
    Writes the length specifier \a len and the buffer \a s to the
    stream and returns a reference to the stream.

    The \a len is serialized as a quint32, followed by \a len bytes
    from \a s. Note that the data is \e not encoded.

    \sa writeRawData(), readBytes()
*/

QDataStream &QDataStream::writeBytes(const char *s, uint len)
{
    CHECK_STREAM_WRITE_PRECOND(*this)
    *this << (quint32)len;                        // write length specifier
    if (len)
        writeRawData(s, len);
    return *this;
}


/*!
    Writes \a len bytes from \a s to the stream. Returns the
    number of bytes actually written, or -1 on error.
    The data is \e not encoded.

    \sa writeBytes(), QIODevice::write(), readRawData()
*/

int QDataStream::writeRawData(const char *s, int len)
{
    CHECK_STREAM_WRITE_PRECOND(-1)
    int ret = dev->write(s, len);
    if (ret != len)
        q_status = WriteFailed;
    return ret;
}

/*!
    \since 4.1

    Skips \a len bytes from the device. Returns the number of bytes
    actually skipped, or -1 on error.

    This is equivalent to calling readRawData() on a buffer of length
    \a len and ignoring the buffer.

    \sa QIODevice::seek()
*/
int QDataStream::skipRawData(int len)
{
    CHECK_STREAM_PRECOND(-1)
    if (q_status != Ok && dev->isTransactionStarted())
        return -1;

    const int skipResult = dev->skip(len);
    if (skipResult != len)
        setStatus(ReadPastEnd);
    return skipResult;
}

QT_END_NAMESPACE

#endif // QT_NO_DATASTREAM
