| 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 |