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