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