/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtDBus 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 "qdbusargument.h"
#include "qdbusargument_p.h"

#include <qatomic.h>
#include <qbytearray.h>
#include <qlist.h>
#include <qmap.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qvariant.h>
#include <qdatetime.h>
#include <qrect.h>
#include <qline.h>

#include "qdbusmetatype_p.h"
#include "qdbusutil_p.h"

#ifndef QT_NO_DBUS

QT_BEGIN_NAMESPACE

QDBusArgumentPrivate::~QDBusArgumentPrivate()
{
    if (message)
        q_dbus_message_unref(message);
}

QByteArray QDBusArgumentPrivate::createSignature(int id)
{
    if (!qdbus_loadLibDBus())
        return "";

    QByteArray signature;
    QDBusMarshaller *marshaller = new QDBusMarshaller(0);
    marshaller->ba = &signature;

    // run it
    void *null = 0;
    QVariant v(id, null);
    QDBusArgument arg(marshaller);
    QDBusMetaType::marshall(arg, v.userType(), v.constData());
    arg.d = 0;

    // delete it
    bool ok = marshaller->ok;
    delete marshaller;

    if (signature.isEmpty() || !ok || !QDBusUtil::isValidSingleSignature(QString::fromLatin1(signature))) {
        qWarning("QDBusMarshaller: type `%s' produces invalid D-BUS signature `%s' "
                 "(Did you forget to call beginStructure() ?)",
                 QMetaType::typeName(id),
                 signature.isEmpty() ? "<empty>" : signature.constData());
        return "";
    } else if ((signature.at(0) != DBUS_TYPE_ARRAY && signature.at(0) != DBUS_STRUCT_BEGIN_CHAR) ||
               (signature.at(0) == DBUS_TYPE_ARRAY && (signature.at(1) == DBUS_TYPE_BYTE ||
                                                       signature.at(1) == DBUS_TYPE_STRING))) {
        qWarning("QDBusMarshaller: type `%s' attempts to redefine basic D-BUS type '%s' (%s) "
                 "(Did you forget to call beginStructure() ?)",
                 QMetaType::typeName(id),
                 signature.constData(),
                 QMetaType::typeName(QDBusMetaType::signatureToType(signature)));
        return "";
    }
    return signature;
}

bool QDBusArgumentPrivate::checkWrite(QDBusArgumentPrivate *&d)
{
    if (!d)
        return false;
    if (d->direction == Marshalling) {
        if (!d->marshaller()->ok)
            return false;

        if (d->message && d->ref.loadRelaxed() != 1) {
            QDBusMarshaller *dd = new QDBusMarshaller(d->capabilities);
            dd->message = q_dbus_message_copy(d->message);
            q_dbus_message_iter_init_append(dd->message, &dd->iterator);

            if (!d->ref.deref())
                delete d;
            d = dd;
        }
        return true;
    }

#ifdef QT_DEBUG
    qFatal("QDBusArgument: write from a read-only object");
#else
    qWarning("QDBusArgument: write from a read-only object");
#endif
    return false;
}

bool QDBusArgumentPrivate::checkRead(QDBusArgumentPrivate *d)
{
    if (!d)
        return false;
    if (d->direction == Demarshalling)
        return true;

#ifdef QT_DEBUG
    qFatal("QDBusArgument: read from a write-only object");
#else
    qWarning("QDBusArgument: read from a write-only object");
#endif

    return false;
}

bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d)
{
    if (!checkRead(d))
        return false;           //  don't bother

    if (d->ref.loadRelaxed() == 1)
        return true;            // no need to detach

    QDBusDemarshaller *dd = new QDBusDemarshaller(d->capabilities);
    dd->message = q_dbus_message_ref(d->message);
    dd->iterator = static_cast<QDBusDemarshaller*>(d)->iterator;

    if (!d->ref.deref())
        delete d;
    d = dd;
    return true;
}

/*!
    \class QDBusArgument
    \inmodule QtDBus
    \since 4.2

    \brief The QDBusArgument class is used to marshall and demarshall D-Bus arguments.

    The class is used to send arguments over D-Bus to remote
    applications and to receive them back. D-Bus offers an extensible
    type system, based on a few primitive types and associations of
    them. See the \l {qdbustypesystem.html}{Qt D-Bus Type System} page
    for more information on the type system.

    QDBusArgument is the central class in the Qt D-Bus type system,
    providing functions to marshall and demarshall the primitive
    types. The compound types are then created by association of one
    or more of the primitive types in arrays, dictionaries or
    structures.

    The following example illustrates how a structure containing an
    integer and a string can be constructed using the \l
    {qdbustypesystem.html}{Qt D-Bus type system}:

    \snippet code/src_qdbus_qdbusargument.cpp 0

    The type has to be registered with qDBusRegisterMetaType() before
    it can be used with QDBusArgument. Therefore, somewhere in your
    program, you should add the following code:

    \snippet code/src_qdbus_qdbusargument.cpp 1

    Once registered, a type can be used in outgoing method calls
    (placed with QDBusAbstractInterface::call()), signal emissions
    from registered objects or in incoming calls from remote
    applications.

    It is important to note that the \c{operator<<} and \c{operator>>}
    streaming functions must always produce the same number of entries
    in case of structures, both in reading and in writing (marshalling
    and demarshalling), otherwise calls and signals may start to
    silently fail.

    The following example illustrates this wrong usage
    in context of a class that may contain invalid data:

    \code
    //bad code
        // Wrongly marshall the MyTime data into a D-Bus argument
        QDBusArgument &operator<<(QDBusArgument &argument, const MyTime &mytime)
        {
            argument.beginStructure();
            if (mytime.isValid)
                argument << true << mytime.hour
                         << mytime.minute << mytime.second;
            else
                argument << false;
            argument.endStructure();
            return argument;
        }
    \endcode

    In this example, both the \c{operator<<} and the \c{operator>>}
    functions may produce a different number of reads/writes. This can
    confuse the Qt D-Bus type system and should be avoided.

    \sa QDBusAbstractInterface, {qdbustypesystem.html}{The Qt D-Bus type
    system}, {usingadaptors.html}{Using Adaptors}, qdbus_cast()
*/

/*!
    \enum QDBusArgument::ElementType
    \since 4.5

    This enum describes the type of element held by the argument.

    \value BasicType A basic element, which is understood by
        QVariant. The following types are considered basic: bool,
        byte, short, ushort, int, uint, qint64, quint64, double,
        QString, QByteArray, QDBusObjectPath, QDBusSignature

    \value VariantType The variant element (QDBusVariant)

    \value ArrayType An array element, usually represented by QList<T>
    or QVector<T>. Note: QByteArray and associative maps are not
    considered arrays, even if the D-Bus protocol transports them as such.

    \value StructureType A custom type represented by a structure,
    like QDateTime, QPoint, etc.

    \value MapType An associative container, like QMap<Key, Value> or
    QHash<Key, Value>

    \value MapEntryType One entry in an associative container: both
    the key and the value form one map-entry type.

    \value UnknownType The type is unknown or we have reached the end
    of the list.

    \sa currentType()
*/

/*!
    \fn template<typename T> T qdbus_cast(const QDBusArgument &arg, T*)
    \relates QDBusArgument
    \since 4.2

    Attempts to demarshall the contents of \a arg into the type
    \c{T}. For example:

    \snippet code/src_qdbus_qdbusargument.cpp 2

    Note that it is equivalent to the following:

    \snippet code/src_qdbus_qdbusargument.cpp 3
*/

/*!
    Constructs an empty QDBusArgument argument.

    An empty QDBusArgument object does not allow either reading or
    writing to be performed.
*/
QDBusArgument::QDBusArgument()
{
    if (!qdbus_loadLibDBus()) {
        d = 0;
        return;
    }

    QDBusMarshaller *dd = new QDBusMarshaller(0);
    d = dd;

    // create a new message with any type, we won't sent it anyways
    dd->message = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
    q_dbus_message_iter_init_append(dd->message, &dd->iterator);
}

/*!
    Constructs a copy of the \a other QDBusArgument object.

    Both objects will therefore contain the same state from this point
    forward. QDBusArguments are explicitly shared and, therefore, any
    modification to either copy will affect the other one too.
*/
QDBusArgument::QDBusArgument(const QDBusArgument &other)
    : d(other.d)
{
    if (d)
        d->ref.ref();
}

/*!
    \internal
*/
QDBusArgument::QDBusArgument(QDBusArgumentPrivate *dd)
    : d(dd)
{
}

/*!
    Copies the \a other QDBusArgument object into this one.

    Both objects will therefore contain the same state from this point
    forward. QDBusArguments are explicitly shared and, therefore, any
    modification to either copy will affect the other one too.
*/
QDBusArgument &QDBusArgument::operator=(const QDBusArgument &other)
{
    qAtomicAssign(d, other.d);
    return *this;
}

/*!
    Disposes of the resources associated with this QDBusArgument
    object.
*/
QDBusArgument::~QDBusArgument()
{
    if (d && !d->ref.deref())
        delete d;
}

/*!
    Appends the primitive value \a arg of type \c{BYTE} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(uchar arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{BOOLEAN} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(bool arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{INT16} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(short arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{UINT16} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(ushort arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{INT32} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(int arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{UINT32} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(uint arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{INT64} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(qlonglong arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{UINT64} to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(qulonglong arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{DOUBLE} (double-precision
    floating-point) to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(double arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{STRING} (Unicode character
    string) to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(const QString &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    \internal
    Appends the primitive value \a arg of type \c{OBJECT_PATH} (path to a D-Bus
    object) to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(const QDBusObjectPath &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    \internal
    Appends the primitive value \a arg of type \c{SIGNATURE} (D-Bus type
    signature) to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(const QDBusSignature &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    \since 4.8
    \internal
    Appends the primitive value \a arg of type \c{UNIX_FILE_DESCRIPTOR} (Unix
    File Descriptor) to the D-Bus stream.
*/
QDBusArgument &QDBusArgument::operator<<(const QDBusUnixFileDescriptor &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the primitive value \a arg of type \c{VARIANT} to the D-Bus stream.

    A D-Bus variant type can contain any type, including other
    variants. It is similar to the Qt QVariant type.
*/
QDBusArgument &QDBusArgument::operator<<(const QDBusVariant &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the QStringList given by \a arg as \c{ARRAY of STRING}
    to the D-Bus stream.

    QStringList and QByteArray are the only two non-primitive types
    that are supported directly by QDBusArgument because of their
    widespread usage in Qt applications.

    Other arrays are supported through compound types in Qt D-Bus.
*/
QDBusArgument &QDBusArgument::operator<<(const QStringList &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \overload
    Appends the QByteArray given by \a arg as \c{ARRAY of BYTE}
    to the D-Bus stream.

    QStringList and QByteArray are the only two non-primitive types
    that are supported directly by QDBusArgument because of their
    widespread usage in Qt applications.

    Other arrays are supported through compound types in Qt D-Bus.
*/
QDBusArgument &QDBusArgument::operator<<(const QByteArray &arg)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->append(arg);
    return *this;
}

/*!
    \internal
    \since 4.5

    Appends the variant \a v.

    \sa asVariant()
*/
void QDBusArgument::appendVariant(const QVariant &v)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d->marshaller()->appendVariantInternal(v);
}

/*!
    \internal
    Returns the type signature of the D-Bus type this QDBusArgument
    object is currently pointing to.
*/
QString QDBusArgument::currentSignature() const
{
    if (!d)
        return QString();
    if (d->direction == QDBusArgumentPrivate::Demarshalling)
        return d->demarshaller()->currentSignature();
    else
        return d->marshaller()->currentSignature();
}

/*!
    \since 4.5
    Returns the classification of the current element type. If an
    error decoding the type occurs or if we're at the end of the
    argument, this function returns QDBusArgument::UnknownType.

    This function only makes sense when demarshalling arguments. If it
    is used while marshalling, it will always return UnknownType.
*/
QDBusArgument::ElementType QDBusArgument::currentType() const
{
    if (!d)
        return UnknownType;
    if (d->direction == QDBusArgumentPrivate::Demarshalling)
        return d->demarshaller()->currentType();
    return UnknownType;
}

/*!
    Extracts one D-BUS primitive argument of type \c{BYTE} from the
    D-BUS stream and puts it into \a arg.
*/
const QDBusArgument &QDBusArgument::operator>>(uchar &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toByte();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{BOOLEAN} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(bool &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toBool();
    else
        arg = false;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{UINT16} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(ushort &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toUShort();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{INT16} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(short &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toShort();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{INT32} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(int &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toInt();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{UINT32} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(uint &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toUInt();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{INT64} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(qlonglong &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toLongLong();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{UINT64} from the
    D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(qulonglong &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toULongLong();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{DOUBLE}
    (double-precision floating pount) from the D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(double &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toDouble();
    else
        arg = 0;
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{STRING} (Unicode
    character string) from the D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(QString &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toString();
    return *this;
}

/*!
    \overload
    \internal
    Extracts one D-Bus primitive argument of type \c{OBJECT_PATH}
    (D-Bus path to an object) from the D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(QDBusObjectPath &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toObjectPath();
    return *this;
}

/*!
    \overload
    \internal
    Extracts one D-Bus primitive argument of type \c{SIGNATURE} (D-Bus
    type signature) from the D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(QDBusSignature &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toSignature();
    return *this;
}

/*!
    \overload
    \since 4.8
    \internal
    Extracts one D-Bus primitive argument of type \c{UNIX_FILE_DESCRIPTOR}
    (Unix file descriptor) from the D-Bus stream.
*/
const QDBusArgument &QDBusArgument::operator>>(QDBusUnixFileDescriptor &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toUnixFileDescriptor();
    return *this;
}

/*!
    \overload
    Extracts one D-Bus primitive argument of type \c{VARIANT} from the
    D-Bus stream.

    A D-Bus variant type can contain any type, including other
    variants. It is similar to the Qt QVariant type.

    In case the variant contains a type not directly supported by
    QDBusArgument, the value of the returned QDBusVariant will contain
    another QDBusArgument. It is your responsibility to further
    demarshall it into another type.
*/
const QDBusArgument &QDBusArgument::operator>>(QDBusVariant &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toVariant();
    return *this;
}

/*!
    \overload
    Extracts an array of strings from the D-Bus stream and return it
    as a QStringList.

    QStringList and QByteArray are the only two non-primitive types
    that are supported directly by QDBusArgument because of their
    widespread usage in Qt applications.

    Other arrays are supported through compound types in Qt D-Bus.
*/
const QDBusArgument &QDBusArgument::operator>>(QStringList &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toStringList();
    return *this;
}

/*!
    \overload
    Extracts an array of bytes from the D-Bus stream and return it
    as a QByteArray.

    QStringList and QByteArray are the only two non-primitive types
    that are supported directly by QDBusArgument because of their
    widespread usage in Qt applications.

    Other arrays are supported through compound types in Qt D-Bus.
*/
const QDBusArgument &QDBusArgument::operator>>(QByteArray &arg) const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        arg = d->demarshaller()->toByteArray();
    return *this;
}

/*!
    Opens a new D-Bus structure suitable for appending new arguments.

    This function is used usually in \c{operator<<} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 4

    Structures can contain other structures, so the following code is
    also valid:

    \snippet code/src_qdbus_qdbusargument.cpp 5

    \sa endStructure(), beginArray(), beginMap()
*/
void QDBusArgument::beginStructure()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->beginStructure();
}

/*!
    Closes a D-Bus structure opened with beginStructure(). This function must be called
    same number of times that beginStructure() is called.

    \sa beginStructure(), endArray(), endMap()
*/
void QDBusArgument::endStructure()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->endStructure();
}

/*!
    Opens a new D-Bus array suitable for appending elements of meta-type \a id.

    This function is used usually in \c{operator<<} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 6

    If the type you want to marshall is a QList, QVector or any of the
    Qt's \l {Container Classes} that take one template parameter,
    you need not declare an \c{operator<<} function for it, since
    Qt D-Bus provides generic templates to do the job of marshalling
    the data. The same applies for STL's sequence containers, such
    as \c {std::list}, \c {std::vector}, etc.

    \sa endArray(), beginStructure(), beginMap()
*/
void QDBusArgument::beginArray(int id)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->beginArray(id);
}

/*!
    Closes a D-Bus array opened with beginArray(). This function must be called
    same number of times that beginArray() is called.

    \sa beginArray(), endStructure(), endMap()
*/
void QDBusArgument::endArray()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->endArray();
}

/*!
    Opens a new D-Bus map suitable for
    appending elements. Maps are containers that associate one entry
    (the key) to another (the value), such as Qt's QMap or QHash. The
    ids of the map's key and value meta types must be passed in \a kid
    and \a vid respectively.

    This function is used usually in \c{operator<<} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 7

    If the type you want to marshall is a QMap or QHash, you need not
    declare an \c{operator<<} function for it, since Qt D-Bus provides
    generic templates to do the job of marshalling the data.

    \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
*/
void QDBusArgument::beginMap(int kid, int vid)
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->beginMap(kid, vid);
}

/*!
    Closes a D-Bus map opened with beginMap(). This function must be called
    same number of times that beginMap() is called.

    \sa beginMap(), endStructure(), endArray()
*/
void QDBusArgument::endMap()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->endMap();
}

/*!
    Opens a D-Bus map entry suitable for
    appending the key and value entries. This function is only valid
    when a map has been opened with beginMap().

    See beginMap() for an example of usage of this function.

    \sa endMapEntry(), beginMap()
*/
void QDBusArgument::beginMapEntry()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->beginMapEntry();
}

/*!
    Closes a D-Bus map entry opened with beginMapEntry(). This function must be called
    same number of times that beginMapEntry() is called.

    \sa beginMapEntry()
*/
void QDBusArgument::endMapEntry()
{
    if (QDBusArgumentPrivate::checkWrite(d))
        d = d->marshaller()->endMapEntry();
}

/*!
    Opens a D-Bus structure suitable for extracting elements.

    This function is used usually in \c{operator>>} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 8

    \sa endStructure(), beginArray(), beginMap()
*/
void QDBusArgument::beginStructure() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->beginStructure();
}

/*!
    Closes the D-Bus structure and allow extracting of the next element
    after the structure.

    \sa beginStructure()
*/
void QDBusArgument::endStructure() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->endStructure();
}

/*!
    Recurses into the D-Bus array to allow extraction of
    the array elements.

    This function is used usually in \c{operator>>} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 9

    If the type you want to demarshall is a QList, QVector or any of the
    Qt's \l {Container Classes} that take one template parameter, you
    need not declare an \c{operator>>} function for it, since Qt D-Bus
    provides generic templates to do the job of demarshalling the data.
    The same applies for STL's sequence containers, such as \c {std::list},
    \c {std::vector}, etc.

    \sa atEnd(), beginStructure(), beginMap()
*/
void QDBusArgument::beginArray() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->beginArray();
}

/*!
    Closes the D-Bus array and allow extracting of the next element
    after the array.

    \sa beginArray()
*/
void QDBusArgument::endArray() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->endArray();
}

/*!
    Recurses into the D-Bus map to allow extraction of
    the map's elements.

    This function is used usually in \c{operator>>} streaming
    operators, as in the following example:

    \snippet code/src_qdbus_qdbusargument.cpp 10

    If the type you want to demarshall is a QMap or QHash, you need not
    declare an \c{operator>>} function for it, since Qt D-Bus provides
    generic templates to do the job of demarshalling the data.

    \sa endMap(), beginStructure(), beginArray(), beginMapEntry()
*/
void QDBusArgument::beginMap() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->beginMap();
}

/*!
    Closes the D-Bus map and allow extracting of the next element
    after the map.

    \sa beginMap()
*/
void QDBusArgument::endMap() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->endMap();
}

/*!
    Recurses into the D-Bus map entry to allow extraction
    of the key and value pair.

    See beginMap() for an example of how this function is usually used.

    \sa endMapEntry(), beginMap()
*/
void QDBusArgument::beginMapEntry() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->beginMapEntry();
}

/*!
    Closes the D-Bus map entry and allow extracting of the next element
    on the map.

    \sa beginMapEntry()
*/
void QDBusArgument::endMapEntry() const
{
    if (QDBusArgumentPrivate::checkReadAndDetach(d))
        d = d->demarshaller()->endMapEntry();
}

/*!
    Returns \c true if there are no more elements to be extracted from
    this QDBusArgument. This function is usually used in QDBusArgument
    objects returned from beginMap() and beginArray().
*/
bool QDBusArgument::atEnd() const
{
    if (QDBusArgumentPrivate::checkRead(d))
        return d->demarshaller()->atEnd();

    return true;                // at least, stop reading
}

/*!
    \since 4.5

    Returns the current argument in the form of a QVariant. Basic
    types will be decoded and returned in the QVariant, but for
    complex types, this function will return a QDBusArgument object in
    the QVariant. It is the caller's responsibility to decode the
    argument (for example, by calling asVariant() in it).

    For example, if the current argument is an INT32, this function
    will return a QVariant with an argument of type QVariant::Int. For
    an array of INT32, it will return a QVariant containing a
    QDBusArgument.

    If an error occurs or if there are no more arguments to decode
    (i.e., we are at the end of the argument list), this function will
    return an invalid QVariant.

    \sa atEnd()
*/
QVariant QDBusArgument::asVariant() const
{
    if (QDBusArgumentPrivate::checkRead(d))
        return d->demarshaller()->toVariantInternal();

    return QVariant();
}

QT_END_NAMESPACE

// for optimization purposes, we include the marshallers here
#include "qdbusmarshaller.cpp"
#include "qdbusdemarshaller.cpp"

QT_BEGIN_NAMESPACE

// QDBusArgument operators

const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v)
{
    QDBusVariant dbv;
    a >> dbv;
    v = dbv.variant();
    return a;
}

// QVariant types
#ifndef QDBUS_NO_SPECIALTYPES
const QDBusArgument &operator>>(const QDBusArgument &a, QDate &date)
{
    int y, m, d;
    a.beginStructure();
    a >> y >> m >> d;
    a.endStructure();

    if (y != 0 && m != 0 && d != 0)
        date.setDate(y, m, d);
    else
        date = QDate();
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QDate &date)
{
    a.beginStructure();
    if (date.isValid())
        a << date.year() << date.month() << date.day();
    else
        a << 0 << 0 << 0;
    a.endStructure();
    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QTime &time)
{
    int h, m, s, ms;
    a.beginStructure();
    a >> h >> m >> s >> ms;
    a.endStructure();

    if (h < 0)
        time = QTime();
    else
        time.setHMS(h, m, s, ms);
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QTime &time)
{
    a.beginStructure();
    if (time.isValid())
        a << time.hour() << time.minute() << time.second() << time.msec();
    else
        a << -1 << -1 << -1 << -1;
    a.endStructure();
    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QDateTime &dt)
{
    QDate date;
    QTime time;
    int timespec;

    a.beginStructure();
    a >> date >> time >> timespec;
    a.endStructure();

    dt = QDateTime(date, time, Qt::TimeSpec(timespec));
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QDateTime &dt)
{
    a.beginStructure();
    a << dt.date() << dt.time() << int(dt.timeSpec());
    a.endStructure();
    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QRect &rect)
{
    int x, y, width, height;
    a.beginStructure();
    a >> x >> y >> width >> height;
    a.endStructure();

    rect.setRect(x, y, width, height);
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QRect &rect)
{
    a.beginStructure();
    a << rect.x() << rect.y() << rect.width() << rect.height();
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QRectF &rect)
{
    double x, y, width, height;
    a.beginStructure();
    a >> x >> y >> width >> height;
    a.endStructure();

    rect.setRect(qreal(x), qreal(y), qreal(width), qreal(height));
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QRectF &rect)
{
    a.beginStructure();
    a << double(rect.x()) << double(rect.y()) << double(rect.width()) << double(rect.height());
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QSize &size)
{
    a.beginStructure();
    a >> size.rwidth() >> size.rheight();
    a.endStructure();

    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QSize &size)
{
    a.beginStructure();
    a << size.width() << size.height();
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QSizeF &size)
{
    double width, height;
    a.beginStructure();
    a >> width >> height;
    a.endStructure();

    size.setWidth(qreal(width));
    size.setHeight(qreal(height));
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QSizeF &size)
{
    a.beginStructure();
    a << double(size.width()) << double(size.height());
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QPoint &pt)
{
    a.beginStructure();
    a >> pt.rx() >> pt.ry();
    a.endStructure();

    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QPoint &pt)
{
    a.beginStructure();
    a << pt.x() << pt.y();
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QPointF &pt)
{
    double x, y;
    a.beginStructure();
    a >> x >> y;
    a.endStructure();

    pt.setX(qreal(x));
    pt.setY(qreal(y));
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QPointF &pt)
{
    a.beginStructure();
    a << double(pt.x()) << double(pt.y());
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QLine &line)
{
    QPoint p1, p2;
    a.beginStructure();
    a >> p1 >> p2;
    a.endStructure();

    line = QLine(p1, p2);
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QLine &line)
{
    a.beginStructure();
    a << line.p1() << line.p2();
    a.endStructure();

    return a;
}

const QDBusArgument &operator>>(const QDBusArgument &a, QLineF &line)
{
    QPointF p1, p2;
    a.beginStructure();
    a >> p1 >> p2;
    a.endStructure();

    line = QLineF(p1, p2);
    return a;
}

QDBusArgument &operator<<(QDBusArgument &a, const QLineF &line)
{
    a.beginStructure();
    a << line.p1() << line.p2();
    a.endStructure();

    return a;
}
#endif

/*!
    \fn void QDBusArgument::swap(QDBusArgument &other)

    Swaps this QDBusArgument instance with \a other.
*/

QT_END_NAMESPACE

#endif // QT_NO_DBUS
