1 // Copyright 2011 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_WIN_SCOPED_VARIANT_H_ 6 #define BASE_WIN_SCOPED_VARIANT_H_ 7 8 #include <windows.h> 9 10 #include <oleauto.h> 11 #include <stdint.h> 12 13 #include "base/base_export.h" 14 15 namespace base { 16 namespace win { 17 18 // Scoped VARIANT class for automatically freeing a COM VARIANT at the 19 // end of a scope. Additionally provides a few functions to make the 20 // encapsulated VARIANT easier to use. 21 // Instead of inheriting from VARIANT, we take the containment approach 22 // in order to have more control over the usage of the variant and guard 23 // against memory leaks. 24 class BASE_EXPORT ScopedVariant { 25 public: 26 // Declaration of a global variant variable that's always VT_EMPTY 27 static const VARIANT kEmptyVariant; 28 29 // Default constructor. ScopedVariant()30 ScopedVariant() { 31 // This is equivalent to what VariantInit does, but less code. 32 var_.vt = VT_EMPTY; 33 } 34 35 // Constructor to create a new VT_BSTR VARIANT. 36 // NOTE: Do not pass a BSTR to this constructor expecting ownership to 37 // be transferred 38 explicit ScopedVariant(const wchar_t* str); 39 40 // Creates a new VT_BSTR variant of a specified length. 41 ScopedVariant(const wchar_t* str, UINT length); 42 43 // Creates a new integral type variant and assigns the value to 44 // VARIANT.lVal (32 bit sized field). 45 explicit ScopedVariant(long value, // NOLINT(runtime/int) 46 VARTYPE vt = VT_I4); 47 48 // Creates a new integral type variant for the int type and assigns the value 49 // to VARIANT.lVal (32 bit sized field). 50 explicit ScopedVariant(int value); 51 52 // Creates a new boolean (VT_BOOL) variant and assigns the value to 53 // VARIANT.boolVal. 54 explicit ScopedVariant(bool value); 55 56 // Creates a new double-precision type variant. |vt| must be either VT_R8 57 // or VT_DATE. 58 explicit ScopedVariant(double value, VARTYPE vt = VT_R8); 59 60 // VT_DISPATCH 61 explicit ScopedVariant(IDispatch* dispatch); 62 63 // VT_UNKNOWN 64 explicit ScopedVariant(IUnknown* unknown); 65 66 // SAFEARRAY 67 explicit ScopedVariant(SAFEARRAY* safearray); 68 69 // Copies the variant. 70 explicit ScopedVariant(const VARIANT& var); 71 72 // Moves the wrapped variant into another ScopedVariant. 73 ScopedVariant(ScopedVariant&& var); 74 75 ScopedVariant(const ScopedVariant&) = delete; 76 ScopedVariant& operator=(const ScopedVariant&) = delete; 77 78 ~ScopedVariant(); 79 type()80 inline VARTYPE type() const { return var_.vt; } 81 82 // Give ScopedVariant ownership over an already allocated VARIANT. 83 void Reset(const VARIANT& var = kEmptyVariant); 84 85 // Releases ownership of the VARIANT to the caller. 86 VARIANT Release(); 87 88 // Swap two ScopedVariant's. 89 void Swap(ScopedVariant& var); 90 91 // Returns a copy of the variant. 92 VARIANT Copy() const; 93 94 // The return value is 0 if the variants are equal, 1 if this object is 95 // greater than |other|, -1 if it is smaller. 96 // Comparison with an array VARIANT is not supported. 97 // 1. VT_NULL and VT_EMPTY is always considered less-than any other VARTYPE. 98 // 2. If both VARIANTS have either VT_UNKNOWN or VT_DISPATCH even if the 99 // VARTYPEs do not match, the address of its IID_IUnknown is compared to 100 // guarantee a logical ordering even though it is not a meaningful order. 101 // e.g. (a.Compare(b) != b.Compare(a)) unless (a == b). 102 // 3. If the VARTYPEs do not match, then the value of the VARTYPE is compared. 103 // 4. Comparing VT_BSTR values is a lexicographical comparison of the contents 104 // of the BSTR, taking into account |ignore_case|. 105 // 5. Otherwise returns the lexicographical comparison of the values held by 106 // the two VARIANTS that share the same VARTYPE. 107 int Compare(const VARIANT& other, bool ignore_case = false) const; 108 109 // Retrieves the pointer address. 110 // Used to receive a VARIANT as an out argument (and take ownership). 111 // The function DCHECKs on the current value being empty/null. 112 // Usage: GetVariant(var.receive()); 113 VARIANT* Receive(); 114 115 void Set(const wchar_t* str); 116 117 // Setters for simple types. 118 void Set(int8_t i8); 119 void Set(uint8_t ui8); 120 void Set(int16_t i16); 121 void Set(uint16_t ui16); 122 void Set(int32_t i32); 123 void Set(uint32_t ui32); 124 void Set(int64_t i64); 125 void Set(uint64_t ui64); 126 void Set(float r32); 127 void Set(double r64); 128 void Set(bool b); 129 130 // Creates a copy of |var| and assigns as this instance's value. 131 // Note that this is different from the Reset() method that's used to 132 // free the current value and assume ownership. 133 void Set(const VARIANT& var); 134 135 // COM object setters 136 void Set(IDispatch* disp); 137 void Set(IUnknown* unk); 138 139 // SAFEARRAY support 140 void Set(SAFEARRAY* array); 141 142 // Special setter for DATE since DATE is a double and we already have 143 // a setter for double. 144 void SetDate(DATE date); 145 146 // Allows const access to the contained variant without DCHECKs etc. 147 // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to 148 // work properly but still doesn't allow modifications since we want control 149 // over that. ptr()150 const VARIANT* ptr() const { return &var_; } 151 152 // Moves the ScopedVariant to another instance. 153 ScopedVariant& operator=(ScopedVariant&& var); 154 155 // Like other scoped classes (e.g. scoped_refptr, ScopedBstr, 156 // Microsoft::WRL::ComPtr) we support the assignment operator for the type we 157 // wrap. 158 ScopedVariant& operator=(const VARIANT& var); 159 160 // A hack to pass a pointer to the variant where the accepting 161 // function treats the variant as an input-only, read-only value 162 // but the function prototype requires a non const variant pointer. 163 // There's no DCHECK or anything here. Callers must know what they're doing. AsInput()164 VARIANT* AsInput() const { 165 // The nature of this function is const, so we declare 166 // it as such and cast away the constness here. 167 return const_cast<VARIANT*>(&var_); 168 } 169 170 // Allows the ScopedVariant instance to be passed to functions either by value 171 // or by const reference. 172 operator const VARIANT&() const { return var_; } 173 174 // Used as a debug check to see if we're leaking anything. 175 static bool IsLeakableVarType(VARTYPE vt); 176 177 protected: 178 VARIANT var_; 179 180 private: 181 // Comparison operators for ScopedVariant are not supported at this point. 182 // Use the Compare method instead. 183 bool operator==(const ScopedVariant& var) const; 184 bool operator!=(const ScopedVariant& var) const; 185 }; 186 187 } // namespace win 188 } // namespace base 189 190 #endif // BASE_WIN_SCOPED_VARIANT_H_ 191