scoped_variant.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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
15namespace base {
16namespace 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.
24class 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.
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
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.
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