| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // Defines utility classes and functions which facilitate working with the | |
| 17 // memory allocation functions CoTaskMemAlloc and CoTaskMemFree. | |
| 18 | |
| 19 #ifndef OMAHA_COMMON_SCOPED_PTR_COTASK_H__ | |
| 20 #define OMAHA_COMMON_SCOPED_PTR_COTASK_H__ | |
| 21 | |
| 22 #include "omaha/base/debug.h" | |
| 23 | |
| 24 // scoped_ptr_cotask is identical to scoped_ptr, except that CoTaskMemFree is | |
| 25 // called instead of delete. For documentation of the interface, see | |
| 26 // scoped_ptr.h. | |
| 27 | |
| 28 template <typename T> | |
| 29 class scoped_ptr_cotask; | |
| 30 | |
| 31 template <typename T> | |
| 32 scoped_ptr_cotask<T> make_scoped_ptr_cotask(T* p); | |
| 33 | |
| 34 template <typename T> | |
| 35 class scoped_ptr_cotask { | |
| 36 private: | |
| 37 T* ptr_; | |
| 38 | |
| 39 scoped_ptr_cotask(scoped_ptr_cotask const &); | |
| 40 scoped_ptr_cotask & operator=(scoped_ptr_cotask const &); | |
| 41 | |
| 42 friend scoped_ptr_cotask<T> make_scoped_ptr_cotask<T>(T* p); | |
| 43 | |
| 44 public: | |
| 45 typedef T element_type; | |
| 46 | |
| 47 explicit scoped_ptr_cotask(T* p = 0): ptr_(p) {} | |
| 48 | |
| 49 ~scoped_ptr_cotask() { | |
| 50 typedef char type_must_be_complete[sizeof(T)]; | |
| 51 ::CoTaskMemFree(ptr_); | |
| 52 } | |
| 53 | |
| 54 void reset(T* p = 0) { | |
| 55 typedef char type_must_be_complete[sizeof(T)]; | |
| 56 | |
| 57 if (ptr_ != p) { | |
| 58 ::CoTaskMemFree(ptr_); | |
| 59 ptr_ = p; | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 T& operator*() const { | |
| 64 assert(ptr_ != 0); | |
| 65 return *ptr_; | |
| 66 } | |
| 67 | |
| 68 T* operator->() const { | |
| 69 assert(ptr_ != 0); | |
| 70 return ptr_; | |
| 71 } | |
| 72 | |
| 73 bool operator==(T* p) const { | |
| 74 return ptr_ == p; | |
| 75 } | |
| 76 | |
| 77 bool operator!=(T* p) const { | |
| 78 return ptr_ != p; | |
| 79 } | |
| 80 | |
| 81 T* get() const { | |
| 82 return ptr_; | |
| 83 } | |
| 84 | |
| 85 void swap(scoped_ptr_cotask & b) { | |
| 86 T* tmp = b.ptr_; | |
| 87 b.ptr_ = ptr_; | |
| 88 ptr_ = tmp; | |
| 89 } | |
| 90 | |
| 91 T* release() { | |
| 92 T* tmp = ptr_; | |
| 93 ptr_ = 0; | |
| 94 return tmp; | |
| 95 } | |
| 96 | |
| 97 private: | |
| 98 template <typename U> bool operator==(scoped_ptr_cotask<U> const& p) const; | |
| 99 template <typename U> bool operator!=(scoped_ptr_cotask<U> const& p) const; | |
| 100 }; | |
| 101 | |
| 102 template <typename T> | |
| 103 scoped_ptr_cotask<T> make_scoped_ptr_cotask(T* p) { | |
| 104 return scoped_ptr_cotask<T>(p); | |
| 105 } | |
| 106 | |
| 107 template <typename T> inline | |
| 108 void swap(scoped_ptr_cotask<T>& a, scoped_ptr_cotask<T>& b) { | |
| 109 a.swap(b); | |
| 110 } | |
| 111 | |
| 112 template <typename T> inline | |
| 113 bool operator==(T* p, const scoped_ptr_cotask<T>& b) { | |
| 114 return p == b.get(); | |
| 115 } | |
| 116 | |
| 117 template <typename T> inline | |
| 118 bool operator!=(T* p, const scoped_ptr_cotask<T>& b) { | |
| 119 return p != b.get(); | |
| 120 } | |
| 121 | |
| 122 template <typename T> | |
| 123 inline T** address(const scoped_ptr_cotask<T>& t) { | |
| 124 COMPILE_ASSERT(sizeof(T*) == sizeof(t), types_do_not_match); | |
| 125 ASSERT1(!t.get()); | |
| 126 return reinterpret_cast<T**>(&const_cast<scoped_ptr_cotask<T>&>(t)); | |
| 127 } | |
| 128 | |
| 129 // scoped_array_cotask manages an array of pointers to objects allocated by | |
| 130 // CoTaskMemAlloc. The array is also allocated via CoTaskMemAlloc. The | |
| 131 // interface is similar to scoped_array, except that an array length must be | |
| 132 // explicitly provided. When the object is destructed, the array and each | |
| 133 // element of the array are explicitly freed. | |
| 134 | |
| 135 template <typename T> | |
| 136 class scoped_array_cotask; | |
| 137 | |
| 138 template <typename T> | |
| 139 class scoped_array_cotask<T*> { | |
| 140 private: | |
| 141 size_t count_; | |
| 142 T** ptr_; | |
| 143 | |
| 144 scoped_array_cotask(scoped_array_cotask const &); | |
| 145 scoped_array_cotask & operator=(scoped_array_cotask const &); | |
| 146 | |
| 147 public: | |
| 148 typedef T* element_type; | |
| 149 | |
| 150 explicit scoped_array_cotask(size_t c, T** p = 0) | |
| 151 : count_(c), ptr_(p) { | |
| 152 if (!ptr_) { | |
| 153 const size_t array_size = sizeof(T*) * count_; | |
| 154 ptr_ = static_cast<T**>(::CoTaskMemAlloc(array_size)); | |
| 155 memset(ptr_, 0, array_size); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 ~scoped_array_cotask() { | |
| 160 typedef char type_must_be_complete[sizeof(T*)]; | |
| 161 if (ptr_) { | |
| 162 for (size_t i = 0; i < count_; ++i) { | |
| 163 ::CoTaskMemFree(ptr_[i]); | |
| 164 } | |
| 165 ::CoTaskMemFree(ptr_); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 size_t size() const { return count_; } | |
| 170 | |
| 171 void reset(size_t c, T** p = 0) { | |
| 172 typedef char type_must_be_complete[sizeof(T*)]; | |
| 173 | |
| 174 if (ptr_ != p) { | |
| 175 if (ptr_) { | |
| 176 for (size_t i = 0; i < count_; ++i) { | |
| 177 ::CoTaskMemFree(ptr_[i]); | |
| 178 } | |
| 179 ::CoTaskMemFree(ptr_); | |
| 180 } | |
| 181 ptr_ = p; | |
| 182 } | |
| 183 count_ = c; | |
| 184 if (!ptr_) { | |
| 185 const size_t array_size = sizeof(T*) * count_; | |
| 186 ptr_ = static_cast<T**>(::CoTaskMemAlloc(array_size)); | |
| 187 memset(ptr_, 0, array_size); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 T*& operator[](std::ptrdiff_t i) const { | |
| 192 assert(ptr_ != 0); | |
| 193 assert(i >= 0); | |
| 194 return ptr_[i]; | |
| 195 } | |
| 196 | |
| 197 bool operator==(T** p) const { | |
| 198 return ptr_ == p; | |
| 199 } | |
| 200 | |
| 201 bool operator!=(T** p) const { | |
| 202 return ptr_ != p; | |
| 203 } | |
| 204 | |
| 205 T** get() const { | |
| 206 return ptr_; | |
| 207 } | |
| 208 | |
| 209 void swap(scoped_array_cotask & b) { | |
| 210 T** tmp = b.ptr_; | |
| 211 b.ptr_ = ptr_; | |
| 212 ptr_ = tmp; | |
| 213 } | |
| 214 | |
| 215 T** release() { | |
| 216 T** tmp = ptr_; | |
| 217 ptr_ = 0; | |
| 218 return tmp; | |
| 219 } | |
| 220 | |
| 221 private: | |
| 222 template <typename U> bool operator==(scoped_array_cotask<U> const& p) const; | |
| 223 template <typename U> bool operator!=(scoped_array_cotask<U> const& p) const; | |
| 224 }; | |
| 225 | |
| 226 template <typename T> inline | |
| 227 void swap(scoped_array_cotask<T>& a, scoped_array_cotask<T>& b) { | |
| 228 a.swap(b); | |
| 229 } | |
| 230 | |
| 231 template <typename T> inline | |
| 232 bool operator==(T* p, const scoped_array_cotask<T>& b) { | |
| 233 return p == b.get(); | |
| 234 } | |
| 235 | |
| 236 template <typename T> inline | |
| 237 bool operator!=(T* p, const scoped_array_cotask<T>& b) { | |
| 238 return p != b.get(); | |
| 239 } | |
| 240 | |
| 241 // address() is not relevant to scoped_array_cotask, due to the count parameter. | |
| 242 // | |
| 243 // template <typename T> | |
| 244 // inline T** address(const scoped_array_cotask<T>& t) { | |
| 245 // COMPILE_ASSERT(sizeof(T*) == sizeof(t), types_do_not_match); | |
| 246 // ASSERT1(!t.get()); | |
| 247 // return reinterpret_cast<T**>(&const_cast<scoped_array_cotask<T>&>(t)); | |
| 248 // } | |
| 249 | |
| 250 // StrDupCoTask allocates a copy of a string using CoTaskMemAlloc. | |
| 251 | |
| 252 template <class T> | |
| 253 inline T* StrDupCoTask(const T* str, size_t length) { | |
| 254 T* mem = static_cast<T*>(::CoTaskMemAlloc(sizeof(T) * (length + 1))); | |
| 255 memcpy(mem, str, sizeof(T) * length); | |
| 256 mem[length] = 0; | |
| 257 return mem; | |
| 258 } | |
| 259 | |
| 260 #endif // OMAHA_COMMON_SCOPED_PTR_COTASK_H__ | |
| OLD | NEW |