Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <rtl/strbuf.hxx>
21 :
22 : #include <com/sun/star/reflection/XIdlField.hpp>
23 : #include <com/sun/star/reflection/XIdlField2.hpp>
24 : #include "com/sun/star/uno/TypeClass.hpp"
25 :
26 : #include "base.hxx"
27 :
28 :
29 : namespace stoc_corefl
30 : {
31 :
32 : //==================================================================================================
33 0 : class IdlCompFieldImpl
34 : : public IdlMemberImpl
35 : , public XIdlField
36 : , public XIdlField2
37 : {
38 : sal_Int32 _nOffset;
39 :
40 : public:
41 18 : IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
42 : typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
43 : sal_Int32 nOffset )
44 : : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
45 18 : , _nOffset( nOffset )
46 18 : {}
47 :
48 : // XInterface
49 : virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException);
50 : virtual void SAL_CALL acquire() throw ();
51 : virtual void SAL_CALL release() throw ();
52 :
53 : // XTypeProvider
54 : virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
55 : virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
56 :
57 : // XIdlMember
58 : virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
59 : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
60 : // XIdlField
61 : virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
62 : virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
63 : virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
64 : 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);
65 : // XIdlField2: getType, getAccessMode and get are equal to XIdlField
66 : 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);
67 : };
68 :
69 : // XInterface
70 : //__________________________________________________________________________________________________
71 23 : Any IdlCompFieldImpl::queryInterface( const Type & rType )
72 : throw(::com::sun::star::uno::RuntimeException)
73 : {
74 : Any aRet( ::cppu::queryInterface( rType,
75 : static_cast< XIdlField * >( this ),
76 23 : static_cast< XIdlField2 * >( this ) ) );
77 23 : return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
78 : }
79 : //__________________________________________________________________________________________________
80 89 : void IdlCompFieldImpl::acquire() throw()
81 : {
82 89 : IdlMemberImpl::acquire();
83 89 : }
84 : //__________________________________________________________________________________________________
85 71 : void IdlCompFieldImpl::release() throw()
86 : {
87 71 : IdlMemberImpl::release();
88 71 : }
89 :
90 : // XTypeProvider
91 : //__________________________________________________________________________________________________
92 0 : Sequence< Type > IdlCompFieldImpl::getTypes()
93 : throw (::com::sun::star::uno::RuntimeException)
94 : {
95 : static OTypeCollection * s_pTypes = 0;
96 0 : if (! s_pTypes)
97 : {
98 0 : MutexGuard aGuard( getMutexAccess() );
99 0 : if (! s_pTypes)
100 : {
101 : static OTypeCollection s_aTypes(
102 0 : ::getCppuType( (const Reference< XIdlField2 > *)0 ),
103 0 : ::getCppuType( (const Reference< XIdlField > *)0 ),
104 0 : IdlMemberImpl::getTypes() );
105 0 : s_pTypes = &s_aTypes;
106 0 : }
107 : }
108 0 : return s_pTypes->getTypes();
109 : }
110 : //__________________________________________________________________________________________________
111 0 : Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId()
112 : throw (::com::sun::star::uno::RuntimeException)
113 : {
114 : static OImplementationId * s_pId = 0;
115 0 : if (! s_pId)
116 : {
117 0 : MutexGuard aGuard( getMutexAccess() );
118 0 : if (! s_pId)
119 : {
120 0 : static OImplementationId s_aId;
121 0 : s_pId = &s_aId;
122 0 : }
123 : }
124 0 : return s_pId->getImplementationId();
125 : }
126 :
127 : // XIdlMember
128 : //__________________________________________________________________________________________________
129 0 : Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass()
130 : throw(::com::sun::star::uno::RuntimeException)
131 : {
132 0 : if (! _xDeclClass.is())
133 : {
134 0 : MutexGuard aGuard( getMutexAccess() );
135 0 : if (! _xDeclClass.is())
136 : {
137 : typelib_CompoundTypeDescription * pTD =
138 0 : (typelib_CompoundTypeDescription *)getDeclTypeDescr();
139 0 : while (pTD)
140 : {
141 0 : typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs;
142 0 : for ( sal_Int32 nPos = pTD->nMembers; nPos--; )
143 : {
144 0 : if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] ))
145 : {
146 0 : _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD );
147 0 : return _xDeclClass;
148 : }
149 : }
150 0 : pTD = pTD->pBaseTypeDescription;
151 : }
152 0 : }
153 : }
154 0 : return _xDeclClass;
155 : }
156 : //__________________________________________________________________________________________________
157 18 : OUString IdlCompFieldImpl::getName()
158 : throw(::com::sun::star::uno::RuntimeException)
159 : {
160 18 : return IdlMemberImpl::getName();
161 : }
162 :
163 : // XIdlField
164 : //__________________________________________________________________________________________________
165 18 : Reference< XIdlClass > IdlCompFieldImpl::getType()
166 : throw(::com::sun::star::uno::RuntimeException)
167 : {
168 18 : return getReflection()->forType( getTypeDescr() );
169 : }
170 : //__________________________________________________________________________________________________
171 18 : FieldAccessMode IdlCompFieldImpl::getAccessMode()
172 : throw(::com::sun::star::uno::RuntimeException)
173 : {
174 18 : return FieldAccessMode_READWRITE;
175 : }
176 : //__________________________________________________________________________________________________
177 2 : Any IdlCompFieldImpl::get( const Any & rObj )
178 : throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
179 : {
180 2 : if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
181 0 : rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
182 : {
183 2 : typelib_TypeDescription * pObjTD = 0;
184 2 : TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
185 :
186 2 : typelib_TypeDescription * pTD = pObjTD;
187 2 : typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
188 4 : while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
189 0 : pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
190 :
191 : OSL_ENSURE( pTD, "### illegal object type!" );
192 2 : if (pTD)
193 : {
194 2 : TYPELIB_DANGER_RELEASE( pObjTD );
195 2 : Any aRet;
196 : uno_any_destruct(
197 2 : &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
198 : uno_any_construct(
199 4 : &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(),
200 6 : reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
201 4 : return aRet;
202 : }
203 0 : TYPELIB_DANGER_RELEASE( pObjTD );
204 : }
205 : throw IllegalArgumentException(
206 : OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
207 0 : (XWeak *)(OWeakObject *)this, 0 );
208 : }
209 : //__________________________________________________________________________________________________
210 0 : void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue )
211 : throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
212 : {
213 0 : if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
214 0 : rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
215 : {
216 0 : typelib_TypeDescription * pObjTD = 0;
217 0 : TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
218 :
219 0 : typelib_TypeDescription * pTD = pObjTD;
220 0 : typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
221 0 : while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
222 0 : pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
223 :
224 : OSL_ENSURE( pTD, "### illegal object type!" );
225 0 : if (pTD)
226 : {
227 0 : TYPELIB_DANGER_RELEASE( pObjTD );
228 0 : if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
229 : {
230 0 : return;
231 : }
232 : else
233 : {
234 : throw IllegalArgumentException(
235 : OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
236 0 : (XWeak *)(OWeakObject *)this, 1 );
237 : }
238 : }
239 0 : TYPELIB_DANGER_RELEASE( pObjTD );
240 : }
241 : throw IllegalArgumentException(
242 : OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
243 0 : (XWeak *)(OWeakObject *)this, 0 );
244 : }
245 :
246 : //__________________________________________________________________________________________________
247 5 : void IdlCompFieldImpl::set( Any & rObj, const Any & rValue )
248 : throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
249 : {
250 5 : if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
251 0 : rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
252 : {
253 5 : typelib_TypeDescription * pObjTD = 0;
254 5 : TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
255 :
256 5 : typelib_TypeDescription * pTD = pObjTD;
257 5 : typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
258 10 : while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
259 0 : pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
260 :
261 : OSL_ENSURE( pTD, "### illegal object type!" );
262 5 : if (pTD)
263 : {
264 5 : TYPELIB_DANGER_RELEASE( pObjTD );
265 5 : if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
266 : {
267 5 : return;
268 : }
269 : else
270 : {
271 : throw IllegalArgumentException(
272 : OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
273 0 : (XWeak *)(OWeakObject *)this, 1 );
274 : }
275 : }
276 0 : TYPELIB_DANGER_RELEASE( pObjTD );
277 : }
278 : throw IllegalArgumentException(
279 : OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
280 0 : (XWeak *)(OWeakObject *)this, 0 );
281 : }
282 :
283 : //##################################################################################################
284 : //##################################################################################################
285 : //##################################################################################################
286 :
287 :
288 : //__________________________________________________________________________________________________
289 6 : CompoundIdlClassImpl::~CompoundIdlClassImpl()
290 : {
291 2 : delete _pFields;
292 4 : }
293 :
294 : //__________________________________________________________________________________________________
295 0 : sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
296 : throw(::com::sun::star::uno::RuntimeException)
297 : {
298 0 : if (xType.is())
299 : {
300 0 : TypeClass eTC = xType->getTypeClass();
301 0 : if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
302 : {
303 0 : if (equals( xType ))
304 0 : return sal_True;
305 : else
306 : {
307 0 : const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
308 0 : if (rSeq.getLength())
309 : {
310 : OSL_ENSURE( rSeq.getLength() == 1, "### unexpected len of super classes!" );
311 0 : return isAssignableFrom( rSeq[0] );
312 0 : }
313 : }
314 : }
315 : }
316 0 : return sal_False;
317 : }
318 : //__________________________________________________________________________________________________
319 0 : Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses()
320 : throw(::com::sun::star::uno::RuntimeException)
321 : {
322 0 : if (! _xSuperClass.is())
323 : {
324 0 : MutexGuard aGuard( getMutexAccess() );
325 0 : if (! _xSuperClass.is())
326 : {
327 0 : typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription;
328 0 : if (pCompTypeDescr)
329 0 : _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr );
330 0 : }
331 : }
332 0 : if (_xSuperClass.is())
333 0 : return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
334 : else
335 0 : return Sequence< Reference< XIdlClass > >();
336 : }
337 : //__________________________________________________________________________________________________
338 0 : Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
339 : throw(::com::sun::star::uno::RuntimeException)
340 : {
341 0 : if (! _pFields)
342 0 : getFields(); // init fields
343 :
344 0 : const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
345 0 : if (iFind != _aName2Field.end())
346 0 : return Reference< XIdlField >( (*iFind).second );
347 : else
348 0 : return Reference< XIdlField >();
349 : }
350 : //__________________________________________________________________________________________________
351 2 : Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
352 : throw(::com::sun::star::uno::RuntimeException)
353 : {
354 2 : MutexGuard aGuard( getMutexAccess() );
355 2 : if (! _pFields)
356 : {
357 2 : sal_Int32 nAll = 0;
358 2 : typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr();
359 4 : for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
360 2 : nAll += pCompTypeDescr->nMembers;
361 :
362 : Sequence< Reference< XIdlField > > * pFields =
363 2 : new Sequence< Reference< XIdlField > >( nAll );
364 2 : Reference< XIdlField > * pSeq = pFields->getArray();
365 :
366 4 : for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr;
367 : pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
368 : {
369 2 : typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
370 2 : rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames;
371 2 : sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets;
372 :
373 22 : for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
374 : {
375 18 : typelib_TypeDescription * pTD = 0;
376 18 : TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] );
377 : OSL_ENSURE( pTD, "### cannot get field in struct!" );
378 18 : if (pTD)
379 : {
380 18 : OUString aName( ppNames[nPos] );
381 18 : _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl(
382 36 : getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] );
383 18 : TYPELIB_DANGER_RELEASE( pTD );
384 : }
385 : }
386 : }
387 :
388 2 : _pFields = pFields;
389 : }
390 2 : return *_pFields;
391 : }
392 :
393 : }
394 :
395 :
396 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|