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 |