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