1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <cppuhelper/queryinterface.hxx>
21 #include <cppuhelper/typeprovider.hxx>
23 #include <com/sun/star/reflection/XIdlField.hpp>
24 #include <com/sun/star/reflection/XIdlField2.hpp>
25 #include <com/sun/star/uno/TypeClass.hpp>
29 using namespace css::lang
;
30 using namespace css::reflection
;
31 using namespace css::uno
;
38 class IdlCompFieldImpl
39 : public IdlMemberImpl
46 IdlCompFieldImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
47 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
,
49 : IdlMemberImpl( pReflection
, rName
, pTypeDescr
, pDeclTypeDescr
)
54 virtual Any SAL_CALL
queryInterface( const Type
& rType
) override
;
55 virtual void SAL_CALL
acquire() throw () override
;
56 virtual void SAL_CALL
release() throw () override
;
59 virtual Sequence
< Type
> SAL_CALL
getTypes() override
;
60 virtual Sequence
< sal_Int8
> SAL_CALL
getImplementationId() override
;
63 virtual Reference
< XIdlClass
> SAL_CALL
getDeclaringClass() override
;
64 virtual OUString SAL_CALL
getName() override
;
66 virtual Reference
< XIdlClass
> SAL_CALL
getType() override
;
67 virtual FieldAccessMode SAL_CALL
getAccessMode() override
;
68 virtual Any SAL_CALL
get( const Any
& rObj
) override
;
69 virtual void SAL_CALL
set( const Any
& rObj
, const Any
& rValue
) override
;
70 // XIdlField2: getType, getAccessMode and get are equal to XIdlField
71 virtual void SAL_CALL
set( Any
& rObj
, const Any
& rValue
) override
;
78 Any
IdlCompFieldImpl::queryInterface( const Type
& rType
)
80 Any
aRet( ::cppu::queryInterface( rType
,
81 static_cast< XIdlField
* >( this ),
82 static_cast< XIdlField2
* >( this ) ) );
83 return (aRet
.hasValue() ? aRet
: IdlMemberImpl::queryInterface( rType
));
86 void IdlCompFieldImpl::acquire() throw()
88 IdlMemberImpl::acquire();
91 void IdlCompFieldImpl::release() throw()
93 IdlMemberImpl::release();
98 Sequence
< Type
> IdlCompFieldImpl::getTypes()
100 static cppu::OTypeCollection
s_aTypes(
101 cppu::UnoType
<XIdlField2
>::get(),
102 cppu::UnoType
<XIdlField
>::get(),
103 IdlMemberImpl::getTypes() );
105 return s_aTypes
.getTypes();
108 Sequence
< sal_Int8
> IdlCompFieldImpl::getImplementationId()
110 return css::uno::Sequence
<sal_Int8
>();
115 Reference
< XIdlClass
> IdlCompFieldImpl::getDeclaringClass()
117 if (! _xDeclClass
.is())
119 ::osl::MutexGuard
aGuard( getMutexAccess() );
120 if (! _xDeclClass
.is())
122 typelib_CompoundTypeDescription
* pTD
=
123 reinterpret_cast<typelib_CompoundTypeDescription
*>(getDeclTypeDescr());
126 typelib_TypeDescriptionReference
** ppTypeRefs
= pTD
->ppTypeRefs
;
127 for ( sal_Int32 nPos
= pTD
->nMembers
; nPos
--; )
129 if (td_equals( getTypeDescr(), ppTypeRefs
[nPos
] ))
131 _xDeclClass
= getReflection()->forType( &pTD
->aBase
);
135 pTD
= pTD
->pBaseTypeDescription
;
142 OUString
IdlCompFieldImpl::getName()
144 return IdlMemberImpl::getName();
149 Reference
< XIdlClass
> IdlCompFieldImpl::getType()
151 return getReflection()->forType( getTypeDescr() );
154 FieldAccessMode
IdlCompFieldImpl::getAccessMode()
156 return FieldAccessMode_READWRITE
;
159 Any
IdlCompFieldImpl::get( const Any
& rObj
)
161 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
162 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
164 typelib_TypeDescription
* pObjTD
= nullptr;
165 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
167 typelib_TypeDescription
* pTD
= pObjTD
;
168 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
169 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
170 pTD
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
172 OSL_ENSURE( pTD
, "### illegal object type!" );
175 TYPELIB_DANGER_RELEASE( pObjTD
);
178 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
180 &aRet
, const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(),
181 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
184 TYPELIB_DANGER_RELEASE( pObjTD
);
186 throw IllegalArgumentException(
187 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
188 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
191 void IdlCompFieldImpl::set( const Any
& rObj
, const Any
& rValue
)
193 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
194 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
196 typelib_TypeDescription
* pObjTD
= nullptr;
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
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
204 OSL_ENSURE( pTD
, "### illegal object type!" );
207 TYPELIB_DANGER_RELEASE( pObjTD
);
208 if (!coerce_assign( const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(), rValue
, getReflection() ))
210 throw IllegalArgumentException(
211 "cannot assign value to destination",
212 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 1 );
216 TYPELIB_DANGER_RELEASE( pObjTD
);
218 throw IllegalArgumentException(
219 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
220 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
224 void IdlCompFieldImpl::set( Any
& rObj
, const Any
& rValue
)
226 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
227 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
229 typelib_TypeDescription
* pObjTD
= nullptr;
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
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
237 OSL_ENSURE( pTD
, "### illegal object type!" );
240 TYPELIB_DANGER_RELEASE( pObjTD
);
241 if (!coerce_assign( const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(), rValue
, getReflection() ))
243 throw IllegalArgumentException(
244 "cannot assign to destination",
245 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 1 );
249 TYPELIB_DANGER_RELEASE( pObjTD
);
251 throw IllegalArgumentException(
252 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
253 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
257 CompoundIdlClassImpl::~CompoundIdlClassImpl()
262 sal_Bool
CompoundIdlClassImpl::isAssignableFrom( const Reference
< XIdlClass
> & xType
)
266 TypeClass eTC
= xType
->getTypeClass();
267 if (eTC
== TypeClass_STRUCT
|| eTC
== TypeClass_EXCEPTION
)
273 const Sequence
< Reference
< XIdlClass
> > & rSeq
= xType
->getSuperclasses();
274 if (rSeq
.hasElements())
276 OSL_ENSURE( rSeq
.getLength() == 1, "### unexpected len of super classes!" );
277 return isAssignableFrom( rSeq
[0] );
285 Sequence
< Reference
< XIdlClass
> > CompoundIdlClassImpl::getSuperclasses()
287 if (! _xSuperClass
.is())
289 ::osl::MutexGuard
aGuard( getMutexAccess() );
290 if (! _xSuperClass
.is())
292 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr()->pBaseTypeDescription
;
294 _xSuperClass
= getReflection()->forType( &pCompTypeDescr
->aBase
);
297 if (_xSuperClass
.is())
298 return Sequence
< Reference
< XIdlClass
> >( &_xSuperClass
, 1 );
300 return Sequence
< Reference
< XIdlClass
> >();
303 Reference
< XIdlField
> CompoundIdlClassImpl::getField( const OUString
& rName
)
306 getFields(); // init fields
308 const OUString2Field::const_iterator
iFind( _aName2Field
.find( rName
) );
309 if (iFind
!= _aName2Field
.end())
310 return Reference
< XIdlField
>( (*iFind
).second
);
312 return Reference
< XIdlField
>();
315 Sequence
< Reference
< XIdlField
> > CompoundIdlClassImpl::getFields()
317 ::osl::MutexGuard
aGuard( getMutexAccess() );
321 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr();
322 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
323 nAll
+= pCompTypeDescr
->nMembers
;
325 Sequence
< Reference
< XIdlField
> > * pFields
=
326 new Sequence
< Reference
< XIdlField
> >( nAll
);
327 Reference
< XIdlField
> * pSeq
= pFields
->getArray();
329 for ( pCompTypeDescr
= getTypeDescr(); pCompTypeDescr
;
330 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
332 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
333 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
334 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
336 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
338 typelib_TypeDescription
* pTD
= nullptr;
339 TYPELIB_DANGER_GET( &pTD
, ppTypeRefs
[nPos
] );
340 OSL_ENSURE( pTD
, "### cannot get field in struct!" );
343 OUString
aName( ppNames
[nPos
] );
344 _aName2Field
[aName
] = pSeq
[--nAll
] = new IdlCompFieldImpl(
345 getReflection(), aName
, pTD
, IdlClassImpl::getTypeDescr(), pMemberOffsets
[nPos
] );
346 TYPELIB_DANGER_RELEASE( pTD
);
351 _pFields
.reset( pFields
);
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */