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 #ifndef BASE_SCOPED_VARIANT_WIN_H_ 6 #define BASE_SCOPED_VARIANT_WIN_H_ 7 8 #include <windows.h> 9 #include <oleauto.h> 10 11 #include "base/basictypes.h" // needed to pick up OS_WIN 12 #include "base/logging.h" 13 14 // Scoped VARIANT class for automatically freeing a COM VARIANT at the 15 // end of a scope. Additionally provides a few functions to make the 16 // encapsulated VARIANT easier to use. 17 // Instead of inheriting from VARIANT, we take the containment approach 18 // in order to have more control over the usage of the variant and guard 19 // against memory leaks. 20 class ScopedVariant { 21 public: 22 // Declaration of a global variant variable that's always VT_EMPTY 23 static const VARIANT kEmptyVariant; 24 25 // Default constructor. 26 ScopedVariant() { 27 // This is equivalent to what VariantInit does, but less code. 28 var_.vt = VT_EMPTY; 29 } 30 31 // Constructor to create a new VT_BSTR VARIANT. 32 // NOTE: Do not pass a BSTR to this constructor expecting ownership to 33 // be transferred 34 explicit ScopedVariant(const wchar_t* str); 35 36 // Creates a new VT_BSTR variant of a specified length. 37 explicit ScopedVariant(const wchar_t* str, UINT length); 38 39 // Creates a new integral type variant and assigns the value to 40 // VARIANT.lVal (32 bit sized field). 41 explicit ScopedVariant(int value, VARTYPE vt = VT_I4); 42 43 // Creates a new double-precision type variant. |vt| must be either VT_R8 44 // or VT_DATE. 45 explicit ScopedVariant(double value, VARTYPE vt = VT_R8); 46 47 // VT_DISPATCH 48 explicit ScopedVariant(IDispatch* dispatch); 49 50 // VT_UNKNOWN 51 explicit ScopedVariant(IUnknown* unknown); 52 53 // SAFEARRAY 54 explicit ScopedVariant(SAFEARRAY* safearray); 55 56 // Copies the variant. 57 explicit ScopedVariant(const VARIANT& var); 58 59 ~ScopedVariant(); 60 61 inline VARTYPE type() const { 62 return var_.vt; 63 } 64 65 // Give ScopedVariant ownership over an already allocated VARIANT. 66 void Reset(const VARIANT& var = kEmptyVariant); 67 68 // Releases ownership of the VARIANT to the caller. 69 VARIANT Release(); 70 71 // Swap two ScopedVariant's. 72 void Swap(ScopedVariant& var); 73 74 // Returns a copy of the variant. 75 VARIANT Copy() const; 76 77 // The return value is 0 if the variants are equal, 1 if this object is 78 // greater than |var|, -1 if it is smaller. 79 int Compare(const VARIANT& var, bool ignore_case = false) const; 80 81 // Retrieves the pointer address. 82 // Used to receive a VARIANT as an out argument (and take ownership). 83 // The function DCHECKs on the current value being empty/null. 84 // Usage: GetVariant(var.receive()); 85 VARIANT* Receive(); 86 87 void Set(const wchar_t* str); 88 89 // Setters for simple types. 90 void Set(int8 i8); 91 void Set(uint8 ui8); 92 void Set(int16 i16); 93 void Set(uint16 ui16); 94 void Set(int32 i32); 95 void Set(uint32 ui32); 96 void Set(int64 i64); 97 void Set(uint64 ui64); 98 void Set(float r32); 99 void Set(double r64); 100 void Set(bool b); 101 102 // Creates a copy of |var| and assigns as this instance's value. 103 // Note that this is different from the Reset() method that's used to 104 // free the current value and assume ownership. 105 void Set(const VARIANT& var); 106 107 // COM object setters 108 void Set(IDispatch* disp); 109 void Set(IUnknown* unk); 110 111 // SAFEARRAY support 112 void Set(SAFEARRAY* array); 113 114 // Special setter for DATE since DATE is a double and we already have 115 // a setter for double. 116 void SetDate(DATE date); 117 118 // Allows const access to the contained variant without DCHECKs etc. 119 // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to 120 // work properly but still doesn't allow modifications since we want control 121 // over that. 122 const VARIANT* operator&() const { 123 return &var_; 124 } 125 126 // Like other scoped classes (e.g scoped_refptr, ScopedComPtr, ScopedBstr) 127 // we support the assignment operator for the type we wrap. 128 ScopedVariant& operator=(const VARIANT& var); 129 130 // A hack to pass a pointer to the variant where the accepting 131 // function treats the variant as an input-only, read-only value 132 // but the function prototype requires a non const variant pointer. 133 // There's no DCHECK or anything here. Callers must know what they're doing. 134 VARIANT* AsInput() const { 135 // The nature of this function is const, so we declare 136 // it as such and cast away the constness here. 137 return const_cast<VARIANT*>(&var_); 138 } 139 140 // Allows the ScopedVariant instance to be passed to functions either by value 141 // or by const reference. 142 operator const VARIANT&() const { 143 return var_; 144 } 145 146 // Used as a debug check to see if we're leaking anything. 147 static bool IsLeakableVarType(VARTYPE vt); 148 149 protected: 150 VARIANT var_; 151 152 private: 153 // Comparison operators for ScopedVariant are not supported at this point. 154 // Use the Compare method instead. 155 bool operator==(const ScopedVariant& var) const; 156 bool operator!=(const ScopedVariant& var) const; 157 DISALLOW_COPY_AND_ASSIGN(ScopedVariant); 158 }; 159 160 #endif // BASE_SCOPED_VARIANT_WIN_H_ 161