| OLD | NEW | 
|    1 // Copyright 2013 The Chromium Authors. All rights reserved. |    1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #ifndef MOJO_SYSTEM_MEMORY_H_ |    5 #ifndef MOJO_SYSTEM_MEMORY_H_ | 
|    6 #define MOJO_SYSTEM_MEMORY_H_ |    6 #define MOJO_SYSTEM_MEMORY_H_ | 
|    7  |    7  | 
|    8 #include <stddef.h> |    8 #include <stddef.h> | 
|    9 #include <stdint.h> |    9 #include <stdint.h> | 
|   10 #include <string.h>  // For |memcpy()|. |   10 #include <string.h>  // For |memcpy()|. | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   22 // Removes |const| from |T| (available as |remove_const<T>::type|): |   22 // Removes |const| from |T| (available as |remove_const<T>::type|): | 
|   23 // TODO(vtl): Remove these once we have the C++11 |remove_const|. |   23 // TODO(vtl): Remove these once we have the C++11 |remove_const|. | 
|   24 template <typename T> struct remove_const { typedef T type; }; |   24 template <typename T> struct remove_const { typedef T type; }; | 
|   25 template <typename T> struct remove_const<const T> { typedef T type; }; |   25 template <typename T> struct remove_const<const T> { typedef T type; }; | 
|   26  |   26  | 
|   27 // Yields |(const) char| if |T| is |(const) void|, else |T|: |   27 // Yields |(const) char| if |T| is |(const) void|, else |T|: | 
|   28 template <typename T> struct VoidToChar { typedef T type; }; |   28 template <typename T> struct VoidToChar { typedef T type; }; | 
|   29 template <> struct VoidToChar<void> { typedef char type; }; |   29 template <> struct VoidToChar<void> { typedef char type; }; | 
|   30 template <> struct VoidToChar<const void> { typedef const char type; }; |   30 template <> struct VoidToChar<const void> { typedef const char type; }; | 
|   31  |   31  | 
 |   32 // Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to | 
 |   33 // a buffer of the given size and alignment (both in bytes). | 
|   32 template <size_t size, size_t alignment> |   34 template <size_t size, size_t alignment> | 
|   33 void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointerHelper(const void* pointer); |   35 void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointer(const void* pointer); | 
|   34  |   36  | 
 |   37 // Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to | 
 |   38 // a buffer of |count| elements of the given size and alignment (both in bytes). | 
|   35 template <size_t size, size_t alignment> |   39 template <size_t size, size_t alignment> | 
|   36 void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointerWithCountHelper( |   40 void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointerWithCount(const void* pointer, | 
|   37     const void* pointer, |   41                                                        size_t count); | 
|   38     size_t count); |   42  | 
 |   43 // Checks (insofar as appropriate/possible) that |pointer| is a valid pointer to | 
 |   44 // a buffer of the given size and alignment (both in bytes). | 
 |   45 template <size_t alignment> | 
 |   46 void MOJO_SYSTEM_IMPL_EXPORT CheckUserPointerWithSize(const void* pointer, | 
 |   47                                                       size_t size); | 
|   39  |   48  | 
|   40 // TODO(vtl): Delete all the |Verify...()| things (and replace them with |   49 // TODO(vtl): Delete all the |Verify...()| things (and replace them with | 
|   41 // |Check...()|. |   50 // |Check...()|. | 
|   42 template <size_t size, size_t alignment> |   51 template <size_t size, size_t alignment> | 
|   43 bool MOJO_SYSTEM_IMPL_EXPORT VerifyUserPointerHelper(const void* pointer); |   52 bool MOJO_SYSTEM_IMPL_EXPORT VerifyUserPointerHelper(const void* pointer); | 
|   44  |   53  | 
|   45 // Note: This is also used by options_validation.h. |   54 // Note: This is also used by options_validation.h. | 
|   46 template <size_t size, size_t alignment> |   55 template <size_t size, size_t alignment> | 
|   47 bool MOJO_SYSTEM_IMPL_EXPORT VerifyUserPointerWithCountHelper( |   56 bool MOJO_SYSTEM_IMPL_EXPORT VerifyUserPointerWithCountHelper( | 
|   48     const void* pointer, |   57     const void* pointer, | 
|   49     size_t count); |   58     size_t count); | 
|   50  |   59  | 
|   51 }  // namespace internal |   60 }  // namespace internal | 
|   52  |   61  | 
|   53 // Forward declarations so that they can be friended. |   62 // Forward declarations so that they can be friended. | 
|   54 template <typename Type> class UserPointerReader; |   63 template <typename Type> class UserPointerReader; | 
|   55 template <typename Type> class UserPointerWriter; |   64 template <typename Type> class UserPointerWriter; | 
|   56 template <typename Type> class UserPointerReaderWriter; |   65 template <typename Type> class UserPointerReaderWriter; | 
 |   66 template <class Options> class UserOptionsReader; | 
|   57  |   67  | 
|   58 // Verify (insofar as possible/necessary) that a |T| can be read from the user |   68 // Verify (insofar as possible/necessary) that a |T| can be read from the user | 
|   59 // |pointer|. |   69 // |pointer|. | 
|   60 template <typename T> |   70 template <typename T> | 
|   61 bool VerifyUserPointer(const T* pointer) { |   71 bool VerifyUserPointer(const T* pointer) { | 
|   62   return internal::VerifyUserPointerHelper<sizeof(T), MOJO_ALIGNOF(T)>(pointer); |   72   return internal::VerifyUserPointerHelper<sizeof(T), MOJO_ALIGNOF(T)>(pointer); | 
|   63 } |   73 } | 
|   64  |   74  | 
|   65 // Verify (insofar as possible/necessary) that |count| |T|s can be read from the |   75 // Verify (insofar as possible/necessary) that |count| |T|s can be read from the | 
|   66 // user |pointer|; |count| may be zero. (This is done carefully since |count * |   76 // user |pointer|; |count| may be zero. (This is done carefully since |count * | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  111  |  121  | 
|  112   // Allow conversion to a "non-const" |UserPointer|. |  122   // Allow conversion to a "non-const" |UserPointer|. | 
|  113   operator UserPointer<const Type>() const { |  123   operator UserPointer<const Type>() const { | 
|  114     return UserPointer<const Type>(pointer_); |  124     return UserPointer<const Type>(pointer_); | 
|  115   } |  125   } | 
|  116  |  126  | 
|  117   bool IsNull() const { |  127   bool IsNull() const { | 
|  118     return !pointer_; |  128     return !pointer_; | 
|  119   } |  129   } | 
|  120  |  130  | 
 |  131   // "Reinterpret casts" to a |UserPointer<ToType>|. | 
 |  132   template <typename ToType> | 
 |  133   UserPointer<ToType> ReinterpretCast() const { | 
 |  134     return UserPointer<ToType>(reinterpret_cast<ToType*>(pointer_)); | 
 |  135   } | 
 |  136  | 
 |  137   // Checks that this pointer points to a valid array (of type |Type|, or just a | 
 |  138   // buffer if |Type| is |void| or |const void|) of |count| elements (or bytes | 
 |  139   // if |Type| is |void| or |const void|) in the same way as |GetArray()| and | 
 |  140   // |PutArray()|. | 
 |  141   // TODO(vtl): Logically, there should be separate read checks and write | 
 |  142   // checks. | 
 |  143   // TODO(vtl): Switch more things to use this. | 
 |  144   void CheckArray(size_t count) const { | 
 |  145     internal::CheckUserPointerWithCount< | 
 |  146         sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); | 
 |  147   } | 
 |  148  | 
|  121   // Gets the value (of type |Type|) pointed to by this user pointer. Use this |  149   // Gets the value (of type |Type|) pointed to by this user pointer. Use this | 
|  122   // when you'd use the rvalue |*user_pointer|, but be aware that this may be |  150   // when you'd use the rvalue |*user_pointer|, but be aware that this may be | 
|  123   // costly -- so if the value will be used multiple times, you should save it. |  151   // costly -- so if the value will be used multiple times, you should save it. | 
|  124   // |  152   // | 
|  125   // (We want to force a copy here, so return |Type| not |const Type&|.) |  153   // (We want to force a copy here, so return |Type| not |const Type&|.) | 
|  126   Type Get() const { |  154   Type Get() const { | 
|  127     internal::CheckUserPointerHelper<sizeof(Type), |  155     internal::CheckUserPointer<sizeof(Type), MOJO_ALIGNOF(Type)>(pointer_); | 
|  128                                      MOJO_ALIGNOF(Type)>(pointer_); |  | 
|  129     return *pointer_; |  156     return *pointer_; | 
|  130   } |  157   } | 
|  131  |  158  | 
|  132   // Gets an array (of type |Type|, or just a buffer if |Type| is |void| or |  159   // Gets an array (of type |Type|, or just a buffer if |Type| is |void| or | 
|  133   // |const void|) of |count| elements (or bytes if |Type| is |void| or |const |  160   // |const void|) of |count| elements (or bytes if |Type| is |void| or |const | 
|  134   // void|) from the location pointed to by this user pointer. Use this when |  161   // void|) from the location pointed to by this user pointer. Use this when | 
|  135   // you'd do something like |memcpy(destination, user_pointer, count * |  162   // you'd do something like |memcpy(destination, user_pointer, count * | 
|  136   // sizeof(Type)|. |  163   // sizeof(Type)|. | 
|  137   void GetArray(typename internal::remove_const<Type>::type* destination, |  164   void GetArray(typename internal::remove_const<Type>::type* destination, | 
|  138                 size_t count) { |  165                 size_t count) const { | 
|  139     internal::CheckUserPointerWithCountHelper< |  166     internal::CheckUserPointerWithCount< | 
|  140         sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); |  167         sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); | 
|  141     memcpy(destination, pointer_, count * sizeof(NonVoidType)); |  168     memcpy(destination, pointer_, count * sizeof(NonVoidType)); | 
|  142   } |  169   } | 
|  143  |  170  | 
|  144   // Puts a value (of type |Type|, or of type |char| if |Type| is |void|) to the |  171   // Puts a value (of type |Type|, or of type |char| if |Type| is |void|) to the | 
|  145   // location pointed to by this user pointer. Use this when you'd use the |  172   // location pointed to by this user pointer. Use this when you'd use the | 
|  146   // lvalue |*user_pointer|. Since this may be costly, you should avoid using |  173   // lvalue |*user_pointer|. Since this may be costly, you should avoid using | 
|  147   // this (for the same user pointer) more than once. |  174   // this (for the same user pointer) more than once. | 
|  148   // |  175   // | 
|  149   // Note: This |Put()| method is not valid when |T| is const, e.g., |const |  176   // Note: This |Put()| method is not valid when |T| is const, e.g., |const | 
|  150   // uint32_t|, but it's okay to include them so long as this template is only |  177   // uint32_t|, but it's okay to include them so long as this template is only | 
|  151   // implicitly instantiated (see 14.7.1 of the C++11 standard) and not |  178   // implicitly instantiated (see 14.7.1 of the C++11 standard) and not | 
|  152   // explicitly instantiated. (On implicit instantiation, only the declarations |  179   // explicitly instantiated. (On implicit instantiation, only the declarations | 
|  153   // need be valid, not the definitions.) |  180   // need be valid, not the definitions.) | 
|  154   // |  181   // | 
|  155   // If |Type| is |void|, we "convert" it to |char|, so that it makes sense. |  182   // If |Type| is |void|, we "convert" it to |char|, so that it makes sense. | 
|  156   // (Otherwise, we'd need a suitable specialization to exclude |Put()|.) |  183   // (Otherwise, we'd need a suitable specialization to exclude |Put()|.) | 
|  157   // |  184   // | 
|  158   // In C++11, we could do something like: |  185   // In C++11, we could do something like: | 
|  159   //   template <typename _Type = Type> |  186   //   template <typename _Type = Type> | 
|  160   //   typename enable_if<!is_const<_Type>::value && |  187   //   typename enable_if<!is_const<_Type>::value && | 
|  161   //                      !is_void<_Type>::value>::type Put( |  188   //                      !is_void<_Type>::value>::type Put( | 
|  162   //       const _Type& value) { ... } |  189   //       const _Type& value) { ... } | 
|  163   // (which obviously be correct), but C++03 doesn't allow default function |  190   // (which obviously be correct), but C++03 doesn't allow default function | 
|  164   // template arguments. |  191   // template arguments. | 
|  165   void Put(const NonVoidType& value) { |  192   void Put(const NonVoidType& value) { | 
|  166     internal::CheckUserPointerHelper<sizeof(NonVoidType), |  193     internal::CheckUserPointer<sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>( | 
|  167                                      MOJO_ALIGNOF(NonVoidType)>(pointer_); |  194         pointer_); | 
|  168     *pointer_ = value; |  195     *pointer_ = value; | 
|  169   } |  196   } | 
|  170  |  197  | 
|  171   // Puts an array (of type |Type|, or just a buffer if |Type| is |void|) with |  198   // Puts an array (of type |Type|, or just a buffer if |Type| is |void|) with | 
|  172   // |count| elements (or bytes |Type| is |void|) to the location pointed to by |  199   // |count| elements (or bytes |Type| is |void|) to the location pointed to by | 
|  173   // this user pointer. Use this when you'd do something like |  200   // this user pointer. Use this when you'd do something like | 
|  174   // |memcpy(user_pointer, source, count * sizeof(Type))|. |  201   // |memcpy(user_pointer, source, count * sizeof(Type))|. | 
|  175   // |  202   // | 
|  176   // Note: The same comments about the validity of |Put()| (except for the part |  203   // Note: The same comments about the validity of |Put()| (except for the part | 
|  177   // about |void|) apply here. |  204   // about |void|) apply here. | 
|  178   void PutArray(const Type* source, size_t count) { |  205   void PutArray(const Type* source, size_t count) { | 
|  179     internal::CheckUserPointerWithCountHelper< |  206     internal::CheckUserPointerWithCount< | 
|  180         sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); |  207         sizeof(NonVoidType), MOJO_ALIGNOF(NonVoidType)>(pointer_, count); | 
|  181     memcpy(pointer_, source, count * sizeof(NonVoidType)); |  208     memcpy(pointer_, source, count * sizeof(NonVoidType)); | 
|  182   } |  209   } | 
|  183  |  210  | 
|  184   // Gets a |UserPointer| at offset |i| (in |Type|s) relative to this. |  211   // Gets a |UserPointer| at offset |i| (in |Type|s) relative to this. | 
|  185   UserPointer At(size_t i) const { |  212   UserPointer At(size_t i) const { | 
|  186     return UserPointer(static_cast<Type*>( |  213     return UserPointer(static_cast<Type*>( | 
|  187         static_cast<NonVoidType*>(pointer_) + i)); |  214         static_cast<NonVoidType*>(pointer_) + i)); | 
|  188   } |  215   } | 
|  189  |  216  | 
|  190   // TODO(vtl): This is temporary. Get rid of this. (We should pass |  | 
|  191   // |UserPointer<>|s along appropriately, or access data in a safe way |  | 
|  192   // everywhere.) |  | 
|  193   Type* GetPointerUnsafe() const { |  | 
|  194     return pointer_; |  | 
|  195   } |  | 
|  196  |  | 
|  197   // These provides safe (read-only/write-only/read-and-write) access to a |  217   // These provides safe (read-only/write-only/read-and-write) access to a | 
|  198   // |UserPointer<Type>| (probably pointing to an array) using just an ordinary |  218   // |UserPointer<Type>| (probably pointing to an array) using just an ordinary | 
|  199   // pointer (obtained via |GetPointer()|). |  219   // pointer (obtained via |GetPointer()|). | 
|  200   // |  220   // | 
|  201   // The memory returned by |GetPointer()| may be a copy of the original user |  221   // The memory returned by |GetPointer()| may be a copy of the original user | 
|  202   // memory, but should be modified only if the user is intended to eventually |  222   // memory, but should be modified only if the user is intended to eventually | 
|  203   // see the change.) If any changes are made, |Commit()| should be called to |  223   // see the change.) If any changes are made, |Commit()| should be called to | 
|  204   // guarantee that the changes are written back to user memory (it may be |  224   // guarantee that the changes are written back to user memory (it may be | 
|  205   // called multiple times). |  225   // called multiple times). | 
|  206   // |  226   // | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  226   //   } |  246   //   } | 
|  227   // |  247   // | 
|  228   // TODO(vtl): Possibly, since we're not really being safe, we should just not |  248   // TODO(vtl): Possibly, since we're not really being safe, we should just not | 
|  229   // copy for Release builds. |  249   // copy for Release builds. | 
|  230   typedef UserPointerReader<Type> Reader; |  250   typedef UserPointerReader<Type> Reader; | 
|  231   typedef UserPointerWriter<Type> Writer; |  251   typedef UserPointerWriter<Type> Writer; | 
|  232   typedef UserPointerReaderWriter<Type> ReaderWriter; |  252   typedef UserPointerReaderWriter<Type> ReaderWriter; | 
|  233  |  253  | 
|  234  private: |  254  private: | 
|  235   friend class UserPointerReader<Type>; |  255   friend class UserPointerReader<Type>; | 
 |  256   friend class UserPointerReader<const Type>; | 
|  236   friend class UserPointerWriter<Type>; |  257   friend class UserPointerWriter<Type>; | 
|  237   friend class UserPointerReaderWriter<Type>; |  258   friend class UserPointerReaderWriter<Type>; | 
 |  259   template <class Options> friend class UserOptionsReader; | 
|  238  |  260  | 
|  239   Type* pointer_; |  261   Type* pointer_; | 
|  240   // Allow copy and assignment. |  262   // Allow copy and assignment. | 
|  241 }; |  263 }; | 
|  242  |  264  | 
|  243 // Provides a convenient way to make a |UserPointer<Type>|. |  265 // Provides a convenient way to make a |UserPointer<Type>|. | 
|  244 template <typename Type> |  266 template <typename Type> | 
|  245 inline UserPointer<Type> MakeUserPointer(Type* pointer) { |  267 inline UserPointer<Type> MakeUserPointer(Type* pointer) { | 
|  246   return UserPointer<Type>(pointer); |  268   return UserPointer<Type>(pointer); | 
|  247 } |  269 } | 
|  248  |  270  | 
|  249 // Implementation of |UserPointer<Type>::Reader|. |  271 // Implementation of |UserPointer<Type>::Reader|. | 
|  250 template <typename Type> |  272 template <typename Type> | 
|  251 class UserPointerReader { |  273 class UserPointerReader { | 
|  252  private: |  274  private: | 
|  253   typedef typename internal::remove_const<Type>::type TypeNoConst; |  275   typedef typename internal::remove_const<Type>::type TypeNoConst; | 
|  254  |  276  | 
|  255  public: |  277  public: | 
 |  278   // Note: If |count| is zero, |GetPointer()| will always return null. | 
|  256   UserPointerReader(UserPointer<const Type> user_pointer, size_t count) { |  279   UserPointerReader(UserPointer<const Type> user_pointer, size_t count) { | 
|  257     Init(user_pointer.pointer_, count); |  280     Init(user_pointer.pointer_, count, true); | 
|  258   } |  281   } | 
|  259   UserPointerReader(UserPointer<TypeNoConst> user_pointer, size_t count) { |  282   UserPointerReader(UserPointer<TypeNoConst> user_pointer, size_t count) { | 
|  260     Init(user_pointer.pointer_, count); |  283     Init(user_pointer.pointer_, count, true); | 
|  261   } |  284   } | 
|  262  |  285  | 
|  263   const Type* GetPointer() const { return buffer_.get(); } |  286   const Type* GetPointer() const { return buffer_.get(); } | 
|  264  |  287  | 
|  265  private: |  288  private: | 
|  266   void Init(const Type* user_pointer, size_t count) { |  289   template <class Options> friend class UserOptionsReader; | 
|  267     internal::CheckUserPointerWithCountHelper< |  290  | 
|  268         sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer, count); |  291   struct NoCheck {}; | 
 |  292   UserPointerReader(NoCheck, | 
 |  293                     UserPointer<const Type> user_pointer, | 
 |  294                     size_t count) { | 
 |  295     Init(user_pointer.pointer_, count, false); | 
 |  296   } | 
 |  297  | 
 |  298   void Init(const Type* user_pointer, size_t count, bool check) { | 
 |  299     if (count == 0) | 
 |  300       return; | 
 |  301  | 
 |  302     if (check) { | 
 |  303       internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( | 
 |  304           user_pointer, count); | 
 |  305     } | 
|  269     buffer_.reset(new TypeNoConst[count]); |  306     buffer_.reset(new TypeNoConst[count]); | 
|  270     memcpy(buffer_.get(), user_pointer, count * sizeof(Type)); |  307     memcpy(buffer_.get(), user_pointer, count * sizeof(Type)); | 
|  271   } |  308   } | 
|  272  |  309  | 
|  273   scoped_ptr<TypeNoConst[]> buffer_; |  310   scoped_ptr<TypeNoConst[]> buffer_; | 
|  274  |  311  | 
|  275   DISALLOW_COPY_AND_ASSIGN(UserPointerReader); |  312   DISALLOW_COPY_AND_ASSIGN(UserPointerReader); | 
|  276 }; |  313 }; | 
|  277  |  314  | 
|  278 // Implementation of |UserPointer<Type>::Writer|. |  315 // Implementation of |UserPointer<Type>::Writer|. | 
|  279 template <typename Type> |  316 template <typename Type> | 
|  280 class UserPointerWriter { |  317 class UserPointerWriter { | 
|  281  public: |  318  public: | 
 |  319   // Note: If |count| is zero, |GetPointer()| will always return null. | 
|  282   UserPointerWriter(UserPointer<Type> user_pointer, size_t count) |  320   UserPointerWriter(UserPointer<Type> user_pointer, size_t count) | 
|  283       : user_pointer_(user_pointer), |  321       : user_pointer_(user_pointer), | 
|  284         count_(count) { |  322         count_(count) { | 
|  285     buffer_.reset(new Type[count_]); |  323     if (count_ > 0) { | 
|  286     memset(buffer_.get(), 0, count_ * sizeof(Type)); |  324       buffer_.reset(new Type[count_]); | 
 |  325       memset(buffer_.get(), 0, count_ * sizeof(Type)); | 
 |  326     } | 
|  287   } |  327   } | 
|  288  |  328  | 
|  289   Type* GetPointer() const { return buffer_.get(); } |  329   Type* GetPointer() const { return buffer_.get(); } | 
|  290  |  330  | 
|  291   void Commit() { |  331   void Commit() { | 
|  292     internal::CheckUserPointerWithCountHelper< |  332     internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( | 
|  293         sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |  333         user_pointer_.pointer_, count_); | 
|  294     memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); |  334     memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); | 
|  295   } |  335   } | 
|  296  |  336  | 
|  297  private: |  337  private: | 
|  298   UserPointer<Type> user_pointer_; |  338   UserPointer<Type> user_pointer_; | 
|  299   size_t count_; |  339   size_t count_; | 
|  300   scoped_ptr<Type[]> buffer_; |  340   scoped_ptr<Type[]> buffer_; | 
|  301  |  341  | 
|  302   DISALLOW_COPY_AND_ASSIGN(UserPointerWriter); |  342   DISALLOW_COPY_AND_ASSIGN(UserPointerWriter); | 
|  303 }; |  343 }; | 
|  304  |  344  | 
|  305 // Implementation of |UserPointer<Type>::ReaderWriter|. |  345 // Implementation of |UserPointer<Type>::ReaderWriter|. | 
|  306 template <typename Type> |  346 template <typename Type> | 
|  307 class UserPointerReaderWriter { |  347 class UserPointerReaderWriter { | 
|  308  public: |  348  public: | 
 |  349   // Note: If |count| is zero, |GetPointer()| will always return null. | 
|  309   UserPointerReaderWriter(UserPointer<Type> user_pointer, size_t count) |  350   UserPointerReaderWriter(UserPointer<Type> user_pointer, size_t count) | 
|  310       : user_pointer_(user_pointer), |  351       : user_pointer_(user_pointer), | 
|  311         count_(count) { |  352         count_(count) { | 
|  312     internal::CheckUserPointerWithCountHelper< |  353     if (count_ > 0) { | 
|  313         sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |  354       internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( | 
|  314     buffer_.reset(new Type[count]); |  355           user_pointer_.pointer_, count_); | 
|  315     memcpy(buffer_.get(), user_pointer.pointer_, count * sizeof(Type)); |  356       buffer_.reset(new Type[count]); | 
 |  357       memcpy(buffer_.get(), user_pointer.pointer_, count * sizeof(Type)); | 
 |  358     } | 
|  316   } |  359   } | 
|  317  |  360  | 
|  318   Type* GetPointer() const { return buffer_.get(); } |  361   Type* GetPointer() const { return buffer_.get(); } | 
|  319   size_t GetCount() const { return count_; } |  362   size_t GetCount() const { return count_; } | 
|  320  |  363  | 
|  321   void Commit() { |  364   void Commit() { | 
|  322     internal::CheckUserPointerWithCountHelper< |  365     internal::CheckUserPointerWithCount<sizeof(Type), MOJO_ALIGNOF(Type)>( | 
|  323         sizeof(Type), MOJO_ALIGNOF(Type)>(user_pointer_.pointer_, count_); |  366         user_pointer_.pointer_, count_); | 
|  324     memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); |  367     memcpy(user_pointer_.pointer_, buffer_.get(), count_ * sizeof(Type)); | 
|  325   } |  368   } | 
|  326  |  369  | 
|  327  private: |  370  private: | 
|  328   UserPointer<Type> user_pointer_; |  371   UserPointer<Type> user_pointer_; | 
|  329   size_t count_; |  372   size_t count_; | 
|  330   scoped_ptr<Type[]> buffer_; |  373   scoped_ptr<Type[]> buffer_; | 
|  331  |  374  | 
|  332   DISALLOW_COPY_AND_ASSIGN(UserPointerReaderWriter); |  375   DISALLOW_COPY_AND_ASSIGN(UserPointerReaderWriter); | 
|  333 }; |  376 }; | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  356 // Provides a convenient way to make a |UserPointerValue<Type>|. |  399 // Provides a convenient way to make a |UserPointerValue<Type>|. | 
|  357 template <typename Type> |  400 template <typename Type> | 
|  358 inline UserPointerValue<Type> MakeUserPointerValue(Type* pointer) { |  401 inline UserPointerValue<Type> MakeUserPointerValue(Type* pointer) { | 
|  359   return UserPointerValue<Type>(pointer); |  402   return UserPointerValue<Type>(pointer); | 
|  360 } |  403 } | 
|  361  |  404  | 
|  362 }  // namespace system |  405 }  // namespace system | 
|  363 }  // namespace mojo |  406 }  // namespace mojo | 
|  364  |  407  | 
|  365 #endif  // MOJO_SYSTEM_MEMORY_H_ |  408 #endif  // MOJO_SYSTEM_MEMORY_H_ | 
| OLD | NEW |