Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / base / win / scoped_variant.cc
blob2cf265740d8b5f94a06866cbe375069e85991c50
1 // Copyright (c) 2010 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.
5 #include "base/win/scoped_variant.h"
6 #include "base/logging.h"
8 namespace base {
9 namespace win {
11 // Global, const instance of an empty variant.
12 const VARIANT ScopedVariant::kEmptyVariant = {{{VT_EMPTY}}};
14 ScopedVariant::~ScopedVariant() {
15 COMPILE_ASSERT(sizeof(ScopedVariant) == sizeof(VARIANT), ScopedVariantSize);
16 ::VariantClear(&var_);
19 ScopedVariant::ScopedVariant(const wchar_t* str) {
20 var_.vt = VT_EMPTY;
21 Set(str);
24 ScopedVariant::ScopedVariant(const wchar_t* str, UINT length) {
25 var_.vt = VT_BSTR;
26 var_.bstrVal = ::SysAllocStringLen(str, length);
29 ScopedVariant::ScopedVariant(int value, VARTYPE vt) {
30 var_.vt = vt;
31 var_.lVal = value;
34 ScopedVariant::ScopedVariant(double value, VARTYPE vt) {
35 DCHECK(vt == VT_R8 || vt == VT_DATE);
36 var_.vt = vt;
37 var_.dblVal = value;
40 ScopedVariant::ScopedVariant(IDispatch* dispatch) {
41 var_.vt = VT_EMPTY;
42 Set(dispatch);
45 ScopedVariant::ScopedVariant(IUnknown* unknown) {
46 var_.vt = VT_EMPTY;
47 Set(unknown);
50 ScopedVariant::ScopedVariant(SAFEARRAY* safearray) {
51 var_.vt = VT_EMPTY;
52 Set(safearray);
55 ScopedVariant::ScopedVariant(const VARIANT& var) {
56 var_.vt = VT_EMPTY;
57 Set(var);
60 void ScopedVariant::Reset(const VARIANT& var) {
61 if (&var != &var_) {
62 ::VariantClear(&var_);
63 var_ = var;
67 VARIANT ScopedVariant::Release() {
68 VARIANT var = var_;
69 var_.vt = VT_EMPTY;
70 return var;
73 void ScopedVariant::Swap(ScopedVariant& var) {
74 VARIANT tmp = var_;
75 var_ = var.var_;
76 var.var_ = tmp;
79 VARIANT* ScopedVariant::Receive() {
80 DCHECK(!IsLeakableVarType(var_.vt)) << "variant leak. type: " << var_.vt;
81 return &var_;
84 VARIANT ScopedVariant::Copy() const {
85 VARIANT ret = {{{VT_EMPTY}}};
86 ::VariantCopy(&ret, &var_);
87 return ret;
90 int ScopedVariant::Compare(const VARIANT& var, bool ignore_case) const {
91 ULONG flags = ignore_case ? NORM_IGNORECASE : 0;
92 HRESULT hr = ::VarCmp(const_cast<VARIANT*>(&var_), const_cast<VARIANT*>(&var),
93 LOCALE_USER_DEFAULT, flags);
94 int ret = 0;
96 switch (hr) {
97 case VARCMP_LT:
98 ret = -1;
99 break;
101 case VARCMP_GT:
102 case VARCMP_NULL:
103 ret = 1;
104 break;
106 default:
107 // Equal.
108 break;
111 return ret;
114 void ScopedVariant::Set(const wchar_t* str) {
115 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
116 var_.vt = VT_BSTR;
117 var_.bstrVal = ::SysAllocString(str);
120 void ScopedVariant::Set(int8 i8) {
121 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
122 var_.vt = VT_I1;
123 var_.cVal = i8;
126 void ScopedVariant::Set(uint8 ui8) {
127 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
128 var_.vt = VT_UI1;
129 var_.bVal = ui8;
132 void ScopedVariant::Set(int16 i16) {
133 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
134 var_.vt = VT_I2;
135 var_.iVal = i16;
138 void ScopedVariant::Set(uint16 ui16) {
139 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
140 var_.vt = VT_UI2;
141 var_.uiVal = ui16;
144 void ScopedVariant::Set(int32 i32) {
145 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
146 var_.vt = VT_I4;
147 var_.lVal = i32;
150 void ScopedVariant::Set(uint32 ui32) {
151 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
152 var_.vt = VT_UI4;
153 var_.ulVal = ui32;
156 void ScopedVariant::Set(int64 i64) {
157 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
158 var_.vt = VT_I8;
159 var_.llVal = i64;
162 void ScopedVariant::Set(uint64 ui64) {
163 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
164 var_.vt = VT_UI8;
165 var_.ullVal = ui64;
168 void ScopedVariant::Set(float r32) {
169 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
170 var_.vt = VT_R4;
171 var_.fltVal = r32;
174 void ScopedVariant::Set(double r64) {
175 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
176 var_.vt = VT_R8;
177 var_.dblVal = r64;
180 void ScopedVariant::SetDate(DATE date) {
181 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
182 var_.vt = VT_DATE;
183 var_.date = date;
186 void ScopedVariant::Set(IDispatch* disp) {
187 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
188 var_.vt = VT_DISPATCH;
189 var_.pdispVal = disp;
190 if (disp)
191 disp->AddRef();
194 void ScopedVariant::Set(bool b) {
195 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
196 var_.vt = VT_BOOL;
197 var_.boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
200 void ScopedVariant::Set(IUnknown* unk) {
201 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
202 var_.vt = VT_UNKNOWN;
203 var_.punkVal = unk;
204 if (unk)
205 unk->AddRef();
208 void ScopedVariant::Set(SAFEARRAY* array) {
209 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
210 if (SUCCEEDED(::SafeArrayGetVartype(array, &var_.vt))) {
211 var_.vt |= VT_ARRAY;
212 var_.parray = array;
213 } else {
214 DCHECK(!array) << "Unable to determine safearray vartype";
215 var_.vt = VT_EMPTY;
219 void ScopedVariant::Set(const VARIANT& var) {
220 DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
221 if (FAILED(::VariantCopy(&var_, &var))) {
222 DLOG(ERROR) << "VariantCopy failed";
223 var_.vt = VT_EMPTY;
227 ScopedVariant& ScopedVariant::operator=(const VARIANT& var) {
228 if (&var != &var_) {
229 VariantClear(&var_);
230 Set(var);
232 return *this;
235 bool ScopedVariant::IsLeakableVarType(VARTYPE vt) {
236 bool leakable = false;
237 switch (vt & VT_TYPEMASK) {
238 case VT_BSTR:
239 case VT_DISPATCH:
240 // we treat VT_VARIANT as leakable to err on the safe side.
241 case VT_VARIANT:
242 case VT_UNKNOWN:
243 case VT_SAFEARRAY:
245 // very rarely used stuff (if ever):
246 case VT_VOID:
247 case VT_PTR:
248 case VT_CARRAY:
249 case VT_USERDEFINED:
250 case VT_LPSTR:
251 case VT_LPWSTR:
252 case VT_RECORD:
253 case VT_INT_PTR:
254 case VT_UINT_PTR:
255 case VT_FILETIME:
256 case VT_BLOB:
257 case VT_STREAM:
258 case VT_STORAGE:
259 case VT_STREAMED_OBJECT:
260 case VT_STORED_OBJECT:
261 case VT_BLOB_OBJECT:
262 case VT_VERSIONED_STREAM:
263 case VT_BSTR_BLOB:
264 leakable = true;
265 break;
268 if (!leakable && (vt & VT_ARRAY) != 0) {
269 leakable = true;
272 return leakable;
275 } // namespace win
276 } // namespace base