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