| Index: src/plugin/COM_Value.h | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/src/plugin/COM_Value.h | 
| @@ -0,0 +1,121 @@ | 
| +/** | 
| + * \file COM_Value.h Support for the values used in COM and Automation. | 
| + */ | 
| +#ifndef COM_VALUE_H | 
| +#define COM_VALUE_H | 
| + | 
| +#include <wtypes.h> | 
| +#include <string> | 
| + | 
| +namespace AdblockPlus | 
| +{ | 
| +  namespace COM | 
| +  { | 
| +    /** | 
| +     * BSTR life cycle manager. Used by a caller to pass BSTR as an argument to a COM call. | 
| +     * | 
| +     * This class manages the life cycle of a BSTR passed as an argument to a COM call. | 
| +     * There are two different life cycles 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]. | 
| +     * In both cases, we must release an allocated string, whether or not we allocated it. | 
| +     * Because of this commonality, it's possible to combine these two uses into a single class. | 
| +     * | 
| +     * The two life cycles differ in how the allocation is done. | 
| +     * When used as an argument, the caller must allocate. | 
| +     * In this case the caller uses the non-trivial constructor, which allocates a copy of its argument. | 
| +     * When used for a result, the called function allocates. | 
| +     * In this case the caller uses the default constructor and the address-of operator; | 
| +     *   the address-of operator does not allocate and its pointer must be assigned an allocated value. | 
| +     * | 
| +     * 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. | 
| +     * Thus their design use requires that they not leave this proximity. | 
| +     * | 
| +     * \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_Argument | 
| +    { | 
| +      /** | 
| +       * The underlying BSTR pointer. | 
| +       */ | 
| +      BSTR bstr; | 
| + | 
| +    public: | 
| +      /** | 
| +       * Default constructor has the value of the empty string. | 
| +       */ | 
| +      BSTR_Argument() | 
| +        : bstr(nullptr) | 
| +      { | 
| +      } | 
| + | 
| +      /** | 
| +       * Constructor from std::wstring. | 
| +       */ | 
| +      BSTR_Argument(const std::wstring& s); | 
| + | 
| +      /** | 
| +       * Destructor | 
| +       * | 
| +       * The destructor frees the BSTR. | 
| +       * Do not use this class when freeing the BSTR is not our responsibility. | 
| +       */ | 
| +      ~BSTR_Argument(); | 
| + | 
| +      /** | 
| +       * Conversion operator to BSTR. | 
| +       */ | 
| +      operator BSTR() const | 
| +      { | 
| +        return bstr; | 
| +      } | 
| + | 
| +      /** | 
| +       * 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 | 
| +       */ | 
| +      BSTR* operator&(); | 
| + | 
| +    private: | 
| +      /** | 
| +       * Copy constructor is deleted | 
| +       */ | 
| +      BSTR_Argument(const BSTR_Argument&);   // = delete | 
| + | 
| +      /** | 
| +       * Move constructor is deleted | 
| +       */ | 
| +      BSTR_Argument(BSTR_Argument&&);   // = delete | 
| + | 
| +      /** | 
| +       * Copy assignment is deleted | 
| +       */ | 
| +      BSTR_Argument& operator=(const BSTR_Argument&);   // = delete | 
| + | 
| +      /** | 
| +       * Move assignment is deleted | 
| +       */ | 
| +      BSTR_Argument& operator=(BSTR_Argument&&);   // = delete | 
| +    }; | 
| +  } | 
| +} | 
| + | 
| +#endif | 
|  |