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