Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: base/scoped_variant_win.cc

Issue 3781009: Move the windows-specific scoped_* stuff from base to base/win and in the bas... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/scoped_variant_win.h"
6 #include "base/logging.h"
7
8 // Global, const instance of an empty variant.
9 const VARIANT ScopedVariant::kEmptyVariant = { VT_EMPTY };
10
11 ScopedVariant::~ScopedVariant() {
12 COMPILE_ASSERT(sizeof(ScopedVariant) == sizeof(VARIANT), ScopedVariantSize);
13 ::VariantClear(&var_);
14 }
15
16 ScopedVariant::ScopedVariant(const wchar_t* str) {
17 var_.vt = VT_EMPTY;
18 Set(str);
19 }
20
21 ScopedVariant::ScopedVariant(const wchar_t* str, UINT length) {
22 var_.vt = VT_BSTR;
23 var_.bstrVal = ::SysAllocStringLen(str, length);
24 }
25
26 ScopedVariant::ScopedVariant(int value, VARTYPE vt) {
27 var_.vt = vt;
28 var_.lVal = value;
29 }
30
31 ScopedVariant::ScopedVariant(double value, VARTYPE vt) {
32 DCHECK(vt == VT_R8 || vt == VT_DATE);
33 var_.vt = vt;
34 var_.dblVal = value;
35 }
36
37 ScopedVariant::ScopedVariant(IDispatch* dispatch) {
38 var_.vt = VT_EMPTY;
39 Set(dispatch);
40 }
41
42 ScopedVariant::ScopedVariant(IUnknown* unknown) {
43 var_.vt = VT_EMPTY;
44 Set(unknown);
45 }
46
47 ScopedVariant::ScopedVariant(SAFEARRAY* safearray) {
48 var_.vt = VT_EMPTY;
49 Set(safearray);
50 }
51
52 ScopedVariant::ScopedVariant(const VARIANT& var) {
53 var_.vt = VT_EMPTY;
54 Set(var);
55 }
56
57 void ScopedVariant::Reset(const VARIANT& var) {
58 if (&var != &var_) {
59 ::VariantClear(&var_);
60 var_ = var;
61 }
62 }
63
64 VARIANT ScopedVariant::Release() {
65 VARIANT var = var_;
66 var_.vt = VT_EMPTY;
67 return var;
68 }
69
70 void ScopedVariant::Swap(ScopedVariant& var) {
71 VARIANT tmp = var_;
72 var_ = var.var_;
73 var.var_ = tmp;
74 }
75
76 VARIANT* ScopedVariant::Receive() {
77 DCHECK(!IsLeakableVarType(var_.vt)) << "variant leak. type: " << var_.vt;
78 return &var_;
79 }
80
81 VARIANT ScopedVariant::Copy() const {
82 VARIANT ret = { VT_EMPTY };
83 ::VariantCopy(&ret, &var_);
84 return ret;
85 }
86
87 int ScopedVariant::Compare(const VARIANT& var, bool ignore_case) const {
88 ULONG flags = ignore_case ? NORM_IGNORECASE : 0;
89 HRESULT hr = ::VarCmp(const_cast<VARIANT*>(&var_), const_cast<VARIANT*>(&var),
90 LOCALE_USER_DEFAULT, flags);
91 int ret = 0;
92
93 switch (hr) {
94 case VARCMP_LT:
95 ret = -1;
96 break;
97
98 case VARCMP_GT:
99 case VARCMP_NULL:
100 ret = 1;
101 break;
102
103 default:
104 // Equal.
105 break;
106 }
107
108 return ret;
109 }
110
111 void ScopedVariant::Set(const wchar_t* str) {
112 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
113 var_.vt = VT_BSTR;
114 var_.bstrVal = ::SysAllocString(str);
115 }
116
117 void ScopedVariant::Set(int8 i8) {
118 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
119 var_.vt = VT_I1;
120 var_.cVal = i8;
121 }
122
123 void ScopedVariant::Set(uint8 ui8) {
124 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
125 var_.vt = VT_UI1;
126 var_.bVal = ui8;
127 }
128
129 void ScopedVariant::Set(int16 i16) {
130 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
131 var_.vt = VT_I2;
132 var_.iVal = i16;
133 }
134
135 void ScopedVariant::Set(uint16 ui16) {
136 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
137 var_.vt = VT_UI2;
138 var_.uiVal = ui16;
139 }
140
141 void ScopedVariant::Set(int32 i32) {
142 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
143 var_.vt = VT_I4;
144 var_.lVal = i32;
145 }
146
147 void ScopedVariant::Set(uint32 ui32) {
148 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
149 var_.vt = VT_UI4;
150 var_.ulVal = ui32;
151 }
152
153 void ScopedVariant::Set(int64 i64) {
154 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
155 var_.vt = VT_I8;
156 var_.llVal = i64;
157 }
158
159 void ScopedVariant::Set(uint64 ui64) {
160 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
161 var_.vt = VT_UI8;
162 var_.ullVal = ui64;
163 }
164
165 void ScopedVariant::Set(float r32) {
166 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
167 var_.vt = VT_R4;
168 var_.fltVal = r32;
169 }
170
171 void ScopedVariant::Set(double r64) {
172 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
173 var_.vt = VT_R8;
174 var_.dblVal = r64;
175 }
176
177 void ScopedVariant::SetDate(DATE date) {
178 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
179 var_.vt = VT_DATE;
180 var_.date = date;
181 }
182
183 void ScopedVariant::Set(IDispatch* disp) {
184 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
185 var_.vt = VT_DISPATCH;
186 var_.pdispVal = disp;
187 if (disp)
188 disp->AddRef();
189 }
190
191 void ScopedVariant::Set(bool b) {
192 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
193 var_.vt = VT_BOOL;
194 var_.boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
195 }
196
197 void ScopedVariant::Set(IUnknown* unk) {
198 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
199 var_.vt = VT_UNKNOWN;
200 var_.punkVal = unk;
201 if (unk)
202 unk->AddRef();
203 }
204
205 void ScopedVariant::Set(SAFEARRAY* array) {
206 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
207 if (SUCCEEDED(::SafeArrayGetVartype(array, &var_.vt))) {
208 var_.vt |= VT_ARRAY;
209 var_.parray = array;
210 } else {
211 DCHECK(array == NULL) << "Unable to determine safearray vartype";
212 var_.vt = VT_EMPTY;
213 }
214 }
215
216 void ScopedVariant::Set(const VARIANT& var) {
217 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
218 if (FAILED(::VariantCopy(&var_, &var))) {
219 DLOG(ERROR) << "VariantCopy failed";
220 var_.vt = VT_EMPTY;
221 }
222 }
223
224 ScopedVariant& ScopedVariant::operator=(const VARIANT& var) {
225 if (&var != &var_) {
226 VariantClear(&var_);
227 Set(var);
228 }
229 return *this;
230 }
231
232 bool ScopedVariant::IsLeakableVarType(VARTYPE vt) {
233 bool leakable = false;
234 switch (vt & VT_TYPEMASK) {
235 case VT_BSTR:
236 case VT_DISPATCH:
237 // we treat VT_VARIANT as leakable to err on the safe side.
238 case VT_VARIANT:
239 case VT_UNKNOWN:
240 case VT_SAFEARRAY:
241
242 // very rarely used stuff (if ever):
243 case VT_VOID:
244 case VT_PTR:
245 case VT_CARRAY:
246 case VT_USERDEFINED:
247 case VT_LPSTR:
248 case VT_LPWSTR:
249 case VT_RECORD:
250 case VT_INT_PTR:
251 case VT_UINT_PTR:
252 case VT_FILETIME:
253 case VT_BLOB:
254 case VT_STREAM:
255 case VT_STORAGE:
256 case VT_STREAMED_OBJECT:
257 case VT_STORED_OBJECT:
258 case VT_BLOB_OBJECT:
259 case VT_VERSIONED_STREAM:
260 case VT_BSTR_BLOB:
261 leakable = true;
262 break;
263 }
264
265 if (!leakable && (vt & VT_ARRAY) != 0) {
266 leakable = true;
267 }
268
269 return leakable;
270 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698