1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_CLI_PROXY_H
21 #define INCLUDED_CLI_PROXY_H
23 #pragma warning(push, 1)
24 #include "uno/environment.hxx"
26 #include "uno/mapping.hxx"
27 #include "uno/dispatcher.h"
28 #include "cli_bridge.h"
29 #include "cli_environment.h"
33 namespace srrp
= System::Runtime::Remoting::Proxies
;
34 namespace srrm
= System::Runtime::Remoting::Messaging
;
35 namespace srr
= System::Runtime::Remoting
;
36 namespace sr
= System::Reflection
;
37 namespace sc
= System::Collections
;
43 public ref
class UnoInterfaceInfo
46 UnoInterfaceInfo(Bridge
const * bridge
, uno_Interface
* unoI
,
47 typelib_InterfaceTypeDescription
* td
);
49 uno_Interface
* m_unoI
; // wrapped interface
50 System::Type
^ m_type
;
51 typelib_InterfaceTypeDescription
* m_typeDesc
;
53 Bridge
const* m_bridge
;
56 public ref
class UnoInterfaceProxy
: public srrp::RealProxy
,
57 public srr::IRemotingTypeInfo
59 /** used for IRemotingTypeInfo.TypeName
61 System::String
^ m_sTypeName
;
62 /** The list is filled with UnoInterfaceInfo objects. The list can only
63 grow and elements are never changed. If an element was added it
66 sc::ArrayList
^ m_listIfaces
;
67 /** The number of UNO interfaces this proxy represents. It corresponds
68 to the number of elements in m_listIfaces.
71 /** The list is filled with additional UnoInterfaceProxy object due
72 to aggregation via bridges. Though the latter is strongly
73 discouraged, this has to be supported.
75 sc::ArrayList
^ m_listAdditionalProxies
;
76 int m_nlistAdditionalProxies
;
78 UnoInterfaceInfo
^ findInfo( ::System::Type
^ type
);
80 Bridge
const* m_bridge
;
81 System::String
^ m_oid
;
83 #if OSL_DEBUG_LEVEL >= 2
84 /** The string contains all names of UNO interfaces which are
85 represented by this proxy. It is used to print out the interfaces
86 when this proxy dies. In the destructor it is not allowed to
87 access m_listIfaces or any other managed object.
89 rtl_uString
* _sInterfaces
;
90 // /** Count of interfaces. Used in conjunction with _sInterfaces.
97 /** Creates a proxy and registers it on the dot NET side.
99 static System::Object
^ create(Bridge
* bridge
,
100 uno_Interface
* pUnoI
,
101 typelib_InterfaceTypeDescription
* pTd
,
102 const OUString
& oid
);
104 /** RealProxy::Invoke */
105 virtual srrm::IMessage
^ Invoke(srrm::IMessage
^ msg
) override
;
107 /** Must be called from within a synchronized section.
108 Add only the interface if it is not already contained.
109 This method is called from the constructor and as a result
110 of IRemotingTypeInfo::CanCastTo
112 void addUnoInterface(uno_Interface
* pUnoI
,
113 typelib_InterfaceTypeDescription
* pTd
);
114 ~UnoInterfaceProxy();
118 inline System::String
^ getOid()
121 //IRemotingTypeInfo ----------------------------------------------
122 virtual bool CanCastTo(System::Type
^ fromType
, System::Object
^ o
);
124 virtual property
System::String
^ TypeName
126 System::String
^ get()
130 void set(System::String
^ name
)
140 uno_Interface
* pUnoI
,
141 typelib_InterfaceTypeDescription
* pTD
,
142 const OUString
& oid
);
144 static srrm::IMessage
^ constructReturnMessage(System::Object
^ retVal
,
145 array
<System::Object
^>^ outArgs
,
146 typelib_InterfaceMethodTypeDescription
* mtd
,
147 srrm::IMessage
^ msg
, System::Object
^ exc
);
149 static System::String
^ m_methodNameString
=
150 gcnew
System::String("__MethodName");
151 static System::String
^ m_typeNameString
= gcnew
System::String("__TypeName");
152 static System::String
^ m_ArgsString
= gcnew
System::String("__Args");
153 static System::String
^ m_CallContextString
=
154 gcnew
System::String("__CallContext");
155 static System::String
^ m_system_Object_String
=
156 gcnew
System::String("System.Object");
157 static System::String
^ m_methodSignatureString
=
158 gcnew
System::String("__MethodSignature");
159 static System::String
^ m_Equals_String
= gcnew
System::String("Equals");
160 static System::String
^ m_GetHashCode_String
=
161 gcnew
System::String("GetHashCode");
162 static System::String
^ m_GetType_String
= gcnew
System::String("GetType");
163 static System::String
^ m_ToString_String
= gcnew
System::String("ToString");
166 srrm::IMessage
^ invokeObject(sc::IDictionary
^ properties
,
167 srrm::LogicalCallContext
^ context
,
168 srrm::IMethodCallMessage
^ mcm
);
172 //Cannot make this __gc because a managed type cannot derive from unmanaged type
173 struct CliProxy
: public uno_Interface
175 mutable oslInterlockedCount m_ref
;
176 const Bridge
* m_bridge
;
177 const gcroot
<System::Object
^> m_cliI
;
178 gcroot
<System::Type
^> m_type
;
179 const com::sun::star::uno::TypeDescription m_unoType
;
180 const gcroot
<System::String
^> m_oid
;
181 const OUString m_usOid
;
183 enum MethodKind
{MK_METHOD
= 0, MK_SET
, MK_GET
};
184 /** The array contains MethodInfos of the cli object. Each one reflects an
185 implemented interface method of the interface for which this proxy was
186 created. The MethodInfos are from the object's method and not from the
187 interface type. That is, they can be used to invoke the methods. The
188 order of the MethodInfo objects corresponds to the order of the
189 interface methods (see member m_type). Position 0 contains the
190 MethodInfo of the first method of the interface which represents the
191 root of the inheritance chain. The last MethodInfo represents the last
192 method of the furthest derived interface.
194 The array is completely initialized in the constructor of this object.
196 When the uno_DispatchMethod is called for this proxy then it receives
197 a typelib_TypeDescription of the member which is either an attribute
198 (setter or getter) or method. After determining the position of the
199 method within the UNO interface one can use the position to obtain the
200 MethodInfo of the corresponding cli method. To obtain the index for the
201 m_arMethodInfos array the function position has to be decreased by 3.
202 This is because, the cli interface does not contain the XInterface
205 gcroot
<array
<sr::MethodInfo
^>^> m_arMethodInfos
;
207 /** This array is similar to m_arMethodInfos but it contains the MethodInfo
208 objects of the interface (not the object). When a call is made from uno
209 to cli then the uno method name is compared to the cli method name. The
210 cli method name can be obtained from the MethodInfo object in this
211 array. The name of the actual implemented method may not be the same as
212 the interface method.
214 gcroot
<array
<sr::MethodInfo
^>^> m_arInterfaceMethodInfos
;
216 /** Maps the position of the method in the UNO interface to the position of
217 the corresponding MethodInfo in m_arMethodInfos. The Uno position must
218 not include the XInterface methods. For example,
219 pos 0 = XInterface::queryInterface
220 pos 1 = XInterface::acquire
221 pos 2 = XInterface::release
223 That is the real Uno position has to be deducted by 3. Then
224 arUnoPosToCliPos[pos] contains the index for m_arMethodInfos.
227 gcroot
<array
<System::Int32
>^> m_arUnoPosToCliPos
;
229 /** Count of inherited interfaces of the cli interface.
231 int m_nInheritedInterfaces
;
232 /** Contains the number of methods of each interface.
234 gcroot
<array
<System::Int32
^>^> m_arInterfaceMethodCount
;
236 CliProxy( Bridge
const* bridge
, System::Object
^ cliI
,
237 typelib_TypeDescription
const* pTD
,
238 const OUString
& usOid
);
241 static uno_Interface
* create(Bridge
const * bridge
,
242 System::Object
^ cliI
,
243 typelib_TypeDescription
const * TD
,
244 OUString
const & usOid
);
246 /** Prepares an array (m_arMethoInfos) containing MethodInfo object of the
247 interface and all inherited interfaces. At index null is the first
248 method of the base interface and at the last position is the last method
249 of the furthest derived interface.
250 If a UNO call is received then one can determine the position of the
251 method (or getter or setter for an attribute) from the passed type
252 information. The position minus 3 (there is no XInterface in the cli
253 mapping) corresponds to the index of the cli interface method in the
256 void makeMethodInfos();
258 /**Obtains a MethodInfo which can be used to invoke the cli object.
259 Internally it maps nUnoFunctionPos to an index that is used to get the
260 corresponding MethodInfo object from m_arMethoInfos. The mapping table
261 is dynamically initialized. If the cli interface has no base interface
262 or exactly one then the mapping table is initialized in one go at the
263 first call. In all ensuing calls the MethodInfo object is immediately
264 retrieved through the mapping table.
266 If the interface has more then one interface in its inheritance chain,
267 that is Type.GetInterfaces return more then one Type, then the mapping
268 table is partially initiallized. On the first call the mappings for the
269 methods of the belonging interface are created.
271 The implementation assumes that the order of interface methods as
272 provided by InterfaceMapping.InterfaceMethods corresponds to the order
273 of methods in the interface declaration.
275 @param nUnoFunctionPos
276 Position of the method in the uno interface.
278 sr::MethodInfo
^ getMethodInfo(int nUnoFunctionPos
,
279 const OUString
& usMethodName
,
282 void SAL_CALL
uno_DispatchMethod(
283 struct _uno_Interface
* pUnoI
,
284 const struct _typelib_TypeDescription
* pMemberType
,
287 uno_Any
** ppException
);
289 inline void acquire() const;
290 inline void release() const;
295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */