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 |