Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/plugin/COM_Value.h

Issue 5070706781978624: Issue #276 - introduce class BSTR_Argument (Closed)
Patch Set: small correction over patch set 2 Created July 29, 2014, 7:22 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/plugin/AdblockPlusDomTraverser.cpp ('k') | src/plugin/COM_Value.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « src/plugin/AdblockPlusDomTraverser.cpp ('k') | src/plugin/COM_Value.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld