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