21#include <osl/diagnose.h>
22#include <osl/interlck.h>
24#include <uno/dispatcher.hxx>
26#include <uno/lbnames.h>
27#include <uno/mapping.hxx>
28#include <uno/environment.hxx>
29#include <typelib/typedescription.hxx>
35#include <com/sun/star/lang/XServiceInfo.hpp>
36#include <com/sun/star/reflection/XProxyFactory.hpp>
37#include <com/sun/star/uno/RuntimeException.hpp>
38#include <com/sun/star/uno/XComponentContext.hpp>
43using namespace css::uno;
49struct FactoryImpl :
public ::cppu::WeakImplHelper< lang::XServiceInfo,
50 reflection::XProxyFactory >
58 UnoInterfaceReference
const & unoI,
59 typelib_InterfaceTypeDescription * pTypeDescr );
69 virtual Reference< XAggregation > SAL_CALL createProxy(
70 Reference< XInterface >
const & xTarget )
override;
74UnoInterfaceReference FactoryImpl::binuno_queryInterface(
75 UnoInterfaceReference
const & unoI,
76 typelib_InterfaceTypeDescription * pTypeDescr )
84 &pQITD,
reinterpret_cast<typelib_InterfaceTypeDescription*
>(pTXInterfaceDescr)
86 TYPELIB_DANGER_RELEASE(pTXInterfaceDescr);
92 pTypeDescr )->pWeakRef;
96 unoI.dispatch( s_pQITD, &ret_val, args, &exc );
100 UnoInterfaceReference ret;
101 if (ret_val.pType->eTypeClass == typelib_TypeClass_INTERFACE)
103 ret.set( *
static_cast< uno_Interface **
>(ret_val.pData),
119 "### RuntimeException expected!" );
122 &cpp_exc, exc,
cppu::UnoType<
decltype(cpp_exc)>::get().getTypeLibType(),
125 ::cppu::throwException( cpp_exc );
127 return UnoInterfaceReference();
138 Reference< XInterface >
const & xTarget );
147struct binuno_Proxy :
public uno_Interface
149 oslInterlockedCount m_nRefCount;
153 TypeDescription m_typeDescr;
157 UnoInterfaceReference target,
158 OUString oid, TypeDescription typeDescr );
165static void binuno_proxy_free(
166 uno_ExtEnvironment * pEnv,
void * pProxy )
168 binuno_Proxy * proxy =
static_cast< binuno_Proxy *
>(
169 static_cast< uno_Interface *
>( pProxy ) );
170 OSL_ASSERT( proxy->m_root->m_factory->m_uno_env.get()->pExtEnv == pEnv );
175static void binuno_proxy_acquire( uno_Interface * pUnoI )
177 binuno_Proxy * that =
static_cast< binuno_Proxy *
>( pUnoI );
178 if (osl_atomic_increment( &that->m_nRefCount ) != 1)
182 uno_ExtEnvironment * uno_env =
183 that->m_root->m_factory->m_uno_env.get()->pExtEnv;
184 OSL_ASSERT( uno_env !=
nullptr );
185 (*uno_env->registerProxyInterface)(
186 uno_env,
reinterpret_cast< void **
>( &pUnoI ), binuno_proxy_free,
188 reinterpret_cast< typelib_InterfaceTypeDescription *
>(
189 that->m_typeDescr.get() ) );
190 OSL_ASSERT( that ==
static_cast< binuno_Proxy *
>( pUnoI ) );
194static void binuno_proxy_release( uno_Interface * pUnoI )
196 binuno_Proxy * that =
static_cast< binuno_Proxy *
>( pUnoI );
197 if (osl_atomic_decrement( &that->m_nRefCount ) == 0)
199 uno_ExtEnvironment * uno_env =
200 that->m_root->m_factory->m_uno_env.get()->pExtEnv;
201 OSL_ASSERT( uno_env !=
nullptr );
202 (*uno_env->revokeInterface)( uno_env, pUnoI );
207static void binuno_proxy_dispatch(
209 void * pReturn,
void * pArgs [],
uno_Any ** ppException )
211 binuno_Proxy * that =
static_cast< binuno_Proxy *
>( pUnoI );
212 switch (
reinterpret_cast< typelib_InterfaceMemberTypeDescription
const *
>(
213 pMemberType )->nPosition)
220 *
static_cast< Type const *
>( pArgs[ 0 ] );
221 Any ret( that->m_root->queryInterface( rType ) );
223 pReturn, &ret,
cppu::UnoType<
decltype(ret)>::get().getTypeLibType(),
224 that->m_root->m_factory->m_cpp2uno.
get() );
225 *ppException =
nullptr;
229 Any exc( ::cppu::getCaughtException() );
231 *ppException,
const_cast< void *
>(exc.getValue()),
232 exc.getValueTypeRef(),
233 that->m_root->m_factory->m_cpp2uno.get() );
238 binuno_proxy_acquire( pUnoI );
239 *ppException =
nullptr;
242 binuno_proxy_release( pUnoI );
243 *ppException =
nullptr;
246 that->m_target.dispatch( pMemberType, pReturn, pArgs, ppException );
254binuno_Proxy::binuno_Proxy(
256 UnoInterfaceReference target,
257 OUString oid, TypeDescription typeDescr )
259 m_root(
std::move( root )),
262 m_typeDescr(
std::move( typeDescr ))
264 uno_Interface::acquire = binuno_proxy_acquire;
265 uno_Interface::release = binuno_proxy_release;
266 uno_Interface::pDispatcher = binuno_proxy_dispatch;
271 Reference< XInterface >
const & xTarget )
272 : m_factory(
std::move( factory ))
274 m_factory->m_cpp2uno.mapInterface(
277 OSL_ENSURE(
m_target.is(),
"### mapping interface failed!" );
281Any ProxyRoot::queryAggregation(
Type const & rType )
283 Any ret( OWeakAggObject::queryAggregation( rType ) );
284 if (! ret.hasValue())
287 TYPELIB_DANGER_GET( &pTypeDescr, rType.getTypeLibType() );
290 Reference< XInterface > xProxy;
291 uno_ExtEnvironment * cpp_env = m_factory->m_cpp_env.get()->pExtEnv;
292 OSL_ASSERT( cpp_env !=
nullptr );
295 Reference< XInterface > xRoot(getXWeak());
297 (*cpp_env->getObjectIdentifier)( cpp_env, &oid.pData, xRoot.get() );
298 OSL_ASSERT( !oid.isEmpty() );
300 (*cpp_env->getRegisteredInterface)(
301 cpp_env,
reinterpret_cast< void **
>( &xProxy ),
302 oid.pData,
reinterpret_cast<
303 typelib_InterfaceTypeDescription *
>(pTypeDescr) );
307 UnoInterfaceReference proxy_target(
308 m_factory->binuno_queryInterface(
310 typelib_InterfaceTypeDescription *
>(pTypeDescr) ) );
311 if (proxy_target.is())
314 UnoInterfaceReference root;
315 m_factory->m_cpp2uno.mapInterface(
316 reinterpret_cast< void **
>( &root.m_pUnoI ),
319 UnoInterfaceReference proxy(
321 new binuno_Proxy(
this, proxy_target, oid, pTypeDescr ),
323 uno_ExtEnvironment * uno_env =
324 m_factory->m_uno_env.get()->pExtEnv;
325 OSL_ASSERT( uno_env !=
nullptr );
326 (*uno_env->registerProxyInterface)(
327 uno_env,
reinterpret_cast< void **
>( &proxy.m_pUnoI ),
328 binuno_proxy_free, oid.pData,
329 reinterpret_cast< typelib_InterfaceTypeDescription *
>(
332 m_factory->m_uno2cpp.mapInterface(
333 reinterpret_cast< void **
>( &xProxy ),
334 proxy.get(), pTypeDescr );
338 ret.setValue( &xProxy, pTypeDescr );
342 TYPELIB_DANGER_RELEASE( pTypeDescr );
345 TYPELIB_DANGER_RELEASE( pTypeDescr );
351FactoryImpl::FactoryImpl()
353 OUString
uno = UNO_LB_UNO;
354 OUString cpp = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
358 OSL_ENSURE( m_uno_env.is(),
"### cannot get binary uno env!" );
361 reinterpret_cast< uno_Environment **
>( &m_cpp_env ), cpp.pData,
nullptr );
362 OSL_ENSURE( m_cpp_env.is(),
"### cannot get C++ uno env!" );
366 m_uno_env.get(), m_cpp_env.get(),
nullptr );
367 OSL_ENSURE( m_uno2cpp.is(),
"### cannot get bridge uno <-> C++!" );
371 m_cpp_env.get(), m_uno_env.get(),
nullptr );
372 OSL_ENSURE( m_cpp2uno.is(),
"### cannot get bridge C++ <-> uno!" );
377Reference< XAggregation > FactoryImpl::createProxy(
378 Reference< XInterface >
const & xTarget )
380 return new ProxyRoot(
this, xTarget );
385OUString FactoryImpl::getImplementationName()
387 return "com.sun.star.comp.reflection.ProxyFactory";
390sal_Bool FactoryImpl::supportsService(
const OUString & rServiceName )
395Sequence< OUString > FactoryImpl::getSupportedServiceNames()
397 return {
"com.sun.star.reflection.ProxyFactory" };
400extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
401stoc_FactoryImpl_get_implementation(
402 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any>
const&)
404 return cppu::acquire(
new FactoryImpl);
void SAL_CALL uno_type_any_constructAndConvert(uno_Any *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void SAL_CALL uno_any_destruct(uno_Any *pValue, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &rType) SAL_OVERRIDE
css::uno::Type const & get()
void SAL_CALL uno_type_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
Reference< XInterface > xTarget
struct _uno_Environment uno_Environment
void SAL_CALL uno_getEnvironment(uno_Environment **ppEnv, rtl_uString *pEnvDcp, void *pContext) SAL_THROW_EXTERN_C()
void SAL_CALL uno_getMapping(uno_Mapping **ppMapping, uno_Environment *pFrom, uno_Environment *pTo, rtl_uString *pAddPurpose) SAL_THROW_EXTERN_C()
struct _uno_Mapping uno_Mapping
struct _typelib_TypeDescription typelib_TypeDescription
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
void * binuno_queryInterface(void *pUnoI, typelib_TypeDescriptionReference *pDestType)
void SAL_CALL typelib_typedescriptionreference_getDescription(typelib_TypeDescription **ppRet, typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(typelib_TypeDescriptionReference *pAssignable, typelib_TypeDescriptionReference *pFrom) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()