nss: upgrade to release 3.73
[LibreOffice.git] / stoc / source / corereflection / criface.cxx
blobf958994d7b1d65f552ec5b210811ec61198b788b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <cassert>
23 #include <cstddef>
24 #include <limits>
26 #ifdef SAL_UNX
27 #include <sal/alloca.h>
28 #endif
29 #include <o3tl/any.hxx>
30 #include <typelib/typedescription.hxx>
31 #include <uno/data.h>
33 #include "base.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;
46 namespace {
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);
55 namespace stoc_corefl
58 namespace {
60 class IdlAttributeFieldImpl
61 : public IdlMemberImpl
62 , public XIdlField
63 , public XIdlField2
65 public:
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 )
74 // XInterface
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;
79 // XTypeProvider
80 virtual Sequence< Type > SAL_CALL getTypes() override;
81 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
83 // XIdlMember
84 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() override;
85 virtual OUString SAL_CALL getName() override;
86 // XIdlField
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;
94 private:
95 void checkException(
96 uno_Any * exception, Reference< XInterface > const & context) const;
101 // XInterface
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();
121 // XTypeProvider
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>();
138 // XIdlMember
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(':');
149 OSL_ASSERT(i >= 0);
150 _xDeclClass = getReflection()->forName(aName.copy(0, i));
153 return _xDeclClass;
156 OUString IdlAttributeFieldImpl::getName()
158 return IdlMemberImpl::getName();
161 // XIdlField
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!" );
180 if (pUnoI)
182 TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
183 typelib_TypeDescription * pTD = aTD.get();
185 uno_Any aExc;
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));
193 Any aRet;
194 uno_any_destruct(
195 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
196 uno_any_constructAndConvert( &aRet, pReturn, pTD, getReflection()->getUno2Cpp().get() );
197 uno_destructData( pReturn, pTD, nullptr );
198 return aRet;
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!" );
217 if (pUnoI)
219 TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
220 typelib_TypeDescription * pTD = aTD.get();
222 // construct uno value to be set
223 void * pArgs[1];
224 void * pArg = pArgs[0] = alloca( pTD->nSize );
226 bool bAssign;
227 if (pTD->eTypeClass == typelib_TypeClass_ANY)
229 uno_copyAndConvertData( pArg, const_cast< Any * >(&rValue),
230 pTD, getReflection()->getCpp2Uno().get() );
231 bAssign = true;
233 else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef ))
235 uno_copyAndConvertData( pArg, const_cast< void * >(rValue.getValue()),
236 pTD, getReflection()->getCpp2Uno().get() );
237 bAssign = true;
239 else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
241 Reference< XInterface > xObj;
242 bAssign = extract(
243 rValue, reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD), xObj,
244 getReflection() );
245 if (bAssign)
247 *static_cast<void **>(pArg) = getReflection()->getCpp2Uno().mapInterface(
248 xObj.get(), reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD) );
251 else
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() );
259 uno_constructData(
260 pArg, pTD );
261 // assignment does simple conversion
262 bAssign = uno_assignData(
263 pArg, pTD, pTemp, pValueTD, nullptr, nullptr, nullptr );
264 uno_destructData(
265 pTemp, pValueTD, nullptr );
266 TYPELIB_DANGER_RELEASE( pValueTD );
269 if (bAssign)
271 uno_Any aExc;
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));
278 return;
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)
300 return;
302 Any e;
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",
314 context, e);
316 cppu::throwException(e);
319 namespace {
321 class IdlInterfaceMethodImpl
322 : public IdlMemberImpl
323 , public XIdlMethod
325 std::unique_ptr<Sequence< Reference< XIdlClass > >> _pExceptionTypes;
326 std::unique_ptr<Sequence< Reference< XIdlClass > >> _pParamTypes;
327 std::unique_ptr<Sequence< ParamInfo >> _pParamInfos;
329 public:
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 )
338 // XInterface
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;
343 // XTypeProvider
344 virtual Sequence< Type > SAL_CALL getTypes() override;
345 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
347 // XIdlMember
348 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() override;
349 virtual OUString SAL_CALL getName() override;
350 // XIdlMethod
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;
361 // XInterface
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();
379 // XTypeProvider
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>();
395 // XIdlMember
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(':');
406 OSL_ASSERT(i >= 0);
407 _xDeclClass = getReflection()->forName(aName.copy(0, i));
410 return _xDeclClass;
413 OUString IdlInterfaceMethodImpl::getName()
415 return IdlMemberImpl::getName();
418 // XIdlMethod
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();
441 while (nExc--)
442 pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] );
444 _pExceptionTypes = std::move(pTempExceptionTypes);
447 return *_pExceptionTypes;
450 Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes()
452 if (! _pParamTypes)
454 ::osl::MutexGuard aGuard( getMutexAccess() );
455 if (! _pParamTypes)
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();
466 while (nParams--)
467 pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef );
469 _pParamTypes = std::move(pTempParamTypes);
472 return *_pParamTypes;
475 Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos()
477 if (! _pParamInfos)
479 ::osl::MutexGuard aGuard( getMutexAccess() );
480 if (! _pParamInfos)
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();
493 while (nParams--)
495 const typelib_MethodParameter & rParam = pTypelibParams[nParams];
496 ParamInfo & rInfo = pParamInfos[nParams];
497 rInfo.aName = rParam.pName;
498 if (rParam.bIn)
499 rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
500 else
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();
513 while (nParams--)
515 const typelib_MethodParameter & rParam = pTypelibParams[nParams];
516 ParamInfo & rInfo = pParamInfos[nParams];
517 rInfo.aName = rParam.pName;
518 if (rParam.bIn)
519 rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
520 else
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()
536 return
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>>(
543 rObj))
545 // acquire()/ release()
546 if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
547 "com.sun.star.uno.XInterface::acquire" ) == 0)
549 (*ifc)->acquire();
550 return Any();
552 else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
553 "com.sun.star.uno.XInterface::release" ) == 0)
555 (*ifc)->release();
556 return Any();
560 uno_Interface * pUnoI = getReflection()->mapToUno(
561 rObj, reinterpret_cast<typelib_InterfaceTypeDescription *>(getDeclTypeDescr()) );
562 OSL_ENSURE( pUnoI, "### illegal destination object given!" );
563 if (pUnoI)
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;
578 TYPELIB_DANGER_GET(
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);
590 // convert arguments
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)
600 bool bAssign;
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() );
607 bAssign = true;
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() );
614 bAssign = true;
616 else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
618 Reference< XInterface > xDest;
619 bAssign = extract(
620 pCppArgs[nPos], reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD),
621 xDest, getReflection() );
622 if (bAssign)
624 *static_cast<void **>(ppUnoArgs[nPos]) = getReflection()->getCpp2Uno().mapInterface(
625 xDest.get(), reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD) );
628 else
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() );
637 uno_constructData(
638 ppUnoArgs[nPos], pTD );
639 // assignment does simple conversion
640 bAssign = uno_assignData(
641 ppUnoArgs[nPos], pTD, pTemp, pValueTD, nullptr, nullptr, nullptr );
642 uno_destructData(
643 pTemp, pValueTD, nullptr );
644 TYPELIB_DANGER_RELEASE( pValueTD );
647 if (! bAssign)
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)
654 + "\"",
655 *o3tl::doAccess<Reference<XInterface>>(rObj), static_cast<sal_Int16>(nPos) );
657 // cleanup
658 while (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 );
667 throw aExc;
672 uno_Any aUnoExc;
673 uno_Any * pUnoExc = &aUnoExc;
675 (*pUnoI->pDispatcher)(
676 pUnoI, getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc );
677 (*pUnoI->release)( pUnoI );
679 Any aRet;
680 if (pUnoExc)
682 // cleanup
683 while (nParams--)
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!";
694 uno_any_destruct(
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 );
701 throw aExc;
703 else
705 // reconvert arguments and cleanup
706 while (nParams--)
708 if (pParams[nParams].bOut) // write back
710 uno_any_destruct(
711 &pCppArgs[nParams],
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] );
720 uno_any_destruct(
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 );
728 return aRet;
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 )
766 sal_Int32 nIndex;
767 if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
769 // methods to front
770 nIndex = _nMethods;
771 ++_nMethods;
773 else
775 ++_nAttributes;
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)
794 if (equals( xType ))
795 return true;
796 else
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); }))
801 return true;
804 return false;
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)
817 initMembers();
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() );
829 return aRet;
832 Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields()
834 ::osl::MutexGuard aGuard( getMutexAccess() );
835 if (! _pSortedMemberInit)
836 initMembers();
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() );
848 return aRet;
851 Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName )
853 ::osl::MutexGuard aGuard( getMutexAccess() );
854 if (! _pSortedMemberInit)
855 initMembers();
857 Reference< XIdlMethod > xRet;
859 // try weak map
860 const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) );
861 if (iFind != _aName2Method.end())
862 xRet = (*iFind).second; // harden ref
864 if (! xRet.is())
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() );
873 break;
877 return xRet;
880 Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName )
882 ::osl::MutexGuard aGuard( getMutexAccess() );
883 if (! _pSortedMemberInit)
884 initMembers();
886 Reference< XIdlField > xRet;
888 // try weak map
889 const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
890 if (iFind != _aName2Field.end())
891 xRet = (*iFind).second; // harden ref
893 if (! xRet.is())
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() );
902 break;
906 return xRet;
909 void InterfaceIdlClassImpl::createObject( Any & rObj )
911 // interfaces cannot be constructed
912 rObj.clear();
918 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */