$$ This is a pump file for generating file templates.  Pump is a python
$$ script that is part of the Google Test suite of utilities.  Description
$$ can be found here:
$$
$$ http://code.google.com/p/googletest/wiki/PumpManual

$$ MAX_ARITY controls the number of arguments that dispatch::Invoke() supports.
$$ It is choosen to match the number of arguments base::Bind() supports.
$var MAX_ARITY = 7
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
#define REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_

#include <oaidl.h>

#include "base/basictypes.h"
#include "base/template_util.h"
#include "base/win/scoped_variant.h"

namespace remoting {

namespace dispatch {

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 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).
//   - [in] [out] parameters are combination of both: the caller initializes
//         them before the call and the callee assigns new values correctly
//         freeing leakable variants.
//
// Using |ScopedVariantArg| instead of naked |VARIANTARG| ensures that
// the resources allocated during the call will be properly freed. It also
// 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.
class ScopedVariantArg : public VARIANTARG {
 public:
  ScopedVariantArg() {
    vt = VT_EMPTY;
  }

  ~ScopedVariantArg() {
    VariantClear(this);
  }

  // Wrap() routines pack the input parameters into VARIANTARG structures so
  // 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) {
    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;
  }

  // Unwrap() routines unpack the output parameters from VARIANTARG structures
  // to the locations specified by the caller.

  void Unwrap(const VARIANT& param_out) {
    // Do nothing for an [in] parameter.
  }

  void Unwrap(VARIANT* const & param_out) {
    // 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);
};

// Make sure the layouts of |VARIANTARG| and |ScopedVariantArg| are identical.
static_assert(sizeof(ScopedVariantArg) == sizeof(VARIANTARG),
              "scoped variant arg should not add data members");

}  // namespace internal

// Invoke() is a convenience wrapper for IDispatch::Invoke. It takes care of
// 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:
//   - more than $(MAX_ARITY) parameters are not supported.
//   - the method ID cannot be cached and reused.
//   - VARIANT is the only supported parameter type at the moment.
$range ARITY 0..MAX_ARITY
$for ARITY [[
$range ARG 1..ARITY


$if ARITY > 0 [[template <$for ARG , [[typename P$(ARG)]]>]]

HRESULT Invoke(IDispatch* object,
               LPCOLESTR const_name,
               WORD flags,
$for ARG [[

               const P$(ARG)& p$(ARG),
]]

               VARIANT* const & result_out) {
  // Retrieve the ID of the method to be called.
  DISPID disp_id;
  LPOLESTR name = const_cast<LPOLESTR>(const_name);
  HRESULT hr = object->GetIDsOfNames(
      IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &disp_id);
  if (FAILED(hr))
    return hr;

  // Request the return value if asked by the caller.
  internal::ScopedVariantArg result;
  VARIANT* disp_result = NULL;
  if (result_out != NULL)
    disp_result = &result;

$if ARITY > 0 [[

  // Wrap the parameters into an array of VARIANT structures.
  internal::ScopedVariantArg disp_args[$(ARITY)];
$for ARG [[

  hr = disp_args[$(ARITY) - $(ARG)].Wrap(p$(ARG));
  if (FAILED(hr))
    return hr;
]]
]]


  // Invoke the method passing the parameters via the DISPPARAMS structure.
  // DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF require the parameter of
  // the property setter to be named, so |cNamedArgs| and |rgdispidNamedArgs|
  // structure members should be initialized.

$if ARITY > 0 [[
  DISPPARAMS disp_params = { disp_args, NULL, $(ARITY), 0 };
]] $else [[
  DISPPARAMS disp_params = { NULL, NULL, 0, 0 };
]]

  DISPID dispid_named = DISPID_PROPERTYPUT;
  if (flags == DISPATCH_PROPERTYPUT || flags == DISPATCH_PROPERTYPUTREF) {
    disp_params.cNamedArgs = 1;
    disp_params.rgdispidNamedArgs = &dispid_named;
  }

  hr = object->Invoke(disp_id, IID_NULL, LOCALE_USER_DEFAULT, flags,
                      &disp_params, disp_result, NULL, NULL);
  if (FAILED(hr))
    return hr;

$if ARITY > 0 [[

  // Unwrap the parameters.
$for ARG [[

  disp_args[$(ARITY) - $(ARG)].Unwrap(p$(ARG));
]]
]]


  // Unwrap the return value.
  if (result_out != NULL) {
    result.Unwrap(result_out);
  }

  return S_OK;
}

]]

} // namespace dispatch

} // namespace remoting

#endif // REMOTING_BASE_IDISPATCH_DRIVER_WIN_H_
