Index: mojo/system/memory.h |
diff --git a/mojo/system/memory.h b/mojo/system/memory.h |
index 1a6f7ec20fa8790eeefb4b1cda08e990cc6778a4..512a05d4e307102f62b22a69ba552ba1440aca11 100644 |
--- a/mojo/system/memory.h |
+++ b/mojo/system/memory.h |
@@ -29,13 +29,22 @@ 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 CheckUserPointerHelper(const void* pointer); |
+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 CheckUserPointerWithCountHelper( |
- const void* pointer, |
- size_t count); |
+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); |
// TODO(vtl): Delete all the |Verify...()| things (and replace them with |
// |Check...()|. |
@@ -54,6 +63,7 @@ bool MOJO_SYSTEM_IMPL_EXPORT VerifyUserPointerWithCountHelper( |
template <typename Type> class UserPointerReader; |
template <typename Type> class UserPointerWriter; |
template <typename Type> class UserPointerReaderWriter; |
+template <class Options> class UserOptionsReader; |
// Verify (insofar as possible/necessary) that a |T| can be read from the user |
// |pointer|. |
@@ -118,14 +128,31 @@ class UserPointer { |
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 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|) 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&|.) |
Type Get() const { |
- internal::CheckUserPointerHelper<sizeof(Type), |
- MOJO_ALIGNOF(Type)>(pointer_); |
+ internal::CheckUserPointer<sizeof(Type), MOJO_ALIGNOF(Type)>(pointer_); |
return *pointer_; |
} |
@@ -135,8 +162,8 @@ class UserPointer { |
// you'd do something like |memcpy(destination, user_pointer, count * |
// sizeof(Type)|. |
void GetArray(typename internal::remove_const<Type>::type* destination, |
- size_t count) { |
- internal::CheckUserPointerWithCountHelper< |
+ size_t count) const { |
+ internal::CheckUserPointerWithCount< |
sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); |
memcpy(destination, pointer_, count * sizeof(NonVoidType)); |
} |
@@ -163,8 +190,8 @@ class UserPointer { |
// (which obviously be correct), but C++03 doesn't allow default function |
// template arguments. |
void Put(const NonVoidType& value) { |
- internal::CheckUserPointerHelper<sizeof(NonVoidType), |
- MOJO_ALIGNOF(NonVoidType)>(pointer_); |
+ internal::CheckUserPointer<sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>( |
+ pointer_); |
*pointer_ = value; |
} |
@@ -176,7 +203,7 @@ class UserPointer { |
// 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) { |
- internal::CheckUserPointerWithCountHelper< |
+ internal::CheckUserPointerWithCount< |
sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); |
memcpy(pointer_, source, count * sizeof(NonVoidType)); |
} |
@@ -187,13 +214,6 @@ class UserPointer { |
static_cast<NonVoidType*>(pointer_) + i)); |
} |
- // TODO(vtl): This is temporary. Get rid of this. (We should pass |
- // |UserPointer<>|s along appropriately, or access data in a safe way |
- // everywhere.) |
- Type* GetPointerUnsafe() const { |
- return 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()|). |
@@ -233,8 +253,10 @@ class UserPointer { |
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. |
@@ -253,19 +275,34 @@ class UserPointerReader { |
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); |
+ Init(user_pointer.pointer_, count, true); |
} |
UserPointerReader(UserPointer<TypeNoConst> user_pointer, size_t count) { |
- Init(user_pointer.pointer_, count); |
+ Init(user_pointer.pointer_, count, true); |
} |
const Type* GetPointer() const { return buffer_.get(); } |
private: |
- void Init(const Type* user_pointer, size_t count) { |
- internal::CheckUserPointerWithCountHelper< |
- sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer, count); |
+ 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)); |
} |
@@ -279,18 +316,21 @@ class UserPointerReader { |
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) { |
- buffer_.reset(new Type[count_]); |
- memset(buffer_.get(), 0, count_ * sizeof(Type)); |
+ if (count_ > 0) { |
+ buffer_.reset(new Type[count_]); |
+ memset(buffer_.get(), 0, count_ * sizeof(Type)); |
+ } |
} |
Type* GetPointer() const { return buffer_.get(); } |
void Commit() { |
- internal::CheckUserPointerWithCountHelper< |
- sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |
+ internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( |
+ user_pointer_.pointer_, count_); |
memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); |
} |
@@ -306,21 +346,24 @@ class UserPointerWriter { |
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) { |
- internal::CheckUserPointerWithCountHelper< |
- sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |
- buffer_.reset(new Type[count]); |
- memcpy(buffer_.get(), user_pointer.pointer_, count * sizeof(Type)); |
+ 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::CheckUserPointerWithCountHelper< |
- sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |
+ internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( |
+ user_pointer_.pointer_, count_); |
memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); |
} |