| Index: src/plugin/COM_Value.h | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/src/plugin/COM_Value.h | 
| @@ -0,0 +1,174 @@ | 
| +/** | 
| + * \file COM_Value.h Support for the values used in COM and Automation. | 
| + * | 
| + * \par BSTR | 
| + *   MSDN BSTR http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069%28v=vs.85%29.aspx | 
| + * | 
| + * \par VARIANT | 
| + *   MSDN VARIANT structure http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627%28v=vs.85%29.aspx | 
| + *   MSDN VARENUM enumeration http://msdn.microsoft.com/en-us/library/windows/desktop/ms221170%28v=vs.85%29.aspx | 
| + */ | 
| +#ifndef COM_VALUE_H | 
| +#define COM_VALUE_H | 
| + | 
| +#include <wtypes.h> | 
| +#include <string> | 
| + | 
| +namespace AdblockPlus | 
| +{ | 
| +  namespace COM | 
| +  { | 
| +    /** | 
| +     * Base class for BSTR life cycle manager classes, used to pass BSTR to a COM call. | 
| +     * | 
| +     * There are two different life cycles for BSTR relevant here. | 
| +     * In the first, the BSTR acts as an ordinary argument; in the second, the BSTR is a return value. | 
| +     * Both these are implemented as arguments to a COM function; | 
| +     *   the difference is that one is an [in] param and the other is an [out] param. | 
| +     * The subclass for [in] params is BSTR_ParamArgument. | 
| +     * The subclass for [out] params is BSTR_ParamResult. | 
| +     * | 
| +     * These two life cycles differ in allocation, but not in deallocation. | 
| +     * When used as an argument, the caller must allocate. | 
| +     * BSTR_ParamArgument uses the non-trivial constructor, which allocates a copy of its argument. | 
| +     * When used for a result, the called function allocates. | 
| +     * BSTR_ParamResult uses the default constructor and implements an address-of operator; | 
| +     *   the address-of operator does not allocate and its pointer must be assigned an allocated value. | 
| +     * In both cases the caller deallocates the BSTR. | 
| +     * Because of this commonality, the present base class implements a destructor common to its subclasses. | 
| +     * | 
| +     * Copy/move constructor/assignment are all deleted, not because they couldn't be implemented, | 
| +     *   but because these class are meant to be used in tight conjunction with API calls. | 
| +     * Their design use requires that they not leave this proximity. | 
| +     * Deleting copy and move helps to ensure this. | 
| +     * | 
| +     * \par Design Notes | 
| +     *   This class is a base class only. | 
| +     *   It turns out that it's not felicitous to combine the subclasses with the base. | 
| +     *   The trouble is that having conversions both to BSTR and std::wstring causes problems in practice. | 
| +     *   Both of these string types define implicit conversions to wchar_t *. | 
| +     *   Having both conversions defined on a single class leads to lots of unnecessary explicit conversions. | 
| +     * | 
| +     * \par Reference | 
| +     *   MSDN "Allocating and Releasing Memory for a BSTR" http://msdn.microsoft.com/en-us/library/vstudio/xda6xzx7%28v=vs.120%29.aspx | 
| +     *   "When you call into a function that expects a BSTR argument, you must allocate the memory for the BSTR before the call and release it afterwards." | 
| +     *   "When you call into a function that returns a BSTR, you must free the string yourself." | 
| +     * | 
| +     * \invariant Either bstr == nullptr or bstr is a non-null system-allocated BSTR. | 
| +     */ | 
| +    class BSTR_Param | 
| +    { | 
| +    protected: | 
| +      /** | 
| +       * The underlying BSTR pointer. | 
| +       */ | 
| +      BSTR bstr; | 
| + | 
| +      /** | 
| +       * Regular constructor has the value of the empty string. | 
| +       * | 
| +       * Subclasses have the responsibility to maintain out class invariant regarding member `bstr`. | 
| +       */ | 
| +      BSTR_Param(BSTR b) | 
| +        : bstr(b) | 
| +      { | 
| +      } | 
| + | 
| +      /** | 
| +       * Destructor | 
| +       * | 
| +       * The destructor frees the BSTR. | 
| +       * Do not use this class when freeing the BSTR is not our responsibility. | 
| +       */ | 
| +      ~BSTR_Param(); | 
| + | 
| +    private: | 
| +      /** | 
| +       * Copy constructor is deleted | 
| +       */ | 
| +      BSTR_Param(const BSTR_Param&);   // = delete | 
| + | 
| +      /** | 
| +       * Move constructor is deleted | 
| +       */ | 
| +      BSTR_Param(BSTR_Param&&);   // = delete | 
| + | 
| +      /** | 
| +       * Copy assignment is deleted | 
| +       */ | 
| +      BSTR_Param& operator=(const BSTR_Param&);   // = delete | 
| + | 
| +      /** | 
| +       * Move assignment is deleted | 
| +       */ | 
| +      BSTR_Param& operator=(BSTR_Param&&);   // = delete | 
| +    }; | 
| + | 
| +    /** | 
| +     * BSTR life cycle manager. | 
| +     * Used by a caller to pass a BSTR parameter as an argument to a COM function. | 
| +     * | 
| +     * This class passes a BSTR value to an [in] parameter of a COM call. | 
| +     * As a conversion class std::wstring --> BSTR. | 
| +     */ | 
| +    class BSTR_ParamArgument | 
| +      : protected BSTR_Param | 
| +    { | 
| +    public: | 
| +      /** | 
| +       * Constructor from std::wstring. | 
| +       */ | 
| +      BSTR_ParamArgument(const std::wstring& s); | 
| + | 
| +      /** | 
| +       * Conversion operator to BSTR. | 
| +       */ | 
| +      operator BSTR() const | 
| +      { | 
| +        return bstr; | 
| +      } | 
| +    }; | 
| + | 
| +    /** | 
| +     * BSTR life cycle manager. | 
| +     * Used by a caller to pass a BSTR parameter to receive a result from a COM function. | 
| +     * | 
| +     * This class receives a BSTR value from an [out] parameter of a COM call. | 
| +     * As a conversion class, it converts only in the direction BSTR --> std::wstring. | 
| +     */ | 
| +    class BSTR_ParamResult | 
| +      : protected BSTR_Param | 
| +    { | 
| +    public: | 
| +      /** | 
| +       * As the receiver of an external value, BSTR_ParamResult always has an empty initial value. | 
| +       */ | 
| +      BSTR_ParamResult() | 
| +        : BSTR_Param(nullptr) | 
| +      { | 
| +      } | 
| + | 
| +      /** | 
| +       * Conversion operator to std::wstring | 
| +       */ | 
| +      operator std::wstring() const; | 
| + | 
| +      /** | 
| +       * Address-of operator. | 
| +       * | 
| +       * This operator is used for assignment directly into our underlying pointer. | 
| +       * In order to avoid leaking memory, this operator also implicitly assigns the null string. | 
| +       * Specifically, this operator is not 'const'. | 
| +       * | 
| +       * \par postcondition | 
| +       *   - bstr == nullptr | 
| +       *   - return value is not null | 
| +       *   - does not throw | 
| +       */ | 
| +      BSTR* operator&(); // noexcept | 
| +    }; | 
| + | 
| +  } | 
| +} | 
| + | 
| +#endif | 
|  |