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: 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 86 void IdlCompFieldImpl::acquire() throw() 87 { 88 IdlMemberImpl::acquire(); 89 } 90 //__________________________________________________________________________________________________ 91 void IdlCompFieldImpl::release() throw() 92 { 93 IdlMemberImpl::release(); 94 } 95 96 // XTypeProvider 97 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 163 OUString IdlCompFieldImpl::getName() 164 throw(::com::sun::star::uno::RuntimeException) 165 { 166 return IdlMemberImpl::getName(); 167 } 168 169 // XIdlField 170 //__________________________________________________________________________________________________ 171 Reference< XIdlClass > IdlCompFieldImpl::getType() 172 throw(::com::sun::star::uno::RuntimeException) 173 { 174 return getReflection()->forType( getTypeDescr() ); 175 } 176 //__________________________________________________________________________________________________ 177 FieldAccessMode IdlCompFieldImpl::getAccessMode() 178 throw(::com::sun::star::uno::RuntimeException) 179 { 180 return FieldAccessMode_READWRITE; 181 } 182 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 295 CompoundIdlClassImpl::~CompoundIdlClassImpl() 296 { 297 delete _pFields; 298 } 299 300 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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 //__________________________________________________________________________________________________ 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