android: Update app-specific/MIME type icons
[LibreOffice.git] / stoc / source / corereflection / crcomp.cxx
blob990e5a63aa1a0a35fbff28dd01fae6e294c1c94d
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 typedef cppu::ImplInheritanceHelper<IdlMemberImpl, XIdlField, XIdlField2> IdlCompFieldImpl_Base;
39 class IdlCompFieldImpl : public IdlCompFieldImpl_Base
41 sal_Int32 _nOffset;
43 public:
44 IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
45 typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
46 sal_Int32 nOffset )
47 : IdlCompFieldImpl_Base( pReflection, rName, pTypeDescr, pDeclTypeDescr )
48 , _nOffset( nOffset )
51 // XIdlMember
52 virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() override;
53 virtual OUString SAL_CALL getName() override;
54 // XIdlField
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;
65 // XIdlMember
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());
76 while (pTD)
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 );
84 return _xDeclClass;
87 pTD = pTD->pBaseTypeDescription;
91 return _xDeclClass;
94 OUString IdlCompFieldImpl::getName()
96 return IdlMemberImpl::getName();
99 // XIdlField
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!" );
125 if (pTD)
127 TYPELIB_DANGER_RELEASE( pObjTD );
128 Any aRet;
129 uno_any_destruct(
130 &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
131 uno_any_construct(
132 &aRet, const_cast<char *>(static_cast<char const *>(rObj.getValue()) + _nOffset), getTypeDescr(),
133 reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
134 return aRet;
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!" );
157 if (pTD)
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 );
166 return;
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!" );
190 if (pTD)
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 );
199 return;
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 )
216 if (xType.is())
218 TypeClass eTC = xType->getTypeClass();
219 if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
221 if (equals( xType ))
222 return true;
223 else
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] );
234 return false;
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;
245 if (pCompTypeDescr)
246 _xSuperClass = getReflection()->forType( &pCompTypeDescr->aBase );
249 if (_xSuperClass.is())
250 return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
251 else
252 return Sequence< Reference< XIdlClass > >();
255 Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
257 if (! m_xFields)
258 getFields(); // init fields
260 const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
261 if (iFind != _aName2Field.end())
262 return Reference< XIdlField >( (*iFind).second );
263 else
264 return Reference< XIdlField >();
267 Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
269 ::osl::MutexGuard aGuard( getMutexAccess() );
270 if (! m_xFields)
272 sal_Int32 nAll = 0;
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!" );
292 if (pTD)
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 );
304 return *m_xFields;
310 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */