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 typedef cppu::ImplInheritanceHelper
<IdlMemberImpl
, XIdlField
, XIdlField2
> IdlCompFieldImpl_Base
;
39 class IdlCompFieldImpl
: public IdlCompFieldImpl_Base
44 IdlCompFieldImpl( IdlReflectionServiceImpl
* pReflection
, const OUString
& rName
,
45 typelib_TypeDescription
* pTypeDescr
, typelib_TypeDescription
* pDeclTypeDescr
,
47 : IdlCompFieldImpl_Base( pReflection
, rName
, pTypeDescr
, pDeclTypeDescr
)
52 virtual Reference
< XIdlClass
> SAL_CALL
getDeclaringClass() override
;
53 virtual OUString SAL_CALL
getName() override
;
55 virtual Reference
< XIdlClass
> SAL_CALL
getType() override
;
56 virtual FieldAccessMode SAL_CALL
getAccessMode() override
;
57 virtual Any SAL_CALL
get( const Any
& rObj
) override
;
58 virtual void SAL_CALL
set( const Any
& rObj
, const Any
& rValue
) override
;
59 // XIdlField2: getType, getAccessMode and get are equal to XIdlField
60 virtual void SAL_CALL
set( Any
& rObj
, const Any
& rValue
) override
;
67 Reference
< XIdlClass
> IdlCompFieldImpl::getDeclaringClass()
69 if (! _xDeclClass
.is())
71 ::osl::MutexGuard
aGuard( getMutexAccess() );
72 if (! _xDeclClass
.is())
74 typelib_CompoundTypeDescription
* pTD
=
75 reinterpret_cast<typelib_CompoundTypeDescription
*>(getDeclTypeDescr());
78 typelib_TypeDescriptionReference
** ppTypeRefs
= pTD
->ppTypeRefs
;
79 for ( sal_Int32 nPos
= pTD
->nMembers
; nPos
--; )
81 if (td_equals( getTypeDescr(), ppTypeRefs
[nPos
] ))
83 _xDeclClass
= getReflection()->forType( &pTD
->aBase
);
87 pTD
= pTD
->pBaseTypeDescription
;
94 OUString
IdlCompFieldImpl::getName()
96 return IdlMemberImpl::getName();
101 Reference
< XIdlClass
> IdlCompFieldImpl::getType()
103 return getReflection()->forType( getTypeDescr() );
106 FieldAccessMode
IdlCompFieldImpl::getAccessMode()
108 return FieldAccessMode_READWRITE
;
111 Any
IdlCompFieldImpl::get( const Any
& rObj
)
113 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
114 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
116 typelib_TypeDescription
* pObjTD
= nullptr;
117 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
119 typelib_TypeDescription
* pTD
= pObjTD
;
120 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
121 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
122 pTD
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
124 OSL_ENSURE( pTD
, "### illegal object type!" );
127 TYPELIB_DANGER_RELEASE( pObjTD
);
130 &aRet
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
132 &aRet
, const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(),
133 reinterpret_cast< uno_AcquireFunc
>(cpp_acquire
) );
136 TYPELIB_DANGER_RELEASE( pObjTD
);
138 throw IllegalArgumentException(
139 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
140 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
143 void IdlCompFieldImpl::set( const Any
& rObj
, const Any
& rValue
)
145 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
146 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
148 typelib_TypeDescription
* pObjTD
= nullptr;
149 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
151 typelib_TypeDescription
* pTD
= pObjTD
;
152 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
153 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
154 pTD
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
156 OSL_ENSURE( pTD
, "### illegal object type!" );
159 TYPELIB_DANGER_RELEASE( pObjTD
);
160 if (!coerce_assign( const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(), rValue
, getReflection() ))
162 throw IllegalArgumentException(
163 "cannot assign value to destination",
164 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 1 );
168 TYPELIB_DANGER_RELEASE( pObjTD
);
170 throw IllegalArgumentException(
171 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
172 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
176 void IdlCompFieldImpl::set( Any
& rObj
, const Any
& rValue
)
178 if (rObj
.getValueTypeClass() == css::uno::TypeClass_STRUCT
||
179 rObj
.getValueTypeClass() == css::uno::TypeClass_EXCEPTION
)
181 typelib_TypeDescription
* pObjTD
= nullptr;
182 TYPELIB_DANGER_GET( &pObjTD
, rObj
.getValueTypeRef() );
184 typelib_TypeDescription
* pTD
= pObjTD
;
185 typelib_TypeDescription
* pDeclTD
= getDeclTypeDescr();
186 while (pTD
&& !typelib_typedescription_equals( pTD
, pDeclTD
))
187 pTD
= &reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
)->pBaseTypeDescription
->aBase
;
189 OSL_ENSURE( pTD
, "### illegal object type!" );
192 TYPELIB_DANGER_RELEASE( pObjTD
);
193 if (!coerce_assign( const_cast<char *>(static_cast<char const *>(rObj
.getValue()) + _nOffset
), getTypeDescr(), rValue
, getReflection() ))
195 throw IllegalArgumentException(
196 "cannot assign to destination",
197 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 1 );
201 TYPELIB_DANGER_RELEASE( pObjTD
);
203 throw IllegalArgumentException(
204 "expected struct or exception, got " + rObj
.getValueType().getTypeName(),
205 static_cast<XWeak
*>(static_cast<OWeakObject
*>(this)), 0 );
209 CompoundIdlClassImpl::~CompoundIdlClassImpl()
214 sal_Bool
CompoundIdlClassImpl::isAssignableFrom( const Reference
< XIdlClass
> & xType
)
218 TypeClass eTC
= xType
->getTypeClass();
219 if (eTC
== TypeClass_STRUCT
|| eTC
== TypeClass_EXCEPTION
)
225 const Sequence
< Reference
< XIdlClass
> > & rSeq
= xType
->getSuperclasses();
226 if (rSeq
.hasElements())
228 OSL_ENSURE( rSeq
.getLength() == 1, "### unexpected len of super classes!" );
229 return isAssignableFrom( rSeq
[0] );
237 Sequence
< Reference
< XIdlClass
> > CompoundIdlClassImpl::getSuperclasses()
239 if (! _xSuperClass
.is())
241 ::osl::MutexGuard
aGuard( getMutexAccess() );
242 if (! _xSuperClass
.is())
244 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr()->pBaseTypeDescription
;
246 _xSuperClass
= getReflection()->forType( &pCompTypeDescr
->aBase
);
249 if (_xSuperClass
.is())
250 return Sequence
< Reference
< XIdlClass
> >( &_xSuperClass
, 1 );
252 return Sequence
< Reference
< XIdlClass
> >();
255 Reference
< XIdlField
> CompoundIdlClassImpl::getField( const OUString
& rName
)
258 getFields(); // init fields
260 const OUString2Field::const_iterator
iFind( _aName2Field
.find( rName
) );
261 if (iFind
!= _aName2Field
.end())
262 return Reference
< XIdlField
>( (*iFind
).second
);
264 return Reference
< XIdlField
>();
267 Sequence
< Reference
< XIdlField
> > CompoundIdlClassImpl::getFields()
269 ::osl::MutexGuard
aGuard( getMutexAccess() );
273 typelib_CompoundTypeDescription
* pCompTypeDescr
= getTypeDescr();
274 for ( ; pCompTypeDescr
; pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
275 nAll
+= pCompTypeDescr
->nMembers
;
277 Sequence
< Reference
< XIdlField
> > aFields( nAll
);
278 Reference
< XIdlField
> * pSeq
= aFields
.getArray();
280 for ( pCompTypeDescr
= getTypeDescr(); pCompTypeDescr
;
281 pCompTypeDescr
= pCompTypeDescr
->pBaseTypeDescription
)
283 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompTypeDescr
->ppTypeRefs
;
284 rtl_uString
** ppNames
= pCompTypeDescr
->ppMemberNames
;
285 sal_Int32
* pMemberOffsets
= pCompTypeDescr
->pMemberOffsets
;
287 for ( sal_Int32 nPos
= pCompTypeDescr
->nMembers
; nPos
--; )
289 typelib_TypeDescription
* pTD
= nullptr;
290 TYPELIB_DANGER_GET( &pTD
, ppTypeRefs
[nPos
] );
291 OSL_ENSURE( pTD
, "### cannot get field in struct!" );
294 OUString
aName( ppNames
[nPos
] );
295 _aName2Field
[aName
] = pSeq
[--nAll
] = new IdlCompFieldImpl(
296 getReflection(), aName
, pTD
, IdlClassImpl::getTypeDescr(), pMemberOffsets
[nPos
] );
297 TYPELIB_DANGER_RELEASE( pTD
);
302 m_xFields
= std::move( aFields
);
310 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */