1 // Copyright (c) 2011 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_WIN_SCOPED_VARIANT_H_ 6 #define BASE_WIN_SCOPED_VARIANT_H_ 7 #pragma once 8 9 #include <windows.h> 10 #include <oleauto.h> 11 12 #include "base/base_api.h" 13 #include "base/basictypes.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_API 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 explicit 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(int value, VARTYPE vt = VT_I4); 46 47 // Creates a new double-precision type variant. |vt| must be either VT_R8 48 // or VT_DATE. 49 explicit ScopedVariant(double value, VARTYPE vt = VT_R8); 50 51 // VT_DISPATCH 52 explicit ScopedVariant(IDispatch* dispatch); 53 54 // VT_UNKNOWN 55 explicit ScopedVariant(IUnknown* unknown); 56 57 // SAFEARRAY 58 explicit ScopedVariant(SAFEARRAY* safearray); 59 60 // Copies the variant. 61 explicit ScopedVariant(const VARIANT& var); 62 63 ~ScopedVariant(); 64 type()65 inline VARTYPE type() const { 66 return var_.vt; 67 } 68 69 // Give ScopedVariant ownership over an already allocated VARIANT. 70 void Reset(const VARIANT& var = kEmptyVariant); 71 72 // Releases ownership of the VARIANT to the caller. 73 VARIANT Release(); 74 75 // Swap two ScopedVariant's. 76 void Swap(ScopedVariant& var); 77 78 // Returns a copy of the variant. 79 VARIANT Copy() const; 80 81 // The return value is 0 if the variants are equal, 1 if this object is 82 // greater than |var|, -1 if it is smaller. 83 int Compare(const VARIANT& var, bool ignore_case = false) const; 84 85 // Retrieves the pointer address. 86 // Used to receive a VARIANT as an out argument (and take ownership). 87 // The function DCHECKs on the current value being empty/null. 88 // Usage: GetVariant(var.receive()); 89 VARIANT* Receive(); 90 91 void Set(const wchar_t* str); 92 93 // Setters for simple types. 94 void Set(int8 i8); 95 void Set(uint8 ui8); 96 void Set(int16 i16); 97 void Set(uint16 ui16); 98 void Set(int32 i32); 99 void Set(uint32 ui32); 100 void Set(int64 i64); 101 void Set(uint64 ui64); 102 void Set(float r32); 103 void Set(double r64); 104 void Set(bool b); 105 106 // Creates a copy of |var| and assigns as this instance's value. 107 // Note that this is different from the Reset() method that's used to 108 // free the current value and assume ownership. 109 void Set(const VARIANT& var); 110 111 // COM object setters 112 void Set(IDispatch* disp); 113 void Set(IUnknown* unk); 114 115 // SAFEARRAY support 116 void Set(SAFEARRAY* array); 117 118 // Special setter for DATE since DATE is a double and we already have 119 // a setter for double. 120 void SetDate(DATE date); 121 122 // Allows const access to the contained variant without DCHECKs etc. 123 // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to 124 // work properly but still doesn't allow modifications since we want control 125 // over that. 126 const VARIANT* operator&() const { 127 return &var_; 128 } 129 130 // Like other scoped classes (e.g scoped_refptr, ScopedComPtr, ScopedBstr) 131 // we support the assignment operator for the type we wrap. 132 ScopedVariant& operator=(const VARIANT& var); 133 134 // A hack to pass a pointer to the variant where the accepting 135 // function treats the variant as an input-only, read-only value 136 // but the function prototype requires a non const variant pointer. 137 // There's no DCHECK or anything here. Callers must know what they're doing. AsInput()138 VARIANT* AsInput() const { 139 // The nature of this function is const, so we declare 140 // it as such and cast away the constness here. 141 return const_cast<VARIANT*>(&var_); 142 } 143 144 // Allows the ScopedVariant instance to be passed to functions either by value 145 // or by const reference. 146 operator const VARIANT&() const { 147 return var_; 148 } 149 150 // Used as a debug check to see if we're leaking anything. 151 static bool IsLeakableVarType(VARTYPE vt); 152 153 protected: 154 VARIANT var_; 155 156 private: 157 // Comparison operators for ScopedVariant are not supported at this point. 158 // Use the Compare method instead. 159 bool operator==(const ScopedVariant& var) const; 160 bool operator!=(const ScopedVariant& var) const; 161 DISALLOW_COPY_AND_ASSIGN(ScopedVariant); 162 }; 163 164 } // namespace win 165 } // namesoace base 166 167 #endif // BASE_WIN_SCOPED_VARIANT_H_ 168