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 occurred 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 occurred 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