/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HIDL_SUPPORT_H
#define ANDROID_HIDL_SUPPORT_H

#include <algorithm>
#include <array>
#include <iterator>
#include <hidl/HidlInternal.h>
#include <map>
#include <sstream>
#include <stddef.h>
#include <tuple>
#include <type_traits>
#include <vector>

// no requirements on types not used in scatter/gather
// no requirements on other libraries
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#include <cutils/native_handle.h>
#include <hidl/Status.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/StrongPointer.h>
#pragma clang diagnostic pop

namespace android {

// this file is included by all hidl interface, so we must forward declare the
// IMemory and IBase types.
namespace hidl {
namespace memory {
namespace V1_0 {

struct IMemory;

}  // namespace V1_0
}  // namespace memory
}  // namespace hidl

namespace hidl {
namespace base {
namespace V1_0 {

struct IBase;

}  // namespace V1_0
}  // namespace base
}  // namespace hidl

namespace hardware {

namespace details {
// Return true on userdebug / eng builds and false on user builds.
bool debuggable();
} //  namespace details

// hidl_death_recipient is a callback interfaced that can be used with
// linkToDeath() / unlinkToDeath()
struct hidl_death_recipient : public virtual RefBase {
    virtual void serviceDied(uint64_t cookie,
            const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
};

// hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
// so that it can safely be transferred between 32-bit and 64-bit processes.
// The ownership semantics for this are:
// 1) The conversion constructor and assignment operator taking a const native_handle_t*
//    do not take ownership of the handle; this is because these operations are usually
//    just done for IPC, and cloning by default is a waste of resources. If you want
//    a hidl_handle to take ownership, call setTo(handle, true /*shouldOwn*/);
// 2) The copy constructor/assignment operator taking a hidl_handle *DO* take ownership;
//    that is because it's not intuitive that this class encapsulates a native_handle_t
//    which needs cloning to be valid; in particular, this allows constructs like this:
//    hidl_handle copy;
//    foo->someHidlCall([&](auto incoming_handle) {
//            copy = incoming_handle;
//    });
//    // copy and its enclosed file descriptors will remain valid here.
// 3) The move constructor does what you would expect; it only owns the handle if the
//    original did.
struct hidl_handle {
    hidl_handle();
    ~hidl_handle();

    hidl_handle(const native_handle_t *handle);

    // copy constructor.
    hidl_handle(const hidl_handle &other);

    // move constructor.
    hidl_handle(hidl_handle &&other) noexcept;

    // assignment operators
    hidl_handle &operator=(const hidl_handle &other);

    hidl_handle &operator=(const native_handle_t *native_handle);

    hidl_handle &operator=(hidl_handle &&other) noexcept;

    void setTo(native_handle_t* handle, bool shouldOwn = false);

    const native_handle_t* operator->() const;

    // implicit conversion to const native_handle_t*
    operator const native_handle_t *() const;

    // explicit conversion
    const native_handle_t *getNativeHandle() const;

    // offsetof(hidl_handle, mHandle) exposed since mHandle is private.
    static const size_t kOffsetOfNativeHandle;

private:
    void freeHandle();

    details::hidl_pointer<const native_handle_t> mHandle;
    bool mOwnsHandle;
    uint8_t mPad[7];
};

struct hidl_string {
    hidl_string();
    ~hidl_string();

    // copy constructor.
    hidl_string(const hidl_string &);
    // copy from a C-style string. nullptr will create an empty string
    hidl_string(const char *);
    // copy the first length characters from a C-style string.
    hidl_string(const char *, size_t length);
    // copy from an std::string.
    hidl_string(const std::string &);

    // move constructor.
    hidl_string(hidl_string &&) noexcept;

    const char *c_str() const;
    size_t size() const;
    bool empty() const;

    // copy assignment operator.
    hidl_string &operator=(const hidl_string &);
    // copy from a C-style string.
    hidl_string &operator=(const char *s);
    // copy from an std::string.
    hidl_string &operator=(const std::string &);
    // move assignment operator.
    hidl_string &operator=(hidl_string &&other) noexcept;
    // cast to std::string.
    operator std::string() const;

    void clear();

    // Reference an external char array. Ownership is _not_ transferred.
    // Caller is responsible for ensuring that underlying memory is valid
    // for the lifetime of this hidl_string.
    //
    // size == strlen(data)
    void setToExternal(const char *data, size_t size);

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;

private:
    details::hidl_pointer<const char> mBuffer;
    uint32_t mSize;  // NOT including the terminating '\0'.
    bool mOwnsBuffer; // if true then mBuffer is a mutable char *
    uint8_t mPad[3];

    // copy from data with size. Assume that my memory is freed
    // (through clear(), for example)
    void copyFrom(const char *data, size_t size);
    // move from another hidl_string
    void moveFrom(hidl_string &&);
};

// Use NOLINT to suppress missing parentheses warnings around OP.
#define HIDL_STRING_OPERATOR(OP)                                              \
    inline bool operator OP(const hidl_string& hs1, const hidl_string& hs2) { \
        return strcmp(hs1.c_str(), hs2.c_str()) OP 0; /* NOLINT */            \
    }                                                                         \
    inline bool operator OP(const hidl_string& hs, const char* s) {           \
        return strcmp(hs.c_str(), s) OP 0; /* NOLINT */                       \
    }                                                                         \
    inline bool operator OP(const char* s, const hidl_string& hs) {           \
        return strcmp(s, hs.c_str()) OP 0; /* NOLINT */                       \
    }

HIDL_STRING_OPERATOR(==)
HIDL_STRING_OPERATOR(!=)
HIDL_STRING_OPERATOR(<)
HIDL_STRING_OPERATOR(<=)
HIDL_STRING_OPERATOR(>)
HIDL_STRING_OPERATOR(>=)

#undef HIDL_STRING_OPERATOR

// Send our content to the output stream
std::ostream& operator<<(std::ostream& os, const hidl_string& str);


// hidl_memory is a structure that can be used to transfer
// pieces of shared memory between processes. The assumption
// of this object is that the memory remains accessible as
// long as the file descriptors in the enclosed mHandle
// - as well as all of its cross-process dups() - remain opened.
struct hidl_memory {

    hidl_memory() : mHandle(nullptr), mSize(0), mName("") {
    }

    /**
     * Creates a hidl_memory object whose handle has the same lifetime
     * as the handle moved into it.
     */
    hidl_memory(const hidl_string& name, hidl_handle&& handle, size_t size)
        : mHandle(std::move(handle)), mSize(size), mName(name) {}

    /**
     * Creates a hidl_memory object, but doesn't take ownership of
     * the passed in native_handle_t; callers are responsible for
     * making sure the handle remains valid while this object is
     * used.
     */
    hidl_memory(const hidl_string &name, const native_handle_t *handle, size_t size)
      :  mHandle(handle),
         mSize(size),
         mName(name)
    {}

    // copy constructor
    hidl_memory(const hidl_memory& other) {
        *this = other;
    }

    // copy assignment
    hidl_memory &operator=(const hidl_memory &other) {
        if (this != &other) {
            mHandle = other.mHandle;
            mSize = other.mSize;
            mName = other.mName;
        }

        return *this;
    }

    // move constructor
    hidl_memory(hidl_memory&& other) noexcept {
        *this = std::move(other);
    }

    // move assignment
    hidl_memory &operator=(hidl_memory &&other) noexcept {
        if (this != &other) {
            mHandle = std::move(other.mHandle);
            mSize = other.mSize;
            mName = std::move(other.mName);
            other.mSize = 0;
        }

        return *this;
    }


    ~hidl_memory() {
    }

    const native_handle_t* handle() const {
        return mHandle;
    }

    const hidl_string &name() const {
        return mName;
    }

    uint64_t size() const {
        return mSize;
    }

    // @return true if it's valid
    inline bool valid() const { return handle() != nullptr; }

    // offsetof(hidl_memory, mHandle) exposed since mHandle is private.
    static const size_t kOffsetOfHandle;
    // offsetof(hidl_memory, mName) exposed since mHandle is private.
    static const size_t kOffsetOfName;

private:
    hidl_handle mHandle;
    uint64_t mSize;
    hidl_string mName;
};

// HidlMemory is a wrapper class to support sp<> for hidl_memory. It also
// provides factory methods to create an instance from hidl_memory or
// from a opened file descriptor. The number of factory methods can be increase
// to support other type of hidl_memory without break the ABI.
class HidlMemory : public virtual hidl_memory, public virtual ::android::RefBase {
public:
    static sp<HidlMemory> getInstance(const hidl_memory& mem);

    static sp<HidlMemory> getInstance(hidl_memory&& mem);

    static sp<HidlMemory> getInstance(const hidl_string& name, hidl_handle&& handle, uint64_t size);
    // @param fd, shall be opened and points to the resource.
    // @note this method takes the ownership of the fd and will close it in
    //     destructor
    // @return nullptr in failure with the fd closed
    static sp<HidlMemory> getInstance(const hidl_string& name, int fd, uint64_t size);

    virtual ~HidlMemory();

protected:
    HidlMemory();
    HidlMemory(const hidl_string& name, hidl_handle&& handle, size_t size);
};
////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct hidl_vec {
    using value_type = T;

    hidl_vec() : mBuffer(nullptr), mSize(0), mOwnsBuffer(false) {
        static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");

        memset(mPad, 0, sizeof(mPad));
    }

    hidl_vec(size_t size) : hidl_vec() { resize(size); }

    hidl_vec(const hidl_vec<T> &other) : hidl_vec() {
        *this = other;
    }

    hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() {
        *this = std::move(other);
    }

    hidl_vec(const std::initializer_list<T> list) : hidl_vec() { *this = list; }

    hidl_vec(const std::vector<T> &other) : hidl_vec() {
        *this = other;
    }

    template <typename InputIterator,
              typename = typename std::enable_if<std::is_convertible<
                  typename std::iterator_traits<InputIterator>::iterator_category,
                  std::input_iterator_tag>::value>::type>
    hidl_vec(InputIterator first, InputIterator last) : hidl_vec() {
        auto size = std::distance(first, last);
        if (size > static_cast<int64_t>(UINT32_MAX)) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        if (size < 0) {
            details::logAlwaysFatal("size can't be negative.");
        }
        mSize = static_cast<uint32_t>(size);
        mBuffer = new T[mSize]();
        mOwnsBuffer = true;

        size_t idx = 0;
        for (; first != last; ++first) {
            mBuffer[idx++] = static_cast<T>(*first);
        }
    }

    ~hidl_vec() {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = nullptr;
    }

    // Reference an existing array, optionally taking ownership. It is the
    // caller's responsibility to ensure that the underlying memory stays
    // valid for the lifetime of this hidl_vec.
    void setToExternal(T *data, size_t size, bool shouldOwn = false) {
        if (mOwnsBuffer) {
            delete [] mBuffer;
        }
        mBuffer = data;
        if (size > UINT32_MAX) {
            details::logAlwaysFatal("external vector size exceeds 2^32 elements.");
        }
        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = shouldOwn;
    }

    T *data() {
        return mBuffer;
    }

    const T *data() const {
        return mBuffer;
    }

    T *releaseData() {
        if (!mOwnsBuffer && mBuffer != nullptr) {
            resize(mSize);
        }
        mOwnsBuffer = false;
        return mBuffer;
    }

    hidl_vec &operator=(hidl_vec &&other) noexcept {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = other.mBuffer;
        mSize = other.mSize;
        mOwnsBuffer = other.mOwnsBuffer;
        other.mOwnsBuffer = false;
        return *this;
    }

    hidl_vec &operator=(const hidl_vec &other) {
        if (this != &other) {
            if (mOwnsBuffer) {
                delete[] mBuffer;
            }
            copyFrom(other, other.mSize);
        }

        return *this;
    }

    // copy from an std::vector.
    hidl_vec &operator=(const std::vector<T> &other) {
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        copyFrom(other, other.size());
        return *this;
    }

    hidl_vec& operator=(const std::initializer_list<T> list) {
        if (list.size() > UINT32_MAX) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mSize = static_cast<uint32_t>(list.size());
        mBuffer = new T[mSize]();
        mOwnsBuffer = true;

        size_t idx = 0;
        for (auto it = list.begin(); it != list.end(); ++it) {
            mBuffer[idx++] = *it;
        }
        return *this;
    }

    // cast to an std::vector.
    operator std::vector<T>() const {
        std::vector<T> v(mSize);
        for (size_t i = 0; i < mSize; ++i) {
            v[i] = mBuffer[i];
        }
        return v;
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_vec &other) const {
        if (mSize != other.size()) {
            return false;
        }
        for (size_t i = 0; i < mSize; ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    // inequality check, assuming that T::operator== is defined.
    inline bool operator!=(const hidl_vec &other) const {
        return !((*this) == other);
    }

    size_t size() const {
        return mSize;
    }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    // Copies over old elements fitting in new size. Value initializes the rest.
    void resize(size_t size) {
        if (size > UINT32_MAX) {
            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
        }
        T* newBuffer = new T[size]();

        for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
            newBuffer[i] = std::move(mBuffer[i]);
        }

        if (mOwnsBuffer) {
            delete[] mBuffer;
        }
        mBuffer = newBuffer;

        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = true;
    }

    // offsetof(hidl_string, mBuffer) exposed since mBuffer is private.
    static const size_t kOffsetOfBuffer;

private:
    // Define std interator interface for walking the array contents
    template<bool is_const>
    class iter : public std::iterator<
            std::random_access_iterator_tag, /* Category */
            T,
            ptrdiff_t, /* Distance */
            typename std::conditional<is_const, const T *, T *>::type /* Pointer */,
            typename std::conditional<is_const, const T &, T &>::type /* Reference */>
    {
        using traits = std::iterator_traits<iter>;
        using ptr_type = typename traits::pointer;
        using ref_type = typename traits::reference;
        using diff_type = typename traits::difference_type;
    public:
        iter(ptr_type ptr) : mPtr(ptr) { }
        inline iter &operator++()    { mPtr++; return *this; }
        inline iter  operator++(int) { iter i = *this; mPtr++; return i; }
        inline iter &operator--()    { mPtr--; return *this; }
        inline iter  operator--(int) { iter i = *this; mPtr--; return i; }
        inline friend iter operator+(diff_type n, const iter &it) { return it.mPtr + n; }
        inline iter  operator+(diff_type n) const { return mPtr + n; }
        inline iter  operator-(diff_type n) const { return mPtr - n; }
        inline diff_type operator-(const iter &other) const { return mPtr - other.mPtr; }
        inline iter &operator+=(diff_type n) { mPtr += n; return *this; }
        inline iter &operator-=(diff_type n) { mPtr -= n; return *this; }
        inline ref_type operator*() const  { return *mPtr; }
        inline ptr_type operator->() const { return mPtr; }
        inline bool operator==(const iter &rhs) const { return mPtr == rhs.mPtr; }
        inline bool operator!=(const iter &rhs) const { return mPtr != rhs.mPtr; }
        inline bool operator< (const iter &rhs) const { return mPtr <  rhs.mPtr; }
        inline bool operator> (const iter &rhs) const { return mPtr >  rhs.mPtr; }
        inline bool operator<=(const iter &rhs) const { return mPtr <= rhs.mPtr; }
        inline bool operator>=(const iter &rhs) const { return mPtr >= rhs.mPtr; }
        inline ref_type operator[](size_t n) const { return mPtr[n]; }
    private:
        ptr_type mPtr;
    };
public:
    using iterator       = iter<false /* is_const */>;
    using const_iterator = iter<true  /* is_const */>;

    iterator begin() { return data(); }
    iterator end() { return data()+mSize; }
    const_iterator begin() const { return data(); }
    const_iterator end() const { return data()+mSize; }
    iterator find(const T& v) { return std::find(begin(), end(), v); }
    const_iterator find(const T& v) const { return std::find(begin(), end(), v); }
    bool contains(const T& v) const { return find(v) != end(); }

  private:
    details::hidl_pointer<T> mBuffer;
    uint32_t mSize;
    bool mOwnsBuffer;
    uint8_t mPad[3];

    // copy from an array-like object, assuming my resources are freed.
    template <typename Array>
    void copyFrom(const Array &data, size_t size) {
        mSize = static_cast<uint32_t>(size);
        mOwnsBuffer = true;
        if (mSize > 0) {
            mBuffer = new T[size]();
            for (size_t i = 0; i < size; ++i) {
                mBuffer[i] = data[i];
            }
        } else {
            mBuffer = nullptr;
        }
    }
};

template <typename T>
const size_t hidl_vec<T>::kOffsetOfBuffer = offsetof(hidl_vec<T>, mBuffer);

////////////////////////////////////////////////////////////////////////////////

namespace details {

    template<size_t SIZE1, size_t... SIZES>
    struct product {
        static constexpr size_t value = SIZE1 * product<SIZES...>::value;
    };

    template<size_t SIZE1>
    struct product<SIZE1> {
        static constexpr size_t value = SIZE1;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct std_array {
        using type = std::array<typename std_array<T, SIZES...>::type, SIZE1>;
    };

    template<typename T, size_t SIZE1>
    struct std_array<T, SIZE1> {
        using type = std::array<T, SIZE1>;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct accessor {

        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;

        explicit accessor(T *base)
            : mBase(base) {
        }

        accessor<T, SIZES...> operator[](size_t index) {
            return accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

        accessor &operator=(const std_array_type &other) {
            for (size_t i = 0; i < SIZE1; ++i) {
                (*this)[i] = other[i];
            }
            return *this;
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct accessor<T, SIZE1> {

        using std_array_type = typename std_array<T, SIZE1>::type;

        explicit accessor(T *base)
            : mBase(base) {
        }

        T &operator[](size_t index) {
            return mBase[index];
        }

        accessor &operator=(const std_array_type &other) {
            for (size_t i = 0; i < SIZE1; ++i) {
                (*this)[i] = other[i];
            }
            return *this;
        }

    private:
        T *mBase;
    };

    template<typename T, size_t SIZE1, size_t... SIZES>
    struct const_accessor {

        using std_array_type = typename std_array<T, SIZE1, SIZES...>::type;

        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const_accessor<T, SIZES...> operator[](size_t index) const {
            return const_accessor<T, SIZES...>(
                    &mBase[index * product<SIZES...>::value]);
        }

        operator std_array_type() {
            std_array_type array;
            for (size_t i = 0; i < SIZE1; ++i) {
                array[i] = (*this)[i];
            }
            return array;
        }

    private:
        const T *mBase;
    };

    template<typename T, size_t SIZE1>
    struct const_accessor<T, SIZE1> {

        using std_array_type = typename std_array<T, SIZE1>::type;

        explicit const_accessor(const T *base)
            : mBase(base) {
        }

        const T &operator[](size_t index) const {
            return mBase[index];
        }

        operator std_array_type() {
            std_array_type array;
            for (size_t i = 0; i < SIZE1; ++i) {
                array[i] = (*this)[i];
            }
            return array;
        }

    private:
        const T *mBase;
    };

}  // namespace details

////////////////////////////////////////////////////////////////////////////////

// A multidimensional array of T's. Assumes that T::operator=(const T &) is defined.
template<typename T, size_t SIZE1, size_t... SIZES>
struct hidl_array {

    using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;

    hidl_array() = default;
    hidl_array(const hidl_array&) noexcept = default;
    hidl_array(hidl_array&&) noexcept = default;

    // Copies the data from source, using T::operator=(const T &).
    hidl_array(const T *source) {
        for (size_t i = 0; i < elementCount(); ++i) {
            mBuffer[i] = source[i];
        }
    }

    // Copies the data from the given std::array, using T::operator=(const T &).
    hidl_array(const std_array_type &array) {
        details::accessor<T, SIZE1, SIZES...> modifier(mBuffer);
        modifier = array;
    }

    hidl_array& operator=(const hidl_array&) noexcept = default;
    hidl_array& operator=(hidl_array&&) noexcept = default;

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    details::accessor<T, SIZES...> operator[](size_t index) {
        return details::accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    details::const_accessor<T, SIZES...> operator[](size_t index) const {
        return details::const_accessor<T, SIZES...>(
                &mBuffer[index * details::product<SIZES...>::value]);
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_array &other) const {
        for (size_t i = 0; i < elementCount(); ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    inline bool operator!=(const hidl_array &other) const {
        return !((*this) == other);
    }

    using size_tuple_type = std::tuple<decltype(SIZE1), decltype(SIZES)...>;

    static constexpr size_tuple_type size() {
        return std::make_tuple(SIZE1, SIZES...);
    }

    static constexpr size_t elementCount() {
        return details::product<SIZE1, SIZES...>::value;
    }

    operator std_array_type() const {
        return details::const_accessor<T, SIZE1, SIZES...>(mBuffer);
    }

private:
    T mBuffer[elementCount()];
};

// An array of T's. Assumes that T::operator=(const T &) is defined.
template<typename T, size_t SIZE1>
struct hidl_array<T, SIZE1> {
    using value_type = T;
    using std_array_type = typename details::std_array<T, SIZE1>::type;

    hidl_array() = default;
    hidl_array(const hidl_array&) noexcept = default;
    hidl_array(hidl_array&&) noexcept = default;

    // Copies the data from source, using T::operator=(const T &).
    hidl_array(const T *source) {
        for (size_t i = 0; i < elementCount(); ++i) {
            mBuffer[i] = source[i];
        }
    }

    // Copies the data from the given std::array, using T::operator=(const T &).
    hidl_array(const std_array_type &array) : hidl_array(array.data()) {}

    hidl_array& operator=(const hidl_array&) noexcept = default;
    hidl_array& operator=(hidl_array&&) noexcept = default;

    T *data() { return mBuffer; }
    const T *data() const { return mBuffer; }

    T &operator[](size_t index) {
        return mBuffer[index];
    }

    const T &operator[](size_t index) const {
        return mBuffer[index];
    }

    // equality check, assuming that T::operator== is defined.
    bool operator==(const hidl_array &other) const {
        for (size_t i = 0; i < elementCount(); ++i) {
            if (!(mBuffer[i] == other.mBuffer[i])) {
                return false;
            }
        }
        return true;
    }

    inline bool operator!=(const hidl_array &other) const {
        return !((*this) == other);
    }

    static constexpr size_t size() { return SIZE1; }
    static constexpr size_t elementCount() { return SIZE1; }

    // Copies the data to an std::array, using T::operator=(T).
    operator std_array_type() const {
        std_array_type array;
        for (size_t i = 0; i < SIZE1; ++i) {
            array[i] = mBuffer[i];
        }
        return array;
    }

private:
    T mBuffer[SIZE1];
};

// ----------------------------------------------------------------------
// Version functions
struct hidl_version {
public:
    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
        static_assert(sizeof(*this) == 4, "wrong size");
    }

    bool operator==(const hidl_version& other) const {
        return (mMajor == other.get_major() && mMinor == other.get_minor());
    }

    bool operator!=(const hidl_version& other) const {
        return !(*this == other);
    }

    bool operator<(const hidl_version& other) const {
        return (mMajor < other.get_major() ||
                (mMajor == other.get_major() && mMinor < other.get_minor()));
    }

    bool operator>(const hidl_version& other) const {
        return other < *this;
    }

    bool operator<=(const hidl_version& other) const {
        return !(*this > other);
    }

    bool operator>=(const hidl_version& other) const {
        return !(*this < other);
    }

    constexpr uint16_t get_major() const { return mMajor; }
    constexpr uint16_t get_minor() const { return mMinor; }

private:
    uint16_t mMajor;
    uint16_t mMinor;
};

inline android::hardware::hidl_version make_hidl_version(uint16_t major, uint16_t minor) {
    return hidl_version(major,minor);
}

///////////////////// toString functions

std::string toString(const void *t);

// toString alias for numeric types
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
inline std::string toString(T t) {
    return std::to_string(t);
}

namespace details {

template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
inline std::string toHexString(T t, bool prefix = true) {
    std::ostringstream os;
    if (prefix) { os << std::showbase; }
    os << std::hex << t;
    return os.str();
}

template<>
inline std::string toHexString(uint8_t t, bool prefix) {
    return toHexString(static_cast<int32_t>(t), prefix);
}

template<>
inline std::string toHexString(int8_t t, bool prefix) {
    return toHexString(static_cast<int32_t>(t), prefix);
}

template<typename Array>
std::string arrayToString(const Array &a, size_t size);

template<size_t SIZE1>
std::string arraySizeToString() {
    return std::string{"["} + toString(SIZE1) + "]";
}

template<size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string arraySizeToString() {
    return std::string{"["} + toString(SIZE1) + "]" + arraySizeToString<SIZE2, SIZES...>();
}

template<typename T, size_t SIZE1>
std::string toString(details::const_accessor<T, SIZE1> a) {
    return arrayToString(a, SIZE1);
}

template<typename Array>
std::string arrayToString(const Array &a, size_t size) {
    using android::hardware::toString;
    std::string os;
    os += "{";
    for (size_t i = 0; i < size; ++i) {
        if (i > 0) {
            os += ", ";
        }
        os += toString(a[i]);
    }
    os += "}";
    return os;
}

template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...> a) {
    return arrayToString(a, SIZE1);
}

}  //namespace details

inline std::string toString(const void *t) {
    return details::toHexString(reinterpret_cast<uintptr_t>(t));
}

// debug string dump. There will be quotes around the string!
inline std::string toString(const hidl_string &hs) {
    return std::string{"\""} + hs.c_str() + "\"";
}

// debug string dump
inline std::string toString(const hidl_handle &hs) {
    return toString(hs.getNativeHandle());
}

inline std::string toString(const hidl_memory &mem) {
    return std::string{"memory {.name = "} + toString(mem.name()) + ", .size = "
              + toString(mem.size())
              + ", .handle = " + toString(mem.handle()) + "}";
}

inline std::string toString(const sp<hidl_death_recipient> &dr) {
    return std::string{"death_recipient@"} + toString(dr.get());
}

// debug string dump, assuming that toString(T) is defined.
template<typename T>
std::string toString(const hidl_vec<T> &a) {
    std::string os;
    os += "[" + toString(a.size()) + "]";
    os += details::arrayToString(a, a.size());
    return os;
}

template<typename T, size_t SIZE1>
std::string toString(const hidl_array<T, SIZE1> &a) {
    return details::arraySizeToString<SIZE1>()
            + details::toString(details::const_accessor<T, SIZE1>(a.data()));
}

template<typename T, size_t SIZE1, size_t SIZE2, size_t... SIZES>
std::string toString(const hidl_array<T, SIZE1, SIZE2, SIZES...> &a) {
    return details::arraySizeToString<SIZE1, SIZE2, SIZES...>()
            + details::toString(details::const_accessor<T, SIZE1, SIZE2, SIZES...>(a.data()));
}

namespace details {
// Never instantiated. Used as a placeholder for template variables.
template <typename T>
struct hidl_invalid_type;

// HIDL generates specializations of this for enums. See hidl_enum_range.
template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
constexpr hidl_invalid_type<T> hidl_enum_values;
}  // namespace details

/**
 * Every HIDL generated enum supports this function.
 * E.x.: for(const auto v : hidl_enum_range<Enum>) { ... }
 */
template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
struct hidl_enum_range {
    // Container-like associated type.
    using value_type = T;

    constexpr auto begin() const { return std::begin(details::hidl_enum_values<T>); }
    constexpr auto cbegin() const { return begin(); }
    constexpr auto rbegin() const { return std::rbegin(details::hidl_enum_values<T>); }
    constexpr auto crbegin() const { return rbegin(); }
    constexpr auto end() const { return std::end(details::hidl_enum_values<T>); }
    constexpr auto cend() const { return end(); }
    constexpr auto rend() const { return std::rend(details::hidl_enum_values<T>); }
    constexpr auto crend() const { return rend(); }
};

template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
struct hidl_enum_iterator {
    static_assert(!std::is_enum<T>::value,
                  "b/78573628: hidl_enum_iterator was renamed to hidl_enum_range because it is not "
                  "actually an iterator. Please use that type instead.");
};

/**
 * Bitfields in HIDL are the underlying type of the enumeration.
 */
template <typename Enum>
using hidl_bitfield = typename std::underlying_type<Enum>::type;

}  // namespace hardware
}  // namespace android


#endif  // ANDROID_HIDL_SUPPORT_H
