| // Copyright 2011 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef BASE_WIN_SCOPED_VARIANT_H_ |
| #define BASE_WIN_SCOPED_VARIANT_H_ |
| |
| #include <windows.h> |
| |
| #include <oleauto.h> |
| #include <stdint.h> |
| |
| #include "base/base_export.h" |
| |
| namespace base { |
| namespace win { |
| |
| // Scoped VARIANT class for automatically freeing a COM VARIANT at the |
| // end of a scope. Additionally provides a few functions to make the |
| // encapsulated VARIANT easier to use. |
| // Instead of inheriting from VARIANT, we take the containment approach |
| // in order to have more control over the usage of the variant and guard |
| // against memory leaks. |
| class BASE_EXPORT ScopedVariant { |
| public: |
| // Declaration of a global variant variable that's always VT_EMPTY |
| static const VARIANT kEmptyVariant; |
| |
| // Default constructor. |
| ScopedVariant() { |
| // This is equivalent to what VariantInit does, but less code. |
| var_.vt = VT_EMPTY; |
| } |
| |
| // Constructor to create a new VT_BSTR VARIANT. |
| // NOTE: Do not pass a BSTR to this constructor expecting ownership to |
| // be transferred |
| explicit ScopedVariant(const wchar_t* str); |
| |
| // Creates a new VT_BSTR variant of a specified length. |
| ScopedVariant(const wchar_t* str, UINT length); |
| |
| // Creates a new integral type variant and assigns the value to |
| // VARIANT.lVal (32 bit sized field). |
| explicit ScopedVariant(long value, // NOLINT(runtime/int) |
| VARTYPE vt = VT_I4); |
| |
| // Creates a new integral type variant for the int type and assigns the value |
| // to VARIANT.lVal (32 bit sized field). |
| explicit ScopedVariant(int value); |
| |
| // Creates a new boolean (VT_BOOL) variant and assigns the value to |
| // VARIANT.boolVal. |
| explicit ScopedVariant(bool value); |
| |
| // Creates a new double-precision type variant. |vt| must be either VT_R8 |
| // or VT_DATE. |
| explicit ScopedVariant(double value, VARTYPE vt = VT_R8); |
| |
| // VT_DISPATCH |
| explicit ScopedVariant(IDispatch* dispatch); |
| |
| // VT_UNKNOWN |
| explicit ScopedVariant(IUnknown* unknown); |
| |
| // SAFEARRAY |
| explicit ScopedVariant(SAFEARRAY* safearray); |
| |
| // Copies the variant. |
| explicit ScopedVariant(const VARIANT& var); |
| |
| // Moves the wrapped variant into another ScopedVariant. |
| ScopedVariant(ScopedVariant&& var); |
| |
| ScopedVariant(const ScopedVariant&) = delete; |
| ScopedVariant& operator=(const ScopedVariant&) = delete; |
| |
| ~ScopedVariant(); |
| |
| inline VARTYPE type() const { return var_.vt; } |
| |
| // Give ScopedVariant ownership over an already allocated VARIANT. |
| void Reset(const VARIANT& var = kEmptyVariant); |
| |
| // Releases ownership of the VARIANT to the caller. |
| VARIANT Release(); |
| |
| // Swap two ScopedVariant's. |
| void Swap(ScopedVariant& var); |
| |
| // Returns a copy of the variant. |
| VARIANT Copy() const; |
| |
| // The return value is 0 if the variants are equal, 1 if this object is |
| // greater than |other|, -1 if it is smaller. |
| // Comparison with an array VARIANT is not supported. |
| // 1. VT_NULL and VT_EMPTY is always considered less-than any other VARTYPE. |
| // 2. If both VARIANTS have either VT_UNKNOWN or VT_DISPATCH even if the |
| // VARTYPEs do not match, the address of its IID_IUnknown is compared to |
| // guarantee a logical ordering even though it is not a meaningful order. |
| // e.g. (a.Compare(b) != b.Compare(a)) unless (a == b). |
| // 3. If the VARTYPEs do not match, then the value of the VARTYPE is compared. |
| // 4. Comparing VT_BSTR values is a lexicographical comparison of the contents |
| // of the BSTR, taking into account |ignore_case|. |
| // 5. Otherwise returns the lexicographical comparison of the values held by |
| // the two VARIANTS that share the same VARTYPE. |
| int Compare(const VARIANT& other, bool ignore_case = false) const; |
| |
| // Retrieves the pointer address. |
| // Used to receive a VARIANT as an out argument (and take ownership). |
| // The function DCHECKs on the current value being empty/null. |
| // Usage: GetVariant(var.receive()); |
| VARIANT* Receive(); |
| |
| void Set(const wchar_t* str); |
| |
| // Setters for simple types. |
| void Set(int8_t i8); |
| void Set(uint8_t ui8); |
| void Set(int16_t i16); |
| void Set(uint16_t ui16); |
| void Set(int32_t i32); |
| void Set(uint32_t ui32); |
| void Set(int64_t i64); |
| void Set(uint64_t ui64); |
| void Set(float r32); |
| void Set(double r64); |
| void Set(bool b); |
| |
| // Creates a copy of |var| and assigns as this instance's value. |
| // Note that this is different from the Reset() method that's used to |
| // free the current value and assume ownership. |
| void Set(const VARIANT& var); |
| |
| // COM object setters |
| void Set(IDispatch* disp); |
| void Set(IUnknown* unk); |
| |
| // SAFEARRAY support |
| void Set(SAFEARRAY* array); |
| |
| // Special setter for DATE since DATE is a double and we already have |
| // a setter for double. |
| void SetDate(DATE date); |
| |
| // Allows const access to the contained variant without DCHECKs etc. |
| // This support is necessary for the V_XYZ (e.g. V_BSTR) set of macros to |
| // work properly but still doesn't allow modifications since we want control |
| // over that. |
| const VARIANT* ptr() const { return &var_; } |
| |
| // Moves the ScopedVariant to another instance. |
| ScopedVariant& operator=(ScopedVariant&& var); |
| |
| // Like other scoped classes (e.g. scoped_refptr, ScopedBstr, |
| // Microsoft::WRL::ComPtr) we support the assignment operator for the type we |
| // wrap. |
| ScopedVariant& operator=(const VARIANT& var); |
| |
| // A hack to pass a pointer to the variant where the accepting |
| // function treats the variant as an input-only, read-only value |
| // but the function prototype requires a non const variant pointer. |
| // There's no DCHECK or anything here. Callers must know what they're doing. |
| VARIANT* AsInput() const { |
| // The nature of this function is const, so we declare |
| // it as such and cast away the constness here. |
| return const_cast<VARIANT*>(&var_); |
| } |
| |
| // Allows the ScopedVariant instance to be passed to functions either by value |
| // or by const reference. |
| operator const VARIANT&() const { return var_; } |
| |
| // Used as a debug check to see if we're leaking anything. |
| static bool IsLeakableVarType(VARTYPE vt); |
| |
| protected: |
| VARIANT var_; |
| |
| private: |
| // Comparison operators for ScopedVariant are not supported at this point. |
| // Use the Compare method instead. |
| bool operator==(const ScopedVariant& var) const; |
| bool operator!=(const ScopedVariant& var) const; |
| }; |
| |
| } // namespace win |
| } // namespace base |
| |
| #endif // BASE_WIN_SCOPED_VARIANT_H_ |