nss: upgrade to release 3.73
[LibreOffice.git] / stoc / source / corereflection / crcomp.cxx
blobda4ad43b83e69b49306c13046c07177ac30d71fa
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
27 #include "base.hxx"
29 using namespace css::lang;
30 using namespace css::reflection;
31 using namespace css::uno;
33 namespace stoc_corefl
36 namespace {
38 class IdlCompFieldImpl
39 : public IdlMemberImpl
40 , public XIdlField
41 , public XIdlField2
43 sal_Int32 _nOffset;
45 public:
46 IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
47 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
48 sal_Int32 nOffset )
49 : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
50 , _nOffset( nOffset )
53 // XInterface
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;
58 // XTypeProvider
59 virtual Sequence< Type > SAL_CALL getTypes() override;
60 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() override;
62 // XIdlMember
63 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() override;
64 virtual OUString SAL_CALL getName() override;
65 // XIdlField
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;
76 // XInterface
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();
96 // XTypeProvider
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>();
113 // XIdlMember
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());
124 while (pTD)
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 );
132 return _xDeclClass;
135 pTD = pTD->pBaseTypeDescription;
139 return _xDeclClass;
142 OUString IdlCompFieldImpl::getName()
144 return IdlMemberImpl::getName();
147 // XIdlField
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!" );
173 if (pTD)
175 TYPELIB_DANGER_RELEASE( pObjTD );
176 Any aRet;
177 uno_any_destruct(
178 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
179 uno_any_construct(
180 &aRet, const_cast<char *>(static_cast<char const *>(rObj.getValue()) + _nOffset), getTypeDescr(),
181 reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
182 return aRet;
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!" );
205 if (pTD)
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 );
214 return;
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!" );
238 if (pTD)
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 );
247 return;
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 )
264 if (xType.is())
266 TypeClass eTC = xType->getTypeClass();
267 if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
269 if (equals( xType ))
270 return true;
271 else
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] );
282 return false;
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;
293 if (pCompTypeDescr)
294 _xSuperClass = getReflection()->forType( &pCompTypeDescr->aBase );
297 if (_xSuperClass.is())
298 return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
299 else
300 return Sequence< Reference< XIdlClass > >();
303 Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
305 if (! _pFields)
306 getFields(); // init fields
308 const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
309 if (iFind != _aName2Field.end())
310 return Reference< XIdlField >( (*iFind).second );
311 else
312 return Reference< XIdlField >();
315 Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
317 ::osl::MutexGuard aGuard( getMutexAccess() );
318 if (! _pFields)
320 sal_Int32 nAll = 0;
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!" );
341 if (pTD)
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 );
353 return *_pFields;
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */