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
14namespace base {
15namespace 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.
23class 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.
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
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.
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