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