// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <arch/user_copy.h>
#include <fbl/type_support.h>
#include <lib/user_copy/internal.h>
#include <zircon/types.h>
#include <vm/vm.h>

// user_ptr<> wraps a pointer to user memory, to differentiate it from kernel
// memory.
template <typename T>
class user_ptr {
public:
    explicit user_ptr(T* p) : ptr_(p) {}

    user_ptr(const user_ptr& other) : ptr_(other.ptr_) {}

    user_ptr& operator=(const user_ptr& other) {
        ptr_ = other.ptr_;
        return *this;
    }

    T* get() const { return ptr_; }

    template <typename C>
    user_ptr<C> reinterpret() const { return user_ptr<C>(reinterpret_cast<C*>(ptr_)); }

    // special operator to return the nullness of the pointer
    explicit operator bool() const { return ptr_ != nullptr; }

    // Returns a user_ptr pointing to the |index|-th element from this one, or a null user_ptr if
    // this pointer is null. Note: This does no other validation, and the behavior is undefined on
    // overflow. (Using this will fail to compile if T is |void|.)
    user_ptr element_offset(size_t index) const {
        return ptr_ ? user_ptr(ptr_ + index) : user_ptr(nullptr);
    }

    // Returns a user_ptr offset by |offset| bytes from this one.
    user_ptr byte_offset(size_t offset) const {
        return ptr_ ? user_ptr(reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(ptr_) + offset))
                    : user_ptr(nullptr);
    }

    // Copies a single T to user memory. (Using this will fail to compile if T is |void|.)
    // Note: The templatization is simply to allow the class to compile if T is |void|.
    template <typename S = T>
    zx_status_t copy_to_user(const S& src) const {
        static_assert(fbl::is_same<S, T>::value, "Do not use the template parameter.");
        return arch_copy_to_user(ptr_, &src, sizeof(S));
    }

    // Copies an array of T to user memory. Note: This takes a count not a size, unless T is |void|.
    // WARNING: This does not check that |count| is reasonable (i.e., that multiplication won't
    // overflow).
    zx_status_t copy_array_to_user(const T* src, size_t count) const {
        return arch_copy_to_user(ptr_, src, count * internal::type_size<T>());
    }

    // Copies an array of T to user memory. Note: This takes a count not a size, unless T is |void|.
    // WARNING: This does not check that |count| is reasonable (i.e., that multiplication won't
    // overflow).
    zx_status_t copy_array_to_user(const T* src, size_t count, size_t offset) const {
        return arch_copy_to_user(ptr_ + offset, src, count * internal::type_size<T>());
    }

    // Copies a single T from user memory. (Using this will fail to compile if T is |void|.)
    zx_status_t copy_from_user(typename fbl::remove_const<T>::type* dst) const {
        // Intentionally use sizeof(T) here, so *using* this method won't compile if T is |void|.
        return arch_copy_from_user(dst, ptr_, sizeof(T));
    }

    // Copies an array of T from user memory. Note: This takes a count not a size, unless T is
    // |void|.
    // WARNING: This does not check that |count| is reasonable (i.e., that multiplication won't
    // overflow).
    zx_status_t copy_array_from_user(typename fbl::remove_const<T>::type* dst, size_t count) const {
        return arch_copy_from_user(dst, ptr_, count * internal::type_size<T>());
    }

    // Copies a sub-array of T from user memory. Note: This takes a count not a size, unless T is
    // |void|.
    // WARNING: This does not check that |count| is reasonable (i.e., that multiplication won't
    // overflow).
    zx_status_t copy_array_from_user(typename fbl::remove_const<T>::type* dst, size_t count, size_t offset) const {
        return arch_copy_from_user(dst, ptr_ + offset, count * internal::type_size<T>());
    }

private:
    // It is very important that this class only wrap the pointer type itself
    // and not include any other members so as not to break the ABI between
    // the kernel and user space.
    T* ptr_;
};

template <typename T>
user_ptr<T> make_user_ptr(T* p) { return user_ptr<T>(p); }
