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