update dev300-m58
[ooovba.git] / stoc / source / corereflection / crcomp.cxx
blobe44ce89d6b78c34152441b98fcf4cf310bba1074
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: crcomp.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
33 #include <rtl/strbuf.hxx>
35 #include <com/sun/star/reflection/XIdlField.hpp>
36 #include <com/sun/star/reflection/XIdlField2.hpp>
37 #include "com/sun/star/uno/TypeClass.hpp"
39 #include "base.hxx"
42 namespace stoc_corefl
45 //==================================================================================================
46 class IdlCompFieldImpl
47 : public IdlMemberImpl
48 , public XIdlField
49 , public XIdlField2
51 sal_Int32 _nOffset;
53 public:
54 IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
55 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
56 sal_Int32 nOffset )
57 : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
58 , _nOffset( nOffset )
61 // XInterface
62 virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException);
63 virtual void SAL_CALL acquire() throw ();
64 virtual void SAL_CALL release() throw ();
66 // XTypeProvider
67 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
68 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
70 // XIdlMember
71 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
72 virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
73 // XIdlField
74 virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
75 virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
76 virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
77 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);
78 // XIdlField2: getType, getAccessMode and get are equal to XIdlField
79 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);
82 // XInterface
83 //__________________________________________________________________________________________________
84 Any IdlCompFieldImpl::queryInterface( const Type & rType )
85 throw(::com::sun::star::uno::RuntimeException)
87 Any aRet( ::cppu::queryInterface( rType,
88 static_cast< XIdlField * >( this ),
89 static_cast< XIdlField2 * >( this ) ) );
90 return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
92 //__________________________________________________________________________________________________
93 void IdlCompFieldImpl::acquire() throw()
95 IdlMemberImpl::acquire();
97 //__________________________________________________________________________________________________
98 void IdlCompFieldImpl::release() throw()
100 IdlMemberImpl::release();
103 // XTypeProvider
104 //__________________________________________________________________________________________________
105 Sequence< Type > IdlCompFieldImpl::getTypes()
106 throw (::com::sun::star::uno::RuntimeException)
108 static OTypeCollection * s_pTypes = 0;
109 if (! s_pTypes)
111 MutexGuard aGuard( getMutexAccess() );
112 if (! s_pTypes)
114 static OTypeCollection s_aTypes(
115 ::getCppuType( (const Reference< XIdlField2 > *)0 ),
116 ::getCppuType( (const Reference< XIdlField > *)0 ),
117 IdlMemberImpl::getTypes() );
118 s_pTypes = &s_aTypes;
121 return s_pTypes->getTypes();
123 //__________________________________________________________________________________________________
124 Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId()
125 throw (::com::sun::star::uno::RuntimeException)
127 static OImplementationId * s_pId = 0;
128 if (! s_pId)
130 MutexGuard aGuard( getMutexAccess() );
131 if (! s_pId)
133 static OImplementationId s_aId;
134 s_pId = &s_aId;
137 return s_pId->getImplementationId();
140 // XIdlMember
141 //__________________________________________________________________________________________________
142 Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass()
143 throw(::com::sun::star::uno::RuntimeException)
145 if (! _xDeclClass.is())
147 MutexGuard aGuard( getMutexAccess() );
148 if (! _xDeclClass.is())
150 typelib_CompoundTypeDescription * pTD =
151 (typelib_CompoundTypeDescription *)getDeclTypeDescr();
152 while (pTD)
154 typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs;
155 for ( sal_Int32 nPos = pTD->nMembers; nPos--; )
157 if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] ))
159 _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD );
160 return _xDeclClass;
163 pTD = pTD->pBaseTypeDescription;
167 return _xDeclClass;
169 //__________________________________________________________________________________________________
170 OUString IdlCompFieldImpl::getName()
171 throw(::com::sun::star::uno::RuntimeException)
173 return IdlMemberImpl::getName();
176 // XIdlField
177 //__________________________________________________________________________________________________
178 Reference< XIdlClass > IdlCompFieldImpl::getType()
179 throw(::com::sun::star::uno::RuntimeException)
181 return getReflection()->forType( getTypeDescr() );
183 //__________________________________________________________________________________________________
184 FieldAccessMode IdlCompFieldImpl::getAccessMode()
185 throw(::com::sun::star::uno::RuntimeException)
187 return FieldAccessMode_READWRITE;
189 //__________________________________________________________________________________________________
190 Any IdlCompFieldImpl::get( const Any & rObj )
191 throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
193 if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
194 rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
196 typelib_TypeDescription * pObjTD = 0;
197 TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
199 typelib_TypeDescription * pTD = pObjTD;
200 typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
201 while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
202 pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
204 OSL_ENSURE( pTD, "### illegal object type!" );
205 if (pTD)
207 TYPELIB_DANGER_RELEASE( pObjTD );
208 Any aRet;
209 uno_any_destruct(
210 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
211 uno_any_construct(
212 &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(),
213 reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
214 return aRet;
216 TYPELIB_DANGER_RELEASE( pObjTD );
218 throw IllegalArgumentException(
219 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
220 (XWeak *)(OWeakObject *)this, 0 );
222 //__________________________________________________________________________________________________
223 void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue )
224 throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
226 if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
227 rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
229 typelib_TypeDescription * pObjTD = 0;
230 TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
232 typelib_TypeDescription * pTD = pObjTD;
233 typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
234 while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
235 pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
237 OSL_ENSURE( pTD, "### illegal object type!" );
238 if (pTD)
240 TYPELIB_DANGER_RELEASE( pObjTD );
241 if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
243 return;
245 else
247 throw IllegalArgumentException(
248 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
249 (XWeak *)(OWeakObject *)this, 1 );
252 TYPELIB_DANGER_RELEASE( pObjTD );
254 throw IllegalArgumentException(
255 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
256 (XWeak *)(OWeakObject *)this, 0 );
259 //__________________________________________________________________________________________________
260 void IdlCompFieldImpl::set( Any & rObj, const Any & rValue )
261 throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
263 if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
264 rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
266 typelib_TypeDescription * pObjTD = 0;
267 TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
269 typelib_TypeDescription * pTD = pObjTD;
270 typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
271 while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
272 pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
274 OSL_ENSURE( pTD, "### illegal object type!" );
275 if (pTD)
277 TYPELIB_DANGER_RELEASE( pObjTD );
278 if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
280 return;
282 else
284 throw IllegalArgumentException(
285 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
286 (XWeak *)(OWeakObject *)this, 1 );
289 TYPELIB_DANGER_RELEASE( pObjTD );
291 throw IllegalArgumentException(
292 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
293 (XWeak *)(OWeakObject *)this, 0 );
296 //##################################################################################################
297 //##################################################################################################
298 //##################################################################################################
301 //__________________________________________________________________________________________________
302 CompoundIdlClassImpl::~CompoundIdlClassImpl()
304 delete _pFields;
307 //__________________________________________________________________________________________________
308 sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
309 throw(::com::sun::star::uno::RuntimeException)
311 if (xType.is())
313 TypeClass eTC = xType->getTypeClass();
314 if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
316 if (equals( xType ))
317 return sal_True;
318 else
320 const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
321 if (rSeq.getLength())
323 OSL_ENSURE( rSeq.getLength() == 1, "### unexpected len of super classes!" );
324 return isAssignableFrom( rSeq[0] );
329 return sal_False;
331 //__________________________________________________________________________________________________
332 Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses()
333 throw(::com::sun::star::uno::RuntimeException)
335 if (! _xSuperClass.is())
337 MutexGuard aGuard( getMutexAccess() );
338 if (! _xSuperClass.is())
340 typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription;
341 if (pCompTypeDescr)
342 _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr );
345 if (_xSuperClass.is())
346 return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
347 else
348 return Sequence< Reference< XIdlClass > >();
350 //__________________________________________________________________________________________________
351 Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
352 throw(::com::sun::star::uno::RuntimeException)
354 if (! _pFields)
355 getFields(); // init fields
357 const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
358 if (iFind != _aName2Field.end())
359 return Reference< XIdlField >( (*iFind).second );
360 else
361 return Reference< XIdlField >();
363 //__________________________________________________________________________________________________
364 Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
365 throw(::com::sun::star::uno::RuntimeException)
367 MutexGuard aGuard( getMutexAccess() );
368 if (! _pFields)
370 sal_Int32 nAll = 0;
371 typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr();
372 for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
373 nAll += pCompTypeDescr->nMembers;
375 Sequence< Reference< XIdlField > > * pFields =
376 new Sequence< Reference< XIdlField > >( nAll );
377 Reference< XIdlField > * pSeq = pFields->getArray();
379 for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr;
380 pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
382 typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
383 rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames;
384 sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets;
386 for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
388 typelib_TypeDescription * pTD = 0;
389 TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] );
390 OSL_ENSURE( pTD, "### cannot get field in struct!" );
391 if (pTD)
393 OUString aName( ppNames[nPos] );
394 _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl(
395 getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] );
396 TYPELIB_DANGER_RELEASE( pTD );
401 _pFields = pFields;
403 return *_pFields;