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

#ifndef MOJO_EDK_SYSTEM_MEMORY_H_
#define MOJO_EDK_SYSTEM_MEMORY_H_

#include <stddef.h>
#include <stdint.h>
#include <string.h>  // For |memcpy()|.

#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "mojo/edk/system/system_impl_export.h"
#include "mojo/public/c/system/macros.h"

namespace mojo {
namespace system {

namespace internal {

// Removes |const| from |T| (available as |remove_const<T>::type|):
// TODO(vtl): Remove these once we have the C++11 |remove_const|.
template <typename T>
struct remove_const {
  typedef T type;
};
template <typename T>
struct remove_const<const T> {
  typedef T type;
};

// Yields |(const) char| if |T| is |(const) void|, else |T|:
template <typename T>
struct VoidToChar {
  typedef T type;
};
template <>
struct VoidToChar<void> {
  typedef char type;
};
template <>
struct VoidToChar<const void> {
  typedef const char type;
};

// Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to
// a buffer of the given size and alignment (both in bytes).
template <size_t size, size_t alignment>
void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointer(const void* pointer);

// Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to
// a buffer of |count| elements of the given size and alignment (both in bytes).
template <size_t size, size_t alignment>
void MOJO_SYSTEM_IMPL_EXPORT
    CheckUserPointerWithCount(const void* pointer, size_t count);

// Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to
// a buffer of the given size and alignment (both in bytes).
template <size_t alignment>
void MOJO_SYSTEM_IMPL_EXPORT
    CheckUserPointerWithSize(const void* pointer, size_t size);

}  // namespace internal

// Forward declarations so that they can be friended.
template <typename Type>
class UserPointerReader;
template <typename Type>
class UserPointerWriter;
template <typename Type>
class UserPointerReaderWriter;
template <class Options>
class UserOptionsReader;

// Provides a convenient way to implicitly get null |UserPointer<Type>|s.
struct NullUserPointer {};

// Represents a user pointer to a single |Type| (which must be POD), for Mojo
// primitive parameters.
//
// Use a const |Type| for in parameters, and non-const |Type|s for out and
// in-out parameters (in which case the |Put()| method is available).
template <typename Type>
class UserPointer {
 private:
  typedef typename internal::VoidToChar<Type>::type NonVoidType;

 public:
  // Instead of explicitly using these constructors, you can often use
  // |MakeUserPointer()| (or |NullUserPointer()| for null pointers). (The common
  // exception is when you have, e.g., a |char*| and want to get a
  // |UserPointer<void>|.)
  UserPointer() : pointer_(nullptr) {}
  explicit UserPointer(Type* pointer) : pointer_(pointer) {}
  // Allow implicit conversion from the "null user pointer".
  UserPointer(NullUserPointer) : pointer_(nullptr) {}
  ~UserPointer() {}

  // Allow assignment from the "null user pointer".
  UserPointer<Type>& operator=(NullUserPointer) {
    pointer_ = nullptr;
    return *this;
  }

  // Allow conversion to a "non-const" |UserPointer|.
  operator UserPointer<const Type>() const {
    return UserPointer<const Type>(pointer_);
  }

  bool IsNull() const { return !pointer_; }

  // "Reinterpret casts" to a |UserPointer<ToType>|.
  template <typename ToType>
  UserPointer<ToType> ReinterpretCast() const {
    return UserPointer<ToType>(reinterpret_cast<ToType*>(pointer_));
  }

  // Checks that this pointer points to a valid |Type| in the same way as
  // |Get()| and |Put()|.
  // TODO(vtl): Logically, there should be separate read checks and write
  // checks.
  void Check() const {
    internal::CheckUserPointer<sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(
        pointer_);
  }

  // Checks that this pointer points to a valid array (of type |Type|, or just a
  // buffer if |Type| is |void| or |const void|) of |count| elements (or bytes
  // if |Type| is |void| or |const void|) in the same way as |GetArray()| and
  // |PutArray()|.
  // TODO(vtl): Logically, there should be separate read checks and write
  // checks.
  // TODO(vtl): Switch more things to use this.
  void CheckArray(size_t count) const {
    internal::CheckUserPointerWithCount<sizeof(NonVoidType),
                                        MOJO_ALIGNOF(NonVoidType)>(pointer_,
                                                                   count);
  }

  // Gets the value (of type |Type|, or a |char| if |Type| is |void|) pointed to
  // by this user pointer. Use this when you'd use the rvalue |*user_pointer|,
  // but be aware that this may be costly -- so if the value will be used
  // multiple times, you should save it.
  //
  // (We want to force a copy here, so return |Type| not |const Type&|.)
  NonVoidType Get() const {
    Check();
    internal::CheckUserPointer<sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(
        pointer_);
    return *pointer_;
  }

  // Gets an array (of type |Type|, or just a buffer if |Type| is |void| or
  // |const void|) of |count| elements (or bytes if |Type| is |void| or |const
  // void|) from the location pointed to by this user pointer. Use this when
  // you'd do something like |memcpy(destination, user_pointer, count *
  // sizeof(Type)|.
  void GetArray(typename internal::remove_const<Type>::type* destination,
                size_t count) const {
    CheckArray(count);
    memcpy(destination, pointer_, count * sizeof(NonVoidType));
  }

  // Puts a value (of type |Type|, or of type |char| if |Type| is |void|) to the
  // location pointed to by this user pointer. Use this when you'd use the
  // lvalue |*user_pointer|. Since this may be costly, you should avoid using
  // this (for the same user pointer) more than once.
  //
  // Note: This |Put()| method is not valid when |T| is const, e.g., |const
  // uint32_t|, but it's okay to include them so long as this template is only
  // implicitly instantiated (see 14.7.1 of the C++11 standard) and not
  // explicitly instantiated. (On implicit instantiation, only the declarations
  // need be valid, not the definitions.)
  //
  // In C++11, we could do something like:
  //   template <typename _Type = Type>
  //   typename enable_if<!is_const<_Type>::value &&
  //                      !is_void<_Type>::value>::type Put(
  //       const _Type& value) { ... }
  // (which obviously be correct), but C++03 doesn't allow default function
  // template arguments.
  void Put(const NonVoidType& value) {
    Check();
    *pointer_ = value;
  }

  // Puts an array (of type |Type|, or just a buffer if |Type| is |void|) with
  // |count| elements (or bytes |Type| is |void|) to the location pointed to by
  // this user pointer. Use this when you'd do something like
  // |memcpy(user_pointer, source, count * sizeof(Type))|.
  //
  // Note: The same comments about the validity of |Put()| (except for the part
  // about |void|) apply here.
  void PutArray(const Type* source, size_t count) {
    CheckArray(count);
    memcpy(pointer_, source, count * sizeof(NonVoidType));
  }

  // Gets a |UserPointer| at offset |i| (in |Type|s) relative to this.
  UserPointer At(size_t i) const {
    return UserPointer(
        static_cast<Type*>(static_cast<NonVoidType*>(pointer_) + i));
  }

  // Gets the value of the |UserPointer| as a |uintptr_t|. This should not be
  // casted back to a pointer (and dereferenced), but may be used as a key for
  // lookup or passed back to the user.
  uintptr_t GetPointerValue() const {
    return reinterpret_cast<uintptr_t>(pointer_);
  }

  // These provides safe (read-only/write-only/read-and-write) access to a
  // |UserPointer<Type>| (probably pointing to an array) using just an ordinary
  // pointer (obtained via |GetPointer()|).
  //
  // The memory returned by |GetPointer()| may be a copy of the original user
  // memory, but should be modified only if the user is intended to eventually
  // see the change.) If any changes are made, |Commit()| should be called to
  // guarantee that the changes are written back to user memory (it may be
  // called multiple times).
  //
  // Note: These classes are designed to allow fast, unsafe implementations (in
  // which |GetPointer()| just returns the user pointer) if desired. Thus if
  // |Commit()| is *not* called, changes may or may not be made visible to the
  // user.
  //
  // Use these classes in the following way:
  //
  //   MojoResult Core::PutFoos(UserPointer<const uint32_t> foos,
  //                            uint32_t num_foos) {
  //     UserPointer<const uint32_t>::Reader foos_reader(foos, num_foos);
  //     return PutFoosImpl(foos_reader.GetPointer(), num_foos);
  //   }
  //
  //   MojoResult Core::GetFoos(UserPointer<uint32_t> foos,
  //                            uint32_t num_foos) {
  //     UserPointer<uint32_t>::Writer foos_writer(foos, num_foos);
  //     MojoResult rv = GetFoosImpl(foos.GetPointer(), num_foos);
  //     foos_writer.Commit();
  //     return rv;
  //   }
  //
  // TODO(vtl): Possibly, since we're not really being safe, we should just not
  // copy for Release builds.
  typedef UserPointerReader<Type> Reader;
  typedef UserPointerWriter<Type> Writer;
  typedef UserPointerReaderWriter<Type> ReaderWriter;

 private:
  friend class UserPointerReader<Type>;
  friend class UserPointerReader<const Type>;
  friend class UserPointerWriter<Type>;
  friend class UserPointerReaderWriter<Type>;
  template <class Options>
  friend class UserOptionsReader;

  Type* pointer_;
  // Allow copy and assignment.
};

// Provides a convenient way to make a |UserPointer<Type>|.
template <typename Type>
inline UserPointer<Type> MakeUserPointer(Type* pointer) {
  return UserPointer<Type>(pointer);
}

// Implementation of |UserPointer<Type>::Reader|.
template <typename Type>
class UserPointerReader {
 private:
  typedef typename internal::remove_const<Type>::type TypeNoConst;

 public:
  // Note: If |count| is zero, |GetPointer()| will always return null.
  UserPointerReader(UserPointer<const Type> user_pointer, size_t count) {
    Init(user_pointer.pointer_, count, true);
  }
  UserPointerReader(UserPointer<TypeNoConst> user_pointer, size_t count) {
    Init(user_pointer.pointer_, count, true);
  }

  const Type* GetPointer() const { return buffer_.get(); }

 private:
  template <class Options>
  friend class UserOptionsReader;

  struct NoCheck {};
  UserPointerReader(NoCheck,
                    UserPointer<const Type> user_pointer,
                    size_t count) {
    Init(user_pointer.pointer_, count, false);
  }

  void Init(const Type* user_pointer, size_t count, bool check) {
    if (count == 0)
      return;

    if (check) {
      internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>(
          user_pointer, count);
    }
    buffer_.reset(new TypeNoConst[count]);
    memcpy(buffer_.get(), user_pointer, count * sizeof(Type));
  }

  scoped_ptr<TypeNoConst[]> buffer_;

  DISALLOW_COPY_AND_ASSIGN(UserPointerReader);
};

// Implementation of |UserPointer<Type>::Writer|.
template <typename Type>
class UserPointerWriter {
 public:
  // Note: If |count| is zero, |GetPointer()| will always return null.
  UserPointerWriter(UserPointer<Type> user_pointer, size_t count)
      : user_pointer_(user_pointer), count_(count) {
    if (count_ > 0) {
      buffer_.reset(new Type[count_]);
      memset(buffer_.get(), 0, count_ * sizeof(Type));
    }
  }

  Type* GetPointer() const { return buffer_.get(); }

  void Commit() {
    internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>(
        user_pointer_.pointer_, count_);
    memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type));
  }

 private:
  UserPointer<Type> user_pointer_;
  size_t count_;
  scoped_ptr<Type[]> buffer_;

  DISALLOW_COPY_AND_ASSIGN(UserPointerWriter);
};

// Implementation of |UserPointer<Type>::ReaderWriter|.
template <typename Type>
class UserPointerReaderWriter {
 public:
  // Note: If |count| is zero, |GetPointer()| will always return null.
  UserPointerReaderWriter(UserPointer<Type> user_pointer, size_t count)
      : user_pointer_(user_pointer), count_(count) {
    if (count_ > 0) {
      internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>(
          user_pointer_.pointer_, count_);
      buffer_.reset(new Type[count]);
      memcpy(buffer_.get(), user_pointer.pointer_, count * sizeof(Type));
    }
  }

  Type* GetPointer() const { return buffer_.get(); }
  size_t GetCount() const { return count_; }

  void Commit() {
    internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>(
        user_pointer_.pointer_, count_);
    memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type));
  }

 private:
  UserPointer<Type> user_pointer_;
  size_t count_;
  scoped_ptr<Type[]> buffer_;

  DISALLOW_COPY_AND_ASSIGN(UserPointerReaderWriter);
};

}  // namespace system
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_MEMORY_H_
