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