297 lines
11 KiB
C++
297 lines
11 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef _UNOOBJW_HXX
|
|
#define _UNOOBJW_HXX
|
|
|
|
#include <com/sun/star/bridge/XBridgeSupplier2.hpp>
|
|
#include <com/sun/star/beans/XExactName.hpp>
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
|
#include <com/sun/star/script/InvocationInfo.hpp>
|
|
#include <salhelper/simplereferenceobject.hxx>
|
|
|
|
#include "comifaces.hxx"
|
|
#include "ole2uno.hxx"
|
|
#include "unoconversionutilities.hxx"
|
|
|
|
//#define INVOCATION_SERVICE L"com.sun.star.script.Invocation"
|
|
#define JSCRIPT_VALUE_FUNC L"_GetValueObject"
|
|
#define GET_STRUCT_FUNC L"_GetStruct"
|
|
#define BRIDGE_VALUE_FUNC L"Bridge_GetValueObject"
|
|
#define BRIDGE_GET_STRUCT_FUNC L"Bridge_GetStruct"
|
|
#define BRIDGE_CREATE_TYPE_FUNC L"Bridge_CreateType"
|
|
|
|
#define DISPID_JSCRIPT_VALUE_FUNC -10l
|
|
#define DISPID_GET_STRUCT_FUNC -102
|
|
#define DISPID_CREATE_TYPE_FUNC -103
|
|
|
|
using namespace std;
|
|
using namespace cppu;
|
|
using namespace com::sun::star::bridge;
|
|
using namespace com::sun::star::script;
|
|
namespace ole_adapter
|
|
{
|
|
|
|
|
|
|
|
struct hash_IUnknown_Impl
|
|
{
|
|
size_t operator()(const IUnknown* p) const
|
|
{
|
|
return (size_t)p;
|
|
}
|
|
};
|
|
|
|
struct equal_to_IUnknown_Impl
|
|
{
|
|
bool operator()(const IUnknown* s1, const IUnknown* s2) const
|
|
{
|
|
return s1 == s2;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
struct MemberInfo
|
|
{
|
|
MemberInfo() : flags(0), name() {}
|
|
MemberInfo(WORD f, const OUString& n) : flags(f), name(n) {}
|
|
|
|
WORD flags;
|
|
OUString name;
|
|
};
|
|
|
|
typedef boost::unordered_map
|
|
<
|
|
OUString,
|
|
DISPID,
|
|
hashOUString_Impl,
|
|
equalOUString_Impl
|
|
> NameToIdMap;
|
|
|
|
typedef boost::unordered_map
|
|
<
|
|
OUString,
|
|
sal_Bool,
|
|
hashOUString_Impl,
|
|
equalOUString_Impl
|
|
> BadNameMap;
|
|
|
|
typedef boost::unordered_map
|
|
<
|
|
DISPID,
|
|
MemberInfo
|
|
> IdToMemberInfoMap;
|
|
|
|
/*****************************************************************************
|
|
|
|
class declaration: InterfaceOleWrapper_Impl
|
|
|
|
*****************************************************************************/
|
|
|
|
class InterfaceOleWrapper_Impl : public WeakImplHelper2<XBridgeSupplier2, XInitialization>,
|
|
public IDispatchEx,
|
|
public UnoConversionUtilities<InterfaceOleWrapper_Impl>,
|
|
public IUnoObjectWrapper
|
|
{
|
|
public:
|
|
|
|
|
|
InterfaceOleWrapper_Impl(Reference<XMultiServiceFactory>& xFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass);
|
|
~InterfaceOleWrapper_Impl();
|
|
|
|
/* IUnknown methods */
|
|
STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
/* IDispatch methods */
|
|
STDMETHOD( GetTypeInfoCount )( unsigned int * pctinfo );
|
|
STDMETHOD( GetTypeInfo )( unsigned int itinfo, LCID lcid, ITypeInfo ** pptinfo );
|
|
STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
|
|
LCID lcid, DISPID * rgdispid );
|
|
STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags,
|
|
DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
|
|
unsigned int * puArgErr );
|
|
|
|
/* IDispatchEx methods */
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDispID(
|
|
/* [in] */ BSTR bstrName,
|
|
/* [in] */ DWORD grfdex,
|
|
/* [out] */ DISPID __RPC_FAR *pid);
|
|
|
|
virtual /* [local] */ HRESULT STDMETHODCALLTYPE InvokeEx(
|
|
/* [in] */ DISPID id,
|
|
/* [in] */ LCID lcid,
|
|
/* [in] */ WORD wFlags,
|
|
/* [in] */ DISPPARAMS __RPC_FAR *pdp,
|
|
/* [out] */ VARIANT __RPC_FAR *pvarRes,
|
|
/* [out] */ EXCEPINFO __RPC_FAR *pei,
|
|
/* [unique][in] */ IServiceProvider __RPC_FAR *pspCaller);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE DeleteMemberByName(
|
|
/* [in] */ BSTR bstr,
|
|
/* [in] */ DWORD grfdex);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE DeleteMemberByDispID(
|
|
/* [in] */ DISPID id);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetMemberProperties(
|
|
/* [in] */ DISPID id,
|
|
/* [in] */ DWORD grfdexFetch,
|
|
/* [out] */ DWORD __RPC_FAR *pgrfdex);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetMemberName(
|
|
/* [in] */ DISPID id,
|
|
/* [out] */ BSTR __RPC_FAR *pbstrName);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetNextDispID(
|
|
/* [in] */ DWORD grfdex,
|
|
/* [in] */ DISPID id,
|
|
/* [out] */ DISPID __RPC_FAR *pid);
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetNameSpaceParent(
|
|
/* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunk);
|
|
|
|
// XBridgeSupplier2 ---------------------------------------------------
|
|
virtual Any SAL_CALL createBridge(const Any& modelDepObject,
|
|
const Sequence<sal_Int8>& ProcessId,
|
|
sal_Int16 sourceModelType,
|
|
sal_Int16 destModelType)
|
|
throw (IllegalArgumentException, RuntimeException);
|
|
|
|
//XInitialization -----------------------------------------------------
|
|
virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException);
|
|
|
|
// IUnoObjectWrapper
|
|
STDMETHOD( getWrapperXInterface)( Reference<XInterface>* pXInt);
|
|
STDMETHOD( getOriginalUnoObject)( Reference<XInterface>* pXInt);
|
|
STDMETHOD( getOriginalUnoStruct)( Any * pStruct);
|
|
|
|
// UnoConversionUtility
|
|
virtual Reference< XInterface > createUnoWrapperInstance();
|
|
virtual Reference< XInterface > createComWrapperInstance();
|
|
|
|
|
|
protected:
|
|
virtual HRESULT doInvoke( DISPPARAMS * pdispparams, VARIANT * pvarResult,
|
|
EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any>& params);
|
|
|
|
virtual HRESULT doGetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult,
|
|
EXCEPINFO * pexcepinfo, OUString & name );
|
|
|
|
virtual HRESULT doSetProperty( DISPPARAMS * pdispparams, VARIANT * pvarResult,
|
|
EXCEPINFO * pexcepinfo, unsigned int * puArgErr, OUString & name, Sequence<Any> params);
|
|
|
|
virtual HRESULT InvokeGeneral( DISPID dispidMember, unsigned short wFlags,
|
|
DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
|
|
unsigned int * puArgErr, sal_Bool& bHandled);
|
|
|
|
void convertDispparamsArgs( DISPID id, unsigned short wFlags, DISPPARAMS* pdispparams,
|
|
Sequence<Any>& rSeq);
|
|
|
|
sal_Bool getInvocationInfoForCall(DISPID id, InvocationInfo& info);
|
|
|
|
Reference<XInvocation> m_xInvocation;
|
|
Reference<XExactName> m_xExactName;
|
|
Reference<XInterface> m_xOrigin;
|
|
NameToIdMap m_nameToDispIdMap;
|
|
vector<MemberInfo> m_MemberInfos;
|
|
// This member is used to determine the default value
|
|
// denoted by DISPID_VALUE (0). For proper results in JavaScript
|
|
// we have to return the default value when we write an object
|
|
// as out parameter. That is, we get an JScript Array as parameter
|
|
// and put a wrapped object on index null. The array object tries
|
|
// to detect the default value. The wrapped object must then return
|
|
// its own IDispatch* otherwise we cannot access it within the script.
|
|
// see InterfaceOleWrapper_Impl::Invoke
|
|
VARTYPE m_defaultValueType;
|
|
|
|
};
|
|
|
|
/*****************************************************************************
|
|
|
|
class declaration: UnoObjectWrapperRemoteOpt
|
|
( Uno Object Wrapper Remote Optimized)
|
|
This is the UNO wrapper used in the service com.sun.star.bridge.OleBridgeSupplierVar1.
|
|
Key features:
|
|
DISPIDs are passed out blindly. That is in GetIDsOfNames is no name checking carried out.
|
|
Only if Invoke fails the name is being checked. Moreover Invoke tries to figure out
|
|
if a call is made to a property or method if the flags are DISPATCH_METHOD | DISPATCH_PROPERTYPUT.
|
|
If something has been found out about a property or member than it is saved
|
|
in a MemberInfo structure hold by a IdToMemberInfoMap stl map.
|
|
|
|
*****************************************************************************/
|
|
class UnoObjectWrapperRemoteOpt: public InterfaceOleWrapper_Impl
|
|
{
|
|
public:
|
|
UnoObjectWrapperRemoteOpt( Reference<XMultiServiceFactory>& aFactory, sal_uInt8 unoWrapperClass, sal_uInt8 comWrapperClass);
|
|
~UnoObjectWrapperRemoteOpt();
|
|
|
|
STDMETHOD( GetIDsOfNames )( REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
|
|
LCID lcid, DISPID * rgdispid );
|
|
STDMETHOD( Invoke )( DISPID dispidMember, REFIID riid, LCID lcid, unsigned short wFlags,
|
|
DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo,
|
|
unsigned int * puArgErr );
|
|
|
|
// UnoConversionUtility
|
|
// If UNO interfaces are converted in methods of this class then
|
|
// they are always wrapped with instances of this class
|
|
virtual Reference< XInterface > createUnoWrapperInstance();
|
|
|
|
protected:
|
|
|
|
HRESULT methodInvoke( DISPID dispidMember, DISPPARAMS * pdispparams, VARIANT * pvarResult,
|
|
EXCEPINFO * pexcepinfo, unsigned int * puArgErr, Sequence<Any> params);
|
|
// In GetIDsOfNames are blindly passed out, that is without verifying
|
|
// the name. If two names are passed in during different calls to
|
|
// GetIDsOfNames and the names differ only in their cases then different
|
|
// id's are passed out ( e.g. "doSomethingMethod" or "dosomethingmethod").
|
|
// In Invoke the DISPID is remapped to the name passed to GetIDsOfNames
|
|
// and the name is used as parameter for XInvocation::invoke. If invoke
|
|
// fails because of a wrong name, then m_xExactName ( XExactName) is used
|
|
// to verify the name. The correct name is then inserted to m_MemberInfos
|
|
// ( vector<MemberInfo> ). During the next call to Invoke the right name
|
|
// is used. .
|
|
|
|
|
|
BadNameMap m_badNameMap;
|
|
|
|
IdToMemberInfoMap m_idToMemberInfoMap;
|
|
|
|
DISPID m_currentId;
|
|
|
|
|
|
};
|
|
|
|
} // end namespace
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|