1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be
3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file.
4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#ifndef BASE_WIN_SCOPED_VARIANT_H_
6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#define BASE_WIN_SCOPED_VARIANT_H_
7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#pragma once
8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <windows.h>
10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <oleauto.h>
11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h"
13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/basictypes.h"
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
15731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base {
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace win {
17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Scoped VARIANT class for automatically freeing a COM VARIANT at the
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// end of a scope.  Additionally provides a few functions to make the
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// encapsulated VARIANT easier to use.
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Instead of inheriting from VARIANT, we take the containment approach
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// in order to have more control over the usage of the variant and guard
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// against memory leaks.
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API ScopedVariant {
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Declaration of a global variant variable that's always VT_EMPTY
27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static const VARIANT kEmptyVariant;
28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Default constructor.
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ScopedVariant() {
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // This is equivalent to what VariantInit does, but less code.
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    var_.vt = VT_EMPTY;
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Constructor to create a new VT_BSTR VARIANT.
36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // NOTE: Do not pass a BSTR to this constructor expecting ownership to
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // be transferred
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(const wchar_t* str);
39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Creates a new VT_BSTR variant of a specified length.
41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(const wchar_t* str, UINT length);
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Creates a new integral type variant and assigns the value to
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // VARIANT.lVal (32 bit sized field).
45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(int value, VARTYPE vt = VT_I4);
46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Creates a new double-precision type variant.  |vt| must be either VT_R8
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // or VT_DATE.
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(double value, VARTYPE vt = VT_R8);
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // VT_DISPATCH
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(IDispatch* dispatch);
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // VT_UNKNOWN
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(IUnknown* unknown);
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // SAFEARRAY
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(SAFEARRAY* safearray);
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Copies the variant.
61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  explicit ScopedVariant(const VARIANT& var);
62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ~ScopedVariant();
64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  inline VARTYPE type() const {
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return var_.vt;
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Give ScopedVariant ownership over an already allocated VARIANT.
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Reset(const VARIANT& var = kEmptyVariant);
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Releases ownership of the VARIANT to the caller.
73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VARIANT Release();
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Swap two ScopedVariant's.
76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Swap(ScopedVariant& var);
77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Returns a copy of the variant.
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VARIANT Copy() const;
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The return value is 0 if the variants are equal, 1 if this object is
82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // greater than |var|, -1 if it is smaller.
83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int Compare(const VARIANT& var, bool ignore_case = false) const;
84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Retrieves the pointer address.
86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Used to receive a VARIANT as an out argument (and take ownership).
87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The function DCHECKs on the current value being empty/null.
88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Usage: GetVariant(var.receive());
89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VARIANT* Receive();
90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(const wchar_t* str);
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Setters for simple types.
94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(int8 i8);
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(uint8 ui8);
96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(int16 i16);
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(uint16 ui16);
98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(int32 i32);
99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(uint32 ui32);
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(int64 i64);
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(uint64 ui64);
102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(float r32);
103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(double r64);
104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(bool b);
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Creates a copy of |var| and assigns as this instance's value.
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Note that this is different from the Reset() method that's used to
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // free the current value and assume ownership.
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(const VARIANT& var);
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // COM object setters
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(IDispatch* disp);
113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(IUnknown* unk);
114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // SAFEARRAY support
116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Set(SAFEARRAY* array);
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Special setter for DATE since DATE is a double and we already have
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a setter for double.
120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void SetDate(DATE date);
121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Allows const access to the contained variant without DCHECKs etc.
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // work properly but still doesn't allow modifications since we want control
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // over that.
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const VARIANT* operator&() const {
127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return &var_;
128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Like other scoped classes (e.g scoped_refptr, ScopedComPtr, ScopedBstr)
131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // we support the assignment operator for the type we wrap.
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ScopedVariant& operator=(const VARIANT& var);
133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // A hack to pass a pointer to the variant where the accepting
135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // function treats the variant as an input-only, read-only value
136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // but the function prototype requires a non const variant pointer.
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // There's no DCHECK or anything here.  Callers must know what they're doing.
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VARIANT* AsInput() const {
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // The nature of this function is const, so we declare
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // it as such and cast away the constness here.
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return const_cast<VARIANT*>(&var_);
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Allows the ScopedVariant instance to be passed to functions either by value
145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // or by const reference.
146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  operator const VARIANT&() const {
147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return var_;
148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Used as a debug check to see if we're leaking anything.
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static bool IsLeakableVarType(VARTYPE vt);
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick protected:
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VARIANT var_;
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Comparison operators for ScopedVariant are not supported at this point.
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Use the Compare method instead.
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool operator==(const ScopedVariant& var) const;
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool operator!=(const ScopedVariant& var) const;
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DISALLOW_COPY_AND_ASSIGN(ScopedVariant);
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namespace win
165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}  // namesoace base
166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif  // BASE_WIN_SCOPED_VARIANT_H_
168