Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | List of all members
base::win::ScopedVariant Class Reference

#include <scoped_variant.h>

Public Member Functions

 ScopedVariant ()
 
 ScopedVariant (const wchar_t *str)
 
 ScopedVariant (const wchar_t *str, UINT length)
 
 ScopedVariant (long value, VARTYPE vt=VT_I4)
 
 ScopedVariant (int value)
 
 ScopedVariant (bool value)
 
 ScopedVariant (double value, VARTYPE vt=VT_R8)
 
 ScopedVariant (IDispatch *dispatch)
 
 ScopedVariant (IUnknown *unknown)
 
 ScopedVariant (SAFEARRAY *safearray)
 
 ScopedVariant (const VARIANT &var)
 
 ScopedVariant (ScopedVariant &&var)
 
 ~ScopedVariant ()
 
VARTYPE type () const
 
void Reset (const VARIANT &var=kEmptyVariant)
 
VARIANT Release ()
 
void Swap (ScopedVariant &var)
 
VARIANT Copy () const
 
int Compare (const VARIANT &other, bool ignore_case=false) const
 
VARIANT * Receive ()
 
void Set (const wchar_t *str)
 
void Set (int8_t i8)
 
void Set (uint8_t ui8)
 
void Set (int16_t i16)
 
void Set (uint16_t ui16)
 
void Set (int32_t i32)
 
void Set (uint32_t ui32)
 
void Set (int64_t i64)
 
void Set (uint64_t ui64)
 
void Set (float r32)
 
void Set (double r64)
 
void Set (bool b)
 
void Set (const VARIANT &var)
 
void Set (IDispatch *disp)
 
void Set (IUnknown *unk)
 
void Set (SAFEARRAY *array)
 
void SetDate (DATE date)
 
const VARIANT * ptr () const
 
ScopedVariantoperator= (ScopedVariant &&var)
 
ScopedVariantoperator= (const VARIANT &var)
 
VARIANT * AsInput () const
 
 operator const VARIANT & () const
 

Static Public Member Functions

static bool IsLeakableVarType (VARTYPE vt)
 

Static Public Attributes

static const VARIANT kEmptyVariant = {{{VT_EMPTY}}}
 

Protected Attributes

VARIANT var_
 

Detailed Description

Definition at line 26 of file scoped_variant.h.

Constructor & Destructor Documentation

◆ ScopedVariant() [1/12]

base::win::ScopedVariant::ScopedVariant ( )
inline

Definition at line 32 of file scoped_variant.h.

32 {
33 // This is equivalent to what VariantInit does, but less code.
34 var_.vt = VT_EMPTY;
35 }

◆ ScopedVariant() [2/12]

base::win::ScopedVariant::ScopedVariant ( const wchar_t *  str)
explicit

Definition at line 33 of file scoped_variant.cc.

33 {
34 var_.vt = VT_EMPTY;
35 Set(str);
36}
void Set(const wchar_t *str)

◆ ScopedVariant() [3/12]

base::win::ScopedVariant::ScopedVariant ( const wchar_t *  str,
UINT  length 
)

Definition at line 38 of file scoped_variant.cc.

38 {
39 var_.vt = VT_BSTR;
40 var_.bstrVal = ::SysAllocStringLen(str, length);
41}
size_t length

◆ ScopedVariant() [4/12]

base::win::ScopedVariant::ScopedVariant ( long  value,
VARTYPE  vt = VT_I4 
)
explicit

Definition at line 43 of file scoped_variant.cc.

43 {
44 var_.vt = vt;
45 var_.lVal = value;
46}
uint8_t value

◆ ScopedVariant() [5/12]

base::win::ScopedVariant::ScopedVariant ( int  value)
explicit

Definition at line 48 of file scoped_variant.cc.

48 {
49 var_.vt = VT_I4;
50 var_.lVal = value;
51}

◆ ScopedVariant() [6/12]

base::win::ScopedVariant::ScopedVariant ( bool  value)
explicit

Definition at line 53 of file scoped_variant.cc.

53 {
54 var_.vt = VT_BOOL;
55 var_.boolVal = value ? VARIANT_TRUE : VARIANT_FALSE;
56}

◆ ScopedVariant() [7/12]

base::win::ScopedVariant::ScopedVariant ( double  value,
VARTYPE  vt = VT_R8 
)
explicit

Definition at line 58 of file scoped_variant.cc.

58 {
59 BASE_DCHECK(vt == VT_R8 || vt == VT_DATE);
60 var_.vt = vt;
61 var_.dblVal = value;
62}
#define BASE_DCHECK(condition)
Definition logging.h:63

◆ ScopedVariant() [8/12]

base::win::ScopedVariant::ScopedVariant ( IDispatch *  dispatch)
explicit

Definition at line 64 of file scoped_variant.cc.

64 {
65 var_.vt = VT_EMPTY;
66 Set(dispatch);
67}

◆ ScopedVariant() [9/12]

base::win::ScopedVariant::ScopedVariant ( IUnknown *  unknown)
explicit

Definition at line 69 of file scoped_variant.cc.

69 {
70 var_.vt = VT_EMPTY;
71 Set(unknown);
72}

◆ ScopedVariant() [10/12]

base::win::ScopedVariant::ScopedVariant ( SAFEARRAY *  safearray)
explicit

Definition at line 74 of file scoped_variant.cc.

74 {
75 var_.vt = VT_EMPTY;
76 Set(safearray);
77}

◆ ScopedVariant() [11/12]

base::win::ScopedVariant::ScopedVariant ( const VARIANT &  var)
explicit

Definition at line 79 of file scoped_variant.cc.

79 {
80 var_.vt = VT_EMPTY;
81 Set(var);
82}

◆ ScopedVariant() [12/12]

base::win::ScopedVariant::ScopedVariant ( ScopedVariant &&  var)

Definition at line 23 of file scoped_variant.cc.

23 {
24 var_.vt = VT_EMPTY;
25 Reset(var.Release());
26}
void Reset(const VARIANT &var=kEmptyVariant)

◆ ~ScopedVariant()

base::win::ScopedVariant::~ScopedVariant ( )

Definition at line 28 of file scoped_variant.cc.

28 {
29 static_assert(sizeof(ScopedVariant) == sizeof(VARIANT), "ScopedVariantSize");
30 ::VariantClear(&var_);
31}

Member Function Documentation

◆ AsInput()

VARIANT * base::win::ScopedVariant::AsInput ( ) const
inline

Definition at line 162 of file scoped_variant.h.

162 {
163 // The nature of this function is const, so we declare
164 // it as such and cast away the constness here.
165 return const_cast<VARIANT*>(&var_);
166 }

◆ Compare()

int base::win::ScopedVariant::Compare ( const VARIANT &  other,
bool  ignore_case = false 
) const

Definition at line 114 of file scoped_variant.cc.

114 {
115 BASE_DCHECK(!V_ISARRAY(&var_))
116 << "Comparison is not supported when |this| owns a SAFEARRAY";
117 BASE_DCHECK(!V_ISARRAY(&other))
118 << "Comparison is not supported when |other| owns a SAFEARRAY";
119
120 const bool this_is_empty = var_.vt == VT_EMPTY || var_.vt == VT_NULL;
121 const bool other_is_empty = other.vt == VT_EMPTY || other.vt == VT_NULL;
122
123 // 1. VT_NULL and VT_EMPTY is always considered less-than any other VARTYPE.
124 if (this_is_empty)
125 return other_is_empty ? 0 : -1;
126 if (other_is_empty)
127 return 1;
128
129 // 2. If both VARIANTS have either VT_UNKNOWN or VT_DISPATCH even if the
130 // VARTYPEs do not match, the address of its IID_IUnknown is compared to
131 // guarantee a logical ordering even though it is not a meaningful order.
132 // e.g. (a.Compare(b) != b.Compare(a)) unless (a == b).
133 const bool this_is_unknown = var_.vt == VT_UNKNOWN || var_.vt == VT_DISPATCH;
134 const bool other_is_unknown =
135 other.vt == VT_UNKNOWN || other.vt == VT_DISPATCH;
136 if (this_is_unknown && other_is_unknown) {
137 // https://docs.microsoft.com/en-us/windows/win32/com/rules-for-implementing-queryinterface
138 // Query IID_IUnknown to determine whether the two variants point
139 // to the same instance of an object
140 Microsoft::WRL::ComPtr<IUnknown> this_unknown;
141 Microsoft::WRL::ComPtr<IUnknown> other_unknown;
142 V_UNKNOWN(&var_)->QueryInterface(IID_PPV_ARGS(&this_unknown));
143 V_UNKNOWN(&other)->QueryInterface(IID_PPV_ARGS(&other_unknown));
144 if (this_unknown.Get() == other_unknown.Get())
145 return 0;
146 // std::less for any pointer type yields a strict total order even if the
147 // built-in operator< does not.
148 return std::less<>{}(this_unknown.Get(), other_unknown.Get()) ? -1 : 1;
149 }
150
151 // 3. If the VARTYPEs do not match, then the value of the VARTYPE is compared.
152 if (V_VT(&var_) != V_VT(&other))
153 return (V_VT(&var_) < V_VT(&other)) ? -1 : 1;
154
155 const VARTYPE shared_vartype = V_VT(&var_);
156 // 4. Comparing VT_BSTR values is a lexicographical comparison of the contents
157 // of the BSTR, taking into account |ignore_case|.
158 if (shared_vartype == VT_BSTR) {
159 ULONG flags = ignore_case ? NORM_IGNORECASE : 0;
160 HRESULT hr =
161 ::VarBstrCmp(V_BSTR(&var_), V_BSTR(&other), LOCALE_USER_DEFAULT, flags);
162 BASE_DCHECK(SUCCEEDED(hr) && hr != VARCMP_NULL)
163 << "unsupported variant comparison: " << var_.vt << " and " << other.vt;
164
165 switch (hr) {
166 case VARCMP_LT:
167 return -1;
168 case VARCMP_GT:
169 case VARCMP_NULL:
170 return 1;
171 default:
172 return 0;
173 }
174 }
175
176 // 5. Otherwise returns the lexicographical comparison of the values held by
177 // the two VARIANTS that share the same VARTYPE.
178 return ::VariantCompare(var_, other);
179}
FlutterSemanticsFlag flags
#define SUCCEEDED(hr)
DWORD ULONG

◆ Copy()

VARIANT base::win::ScopedVariant::Copy ( ) const

Definition at line 108 of file scoped_variant.cc.

108 {
109 VARIANT ret = {{{VT_EMPTY}}};
110 ::VariantCopy(&ret, &var_);
111 return ret;
112}

◆ IsLeakableVarType()

bool base::win::ScopedVariant::IsLeakableVarType ( VARTYPE  vt)
static

Definition at line 308 of file scoped_variant.cc.

308 {
309 bool leakable = false;
310 switch (vt & VT_TYPEMASK) {
311 case VT_BSTR:
312 case VT_DISPATCH:
313 // we treat VT_VARIANT as leakable to err on the safe side.
314 case VT_VARIANT:
315 case VT_UNKNOWN:
316 case VT_SAFEARRAY:
317
318 // very rarely used stuff (if ever):
319 case VT_VOID:
320 case VT_PTR:
321 case VT_CARRAY:
322 case VT_USERDEFINED:
323 case VT_LPSTR:
324 case VT_LPWSTR:
325 case VT_RECORD:
326 case VT_INT_PTR:
327 case VT_UINT_PTR:
328 case VT_FILETIME:
329 case VT_BLOB:
330 case VT_STREAM:
331 case VT_STORAGE:
332 case VT_STREAMED_OBJECT:
333 case VT_STORED_OBJECT:
334 case VT_BLOB_OBJECT:
335 case VT_VERSIONED_STREAM:
336 case VT_BSTR_BLOB:
337 leakable = true;
338 break;
339 }
340
341 if (!leakable && (vt & VT_ARRAY) != 0) {
342 leakable = true;
343 }
344
345 return leakable;
346}

◆ operator const VARIANT &()

base::win::ScopedVariant::operator const VARIANT & ( ) const
inline

Definition at line 170 of file scoped_variant.h.

170{ return var_; }

◆ operator=() [1/2]

ScopedVariant & base::win::ScopedVariant::operator= ( const VARIANT &  var)

Definition at line 300 of file scoped_variant.cc.

300 {
301 if (&var != &var_) {
302 VariantClear(&var_);
303 Set(var);
304 }
305 return *this;
306}

◆ operator=() [2/2]

ScopedVariant & base::win::ScopedVariant::operator= ( ScopedVariant &&  var)

Definition at line 294 of file scoped_variant.cc.

294 {
295 if (var.ptr() != &var_)
296 Reset(var.Release());
297 return *this;
298}

◆ ptr()

const VARIANT * base::win::ScopedVariant::ptr ( ) const
inline

Definition at line 148 of file scoped_variant.h.

148{ return &var_; }

◆ Receive()

VARIANT * base::win::ScopedVariant::Receive ( )

Definition at line 103 of file scoped_variant.cc.

103 {
104 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "variant leak. type: " << var_.vt;
105 return &var_;
106}
static bool IsLeakableVarType(VARTYPE vt)

◆ Release()

VARIANT base::win::ScopedVariant::Release ( )

Definition at line 91 of file scoped_variant.cc.

91 {
92 VARIANT var = var_;
93 var_.vt = VT_EMPTY;
94 return var;
95}

◆ Reset()

void base::win::ScopedVariant::Reset ( const VARIANT &  var = kEmptyVariant)

Definition at line 84 of file scoped_variant.cc.

84 {
85 if (&var != &var_) {
86 ::VariantClear(&var_);
87 var_ = var;
88 }
89}

◆ Set() [1/16]

void base::win::ScopedVariant::Set ( bool  b)

Definition at line 261 of file scoped_variant.cc.

261 {
262 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
263 var_.vt = VT_BOOL;
264 var_.boolVal = b ? VARIANT_TRUE : VARIANT_FALSE;
265}
static bool b

◆ Set() [2/16]

void base::win::ScopedVariant::Set ( const VARIANT &  var)

Definition at line 286 of file scoped_variant.cc.

286 {
287 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
288 if (FAILED(::VariantCopy(&var_, &var))) {
289 BASE_DLOG() << "Error: VariantCopy failed";
290 var_.vt = VT_EMPTY;
291 }
292}
#define BASE_DLOG()
Definition logging.h:62
#define FAILED(hr)

◆ Set() [3/16]

void base::win::ScopedVariant::Set ( const wchar_t *  str)

Definition at line 181 of file scoped_variant.cc.

181 {
182 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
183 var_.vt = VT_BSTR;
184 var_.bstrVal = ::SysAllocString(str);
185}

◆ Set() [4/16]

void base::win::ScopedVariant::Set ( double  r64)

Definition at line 241 of file scoped_variant.cc.

241 {
242 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
243 var_.vt = VT_R8;
244 var_.dblVal = r64;
245}

◆ Set() [5/16]

void base::win::ScopedVariant::Set ( float  r32)

Definition at line 235 of file scoped_variant.cc.

235 {
236 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
237 var_.vt = VT_R4;
238 var_.fltVal = r32;
239}

◆ Set() [6/16]

void base::win::ScopedVariant::Set ( IDispatch *  disp)

Definition at line 253 of file scoped_variant.cc.

253 {
254 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
255 var_.vt = VT_DISPATCH;
256 var_.pdispVal = disp;
257 if (disp)
258 disp->AddRef();
259}

◆ Set() [7/16]

void base::win::ScopedVariant::Set ( int16_t  i16)

Definition at line 199 of file scoped_variant.cc.

199 {
200 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
201 var_.vt = VT_I2;
202 var_.iVal = i16;
203}

◆ Set() [8/16]

void base::win::ScopedVariant::Set ( int32_t  i32)

Definition at line 211 of file scoped_variant.cc.

211 {
212 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
213 var_.vt = VT_I4;
214 var_.lVal = i32;
215}

◆ Set() [9/16]

void base::win::ScopedVariant::Set ( int64_t  i64)

Definition at line 223 of file scoped_variant.cc.

223 {
224 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
225 var_.vt = VT_I8;
226 var_.llVal = i64;
227}

◆ Set() [10/16]

void base::win::ScopedVariant::Set ( int8_t  i8)

Definition at line 187 of file scoped_variant.cc.

187 {
188 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
189 var_.vt = VT_I1;
190 var_.cVal = i8;
191}

◆ Set() [11/16]

void base::win::ScopedVariant::Set ( IUnknown *  unk)

Definition at line 267 of file scoped_variant.cc.

267 {
268 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
269 var_.vt = VT_UNKNOWN;
270 var_.punkVal = unk;
271 if (unk)
272 unk->AddRef();
273}

◆ Set() [12/16]

void base::win::ScopedVariant::Set ( SAFEARRAY *  array)

Definition at line 275 of file scoped_variant.cc.

275 {
276 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
277 if (SUCCEEDED(::SafeArrayGetVartype(array, &var_.vt))) {
278 var_.vt |= VT_ARRAY;
279 var_.parray = array;
280 } else {
281 BASE_DCHECK(!array) << "Unable to determine safearray vartype";
282 var_.vt = VT_EMPTY;
283 }
284}

◆ Set() [13/16]

void base::win::ScopedVariant::Set ( uint16_t  ui16)

Definition at line 205 of file scoped_variant.cc.

205 {
206 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
207 var_.vt = VT_UI2;
208 var_.uiVal = ui16;
209}

◆ Set() [14/16]

void base::win::ScopedVariant::Set ( uint32_t  ui32)

Definition at line 217 of file scoped_variant.cc.

217 {
218 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
219 var_.vt = VT_UI4;
220 var_.ulVal = ui32;
221}

◆ Set() [15/16]

void base::win::ScopedVariant::Set ( uint64_t  ui64)

Definition at line 229 of file scoped_variant.cc.

229 {
230 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
231 var_.vt = VT_UI8;
232 var_.ullVal = ui64;
233}

◆ Set() [16/16]

void base::win::ScopedVariant::Set ( uint8_t  ui8)

Definition at line 193 of file scoped_variant.cc.

193 {
194 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
195 var_.vt = VT_UI1;
196 var_.bVal = ui8;
197}

◆ SetDate()

void base::win::ScopedVariant::SetDate ( DATE  date)

Definition at line 247 of file scoped_variant.cc.

247 {
248 BASE_DCHECK(!IsLeakableVarType(var_.vt)) << "leaking variant: " << var_.vt;
249 var_.vt = VT_DATE;
250 var_.date = date;
251}

◆ Swap()

void base::win::ScopedVariant::Swap ( ScopedVariant var)

Definition at line 97 of file scoped_variant.cc.

97 {
98 VARIANT tmp = var_;
99 var_ = var.var_;
100 var.var_ = tmp;
101}

◆ type()

VARTYPE base::win::ScopedVariant::type ( ) const
inline

Definition at line 78 of file scoped_variant.h.

78{ return var_.vt; }

Member Data Documentation

◆ kEmptyVariant

const VARIANT base::win::ScopedVariant::kEmptyVariant = {{{VT_EMPTY}}}
static

Definition at line 29 of file scoped_variant.h.

◆ var_

VARIANT base::win::ScopedVariant::var_
protected

Definition at line 176 of file scoped_variant.h.


The documentation for this class was generated from the following files: