• 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 #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