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 #include <sal/config.h>
27 #include <sal/alloca.h>
29 #include <o3tl/any.hxx>
30 #include <typelib/typedescription.hxx>
35 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
36 #include <com/sun/star/reflection/XIdlField2.hpp>
37 #include <com/sun/star/uno/RuntimeException.hpp>
38 #include <cppuhelper/queryinterface.hxx>
39 #include <cppuhelper/exc_hlp.hxx>
40 #include <cppuhelper/typeprovider.hxx>
42 using namespace css::lang
;
43 using namespace css::reflection
;
44 using namespace css::uno
;
48 std::size_t multipleOf16(std::size_t n
) {
49 assert(n
<= std::numeric_limits
<std::size_t>::max() - 15);
50 return (n
+ 15) & ~std::size_t(15);
60 class IdlAttributeFieldImpl
61 : public IdlMemberImpl
66 typelib_InterfaceAttributeTypeDescription
* getAttributeTypeDescr() const
67 { return reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(getTypeDescr()); }
69 IdlAttributeFieldImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
70 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
)
71 : IdlMemberImpl( pReflection
, rName
, pTypeDescr
, pDeclTypeDescr
)
75 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
76 virtual void SAL_CALL
acquire() throw() override
;
77 virtual void SAL_CALL
release() throw() override
;
80 virtual Sequence
< Type
> SAL_CALL
getTypes() override
;
81 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
84 virtual Reference
< XIdlClass
> SAL_CALL
getDeclaringClass() override
;
85 virtual OUString SAL_CALL
getName() override
;
87 virtual Reference
< XIdlClass
> SAL_CALL
getType() override
;
88 virtual FieldAccessMode SAL_CALL
getAccessMode() override
;
89 virtual Any SAL_CALL
get( const Any
& rObj
) override
;
90 virtual void SAL_CALL
set( const Any
& rObj
, const Any
& rValue
) override
;
91 // XIdlField2: getType, getAccessMode and get are equal to XIdlField
92 virtual void SAL_CALL
set( Any
& rObj
, const Any
& rValue
) override
;
96 uno_Any
* exception
, Reference
< XInterface
> const & context
) const;
103 Any
IdlAttributeFieldImpl::queryInterface( const Type
& rType
)
105 Any
aRet( ::cppu::queryInterface( rType
,
106 static_cast< XIdlField
* >( this ),
107 static_cast< XIdlField2
* >( this ) ) );
108 return (aRet
.hasValue() ? aRet
: IdlMemberImpl::queryInterface( rType
));
111 void IdlAttributeFieldImpl::acquire() throw()
113 IdlMemberImpl::acquire();
116 void IdlAttributeFieldImpl::release() throw()
118 IdlMemberImpl::release();
123 Sequence
< Type
> IdlAttributeFieldImpl::getTypes()
125 static cppu::OTypeCollection
s_aTypes(
126 cppu::UnoType
<XIdlField2
>::get(),
127 cppu::UnoType
<XIdlField
>::get(),
128 IdlMemberImpl::getTypes() );
130 return s_aTypes
.getTypes();
133 Sequence
< sal_Int8
> IdlAttributeFieldImpl::getImplementationId()
135 return css::uno::Sequence
<sal_Int8
>();
140 Reference
< XIdlClass
> IdlAttributeFieldImpl::getDeclaringClass()
142 if (! _xDeclClass
.is())
144 ::osl::MutexGuard
aGuard( getMutexAccess() );
145 if (! _xDeclClass
.is())
147 OUString
aName(getAttributeTypeDescr()->aBase
.aBase
.pTypeName
);
148 sal_Int32 i
= aName
.indexOf(':');
150 _xDeclClass
= getReflection()->forName(aName
.copy(0, i
));
156 OUString
IdlAttributeFieldImpl::getName()
158 return IdlMemberImpl::getName();
163 Reference
< XIdlClass
> IdlAttributeFieldImpl::getType()
165 return getReflection()->forType(
166 getAttributeTypeDescr()->pAttributeTypeRef
);
169 FieldAccessMode
IdlAttributeFieldImpl::getAccessMode()
171 return (getAttributeTypeDescr()->bReadOnly
172 ? FieldAccessMode_READONLY
: FieldAccessMode_READWRITE
);
175 Any
IdlAttributeFieldImpl::get( const Any
& rObj
)
177 uno_Interface
* pUnoI
= getReflection()->mapToUno(
178 rObj
, reinterpret_cast<typelib_InterfaceTypeDescription
*>(getDeclTypeDescr()) );
179 OSL_ENSURE( pUnoI
, "### illegal destination object given!" );
182 TypeDescription
aTD( getAttributeTypeDescr()->pAttributeTypeRef
);
183 typelib_TypeDescription
* pTD
= aTD
.get();
186 uno_Any
* pExc
= &aExc
;
187 void * pReturn
= alloca( pTD
->nSize
);
189 (*pUnoI
->pDispatcher
)( pUnoI
, getTypeDescr(), pReturn
, nullptr, &pExc
);
190 (*pUnoI
->release
)( pUnoI
);
192 checkException(pExc
, *o3tl::doAccess
<Reference
<XInterface
>>(rObj
));
195 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
196 uno_any_constructAndConvert( &aRet
, pReturn
, pTD
, getReflection()->getUno2Cpp().get() );
197 uno_destructData( pReturn
, pTD
, nullptr );
200 throw IllegalArgumentException(
201 "illegal object given!",
202 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
205 void IdlAttributeFieldImpl::set( Any
& rObj
, const Any
& rValue
)
207 if (getAttributeTypeDescr()->bReadOnly
)
209 throw IllegalAccessException(
210 "cannot set readonly attribute!",
211 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)) );
214 uno_Interface
* pUnoI
= getReflection()->mapToUno(
215 rObj
, reinterpret_cast<typelib_InterfaceTypeDescription
*>(getDeclTypeDescr()) );
216 OSL_ENSURE( pUnoI
, "### illegal destination object given!" );
219 TypeDescription
aTD( getAttributeTypeDescr()->pAttributeTypeRef
);
220 typelib_TypeDescription
* pTD
= aTD
.get();
222 // construct uno value to be set
224 void * pArg
= pArgs
[0] = alloca( pTD
->nSize
);
227 if (pTD
->eTypeClass
== typelib_TypeClass_ANY
)
229 uno_copyAndConvertData( pArg
, const_cast< Any
* >(&rValue
),
230 pTD
, getReflection()->getCpp2Uno().get() );
233 else if (typelib_typedescriptionreference_equals( rValue
.getValueTypeRef(), pTD
->pWeakRef
))
235 uno_copyAndConvertData( pArg
, const_cast< void * >(rValue
.getValue()),
236 pTD
, getReflection()->getCpp2Uno().get() );
239 else if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
)
241 Reference
< XInterface
> xObj
;
243 rValue
, reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
), xObj
,
247 *static_cast<void **>(pArg
) = getReflection()->getCpp2Uno().mapInterface(
248 xObj
.get(), reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
) );
253 typelib_TypeDescription
* pValueTD
= nullptr;
254 TYPELIB_DANGER_GET( &pValueTD
, rValue
.getValueTypeRef() );
255 // construct temp uno val to do proper assignment: todo opt
256 void * pTemp
= alloca( pValueTD
->nSize
);
257 uno_copyAndConvertData(
258 pTemp
, const_cast<void *>(rValue
.getValue()), pValueTD
, getReflection()->getCpp2Uno().get() );
261 // assignment does simple conversion
262 bAssign
= uno_assignData(
263 pArg
, pTD
, pTemp
, pValueTD
, nullptr, nullptr, nullptr );
265 pTemp
, pValueTD
, nullptr );
266 TYPELIB_DANGER_RELEASE( pValueTD
);
272 uno_Any
* pExc
= &aExc
;
273 (*pUnoI
->pDispatcher
)( pUnoI
, getTypeDescr(), nullptr, pArgs
, &pExc
);
274 (*pUnoI
->release
)( pUnoI
);
276 uno_destructData( pArg
, pTD
, nullptr );
277 checkException(pExc
, *o3tl::doAccess
<Reference
<XInterface
>>(rObj
));
280 (*pUnoI
->release
)( pUnoI
);
282 throw IllegalArgumentException(
283 "illegal value given!",
284 *o3tl::doAccess
<Reference
<XInterface
>>(rObj
), 1 );
286 throw IllegalArgumentException(
287 "illegal destination object given!",
288 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
291 void IdlAttributeFieldImpl::set( const Any
& rObj
, const Any
& rValue
)
293 IdlAttributeFieldImpl::set( const_cast< Any
& >( rObj
), rValue
);
296 void IdlAttributeFieldImpl::checkException(
297 uno_Any
* exception
, Reference
< XInterface
> const & context
) const
299 if (exception
== nullptr)
303 uno_any_destruct(&e
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
));
304 uno_type_any_constructAndConvert(
305 &e
, exception
->pData
, exception
->pType
,
306 getReflection()->getUno2Cpp().get());
307 uno_any_destruct(exception
, nullptr);
308 if (!e
.isExtractableTo(
309 cppu::UnoType
<RuntimeException
>::get()))
311 throw WrappedTargetRuntimeException(
312 "non-RuntimeException occurred when accessing an"
313 " interface type attribute",
316 cppu::throwException(e
);
321 class IdlInterfaceMethodImpl
322 : public IdlMemberImpl
325 std::unique_ptr
<Sequence
< Reference
< XIdlClass
> >> _pExceptionTypes
;
326 std::unique_ptr
<Sequence
< Reference
< XIdlClass
> >> _pParamTypes
;
327 std::unique_ptr
<Sequence
< ParamInfo
>> _pParamInfos
;
330 typelib_InterfaceMethodTypeDescription
* getMethodTypeDescr() const
331 { return reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>(getTypeDescr()); }
333 IdlInterfaceMethodImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
334 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
)
335 : IdlMemberImpl( pReflection
, rName
, pTypeDescr
, pDeclTypeDescr
)
339 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
340 virtual void SAL_CALL
acquire() throw() override
;
341 virtual void SAL_CALL
release() throw() override
;
344 virtual Sequence
< Type
> SAL_CALL
getTypes() override
;
345 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
348 virtual Reference
< XIdlClass
> SAL_CALL
getDeclaringClass() override
;
349 virtual OUString SAL_CALL
getName() override
;
351 virtual Reference
< XIdlClass
> SAL_CALL
getReturnType() override
;
352 virtual Sequence
< Reference
< XIdlClass
> > SAL_CALL
getParameterTypes() override
;
353 virtual Sequence
< ParamInfo
> SAL_CALL
getParameterInfos() override
;
354 virtual Sequence
< Reference
< XIdlClass
> > SAL_CALL
getExceptionTypes() override
;
355 virtual MethodMode SAL_CALL
getMode() override
;
356 virtual Any SAL_CALL
invoke( const Any
& rObj
, Sequence
< Any
> & rArgs
) override
;
363 Any
IdlInterfaceMethodImpl::queryInterface( const Type
& rType
)
365 Any
aRet( ::cppu::queryInterface( rType
, static_cast< XIdlMethod
* >( this ) ) );
366 return (aRet
.hasValue() ? aRet
: IdlMemberImpl::queryInterface( rType
));
369 void IdlInterfaceMethodImpl::acquire() throw()
371 IdlMemberImpl::acquire();
374 void IdlInterfaceMethodImpl::release() throw()
376 IdlMemberImpl::release();
381 Sequence
< Type
> IdlInterfaceMethodImpl::getTypes()
383 static cppu::OTypeCollection
s_aTypes(
384 cppu::UnoType
<XIdlMethod
>::get(),
385 IdlMemberImpl::getTypes() );
387 return s_aTypes
.getTypes();
390 Sequence
< sal_Int8
> IdlInterfaceMethodImpl::getImplementationId()
392 return css::uno::Sequence
<sal_Int8
>();
397 Reference
< XIdlClass
> IdlInterfaceMethodImpl::getDeclaringClass()
399 if (! _xDeclClass
.is())
401 ::osl::MutexGuard
aGuard( getMutexAccess() );
402 if (! _xDeclClass
.is())
404 OUString
aName(getMethodTypeDescr()->aBase
.aBase
.pTypeName
);
405 sal_Int32 i
= aName
.indexOf(':');
407 _xDeclClass
= getReflection()->forName(aName
.copy(0, i
));
413 OUString
IdlInterfaceMethodImpl::getName()
415 return IdlMemberImpl::getName();
420 Reference
< XIdlClass
> SAL_CALL
IdlInterfaceMethodImpl::getReturnType()
422 return getReflection()->forType( getMethodTypeDescr()->pReturnTypeRef
);
425 Sequence
< Reference
< XIdlClass
> > IdlInterfaceMethodImpl::getExceptionTypes()
427 if (! _pExceptionTypes
)
429 ::osl::MutexGuard
aGuard( getMutexAccess() );
430 if (! _pExceptionTypes
)
432 sal_Int32 nExc
= getMethodTypeDescr()->nExceptions
;
433 std::unique_ptr
<Sequence
< Reference
< XIdlClass
> >> pTempExceptionTypes(
434 new Sequence
< Reference
< XIdlClass
> >( nExc
));
435 Reference
< XIdlClass
> * pExceptionTypes
= pTempExceptionTypes
->getArray();
437 typelib_TypeDescriptionReference
** ppExc
=
438 getMethodTypeDescr()->ppExceptions
;
439 IdlReflectionServiceImpl
* pRefl
= getReflection();
442 pExceptionTypes
[nExc
] = pRefl
->forType( ppExc
[nExc
] );
444 _pExceptionTypes
= std::move(pTempExceptionTypes
);
447 return *_pExceptionTypes
;
450 Sequence
< Reference
< XIdlClass
> > IdlInterfaceMethodImpl::getParameterTypes()
454 ::osl::MutexGuard
aGuard( getMutexAccess() );
457 sal_Int32 nParams
= getMethodTypeDescr()->nParams
;
458 std::unique_ptr
<Sequence
< Reference
< XIdlClass
> > > pTempParamTypes(
459 new Sequence
< Reference
< XIdlClass
> >( nParams
));
460 Reference
< XIdlClass
> * pParamTypes
= pTempParamTypes
->getArray();
462 typelib_MethodParameter
* pTypelibParams
=
463 getMethodTypeDescr()->pParams
;
464 IdlReflectionServiceImpl
* pRefl
= getReflection();
467 pParamTypes
[nParams
] = pRefl
->forType( pTypelibParams
[nParams
].pTypeRef
);
469 _pParamTypes
= std::move(pTempParamTypes
);
472 return *_pParamTypes
;
475 Sequence
< ParamInfo
> IdlInterfaceMethodImpl::getParameterInfos()
479 ::osl::MutexGuard
aGuard( getMutexAccess() );
482 sal_Int32 nParams
= getMethodTypeDescr()->nParams
;
483 std::unique_ptr
<Sequence
< ParamInfo
> > pTempParamInfos( new Sequence
< ParamInfo
>( nParams
) );
484 ParamInfo
* pParamInfos
= pTempParamInfos
->getArray();
486 typelib_MethodParameter
* pTypelibParams
=
487 getMethodTypeDescr()->pParams
;
489 if (_pParamTypes
) // use param types
491 const Reference
< XIdlClass
> * pParamTypes
= _pParamTypes
->getConstArray();
495 const typelib_MethodParameter
& rParam
= pTypelibParams
[nParams
];
496 ParamInfo
& rInfo
= pParamInfos
[nParams
];
497 rInfo
.aName
= rParam
.pName
;
499 rInfo
.aMode
= (rParam
.bOut
? ParamMode_INOUT
: ParamMode_IN
);
501 rInfo
.aMode
= ParamMode_OUT
;
502 rInfo
.aType
= pParamTypes
[nParams
];
505 else // make also param types sequence if not already initialized
507 std::unique_ptr
<Sequence
< Reference
< XIdlClass
> > > pTempParamTypes(
508 new Sequence
< Reference
< XIdlClass
> >( nParams
));
509 Reference
< XIdlClass
> * pParamTypes
= pTempParamTypes
->getArray();
511 IdlReflectionServiceImpl
* pRefl
= getReflection();
515 const typelib_MethodParameter
& rParam
= pTypelibParams
[nParams
];
516 ParamInfo
& rInfo
= pParamInfos
[nParams
];
517 rInfo
.aName
= rParam
.pName
;
519 rInfo
.aMode
= (rParam
.bOut
? ParamMode_INOUT
: ParamMode_IN
);
521 rInfo
.aMode
= ParamMode_OUT
;
522 rInfo
.aType
= pParamTypes
[nParams
] = pRefl
->forType( rParam
.pTypeRef
);
525 _pParamTypes
= std::move(pTempParamTypes
);
528 _pParamInfos
= std::move(pTempParamInfos
);
531 return *_pParamInfos
;
534 MethodMode SAL_CALL
IdlInterfaceMethodImpl::getMode()
537 getMethodTypeDescr()->bOneWay
? MethodMode_ONEWAY
: MethodMode_TWOWAY
;
540 Any SAL_CALL
IdlInterfaceMethodImpl::invoke( const Any
& rObj
, Sequence
< Any
> & rArgs
)
542 if (auto ifc
= o3tl::tryAccess
<css::uno::Reference
<css::uno::XInterface
>>(
545 // acquire()/ release()
546 if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName
->buffer
,
547 "com.sun.star.uno.XInterface::acquire" ) == 0)
552 else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName
->buffer
,
553 "com.sun.star.uno.XInterface::release" ) == 0)
560 uno_Interface
* pUnoI
= getReflection()->mapToUno(
561 rObj
, reinterpret_cast<typelib_InterfaceTypeDescription
*>(getDeclTypeDescr()) );
562 OSL_ENSURE( pUnoI
, "### illegal destination object given!" );
565 sal_Int32 nParams
= getMethodTypeDescr()->nParams
;
566 if (rArgs
.getLength() != nParams
)
568 (*pUnoI
->release
)( pUnoI
);
569 throw IllegalArgumentException(
570 "expected " + OUString::number(nParams
) +
571 " arguments, got " + OUString::number(rArgs
.getLength()),
572 *o3tl::doAccess
<Reference
<XInterface
>>(rObj
), 1 );
575 Any
* pCppArgs
= rArgs
.getArray();
576 typelib_MethodParameter
* pParams
= getMethodTypeDescr()->pParams
;
577 typelib_TypeDescription
* pReturnType
= nullptr;
579 &pReturnType
, getMethodTypeDescr()->pReturnTypeRef
);
581 // C/C++ ABIs typically assume that structs are padded at the end, and
582 // that those padding bytes may be written to (e.g., to write into the
583 // end of a "short" struct by writing the full contents of a "long"
584 // register); so create enough space here (assuming that no ABI requires
585 // padding larger than 16 byte boundaries):
586 void * pUnoReturn
= (pReturnType
->nSize
== 0) ? nullptr : alloca( multipleOf16(pReturnType
->nSize
) );
587 void ** ppUnoArgs
= static_cast<void **>(alloca( sizeof(void *) * nParams
*2 ));
588 typelib_TypeDescription
** ppParamTypes
= reinterpret_cast<typelib_TypeDescription
**>(ppUnoArgs
+ nParams
);
591 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
593 ppParamTypes
[nPos
] = nullptr;
594 TYPELIB_DANGER_GET( ppParamTypes
+ nPos
, pParams
[nPos
].pTypeRef
);
595 typelib_TypeDescription
* pTD
= ppParamTypes
[nPos
];
597 ppUnoArgs
[nPos
] = alloca( pTD
->nSize
);
598 if (pParams
[nPos
].bIn
)
601 if (typelib_typedescriptionreference_equals(
602 pCppArgs
[nPos
].getValueTypeRef(), pTD
->pWeakRef
))
604 uno_type_copyAndConvertData(
605 ppUnoArgs
[nPos
], const_cast<void *>(pCppArgs
[nPos
].getValue()),
606 pCppArgs
[nPos
].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
609 else if (pTD
->eTypeClass
== typelib_TypeClass_ANY
)
611 uno_type_any_constructAndConvert(
612 static_cast<uno_Any
*>(ppUnoArgs
[nPos
]), const_cast<void *>(pCppArgs
[nPos
].getValue()),
613 pCppArgs
[nPos
].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
616 else if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
)
618 Reference
< XInterface
> xDest
;
620 pCppArgs
[nPos
], reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
),
621 xDest
, getReflection() );
624 *static_cast<void **>(ppUnoArgs
[nPos
]) = getReflection()->getCpp2Uno().mapInterface(
625 xDest
.get(), reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
) );
630 typelib_TypeDescription
* pValueTD
= nullptr;
631 TYPELIB_DANGER_GET( &pValueTD
, pCppArgs
[nPos
].getValueTypeRef() );
632 // construct temp uno val to do proper assignment: todo opt
633 void * pTemp
= alloca( pValueTD
->nSize
);
634 uno_copyAndConvertData(
635 pTemp
, const_cast<void *>(pCppArgs
[nPos
].getValue()), pValueTD
,
636 getReflection()->getCpp2Uno().get() );
638 ppUnoArgs
[nPos
], pTD
);
639 // assignment does simple conversion
640 bAssign
= uno_assignData(
641 ppUnoArgs
[nPos
], pTD
, pTemp
, pValueTD
, nullptr, nullptr, nullptr );
643 pTemp
, pValueTD
, nullptr );
644 TYPELIB_DANGER_RELEASE( pValueTD
);
649 IllegalArgumentException
aExc(
650 "cannot coerce argument type during corereflection call:"
651 "\narg no.: " + OUString::number(nPos
)
652 + " expected: \"" + OUString::unacquired(&pTD
->pTypeName
)
653 + "\" actual: \"" + OUString::unacquired(&pCppArgs
[nPos
].getValueTypeRef()->pTypeName
)
655 *o3tl::doAccess
<Reference
<XInterface
>>(rObj
), static_cast<sal_Int16
>(nPos
) );
660 if (pParams
[nPos
].bIn
)
661 uno_destructData( ppUnoArgs
[nPos
], ppParamTypes
[nPos
], nullptr );
662 TYPELIB_DANGER_RELEASE( ppParamTypes
[nPos
] );
664 TYPELIB_DANGER_RELEASE( pReturnType
);
665 (*pUnoI
->release
)( pUnoI
);
673 uno_Any
* pUnoExc
= &aUnoExc
;
675 (*pUnoI
->pDispatcher
)(
676 pUnoI
, getTypeDescr(), pUnoReturn
, ppUnoArgs
, &pUnoExc
);
677 (*pUnoI
->release
)( pUnoI
);
685 if (pParams
[nParams
].bIn
)
686 uno_destructData( ppUnoArgs
[nParams
], ppParamTypes
[nParams
], nullptr );
687 TYPELIB_DANGER_RELEASE( ppParamTypes
[nParams
] );
689 TYPELIB_DANGER_RELEASE( pReturnType
);
691 InvocationTargetException aExc
;
692 aExc
.Context
= *o3tl::doAccess
<Reference
<XInterface
>>(rObj
);
693 aExc
.Message
= "exception occurred during invocation!";
695 &aExc
.TargetException
,
696 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
697 uno_type_copyAndConvertData(
698 &aExc
.TargetException
, pUnoExc
, cppu::UnoType
<Any
>::get().getTypeLibType(),
699 getReflection()->getUno2Cpp().get() );
700 uno_any_destruct( pUnoExc
, nullptr );
705 // reconvert arguments and cleanup
708 if (pParams
[nParams
].bOut
) // write back
712 reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
713 uno_any_constructAndConvert(
714 &pCppArgs
[nParams
], ppUnoArgs
[nParams
], ppParamTypes
[nParams
],
715 getReflection()->getUno2Cpp().get() );
717 uno_destructData( ppUnoArgs
[nParams
], ppParamTypes
[nParams
], nullptr );
718 TYPELIB_DANGER_RELEASE( ppParamTypes
[nParams
] );
721 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
722 uno_any_constructAndConvert(
723 &aRet
, pUnoReturn
, pReturnType
,
724 getReflection()->getUno2Cpp().get() );
725 uno_destructData( pUnoReturn
, pReturnType
, nullptr );
726 TYPELIB_DANGER_RELEASE( pReturnType
);
730 throw IllegalArgumentException(
731 "illegal destination object given!",
732 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
736 InterfaceIdlClassImpl::~InterfaceIdlClassImpl()
738 for ( sal_Int32 nPos
= _nMethods
+ _nAttributes
; nPos
--; )
739 typelib_typedescription_release( _pSortedMemberInit
[nPos
].second
);
743 Sequence
< Reference
< XIdlClass
> > InterfaceIdlClassImpl::getSuperclasses()
745 ::osl::MutexGuard
aGuard(getMutexAccess());
746 if (!_xSuperClasses
.hasElements()) {
747 typelib_InterfaceTypeDescription
* pType
= getTypeDescr();
748 _xSuperClasses
.realloc(pType
->nBaseTypes
);
749 for (sal_Int32 i
= 0; i
< pType
->nBaseTypes
; ++i
) {
750 _xSuperClasses
[i
] = getReflection()->forType(
751 &pType
->ppBaseTypes
[i
]->aBase
);
752 OSL_ASSERT(_xSuperClasses
[i
].is());
755 return _xSuperClasses
;
758 void InterfaceIdlClassImpl::initMembers()
760 sal_Int32 nAll
= getTypeDescr()->nAllMembers
;
761 std::unique_ptr
<MemberInit
[]> pSortedMemberInit(new MemberInit
[nAll
]);
762 typelib_TypeDescriptionReference
** ppAllMembers
= getTypeDescr()->ppAllMembers
;
764 for ( sal_Int32 nPos
= 0; nPos
< nAll
; ++nPos
)
767 if (ppAllMembers
[nPos
]->eTypeClass
== typelib_TypeClass_INTERFACE_METHOD
)
776 nIndex
= (nAll
- _nAttributes
);
777 // attributes at the back
780 typelib_TypeDescription
* pTD
= nullptr;
781 typelib_typedescriptionreference_getDescription( &pTD
, ppAllMembers
[nPos
] );
782 assert(pTD
&& "### cannot get type description!");
783 pSortedMemberInit
[nIndex
].first
= reinterpret_cast<typelib_InterfaceMemberTypeDescription
*>(pTD
)->pMemberName
;
784 pSortedMemberInit
[nIndex
].second
= pTD
;
787 _pSortedMemberInit
= std::move(pSortedMemberInit
);
790 sal_Bool
InterfaceIdlClassImpl::isAssignableFrom( const Reference
< XIdlClass
> & xType
)
792 if (xType
.is() && xType
->getTypeClass() == TypeClass_INTERFACE
)
798 const Sequence
< Reference
< XIdlClass
> > & rSeq
= xType
->getSuperclasses();
799 if (std::any_of(rSeq
.begin(), rSeq
.end(),
800 [this](const Reference
<XIdlClass
>& rType
){ return isAssignableFrom(rType
); }))
807 Uik
InterfaceIdlClassImpl::getUik()
809 return Uik(0, 0, 0, 0, 0);
810 // Uiks are deprecated and this function must not be called
813 Sequence
< Reference
< XIdlMethod
> > InterfaceIdlClassImpl::getMethods()
815 ::osl::MutexGuard
aGuard( getMutexAccess() );
816 if (! _pSortedMemberInit
)
819 // create methods sequence
820 Sequence
< Reference
< XIdlMethod
> > aRet( _nMethods
);
821 Reference
< XIdlMethod
> * pRet
= aRet
.getArray();
822 for ( sal_Int32 nPos
= _nMethods
; nPos
--; )
825 /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet
[nPos
] = new IdlInterfaceMethodImpl(
826 getReflection(), _pSortedMemberInit
[nPos
].first
,
827 _pSortedMemberInit
[nPos
].second
, IdlClassImpl::getTypeDescr() );
832 Sequence
< Reference
< XIdlField
> > InterfaceIdlClassImpl::getFields()
834 ::osl::MutexGuard
aGuard( getMutexAccess() );
835 if (! _pSortedMemberInit
)
838 // create fields sequence
839 Sequence
< Reference
< XIdlField
> > aRet( _nAttributes
);
840 Reference
< XIdlField
> * pRet
= aRet
.getArray();
841 for ( sal_Int32 nPos
= _nAttributes
; nPos
--; )
843 /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet
[_nAttributes
-nPos
-1] =
844 new IdlAttributeFieldImpl(
845 getReflection(), _pSortedMemberInit
[_nMethods
+nPos
].first
,
846 _pSortedMemberInit
[_nMethods
+nPos
].second
, IdlClassImpl::getTypeDescr() );
851 Reference
< XIdlMethod
> InterfaceIdlClassImpl::getMethod( const OUString
& rName
)
853 ::osl::MutexGuard
aGuard( getMutexAccess() );
854 if (! _pSortedMemberInit
)
857 Reference
< XIdlMethod
> xRet
;
860 const OUString2Method::const_iterator
iFind( _aName2Method
.find( rName
) );
861 if (iFind
!= _aName2Method
.end())
862 xRet
= (*iFind
).second
; // harden ref
866 for ( sal_Int32 nPos
= _nMethods
; nPos
--; )
868 if (_pSortedMemberInit
[nPos
].first
== rName
)
870 _aName2Method
[rName
] = xRet
= new IdlInterfaceMethodImpl(
871 getReflection(), rName
,
872 _pSortedMemberInit
[nPos
].second
, IdlClassImpl::getTypeDescr() );
880 Reference
< XIdlField
> InterfaceIdlClassImpl::getField( const OUString
& rName
)
882 ::osl::MutexGuard
aGuard( getMutexAccess() );
883 if (! _pSortedMemberInit
)
886 Reference
< XIdlField
> xRet
;
889 const OUString2Field::const_iterator
iFind( _aName2Field
.find( rName
) );
890 if (iFind
!= _aName2Field
.end())
891 xRet
= (*iFind
).second
; // harden ref
895 for ( sal_Int32 nPos
= _nAttributes
; nPos
--; )
897 if (_pSortedMemberInit
[_nMethods
+nPos
].first
== rName
)
899 _aName2Field
[rName
] = xRet
= new IdlAttributeFieldImpl(
900 getReflection(), rName
,
901 _pSortedMemberInit
[_nMethods
+nPos
].second
, IdlClassImpl::getTypeDescr() );
909 void InterfaceIdlClassImpl::createObject( Any
& rObj
)
911 // interfaces cannot be constructed
918 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */