summaryrefslogtreecommitdiffstats
path: root/remoting/base/dispatch_win.h
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-21 20:42:25 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-21 20:42:25 +0000
commit56a5107804d263d258858af7c3905d3cd5c5957e (patch)
tree42030f41b1b7ce87a16a0c346e928bbc0042d101 /remoting/base/dispatch_win.h
parent6264f9d8a57df8a3cefae27a00b070113f0de67d (diff)
downloadchromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.zip
chromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.tar.gz
chromium_src-56a5107804d263d258858af7c3905d3cd5c5957e.tar.bz2
Adding support of [in] [out] parameters to remoting::dispatch::Invoke().
BUG=131498 Review URL: https://chromiumcodereview.appspot.com/10532143 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143443 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/dispatch_win.h')
-rw-r--r--remoting/base/dispatch_win.h65
1 files changed, 47 insertions, 18 deletions
diff --git a/remoting/base/dispatch_win.h b/remoting/base/dispatch_win.h
index 1d12a70..aa20710 100644
--- a/remoting/base/dispatch_win.h
+++ b/remoting/base/dispatch_win.h
@@ -23,7 +23,7 @@ namespace internal {
// A helper wrapper for |VARIANTARG| that is used to pass parameters to and from
// IDispatch::Invoke(). The latter accepts parameters as an array of
-// |VARIANTARG| structures. The calling convention is:
+// |VARIANTARG| structures. The calling convention of IDispatch::Invoke() is:
// - [in] parameters are initialized and freed if needed by the caller.
// - [out] parameters are initialized by IDispatch::Invoke(). It is up to
// the caller to free leakable variants (such as VT_DISPATCH).
@@ -33,11 +33,9 @@ namespace internal {
//
// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
// the resources allocated during the call will be properly freed. It also
-// provides wraping methods that convert between C++ types and VARIANTs.
-// The current convention is:
-// - constant references are considered input parameters.
-// - pointers to non-constant objects are considered output parameters.
-// - [in] [out] parameters are not supported.
+// provides wrapping methods that convert between C++ types and VARIANTs.
+// At the moment the only supported parameter type is |VARIANT| (or
+// |VARIANTARG|).
//
// It must be possible to cast a pointer to an array of |ScopedVariantArg| to
// a pointer to an array of |VARIANTARG| structures.
@@ -55,11 +53,20 @@ class ScopedVariantArg : public VARIANTARG {
// that they can be passed to IDispatch::Invoke.
HRESULT Wrap(const VARIANT& param) {
+ DCHECK(vt == VT_EMPTY);
return VariantCopy(this, &param);
}
HRESULT Wrap(VARIANT* const & param) {
- // Do nothing for an [out] parameter.
+ DCHECK(vt == VT_EMPTY);
+
+ // Make the input value of an [in] [out] parameter visible to
+ // IDispatch::Invoke().
+ //
+ // N.B. We treat both [out] and [in] [out] parameters as [in] [out]. In
+ // other words the caller is always responsible for initializing and freeing
+ // [out] and [in] [out] parameters.
+ Swap(param);
return S_OK;
}
@@ -71,11 +78,19 @@ class ScopedVariantArg : public VARIANTARG {
}
void Unwrap(VARIANT* const & param_out) {
- *param_out = *this;
- vt = VT_EMPTY;
+ // Return the output value of an [in] [out] parameter to the caller.
+ Swap(param_out);
}
private:
+ // Exchanges the value (and ownership) of the passed VARIANT with the one
+ // wrapped by |ScopedVariantArg|.
+ void Swap(VARIANT* other) {
+ VARIANT temp = *other;
+ *other = *this;
+ *static_cast<VARIANTARG*>(this) = temp;
+ }
+
DISALLOW_COPY_AND_ASSIGN(ScopedVariantArg);
};
@@ -89,8 +104,14 @@ COMPILE_ASSERT(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
// calling the desired method by its ID and implements logic for passing
// a variable number of in/out parameters to the called method.
//
+// The calling convention is:
+// - [in] parameters are passsed as a constant reference or by value.
+// - [out] and [in] [out] parameters are passed by pointer. The pointed value
+// is overwritten when the function returns. The pointed-to value must
+// be initialized before the call, and will be replaced when it returns.
+// [out] parameters may be initialized to VT_EMPTY.
+//
// Current limitations:
-// - in_out parameters are not supported.
// - more than 7 parameters are not supported.
// - the method ID cannot be cached and reused.
// - VARIANT is the only supported parameter type at the moment.
@@ -122,8 +143,9 @@ HRESULT Invoke(IDispatch* object,
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -164,8 +186,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[1 - 1].Unwrap(p1);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -211,8 +234,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[2 - 2].Unwrap(p2);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -263,8 +287,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[3 - 3].Unwrap(p3);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -320,8 +345,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[4 - 4].Unwrap(p4);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -382,8 +408,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[5 - 5].Unwrap(p5);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -450,8 +477,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[6 - 6].Unwrap(p6);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}
@@ -523,8 +551,9 @@ HRESULT Invoke(IDispatch* object,
disp_args[7 - 7].Unwrap(p7);
// Unwrap the return value.
- if (result_out != NULL)
+ if (result_out != NULL) {
result.Unwrap(result_out);
+ }
return S_OK;
}