/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** 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$
**
****************************************************************************/

#ifndef QENDIAN_H
#define QENDIAN_H

#include <QtCore/qfloat16.h>
#include <QtCore/qglobal.h>

// include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems
#include <stdlib.h>
#include <string.h>

#ifdef min // MSVC
#undef min
#undef max
#endif

QT_BEGIN_NAMESPACE

/*
 * ENDIAN FUNCTIONS
*/

// Used to implement a type-safe and alignment-safe copy operation
// If you want to avoid the memcpy, you must write specializations for these functions
template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, void *dest)
{
    // Using sizeof(T) inside memcpy function produces internal compiler error with
    // MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T.
    const size_t size = sizeof(T);
#if __has_builtin(__builtin_memcpy)
    __builtin_memcpy
#else
    memcpy
#endif
            (dest, &src, size);
}

template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const void *src)
{
    T dest;
    const size_t size = sizeof(T);
#if __has_builtin(__builtin_memcpy)
    __builtin_memcpy
#else
    memcpy
#endif
            (&dest, src, size);
    return dest;
}

/*
 * T qbswap(T source).
 * Changes the byte order of a value from big endian to little endian or vice versa.
 * This function can be used if you are not concerned about alignment issues,
 * and it is therefore a bit more convenient and in most cases more efficient.
*/
template <typename T> Q_DECL_CONSTEXPR T qbswap(T source);

// These definitions are written so that they are recognized by most compilers
// as bswap and replaced with single instruction builtins if available.
template <> inline Q_DECL_CONSTEXPR quint64 qbswap<quint64>(quint64 source)
{
    return 0
        | ((source & Q_UINT64_C(0x00000000000000ff)) << 56)
        | ((source & Q_UINT64_C(0x000000000000ff00)) << 40)
        | ((source & Q_UINT64_C(0x0000000000ff0000)) << 24)
        | ((source & Q_UINT64_C(0x00000000ff000000)) << 8)
        | ((source & Q_UINT64_C(0x000000ff00000000)) >> 8)
        | ((source & Q_UINT64_C(0x0000ff0000000000)) >> 24)
        | ((source & Q_UINT64_C(0x00ff000000000000)) >> 40)
        | ((source & Q_UINT64_C(0xff00000000000000)) >> 56);
}

template <> inline Q_DECL_CONSTEXPR quint32 qbswap<quint32>(quint32 source)
{
    return 0
        | ((source & 0x000000ff) << 24)
        | ((source & 0x0000ff00) << 8)
        | ((source & 0x00ff0000) >> 8)
        | ((source & 0xff000000) >> 24);
}

template <> inline Q_DECL_CONSTEXPR quint16 qbswap<quint16>(quint16 source)
{
    return quint16( 0
                    | ((source & 0x00ff) << 8)
                    | ((source & 0xff00) >> 8) );
}

template <> inline Q_DECL_CONSTEXPR quint8 qbswap<quint8>(quint8 source)
{
    return source;
}

// signed specializations
template <> inline Q_DECL_CONSTEXPR qint64 qbswap<qint64>(qint64 source)
{
    return qbswap<quint64>(quint64(source));
}

template <> inline Q_DECL_CONSTEXPR qint32 qbswap<qint32>(qint32 source)
{
    return qbswap<quint32>(quint32(source));
}

template <> inline Q_DECL_CONSTEXPR qint16 qbswap<qint16>(qint16 source)
{
    return qbswap<quint16>(quint16(source));
}

template <> inline Q_DECL_CONSTEXPR qint8 qbswap<qint8>(qint8 source)
{
    return source;
}

// floating specializations
template<typename Float>
Float qbswapFloatHelper(Float source)
{
    // memcpy call in qFromUnaligned is recognized by optimizer as a correct way of type prunning
    auto temp = qFromUnaligned<typename QIntegerForSizeof<Float>::Unsigned>(&source);
    temp = qbswap(temp);
    return qFromUnaligned<Float>(&temp);
}

inline qfloat16 qbswap(qfloat16 source)
{
    return qbswapFloatHelper(source);
}

inline float qbswap(float source)
{
    return qbswapFloatHelper(source);
}

inline double qbswap(double source)
{
    return qbswapFloatHelper(source);
}

/*
 * qbswap(const T src, const void *dest);
 * Changes the byte order of \a src from big endian to little endian or vice versa
 * and stores the result in \a dest.
 * There is no alignment requirements for \a dest.
*/
template <typename T> inline void qbswap(const T src, void *dest)
{
    qToUnaligned<T>(qbswap(src), dest);
}

template <int Size> void *qbswap(const void *source, qsizetype count, void *dest) noexcept;
template<> inline void *qbswap<1>(const void *source, qsizetype count, void *dest) noexcept
{
    return source != dest ? memcpy(dest, source, size_t(count)) : dest;
}
template<> Q_CORE_EXPORT void *qbswap<2>(const void *source, qsizetype count, void *dest) noexcept;
template<> Q_CORE_EXPORT void *qbswap<4>(const void *source, qsizetype count, void *dest) noexcept;
template<> Q_CORE_EXPORT void *qbswap<8>(const void *source, qsizetype count, void *dest) noexcept;

#if Q_BYTE_ORDER == Q_BIG_ENDIAN

template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source)
{ return source; }
template <typename T> inline Q_DECL_CONSTEXPR T qFromBigEndian(T source)
{ return source; }
template <typename T> inline Q_DECL_CONSTEXPR T qToLittleEndian(T source)
{ return qbswap(source); }
template <typename T> inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source)
{ return qbswap(source); }
template <typename T> inline void qToBigEndian(T src, void *dest)
{ qToUnaligned<T>(src, dest); }
template <typename T> inline void qToLittleEndian(T src, void *dest)
{ qbswap<T>(src, dest); }

template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
{ qbswap<sizeof(T)>(source, count, dest); }
template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
{ qbswap<sizeof(T)>(source, count, dest); }
#else // Q_LITTLE_ENDIAN

template <typename T> inline Q_DECL_CONSTEXPR T qToBigEndian(T source)
{ return qbswap(source); }
template <typename T> inline Q_DECL_CONSTEXPR T qFromBigEndian(T source)
{ return qbswap(source); }
template <typename T> inline Q_DECL_CONSTEXPR T qToLittleEndian(T source)
{ return source; }
template <typename T> inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source)
{ return source; }
template <typename T> inline void qToBigEndian(T src, void *dest)
{ qbswap<T>(src, dest); }
template <typename T> inline void qToLittleEndian(T src, void *dest)
{ qToUnaligned<T>(src, dest); }

template <typename T> inline void qToBigEndian(const void *source, qsizetype count, void *dest)
{ qbswap<sizeof(T)>(source, count, dest); }
template <typename T> inline void qToLittleEndian(const void *source, qsizetype count, void *dest)
{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
template <typename T> inline void qFromBigEndian(const void *source, qsizetype count, void *dest)
{ qbswap<sizeof(T)>(source, count, dest); }
template <typename T> inline void qFromLittleEndian(const void *source, qsizetype count, void *dest)
{ if (source != dest) memcpy(dest, source, count * sizeof(T)); }
#endif // Q_BYTE_ORDER == Q_BIG_ENDIAN


/* T qFromLittleEndian(const void *src)
 * This function will read a little-endian encoded value from \a src
 * and return the value in host-endian encoding.
 * There is no requirement that \a src must be aligned.
*/
template <typename T> inline T qFromLittleEndian(const void *src)
{
    return qFromLittleEndian(qFromUnaligned<T>(src));
}

template <> inline quint8 qFromLittleEndian<quint8>(const void *src)
{ return static_cast<const quint8 *>(src)[0]; }
template <> inline qint8 qFromLittleEndian<qint8>(const void *src)
{ return static_cast<const qint8 *>(src)[0]; }

/* This function will read a big-endian (also known as network order) encoded value from \a src
 * and return the value in host-endian encoding.
 * There is no requirement that \a src must be aligned.
*/
template <class T> inline T qFromBigEndian(const void *src)
{
    return qFromBigEndian(qFromUnaligned<T>(src));
}

template <> inline quint8 qFromBigEndian<quint8>(const void *src)
{ return static_cast<const quint8 *>(src)[0]; }
template <> inline qint8 qFromBigEndian<qint8>(const void *src)
{ return static_cast<const qint8 *>(src)[0]; }

template<class S>
class QSpecialInteger
{
    typedef typename S::StorageType T;
    T val;
public:
    QSpecialInteger() = default;
    explicit Q_DECL_CONSTEXPR QSpecialInteger(T i) : val(S::toSpecial(i)) {}

    QSpecialInteger &operator =(T i) { val = S::toSpecial(i); return *this; }
    operator T() const { return S::fromSpecial(val); }

    bool operator ==(QSpecialInteger<S> i) const { return val == i.val; }
    bool operator !=(QSpecialInteger<S> i) const { return val != i.val; }

    QSpecialInteger &operator +=(T i)
    {   return (*this = S::fromSpecial(val) + i); }
    QSpecialInteger &operator -=(T i)
    {   return (*this = S::fromSpecial(val) - i); }
    QSpecialInteger &operator *=(T i)
    {   return (*this = S::fromSpecial(val) * i); }
    QSpecialInteger &operator >>=(T i)
    {   return (*this = S::fromSpecial(val) >> i); }
    QSpecialInteger &operator <<=(T i)
    {   return (*this = S::fromSpecial(val) << i); }
    QSpecialInteger &operator /=(T i)
    {   return (*this = S::fromSpecial(val) / i); }
    QSpecialInteger &operator %=(T i)
    {   return (*this = S::fromSpecial(val) % i); }
    QSpecialInteger &operator |=(T i)
    {   return (*this = S::fromSpecial(val) | i); }
    QSpecialInteger &operator &=(T i)
    {   return (*this = S::fromSpecial(val) & i); }
    QSpecialInteger &operator ^=(T i)
    {   return (*this = S::fromSpecial(val) ^ i); }
    QSpecialInteger &operator ++()
    {   return (*this = S::fromSpecial(val) + 1); }
    QSpecialInteger &operator --()
    {   return (*this = S::fromSpecial(val) - 1); }
    QSpecialInteger operator ++(int)
    {
        QSpecialInteger<S> pre = *this;
        *this += 1;
        return pre;
    }
    QSpecialInteger operator --(int)
    {
        QSpecialInteger<S> pre = *this;
        *this -= 1;
        return pre;
    }

    static Q_DECL_CONSTEXPR QSpecialInteger max()
    { return QSpecialInteger(std::numeric_limits<T>::max()); }
    static Q_DECL_CONSTEXPR QSpecialInteger min()
    { return QSpecialInteger(std::numeric_limits<T>::min()); }
};

template<typename T>
class QLittleEndianStorageType {
public:
    typedef T StorageType;
    static Q_DECL_CONSTEXPR T toSpecial(T source) { return qToLittleEndian(source); }
    static Q_DECL_CONSTEXPR T fromSpecial(T source) { return qFromLittleEndian(source); }
};

template<typename T>
class QBigEndianStorageType {
public:
    typedef T StorageType;
    static Q_DECL_CONSTEXPR T toSpecial(T source) { return qToBigEndian(source); }
    static Q_DECL_CONSTEXPR T fromSpecial(T source) { return qFromBigEndian(source); }
};

#ifdef Q_CLANG_QDOC
template<typename T>
class QLEInteger {
public:
    explicit Q_DECL_CONSTEXPR QLEInteger(T i);
    QLEInteger &operator =(T i);
    operator T() const;
    bool operator ==(QLEInteger i) const;
    bool operator !=(QLEInteger i) const;
    QLEInteger &operator +=(T i);
    QLEInteger &operator -=(T i);
    QLEInteger &operator *=(T i);
    QLEInteger &operator >>=(T i);
    QLEInteger &operator <<=(T i);
    QLEInteger &operator /=(T i);
    QLEInteger &operator %=(T i);
    QLEInteger &operator |=(T i);
    QLEInteger &operator &=(T i);
    QLEInteger &operator ^=(T i);
    QLEInteger &operator ++();
    QLEInteger &operator --();
    QLEInteger &operator ++(int);
    QLEInteger &operator --(int);

    static Q_DECL_CONSTEXPR QLEInteger max();
    static Q_DECL_CONSTEXPR QLEInteger min();
};

template<typename T>
class QBEInteger {
public:
    explicit Q_DECL_CONSTEXPR QBEInteger(T i);
    QBEInteger &operator =(T i);
    operator T() const;
    bool operator ==(QBEInteger i) const;
    bool operator !=(QBEInteger i) const;
    QBEInteger &operator +=(T i);
    QBEInteger &operator -=(T i);
    QBEInteger &operator *=(T i);
    QBEInteger &operator >>=(T i);
    QBEInteger &operator <<=(T i);
    QBEInteger &operator /=(T i);
    QBEInteger &operator %=(T i);
    QBEInteger &operator |=(T i);
    QBEInteger &operator &=(T i);
    QBEInteger &operator ^=(T i);
    QBEInteger &operator ++();
    QBEInteger &operator --();
    QBEInteger &operator ++(int);
    QBEInteger &operator --(int);

    static Q_DECL_CONSTEXPR QBEInteger max();
    static Q_DECL_CONSTEXPR QBEInteger min();
};
#else

template<typename T>
using QLEInteger = QSpecialInteger<QLittleEndianStorageType<T>>;

template<typename T>
using QBEInteger = QSpecialInteger<QBigEndianStorageType<T>>;
#endif
template <typename T>
class QTypeInfo<QLEInteger<T> >
    : public QTypeInfoMerger<QLEInteger<T>, T> {};

template <typename T>
class QTypeInfo<QBEInteger<T> >
    : public QTypeInfoMerger<QBEInteger<T>, T> {};

typedef QLEInteger<qint16> qint16_le;
typedef QLEInteger<qint32> qint32_le;
typedef QLEInteger<qint64> qint64_le;
typedef QLEInteger<quint16> quint16_le;
typedef QLEInteger<quint32> quint32_le;
typedef QLEInteger<quint64> quint64_le;

typedef QBEInteger<qint16> qint16_be;
typedef QBEInteger<qint32> qint32_be;
typedef QBEInteger<qint64> qint64_be;
typedef QBEInteger<quint16> quint16_be;
typedef QBEInteger<quint32> quint32_be;
typedef QBEInteger<quint64> quint64_be;

QT_END_NAMESPACE

#endif // QENDIAN_H
