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