xref: /AOO41X/main/stoc/source/corereflection/crcomp.cxx (revision 647a425c57429e1e89af1c7acf2de6af6f1bb730)
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