Home | History | Annotate | Download | only in win
      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.
     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