xref: /trunk/main/stoc/source/corereflection/criface.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 
27 #include <sal/config.h>
28 #ifdef SAL_UNX
29 #include <sal/alloca.h>
30 #endif
31 #if !(defined(MACOSX) || defined(FREEBSD))
32 #include <malloc.h>
33 #endif
34 #include <rtl/alloc.h>
35 #include <typelib/typedescription.hxx>
36 #include <uno/data.h>
37 
38 #include "base.hxx"
39 
40 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
41 #include "com/sun/star/uno/RuntimeException.hpp"
42 #include "cppuhelper/exc_hlp.hxx"
43 
44 namespace stoc_corefl
45 {
46 
47 //==================================================================================================
48 class IdlAttributeFieldImpl
49     : public IdlMemberImpl
50     , public XIdlField
51     , public XIdlField2
52 {
53 public:
getAttributeTypeDescr()54     typelib_InterfaceAttributeTypeDescription * getAttributeTypeDescr()
55         { return (typelib_InterfaceAttributeTypeDescription *)getTypeDescr(); }
56 
IdlAttributeFieldImpl(IdlReflectionServiceImpl * pReflection,const OUString & rName,typelib_TypeDescription * pTypeDescr,typelib_TypeDescription * pDeclTypeDescr)57     IdlAttributeFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
58                            typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr )
59         : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
60         {}
61 
62     // XInterface
63     virtual Any SAL_CALL queryInterface( const Type & rType );
64     virtual void SAL_CALL acquire() throw();
65     virtual void SAL_CALL release() throw();
66 
67     // XTypeProvider
68     virtual Sequence< Type > SAL_CALL getTypes();
69     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId();
70 
71     // XIdlMember
72     virtual Reference< XIdlClass > SAL_CALL getDeclaringClass();
73     virtual OUString SAL_CALL getName();
74     // XIdlField
75     virtual Reference< XIdlClass > SAL_CALL getType();
76     virtual FieldAccessMode SAL_CALL getAccessMode();
77     virtual Any SAL_CALL get( const Any & rObj );
78     virtual void SAL_CALL set( const Any & rObj, const Any & rValue );
79     // XIdlField2: getType, getAccessMode and get are equal to XIdlField
80     virtual void SAL_CALL set( Any & rObj, const Any & rValue );
81 
82 private:
83     void checkException(
84         uno_Any * exception, Reference< XInterface > const & context);
85 };
86 
87 // XInterface
88 //__________________________________________________________________________________________________
queryInterface(const Type & rType)89 Any IdlAttributeFieldImpl::queryInterface( const Type & rType )
90 {
91     Any aRet( ::cppu::queryInterface( rType,
92                                       static_cast< XIdlField * >( this ),
93                                       static_cast< XIdlField2 * >( this ) ) );
94     return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
95 }
96 //__________________________________________________________________________________________________
acquire()97 void IdlAttributeFieldImpl::acquire() throw()
98 {
99     IdlMemberImpl::acquire();
100 }
101 //__________________________________________________________________________________________________
release()102 void IdlAttributeFieldImpl::release() throw()
103 {
104     IdlMemberImpl::release();
105 }
106 
107 // XTypeProvider
108 //__________________________________________________________________________________________________
getTypes()109 Sequence< Type > IdlAttributeFieldImpl::getTypes()
110 {
111     static OTypeCollection * s_pTypes = 0;
112     if (! s_pTypes)
113     {
114         MutexGuard aGuard( getMutexAccess() );
115         if (! s_pTypes)
116         {
117             static OTypeCollection s_aTypes(
118                 ::getCppuType( (const Reference< XIdlField2 > *)0 ),
119                 ::getCppuType( (const Reference< XIdlField > *)0 ),
120                 IdlMemberImpl::getTypes() );
121             s_pTypes = &s_aTypes;
122         }
123     }
124     return s_pTypes->getTypes();
125 }
126 //__________________________________________________________________________________________________
getImplementationId()127 Sequence< sal_Int8 > IdlAttributeFieldImpl::getImplementationId()
128 {
129     static OImplementationId * s_pId = 0;
130     if (! s_pId)
131     {
132         MutexGuard aGuard( getMutexAccess() );
133         if (! s_pId)
134         {
135             static OImplementationId s_aId;
136             s_pId = &s_aId;
137         }
138     }
139     return s_pId->getImplementationId();
140 }
141 
142 // XIdlMember
143 //__________________________________________________________________________________________________
getDeclaringClass()144 Reference< XIdlClass > IdlAttributeFieldImpl::getDeclaringClass()
145 {
146     if (! _xDeclClass.is())
147     {
148         MutexGuard aGuard( getMutexAccess() );
149         if (! _xDeclClass.is())
150         {
151             rtl::OUString aName(getAttributeTypeDescr()->aBase.aBase.pTypeName);
152             sal_Int32 i = aName.indexOf(':');
153             OSL_ASSERT(i >= 0);
154             _xDeclClass = getReflection()->forName(aName.copy(0, i));
155         }
156     }
157     return _xDeclClass;
158 }
159 //__________________________________________________________________________________________________
getName()160 OUString IdlAttributeFieldImpl::getName()
161 {
162     return IdlMemberImpl::getName();
163 }
164 
165 // XIdlField
166 //__________________________________________________________________________________________________
getType()167 Reference< XIdlClass > IdlAttributeFieldImpl::getType()
168 {
169     return getReflection()->forType(
170         getAttributeTypeDescr()->pAttributeTypeRef );
171 }
172 //__________________________________________________________________________________________________
getAccessMode()173 FieldAccessMode IdlAttributeFieldImpl::getAccessMode()
174 {
175     return (((typelib_InterfaceAttributeTypeDescription *)getAttributeTypeDescr())->bReadOnly
176             ? FieldAccessMode_READONLY : FieldAccessMode_READWRITE);
177 }
178 //__________________________________________________________________________________________________
get(const Any & rObj)179 Any IdlAttributeFieldImpl::get( const Any & rObj )
180 {
181     uno_Interface * pUnoI = getReflection()->mapToUno(
182         rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
183     OSL_ENSURE( pUnoI, "### illegal destination object given!" );
184     if (pUnoI)
185     {
186         TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
187         typelib_TypeDescription * pTD = aTD.get();
188 
189         uno_Any aExc;
190         uno_Any * pExc = &aExc;
191         void * pReturn = alloca( pTD->nSize );
192 
193         (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), pReturn, 0, &pExc );
194         (*pUnoI->release)( pUnoI );
195 
196         checkException(
197             pExc,
198             *static_cast< Reference< XInterface > const * >(rObj.getValue()));
199         Any aRet;
200         uno_any_destruct(
201             &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
202         uno_any_constructAndConvert( &aRet, pReturn, pTD, getReflection()->getUno2Cpp().get() );
203         uno_destructData( pReturn, pTD, 0 );
204         return aRet;
205     }
206     throw IllegalArgumentException(
207         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
208         (XWeak *)(OWeakObject *)this, 0 );
209 }
210 //__________________________________________________________________________________________________
set(Any & rObj,const Any & rValue)211 void IdlAttributeFieldImpl::set( Any & rObj, const Any & rValue )
212 {
213     if (getAttributeTypeDescr()->bReadOnly)
214     {
215         throw IllegalAccessException(
216             OUString( RTL_CONSTASCII_USTRINGPARAM("cannot set readonly attribute!") ),
217             (XWeak *)(OWeakObject *)this );
218     }
219 
220     uno_Interface * pUnoI = getReflection()->mapToUno(
221         rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
222     OSL_ENSURE( pUnoI, "### illegal destination object given!" );
223     if (pUnoI)
224     {
225         TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
226         typelib_TypeDescription * pTD = aTD.get();
227 
228         // construct uno value to be set
229         void * pArgs[1];
230         void * pArg = pArgs[0] = alloca( pTD->nSize );
231 
232         sal_Bool bAssign;
233         if (pTD->eTypeClass == typelib_TypeClass_ANY)
234         {
235             uno_copyAndConvertData( pArg, SAL_CONST_CAST( Any *, &rValue ),
236                                     pTD, getReflection()->getCpp2Uno().get() );
237             bAssign = sal_True;
238         }
239         else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef ))
240         {
241             uno_copyAndConvertData( pArg, SAL_CONST_CAST( void *, rValue.getValue() ),
242                                     pTD, getReflection()->getCpp2Uno().get() );
243             bAssign = sal_True;
244         }
245         else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
246         {
247             Reference< XInterface > xObj;
248             bAssign = extract(
249                 rValue, (typelib_InterfaceTypeDescription *)pTD, xObj,
250                 getReflection() );
251             if (bAssign)
252             {
253                 *(void **)pArg = getReflection()->getCpp2Uno().mapInterface(
254                     xObj.get(), (typelib_InterfaceTypeDescription *)pTD );
255             }
256         }
257         else
258         {
259             typelib_TypeDescription * pValueTD = 0;
260             TYPELIB_DANGER_GET( &pValueTD, rValue.getValueTypeRef() );
261             // construct temp uno val to do proper assignment: todo opt
262             void * pTemp = alloca( pValueTD->nSize );
263             uno_copyAndConvertData(
264                 pTemp, (void *)rValue.getValue(), pValueTD, getReflection()->getCpp2Uno().get() );
265             uno_constructData(
266                 pArg, pTD );
267             // assignment does simple conversion
268             bAssign = uno_assignData(
269                 pArg, pTD, pTemp, pValueTD, 0, 0, 0 );
270             uno_destructData(
271                 pTemp, pValueTD, 0 );
272             TYPELIB_DANGER_RELEASE( pValueTD );
273         }
274 
275         if (bAssign)
276         {
277             uno_Any aExc;
278             uno_Any * pExc = &aExc;
279             (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), 0, pArgs, &pExc );
280             (*pUnoI->release)( pUnoI );
281 
282             uno_destructData( pArg, pTD, 0 );
283             checkException(
284                 pExc,
285                 *static_cast< Reference< XInterface > const * >(
286                     rObj.getValue()));
287             return;
288         }
289         (*pUnoI->release)( pUnoI );
290 
291         throw IllegalArgumentException(
292             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
293             *(const Reference< XInterface > *)rObj.getValue(), 1 );
294     }
295     throw IllegalArgumentException(
296         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ),
297         (XWeak *)(OWeakObject *)this, 0 );
298 }
299 //__________________________________________________________________________________________________
set(const Any & rObj,const Any & rValue)300 void IdlAttributeFieldImpl::set( const Any & rObj, const Any & rValue )
301 {
302     IdlAttributeFieldImpl::set( const_cast< Any & >( rObj ), rValue );
303 }
304 
checkException(uno_Any * exception,Reference<XInterface> const & context)305 void IdlAttributeFieldImpl::checkException(
306     uno_Any * exception, Reference< XInterface > const & context)
307 {
308     if (exception != 0) {
309         Any e;
310         uno_any_destruct(&e, reinterpret_cast< uno_ReleaseFunc >(cpp_release));
311         uno_type_any_constructAndConvert(
312             &e, exception->pData, exception->pType,
313             getReflection()->getUno2Cpp().get());
314         uno_any_destruct(exception, 0);
315         if (e.isExtractableTo(
316                 getCppuType(static_cast< RuntimeException const * >(0))))
317         {
318             cppu::throwException(e);
319         } else {
320             throw WrappedTargetRuntimeException(
321                 OUString(
322                     RTL_CONSTASCII_USTRINGPARAM(
323                         "non-RuntimeException occurred when accessing an"
324                         " interface type attribute")),
325                 context, e);
326         }
327     }
328 }
329 
330 //##################################################################################################
331 //##################################################################################################
332 //##################################################################################################
333 
334 
335 //==================================================================================================
336 class IdlInterfaceMethodImpl
337     : public IdlMemberImpl
338     , public XIdlMethod
339 {
340     Sequence< Reference< XIdlClass > > * _pExceptionTypes;
341     Sequence< Reference< XIdlClass > > * _pParamTypes;
342     Sequence< ParamInfo > *              _pParamInfos;
343 
344 public:
getMethodTypeDescr()345     typelib_InterfaceMethodTypeDescription * getMethodTypeDescr()
346         { return (typelib_InterfaceMethodTypeDescription *)getTypeDescr(); }
347 
IdlInterfaceMethodImpl(IdlReflectionServiceImpl * pReflection,const OUString & rName,typelib_TypeDescription * pTypeDescr,typelib_TypeDescription * pDeclTypeDescr)348     IdlInterfaceMethodImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
349                             typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr )
350         : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
351         , _pExceptionTypes( 0 )
352         , _pParamTypes( 0 )
353         , _pParamInfos( 0 )
354         {}
355     virtual ~IdlInterfaceMethodImpl();
356 
357     // XInterface
358     virtual Any SAL_CALL queryInterface( const Type & rType );
359     virtual void SAL_CALL acquire() throw();
360     virtual void SAL_CALL release() throw();
361 
362     // XTypeProvider
363     virtual Sequence< Type > SAL_CALL getTypes();
364     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId();
365 
366     // XIdlMember
367     virtual Reference< XIdlClass > SAL_CALL getDeclaringClass();
368     virtual OUString SAL_CALL getName();
369     // XIdlMethod
370     virtual Reference< XIdlClass > SAL_CALL getReturnType();
371     virtual Sequence< Reference< XIdlClass > > SAL_CALL getParameterTypes();
372     virtual Sequence< ParamInfo > SAL_CALL getParameterInfos();
373     virtual Sequence< Reference< XIdlClass > > SAL_CALL getExceptionTypes();
374     virtual MethodMode SAL_CALL getMode();
375     virtual Any SAL_CALL invoke( const Any & rObj, Sequence< Any > & rArgs );
376 };
377 //__________________________________________________________________________________________________
~IdlInterfaceMethodImpl()378 IdlInterfaceMethodImpl::~IdlInterfaceMethodImpl()
379 {
380     delete _pParamInfos;
381     delete _pParamTypes;
382     delete _pExceptionTypes;
383 }
384 
385 // XInterface
386 //__________________________________________________________________________________________________
queryInterface(const Type & rType)387 Any IdlInterfaceMethodImpl::queryInterface( const Type & rType )
388 {
389     Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlMethod * >( this ) ) );
390     return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
391 }
392 //__________________________________________________________________________________________________
acquire()393 void IdlInterfaceMethodImpl::acquire() throw()
394 {
395     IdlMemberImpl::acquire();
396 }
397 //__________________________________________________________________________________________________
release()398 void IdlInterfaceMethodImpl::release() throw()
399 {
400     IdlMemberImpl::release();
401 }
402 
403 // XTypeProvider
404 //__________________________________________________________________________________________________
getTypes()405 Sequence< Type > IdlInterfaceMethodImpl::getTypes()
406 {
407     static OTypeCollection * s_pTypes = 0;
408     if (! s_pTypes)
409     {
410         MutexGuard aGuard( getMutexAccess() );
411         if (! s_pTypes)
412         {
413             static OTypeCollection s_aTypes(
414                 ::getCppuType( (const Reference< XIdlMethod > *)0 ),
415                 IdlMemberImpl::getTypes() );
416             s_pTypes = &s_aTypes;
417         }
418     }
419     return s_pTypes->getTypes();
420 }
421 //__________________________________________________________________________________________________
getImplementationId()422 Sequence< sal_Int8 > IdlInterfaceMethodImpl::getImplementationId()
423 {
424     static OImplementationId * s_pId = 0;
425     if (! s_pId)
426     {
427         MutexGuard aGuard( getMutexAccess() );
428         if (! s_pId)
429         {
430             static OImplementationId s_aId;
431             s_pId = &s_aId;
432         }
433     }
434     return s_pId->getImplementationId();
435 }
436 
437 // XIdlMember
438 //__________________________________________________________________________________________________
getDeclaringClass()439 Reference< XIdlClass > IdlInterfaceMethodImpl::getDeclaringClass()
440 {
441     if (! _xDeclClass.is())
442     {
443         MutexGuard aGuard( getMutexAccess() );
444         if (! _xDeclClass.is())
445         {
446             rtl::OUString aName(getMethodTypeDescr()->aBase.aBase.pTypeName);
447             sal_Int32 i = aName.indexOf(':');
448             OSL_ASSERT(i >= 0);
449             _xDeclClass = getReflection()->forName(aName.copy(0, i));
450         }
451     }
452     return _xDeclClass;
453 }
454 //__________________________________________________________________________________________________
getName()455 OUString IdlInterfaceMethodImpl::getName()
456 {
457     return IdlMemberImpl::getName();
458 }
459 
460 // XIdlMethod
461 //__________________________________________________________________________________________________
getReturnType()462 Reference< XIdlClass > SAL_CALL IdlInterfaceMethodImpl::getReturnType()
463 {
464     return getReflection()->forType( getMethodTypeDescr()->pReturnTypeRef );
465 }
466 //__________________________________________________________________________________________________
getExceptionTypes()467 Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getExceptionTypes()
468 {
469     if (! _pExceptionTypes)
470     {
471         MutexGuard aGuard( getMutexAccess() );
472         if (! _pExceptionTypes)
473         {
474             sal_Int32 nExc = getMethodTypeDescr()->nExceptions;
475             Sequence< Reference< XIdlClass > > * pTempExceptionTypes =
476                 new Sequence< Reference< XIdlClass > >( nExc );
477             Reference< XIdlClass > * pExceptionTypes = pTempExceptionTypes->getArray();
478 
479             typelib_TypeDescriptionReference ** ppExc =
480                 getMethodTypeDescr()->ppExceptions;
481             IdlReflectionServiceImpl * pRefl = getReflection();
482 
483             while (nExc--)
484                 pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] );
485 
486             _pExceptionTypes = pTempExceptionTypes;
487         }
488     }
489     return *_pExceptionTypes;
490 }
491 //__________________________________________________________________________________________________
getParameterTypes()492 Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes()
493 {
494     if (! _pParamTypes)
495     {
496         MutexGuard aGuard( getMutexAccess() );
497         if (! _pParamTypes)
498         {
499             sal_Int32 nParams = getMethodTypeDescr()->nParams;
500             Sequence< Reference< XIdlClass > > * pTempParamTypes =
501                 new Sequence< Reference< XIdlClass > >( nParams );
502             Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray();
503 
504             typelib_MethodParameter * pTypelibParams =
505                 getMethodTypeDescr()->pParams;
506             IdlReflectionServiceImpl * pRefl = getReflection();
507 
508             while (nParams--)
509                 pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef );
510 
511             _pParamTypes = pTempParamTypes;
512         }
513     }
514     return *_pParamTypes;
515 }
516 //__________________________________________________________________________________________________
getParameterInfos()517 Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos()
518 {
519     if (! _pParamInfos)
520     {
521         MutexGuard aGuard( getMutexAccess() );
522         if (! _pParamInfos)
523         {
524             sal_Int32 nParams = getMethodTypeDescr()->nParams;
525             Sequence< ParamInfo > * pTempParamInfos = new Sequence< ParamInfo >( nParams );
526             ParamInfo * pParamInfos = pTempParamInfos->getArray();
527 
528             typelib_MethodParameter * pTypelibParams =
529                 getMethodTypeDescr()->pParams;
530 
531             if (_pParamTypes) // use param types
532             {
533                 const Reference< XIdlClass > * pParamTypes = _pParamTypes->getConstArray();
534 
535                 while (nParams--)
536                 {
537                     const typelib_MethodParameter & rParam = pTypelibParams[nParams];
538                     ParamInfo & rInfo = pParamInfos[nParams];
539                     rInfo.aName = rParam.pName;
540                     if (rParam.bIn)
541                         rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
542                     else
543                         rInfo.aMode = ParamMode_OUT;
544                     rInfo.aType = pParamTypes[nParams];
545                 }
546             }
547             else // make also param types sequence if not already initialized
548             {
549                 Sequence< Reference< XIdlClass > > * pTempParamTypes =
550                     new Sequence< Reference< XIdlClass > >( nParams );
551                 Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray();
552 
553                 IdlReflectionServiceImpl * pRefl = getReflection();
554 
555                 while (nParams--)
556                 {
557                     const typelib_MethodParameter & rParam = pTypelibParams[nParams];
558                     ParamInfo & rInfo = pParamInfos[nParams];
559                     rInfo.aName = rParam.pName;
560                     if (rParam.bIn)
561                         rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
562                     else
563                         rInfo.aMode = ParamMode_OUT;
564                     rInfo.aType = pParamTypes[nParams] = pRefl->forType( rParam.pTypeRef );
565                 }
566 
567                 _pParamTypes = pTempParamTypes;
568             }
569 
570             _pParamInfos = pTempParamInfos;
571         }
572     }
573     return *_pParamInfos;
574 }
575 //__________________________________________________________________________________________________
getMode()576 MethodMode SAL_CALL IdlInterfaceMethodImpl::getMode()
577 {
578     return
579         getMethodTypeDescr()->bOneWay ? MethodMode_ONEWAY : MethodMode_TWOWAY;
580 }
581 //__________________________________________________________________________________________________
invoke(const Any & rObj,Sequence<Any> & rArgs)582 Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & rArgs )
583 {
584     if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
585     {
586         // acquire()/ release()
587         if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
588                                     "com.sun.star.uno.XInterface::acquire" ) == 0)
589         {
590             (*(const Reference< XInterface > *)rObj.getValue())->acquire();
591             return Any();
592         }
593         else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
594                                          "com.sun.star.uno.XInterface::release" ) == 0)
595         {
596             (*(const Reference< XInterface > *)rObj.getValue())->release();
597             return Any();
598         }
599     }
600 
601     uno_Interface * pUnoI = getReflection()->mapToUno(
602         rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
603     OSL_ENSURE( pUnoI, "### illegal destination object given!" );
604     if (pUnoI)
605     {
606         sal_Int32 nParams = getMethodTypeDescr()->nParams;
607         if (rArgs.getLength() != nParams)
608         {
609             (*pUnoI->release)( pUnoI );
610             throw IllegalArgumentException(
611                 OUString( RTL_CONSTASCII_USTRINGPARAM("arguments len differ!") ),
612                 *(const Reference< XInterface > *)rObj.getValue(), 1 );
613         }
614 
615         Any * pCppArgs = rArgs.getArray();
616         typelib_MethodParameter * pParams = getMethodTypeDescr()->pParams;
617         typelib_TypeDescription * pReturnType = 0;
618         TYPELIB_DANGER_GET(
619             &pReturnType, getMethodTypeDescr()->pReturnTypeRef );
620 
621         void * pUnoReturn = alloca( pReturnType->nSize );
622         void ** ppUnoArgs = (void **)alloca( sizeof(void *) * nParams *2 );
623         typelib_TypeDescription ** ppParamTypes = (typelib_TypeDescription **)(ppUnoArgs + nParams);
624 
625         // convert arguments
626         for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
627         {
628             ppParamTypes[nPos] = 0;
629             TYPELIB_DANGER_GET( ppParamTypes + nPos, pParams[nPos].pTypeRef );
630             typelib_TypeDescription * pTD = ppParamTypes[nPos];
631 
632             ppUnoArgs[nPos] = alloca( pTD->nSize );
633             if (pParams[nPos].bIn)
634             {
635                 sal_Bool bAssign;
636                 if (typelib_typedescriptionreference_equals(
637                         pCppArgs[nPos].getValueTypeRef(), pTD->pWeakRef ))
638                 {
639                     uno_type_copyAndConvertData(
640                         ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(),
641                         pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
642                     bAssign = sal_True;
643                 }
644                 else if (pTD->eTypeClass == typelib_TypeClass_ANY)
645                 {
646                     uno_type_any_constructAndConvert(
647                         (uno_Any *)ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(),
648                         pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
649                     bAssign = sal_True;
650                 }
651                 else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
652                 {
653                     Reference< XInterface > xDest;
654                     bAssign = extract(
655                         pCppArgs[nPos], (typelib_InterfaceTypeDescription *)pTD,
656                         xDest, getReflection() );
657                     if (bAssign)
658                     {
659                         *(void **)ppUnoArgs[nPos] = getReflection()->getCpp2Uno().mapInterface(
660                             xDest.get(), (typelib_InterfaceTypeDescription *)pTD );
661                     }
662                 }
663                 else
664                 {
665                     typelib_TypeDescription * pValueTD = 0;
666                     TYPELIB_DANGER_GET( &pValueTD, pCppArgs[nPos].getValueTypeRef() );
667                     // construct temp uno val to do proper assignment: todo opt
668                     void * pTemp = alloca( pValueTD->nSize );
669                     uno_copyAndConvertData(
670                         pTemp, (void *)pCppArgs[nPos].getValue(), pValueTD,
671                         getReflection()->getCpp2Uno().get() );
672                     uno_constructData(
673                         ppUnoArgs[nPos], pTD );
674                     // assignment does simple conversion
675                     bAssign = uno_assignData(
676                         ppUnoArgs[nPos], pTD, pTemp, pValueTD, 0, 0, 0 );
677                     uno_destructData(
678                         pTemp, pValueTD, 0 );
679                     TYPELIB_DANGER_RELEASE( pValueTD );
680                 }
681 
682                 if (! bAssign)
683                 {
684                     IllegalArgumentException aExc(
685                         OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce argument type during corereflection call!") ),
686                         *(const Reference< XInterface > *)rObj.getValue(), (sal_Int16)nPos );
687 
688                     // cleanup
689                     while (nPos--)
690                     {
691                         if (pParams[nPos].bIn)
692                             uno_destructData( ppUnoArgs[nPos], ppParamTypes[nPos], 0 );
693                         TYPELIB_DANGER_RELEASE( ppParamTypes[nPos] );
694                     }
695                     TYPELIB_DANGER_RELEASE( pReturnType );
696                     (*pUnoI->release)( pUnoI );
697 
698                     throw aExc;
699                 }
700             }
701         }
702 
703         uno_Any aUnoExc;
704         uno_Any * pUnoExc = &aUnoExc;
705 
706         (*pUnoI->pDispatcher)(
707             pUnoI, getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc );
708         (*pUnoI->release)( pUnoI );
709 
710         Any aRet;
711         if (pUnoExc)
712         {
713             // cleanup
714             while (nParams--)
715             {
716                 if (pParams[nParams].bIn)
717                     uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 );
718                 TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] );
719             }
720             TYPELIB_DANGER_RELEASE( pReturnType );
721 
722             InvocationTargetException aExc;
723             aExc.Context = *(const Reference< XInterface > *)rObj.getValue();
724             aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("exception occurred during invocation!") );
725             uno_any_destruct(
726                 &aExc.TargetException,
727                 reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
728             uno_type_copyAndConvertData(
729                 &aExc.TargetException, pUnoExc, ::getCppuType( (const Any *)0 ).getTypeLibType(),
730                 getReflection()->getUno2Cpp().get() );
731             uno_any_destruct( pUnoExc, 0 );
732             throw aExc;
733         }
734         else
735         {
736             // reconvert arguments and cleanup
737             while (nParams--)
738             {
739                 if (pParams[nParams].bOut) // write back
740                 {
741                     uno_any_destruct(
742                         &pCppArgs[nParams],
743                         reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
744                     uno_any_constructAndConvert(
745                         &pCppArgs[nParams], ppUnoArgs[nParams], ppParamTypes[nParams],
746                         getReflection()->getUno2Cpp().get() );
747                 }
748                 uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 );
749                 TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] );
750             }
751             uno_any_destruct(
752                 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
753             uno_any_constructAndConvert(
754                 &aRet, pUnoReturn, pReturnType,
755                 getReflection()->getUno2Cpp().get() );
756             uno_destructData( pUnoReturn, pReturnType, 0 );
757             TYPELIB_DANGER_RELEASE( pReturnType );
758         }
759         return aRet;
760     }
761     throw IllegalArgumentException(
762         OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ),
763         (XWeak *)(OWeakObject *)this, 0 );
764 }
765 
766 
767 //##################################################################################################
768 //##################################################################################################
769 //##################################################################################################
770 
771 
772 //__________________________________________________________________________________________________
~InterfaceIdlClassImpl()773 InterfaceIdlClassImpl::~InterfaceIdlClassImpl()
774 {
775     for ( sal_Int32 nPos = _nMethods + _nAttributes; nPos--; )
776         typelib_typedescription_release( _pSortedMemberInit[nPos].second );
777 
778     delete [] _pSortedMemberInit;
779 }
780 
781 //__________________________________________________________________________________________________
getSuperclasses()782 Sequence< Reference< XIdlClass > > InterfaceIdlClassImpl::getSuperclasses()
783 {
784     MutexGuard aGuard(getMutexAccess());
785     if (_xSuperClasses.getLength() == 0) {
786         typelib_InterfaceTypeDescription * pType = getTypeDescr();
787         _xSuperClasses.realloc(pType->nBaseTypes);
788         for (sal_Int32 i = 0; i < pType->nBaseTypes; ++i) {
789             _xSuperClasses[i] = getReflection()->forType(
790                 &pType->ppBaseTypes[i]->aBase);
791             OSL_ASSERT(_xSuperClasses[i].is());
792         }
793     }
794     return Sequence< Reference< XIdlClass > >(_xSuperClasses);
795 }
796 //__________________________________________________________________________________________________
initMembers()797 void InterfaceIdlClassImpl::initMembers()
798 {
799     sal_Int32 nAll = getTypeDescr()->nAllMembers;
800     MemberInit * pSortedMemberInit = new MemberInit[nAll];
801     typelib_TypeDescriptionReference ** ppAllMembers = getTypeDescr()->ppAllMembers;
802 
803     for ( sal_Int32 nPos = 0; nPos < nAll; ++nPos )
804     {
805         sal_Int32 nIndex;
806         if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
807         {
808             // methods to front
809             nIndex = _nMethods;
810             ++_nMethods;
811         }
812         else
813         {
814             ++_nAttributes;
815             nIndex = (nAll - _nAttributes);
816             // attributes at the back
817         }
818 
819         typelib_TypeDescription * pTD = 0;
820         typelib_typedescriptionreference_getDescription( &pTD, ppAllMembers[nPos] );
821         OSL_ENSURE( pTD, "### cannot get type description!" );
822         pSortedMemberInit[nIndex].first = ((typelib_InterfaceMemberTypeDescription *)pTD)->pMemberName;
823         pSortedMemberInit[nIndex].second = pTD;
824     }
825 
826     _pSortedMemberInit = pSortedMemberInit;
827 }
828 //__________________________________________________________________________________________________
isAssignableFrom(const Reference<XIdlClass> & xType)829 sal_Bool InterfaceIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
830 {
831     if (xType.is() && xType->getTypeClass() == TypeClass_INTERFACE)
832     {
833         if (equals( xType ))
834             return sal_True;
835         else
836         {
837             const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
838             for (sal_Int32 i = 0; i < rSeq.getLength(); ++i) {
839                 if (isAssignableFrom(rSeq[i])) {
840                     return true;
841                 }
842             }
843         }
844     }
845     return sal_False;
846 }
847 //__________________________________________________________________________________________________
getUik()848 Uik InterfaceIdlClassImpl::getUik()
849 {
850     return Uik(0, 0, 0, 0, 0);
851         // Uiks are deprecated and this function must not be called
852 }
853 //__________________________________________________________________________________________________
getMethods()854 Sequence< Reference< XIdlMethod > > InterfaceIdlClassImpl::getMethods()
855 {
856     MutexGuard aGuard( getMutexAccess() );
857     if (! _pSortedMemberInit)
858         initMembers();
859 
860     // create methods sequence
861     Sequence< Reference< XIdlMethod > > aRet( _nMethods );
862     Reference< XIdlMethod > * pRet = aRet.getArray();
863     for ( sal_Int32 nPos = _nMethods; nPos--; )
864     {
865 
866         /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet[nPos] = new IdlInterfaceMethodImpl(
867             getReflection(), _pSortedMemberInit[nPos].first,
868             _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() );
869     }
870     return aRet;
871 }
872 //__________________________________________________________________________________________________
getFields()873 Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields()
874 {
875     MutexGuard aGuard( getMutexAccess() );
876     if (! _pSortedMemberInit)
877         initMembers();
878 
879     // create fields sequence
880     Sequence< Reference< XIdlField > > aRet( _nAttributes );
881     Reference< XIdlField > * pRet = aRet.getArray();
882     for ( sal_Int32 nPos = _nAttributes; nPos--; )
883     {
884         /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet[_nAttributes-nPos-1] =
885             new IdlAttributeFieldImpl(
886                 getReflection(), _pSortedMemberInit[_nMethods+nPos].first,
887                 _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() );
888     }
889     return aRet;
890 }
891 //__________________________________________________________________________________________________
getMethod(const OUString & rName)892 Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName )
893 {
894     MutexGuard aGuard( getMutexAccess() );
895     if (! _pSortedMemberInit)
896         initMembers();
897 
898     Reference< XIdlMethod > xRet;
899 
900     // try weak map
901     const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) );
902     if (iFind != _aName2Method.end())
903         xRet = (*iFind).second; // harden ref
904 
905     if (! xRet.is())
906     {
907         for ( sal_Int32 nPos = _nMethods; nPos--; )
908         {
909             if (_pSortedMemberInit[nPos].first == rName)
910             {
911                 _aName2Method[rName] = xRet = new IdlInterfaceMethodImpl(
912                     getReflection(), rName,
913                     _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() );
914                 break;
915             }
916         }
917     }
918     return xRet;
919 }
920 //__________________________________________________________________________________________________
getField(const OUString & rName)921 Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName )
922 {
923     MutexGuard aGuard( getMutexAccess() );
924     if (! _pSortedMemberInit)
925         initMembers();
926 
927     Reference< XIdlField > xRet;
928 
929     // try weak map
930     const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
931     if (iFind != _aName2Field.end())
932         xRet = (*iFind).second; // harden ref
933 
934     if (! xRet.is())
935     {
936         for ( sal_Int32 nPos = _nAttributes; nPos--; )
937         {
938             if (_pSortedMemberInit[_nMethods+nPos].first == rName)
939             {
940                 _aName2Field[rName] = xRet = new IdlAttributeFieldImpl(
941                     getReflection(), rName,
942                     _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() );
943                 break;
944             }
945         }
946     }
947     return xRet;
948 }
949 //__________________________________________________________________________________________________
createObject(Any & rObj)950 void InterfaceIdlClassImpl::createObject( Any & rObj )
951 {
952     // interfaces cannot be constructed
953     rObj.clear();
954 }
955 
956 }
957