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