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 |