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