1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef INCLUDED_CLI_PROXY_H 29*cdf0e10cSrcweir #define INCLUDED_CLI_PROXY_H 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #pragma warning(push, 1) 32*cdf0e10cSrcweir #include "uno/environment.hxx" 33*cdf0e10cSrcweir #pragma warning(pop) 34*cdf0e10cSrcweir #include "uno/mapping.hxx" 35*cdf0e10cSrcweir #include "uno/dispatcher.h" 36*cdf0e10cSrcweir #include "cli_bridge.h" 37*cdf0e10cSrcweir #include "cli_environment.h" 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir #using <mscorlib.dll> 40*cdf0e10cSrcweir #using <cli_ure.dll> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir namespace srrp = System::Runtime::Remoting::Proxies; 43*cdf0e10cSrcweir namespace srrm = System::Runtime::Remoting::Messaging; 44*cdf0e10cSrcweir namespace srr = System::Runtime::Remoting; 45*cdf0e10cSrcweir namespace sr = System::Reflection; 46*cdf0e10cSrcweir namespace sc = System::Collections; 47*cdf0e10cSrcweir using namespace uno; 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir namespace cli_uno 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir public __gc class UnoInterfaceInfo 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir public: 55*cdf0e10cSrcweir UnoInterfaceInfo(Bridge const * bridge, uno_Interface* unoI, 56*cdf0e10cSrcweir typelib_InterfaceTypeDescription* td); 57*cdf0e10cSrcweir ~UnoInterfaceInfo(); 58*cdf0e10cSrcweir uno_Interface * m_unoI; // wrapped interface 59*cdf0e10cSrcweir System::Type * m_type; 60*cdf0e10cSrcweir typelib_InterfaceTypeDescription* m_typeDesc; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir Bridge const* m_bridge; 63*cdf0e10cSrcweir }; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir public __gc class UnoInterfaceProxy: public srrp::RealProxy, 66*cdf0e10cSrcweir public srr::IRemotingTypeInfo 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir /** used for IRemotingTypeInfo.TypeName 69*cdf0e10cSrcweir */ 70*cdf0e10cSrcweir System::String* m_sTypeName; 71*cdf0e10cSrcweir /** The list is filled with UnoInterfaceInfo objects. The list can only 72*cdf0e10cSrcweir grow and elements are never changed. If an element was added it 73*cdf0e10cSrcweir must not be changed! 74*cdf0e10cSrcweir */ 75*cdf0e10cSrcweir sc::ArrayList* m_listIfaces; 76*cdf0e10cSrcweir /** The number of UNO interfaces this proxy represents. It corresponds 77*cdf0e10cSrcweir to the the number of elements in m_listIfaces. 78*cdf0e10cSrcweir */ 79*cdf0e10cSrcweir int m_numUnoIfaces; 80*cdf0e10cSrcweir /** The list is filled with additional UnoInterfaceProxy object due 81*cdf0e10cSrcweir to aggregation via bridges. Though the latter is strongly 82*cdf0e10cSrcweir discouraged, this has to be supported. 83*cdf0e10cSrcweir */ 84*cdf0e10cSrcweir sc::ArrayList* m_listAdditionalProxies; 85*cdf0e10cSrcweir int m_nlistAdditionalProxies; 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir UnoInterfaceInfo * findInfo( ::System::Type * type ); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir Bridge const* m_bridge; 90*cdf0e10cSrcweir System::String* m_oid; 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2 93*cdf0e10cSrcweir /** The string contains all names of UNO interfaces which are 94*cdf0e10cSrcweir represented by this proxy. It is used to print out the interfaces 95*cdf0e10cSrcweir when this proxy dies. In the destructor it is not allowed to 96*cdf0e10cSrcweir access m_listIfaces or any other managed object. 97*cdf0e10cSrcweir */ 98*cdf0e10cSrcweir rtl_uString * _sInterfaces; 99*cdf0e10cSrcweir // /** Count of interfaces. Used in conjunction with _sInterfaces. 100*cdf0e10cSrcweir // */ 101*cdf0e10cSrcweir int _numInterfaces; 102*cdf0e10cSrcweir #endif 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir public: 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir /** Creates a proxy and registers it on the dot NET side. 107*cdf0e10cSrcweir */ 108*cdf0e10cSrcweir static System::Object* create(Bridge * bridge, 109*cdf0e10cSrcweir uno_Interface * pUnoI, 110*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTd, 111*cdf0e10cSrcweir const rtl::OUString& oid); 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir /** RealProxy::Invoke */ 114*cdf0e10cSrcweir srrm::IMessage* Invoke(srrm::IMessage* msg); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir /** Must be called from within a synchronized section. 117*cdf0e10cSrcweir Add only the interface if it is not already contained. 118*cdf0e10cSrcweir This method is called from the constructor and as a result 119*cdf0e10cSrcweir of IRemotingTypeInfo::CanCastTo 120*cdf0e10cSrcweir */ 121*cdf0e10cSrcweir void addUnoInterface(uno_Interface* pUnoI, 122*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTd); 123*cdf0e10cSrcweir ~UnoInterfaceProxy(); 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir /** 126*cdf0e10cSrcweir */ 127*cdf0e10cSrcweir inline System::String * getOid() 128*cdf0e10cSrcweir { return m_oid; } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir //IRemotingTypeInfo ---------------------------------------------- 131*cdf0e10cSrcweir bool CanCastTo(System::Type* fromType, System::Object* o); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir __property System::String* get_TypeName() 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir return m_sTypeName; 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir __property void set_TypeName(System::String* name) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir m_sTypeName = name; 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir private: 144*cdf0e10cSrcweir UnoInterfaceProxy( 145*cdf0e10cSrcweir Bridge * bridge, 146*cdf0e10cSrcweir uno_Interface * pUnoI, 147*cdf0e10cSrcweir typelib_InterfaceTypeDescription* pTD, 148*cdf0e10cSrcweir const rtl::OUString& oid ); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir static srrm::IMessage* constructReturnMessage(System::Object* retVal, 151*cdf0e10cSrcweir System::Object* outArgs[], 152*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription* mtd, 153*cdf0e10cSrcweir srrm::IMessage* msg, System::Object* exc); 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir static System::String* m_methodNameString = 156*cdf0e10cSrcweir new System::String("__MethodName"); 157*cdf0e10cSrcweir static System::String* m_typeNameString = new System::String("__TypeName"); 158*cdf0e10cSrcweir static System::String* m_ArgsString = new System::String("__Args"); 159*cdf0e10cSrcweir static System::String* m_CallContextString = 160*cdf0e10cSrcweir new System::String("__CallContext"); 161*cdf0e10cSrcweir static System::String* m_system_Object_String = 162*cdf0e10cSrcweir new System::String("System.Object"); 163*cdf0e10cSrcweir static System::String* m_methodSignatureString = 164*cdf0e10cSrcweir new System::String("__MethodSignature"); 165*cdf0e10cSrcweir static System::String* m_Equals_String = new System::String("Equals"); 166*cdf0e10cSrcweir static System::String* m_GetHashCode_String = 167*cdf0e10cSrcweir new System::String("GetHashCode"); 168*cdf0e10cSrcweir static System::String* m_GetType_String = new System::String("GetType"); 169*cdf0e10cSrcweir static System::String* m_ToString_String = new System::String("ToString"); 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir protected: 172*cdf0e10cSrcweir srrm::IMessage* invokeObject(sc::IDictionary* properties, 173*cdf0e10cSrcweir srrm::LogicalCallContext* context, 174*cdf0e10cSrcweir srrm::IMethodCallMessage* mcm); 175*cdf0e10cSrcweir }; 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir //Cannot make this __gc because a managed type cannot derive from unmanaged type 179*cdf0e10cSrcweir struct CliProxy: public uno_Interface 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir mutable oslInterlockedCount m_ref; 182*cdf0e10cSrcweir const Bridge* m_bridge; 183*cdf0e10cSrcweir const gcroot<System::Object*> m_cliI; 184*cdf0e10cSrcweir gcroot<System::Type*> m_type; 185*cdf0e10cSrcweir const com::sun::star::uno::TypeDescription m_unoType; 186*cdf0e10cSrcweir const gcroot<System::String*> m_oid; 187*cdf0e10cSrcweir const rtl::OUString m_usOid; 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir enum MethodKind {MK_METHOD = 0, MK_SET, MK_GET}; 190*cdf0e10cSrcweir /** The array contains MethodInfos of the cli object. Each one reflects an 191*cdf0e10cSrcweir implemented interface method of the interface for which this proxy was 192*cdf0e10cSrcweir created. The MethodInfos are from the object's method and not from the 193*cdf0e10cSrcweir interface type. That is, they can be used to invoke the methods. The 194*cdf0e10cSrcweir order of the MethodInfo objects corresponds to the order of the 195*cdf0e10cSrcweir interface methods (see member m_type). Position 0 contains the 196*cdf0e10cSrcweir MethodInfo of the first method of the interface which represents the 197*cdf0e10cSrcweir root of the inheritance chain. The last MethodInfo represents the last 198*cdf0e10cSrcweir method of the furthest derived interface. 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir The array is completely initialized in the constructor of this object. 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir When the uno_DispatchMethod is called for this proxy then it receives 203*cdf0e10cSrcweir a typelib_TypeDescription of the member which is either an attribute 204*cdf0e10cSrcweir (setter or getter) or method. After determining the position of the 205*cdf0e10cSrcweir method within the UNO interface one can use the position to obtain the 206*cdf0e10cSrcweir MethodInfo of the corresponding cli method. To obtain the index for the 207*cdf0e10cSrcweir m_arMethodInfos array the function position has to be decreased by 3. 208*cdf0e10cSrcweir This is becaus, the cli interface does not contain the XInterface 209*cdf0e10cSrcweir methods. 210*cdf0e10cSrcweir */ 211*cdf0e10cSrcweir gcroot<sr::MethodInfo*[]> m_arMethodInfos; 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir /** This array is similar to m_arMethodInfos but it contains the MethodInfo 214*cdf0e10cSrcweir objects of the interface (not the object). When a call is made from uno 215*cdf0e10cSrcweir to cli then the uno method name is compared to the cli method name. The 216*cdf0e10cSrcweir cli method name can be obtained from the MethodInfo object in this 217*cdf0e10cSrcweir array. The name of the actual implemented method may not be the same as 218*cdf0e10cSrcweir the interface method. 219*cdf0e10cSrcweir */ 220*cdf0e10cSrcweir gcroot<sr::MethodInfo*[]> m_arInterfaceMethodInfos; 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir /** Maps the position of the method in the UNO interface to the position of 223*cdf0e10cSrcweir the corresponding MethodInfo in m_arMethodInfos. The Uno position must 224*cdf0e10cSrcweir not include the XInterface methods. For example, 225*cdf0e10cSrcweir pos 0 = XInterface::queryInterface 226*cdf0e10cSrcweir pos 1 = XInterface::acquire 227*cdf0e10cSrcweir pos 2 = XInterface::release 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir That is the real Uno position has to be deducted by 3. Then 230*cdf0e10cSrcweir arUnoPosToCliPos[pos] contains the index for m_arMethodInfos. 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir */ 233*cdf0e10cSrcweir gcroot<System::Int32[]> m_arUnoPosToCliPos; 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir /** Count of inherited interfaces of the cli interface. 236*cdf0e10cSrcweir */ 237*cdf0e10cSrcweir int m_nInheritedInterfaces; 238*cdf0e10cSrcweir /** Contains the number of methods of each interface. 239*cdf0e10cSrcweir */ 240*cdf0e10cSrcweir gcroot<System::Int32[]> m_arInterfaceMethodCount; 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir CliProxy( Bridge const* bridge, System::Object* cliI, 243*cdf0e10cSrcweir typelib_TypeDescription const* pTD, 244*cdf0e10cSrcweir const rtl::OUString& usOid); 245*cdf0e10cSrcweir ~CliProxy(); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir static uno_Interface* create(Bridge const * bridge, 248*cdf0e10cSrcweir System::Object* cliI, 249*cdf0e10cSrcweir typelib_TypeDescription const * TD, 250*cdf0e10cSrcweir rtl::OUString const & usOid ); 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir /** Prepares an array (m_arMethoInfos) containing MethodInfo object of the 253*cdf0e10cSrcweir interface and all inherited interfaces. At index null is the first 254*cdf0e10cSrcweir method of the base interface and at the last position is the last method 255*cdf0e10cSrcweir of the furthest derived interface. 256*cdf0e10cSrcweir If a UNO call is received then one can determine the position of the 257*cdf0e10cSrcweir method (or getter or setter for an attribute) from the passed type 258*cdf0e10cSrcweir information. The position minus 3 (there is no XInterface in the cli 259*cdf0e10cSrcweir mapping) corresponds to the index of the cli interface method in the 260*cdf0e10cSrcweir array. 261*cdf0e10cSrcweir */ 262*cdf0e10cSrcweir void makeMethodInfos(); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir /**Obtains a MethodInfo which can be used to invoke the cli object. 265*cdf0e10cSrcweir Internally it maps nUnoFunctionPos to an index that is used to get the 266*cdf0e10cSrcweir corresponding MethodInfo object from m_arMethoInfos. The mapping table 267*cdf0e10cSrcweir is dynamically initialized. If the cli interface has no base interface 268*cdf0e10cSrcweir or exactly one then the mapping table is initialized in one go at the 269*cdf0e10cSrcweir first call. In all ensuing calls the MethodInfo object is immediately 270*cdf0e10cSrcweir retrieved through the mapping table. 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir If the interface has more then one interface in its inheritance chain, 273*cdf0e10cSrcweir that is Type.GetInterfaces return more then one Type, then the mapping 274*cdf0e10cSrcweir table is partially initiallized. On the first call the mappings for the 275*cdf0e10cSrcweir methods of the belonging interface are created. 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir The implementation assumes that the order of interface methods as 278*cdf0e10cSrcweir provided by InterfaceMapping.InterfaceMethods corresponds to the order 279*cdf0e10cSrcweir of methods in the interface declaration. 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir @param nUnoFunctionPos 282*cdf0e10cSrcweir Position of the method in the uno interface. 283*cdf0e10cSrcweir */ 284*cdf0e10cSrcweir sr::MethodInfo* getMethodInfo(int nUnoFunctionPos, 285*cdf0e10cSrcweir const rtl::OUString & usMethodName, 286*cdf0e10cSrcweir MethodKind mk); 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir void SAL_CALL uno_DispatchMethod( 289*cdf0e10cSrcweir struct _uno_Interface * pUnoI, 290*cdf0e10cSrcweir const struct _typelib_TypeDescription * pMemberType, 291*cdf0e10cSrcweir void * pReturn, 292*cdf0e10cSrcweir void * pArgs[], 293*cdf0e10cSrcweir uno_Any ** ppException ); 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir inline void acquire() const; 296*cdf0e10cSrcweir inline void release() const; 297*cdf0e10cSrcweir }; 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir #endif 300