Index: src/plugin/COM_Client.h |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/src/plugin/COM_Client.h |
@@ -0,0 +1,120 @@ |
+ |
Oleksandr
2014/06/26 00:48:43
I guess COM_Client.h is not needed?
Eric
2014/06/26 15:13:56
I take it you mean COM_Client.cpp.
Right now, all
|
+/** |
+ * Wrapper for BSTR values returned by COM components. |
+ * |
+ * The term "values returned" here means "out" parameters to COM interfaces. |
+ * A number of IBrowser functions return allocated BSTR values this way, |
+ * values that require the caller to free them. |
+ * ATL provides CComBSTR for these return values. |
+ * CComBSTR, however, implements a number of general purpose string functions, |
+ * but the present one does not. |
+ * |
+ * The sole responsibility of this class is to manage the allocated resource. |
+ * The supported pattern of use is exactly two steps: |
+ * -# Construct an instance with the BSTR value returned from the COM call |
+ * -# Copy the contents to a std::wstring. |
+ * There generally no reason even to declare a separate variable of this type, |
+ * since the value of the conversion operator can be assigned directly. |
+ * |
+ * This class does no error checking for null pointer values. |
+ * There is, however, no default constructor to initialize one easily. |
+ * The only constructor takes a BSTR argument, |
+ * so the caller has the opportunity to test the value of the "out" argument. |
+ */ |
+class Returned_BSTR |
Oleksandr
2014/06/26 00:48:43
This multiple classes approach is a bit confusing,
Eric
2014/06/26 15:13:56
The biggest confusion to my eye is the naming. I d
sergei
2014/07/08 11:58:34
I also would like to have only one class.
As well
Eric
2014/07/08 17:46:37
Here's the place for the longer rant about address
|
+{ |
+ /** |
+ * The underlying BSTR variable. |
+ */ |
+ wchar_t * _bstr ; |
+ |
+public: |
+ /** |
+ * Ordinary constructor. |
+ */ |
+ Returned_BSTR( wchar_t * b ) |
+ : _bstr( b ) |
+ {} |
+ |
+ ~Returned_BSTR() |
+ { |
+ ::SysFreeString( _bstr ); |
+ } |
+ |
+ operator std::wstring() |
+ { |
+ return std::wstring( _bstr, ::SysStringLen( _bstr ) ); |
+ } |
+}; |
+ |
+class Invoke_Result |
+{ |
+ VARIANT & _result; |
+ |
+public: |
+ /** |
+ * Ordinary constructor. |
+ * |
+ * The caller has responsibility for checking that the result pointer argument in Invoke() is not null. |
+ * Thus the argument is a reference, not a pointer, to ensure that the caller fulfills its responsibility. |
+ */ |
+ Invoke_Result( VARIANT & result ) |
+ : _result( result ) |
+ {} |
+ |
+ void assign_wstring( std::wstring x ) |
+ { |
+ _result.vt = VT_BSTR; |
+ _result.bstrVal = SysAllocString( x.c_str() ); |
+ } |
+}; |
+ |
+inline void invoke_result_wstring( VARIANT & result, std::wstring s ) |
+{ |
+ Invoke_Result ir( result ); |
+ ir.assign_wstring( s ); |
+} |
+ |
+class BSTR_Argument |
+{ |
+ BSTR _bstr; |
+public: |
+ BSTR_Argument( std::wstring s ) |
+ : _bstr( SysAllocStringLen( s.c_str(), s.length() ) ) |
+ { |
+ // Preserve invariant that _bstr is not null |
+ if ( !_bstr ) |
+ { |
+ // Assert SysAllocStringLen return null, meaning out of memory |
+ throw std::bad_alloc(); |
+ } |
+ } |
+ |
+ ~BSTR_Argument() |
+ { |
+ SysFreeString( _bstr ); |
+ } |
+ |
+ inline operator BSTR() |
+ { |
+ return _bstr; |
+ } |
+}; |
+ |
+/** |
+ * Constructor class for incoming BSTR argument for dispatch entry points. |
+ * |
+ * The BSTR coming in as arguments from dispatch calls are allocated by the caller. |
+ * We don't need to manage the lifetime of these arguments. |
+ * Since we are immediately converting to wstring, we don't need to allocate our own BSTR. |
+ * Thus, even though the constructor pattern looks like BSTR_Argument, |
+ * we don't want the allocate/free behavior of its implementation. |
+ */ |
+class Incoming_BSTR |
+ : public std::wstring |
+{ |
+public: |
+ Incoming_BSTR( BSTR bstr ) |
+ : std::wstring( bstr, SysStringLen( bstr ) ) |
+ {} |
+}; |