| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_stoc.hxx" |
| #include <osl/diagnose.h> |
| #include <rtl/ustrbuf.hxx> |
| #include "registry/reader.hxx" |
| #include "registry/version.h" |
| |
| #include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp> |
| #include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp> |
| #include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp> |
| #include <com/sun/star/reflection/XMethodParameter.hpp> |
| #include <com/sun/star/reflection/XParameter.hpp> |
| #include "com/sun/star/uno/RuntimeException.hpp" |
| #include "base.hxx" |
| #include "functiondescription.hxx" |
| #include "methoddescription.hxx" |
| |
| #include <memory> |
| #include <set> |
| |
| namespace stoc_rdbtdp |
| { |
| |
| //================================================================================================== |
| class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription > |
| { |
| stoc::registry_tdprovider::MethodDescription _desc; |
| |
| Reference< XHierarchicalNameAccess > _xTDMgr; |
| |
| OUString _aTypeName; |
| |
| OUString _aReturnType; |
| Reference< XTypeDescription > _xReturnTD; |
| |
| sal_Bool _bIsOneWay; |
| sal_Int32 _nPosition; |
| |
| public: |
| InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr, |
| const OUString & rTypeName, |
| const OUString & rMemberName, |
| const OUString & rReturnType, |
| const Sequence< sal_Int8 > & rBytes, |
| sal_uInt16 nMethodIndex, |
| sal_Bool bIsOneWay, |
| sal_Int32 nPosition ) |
| : _desc(xTDMgr, rMemberName, rBytes, nMethodIndex) |
| , _xTDMgr( xTDMgr ) |
| , _aTypeName( rTypeName ) |
| , _aReturnType( rReturnType ) |
| , _bIsOneWay( bIsOneWay ) |
| , _nPosition( nPosition ) |
| { |
| g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); |
| } |
| virtual ~InterfaceMethodImpl(); |
| |
| // XTypeDescription |
| virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); |
| virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); |
| |
| // XInterfaceMemberTypeDescription |
| virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException) |
| { return _desc.getName(); } |
| virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); |
| |
| // XInterfaceMethodTypeDescription |
| virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException); |
| virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException); |
| virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException); |
| virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException); |
| }; |
| //__________________________________________________________________________________________________ |
| InterfaceMethodImpl::~InterfaceMethodImpl() |
| { |
| g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); |
| } |
| |
| // XTypeDescription |
| //__________________________________________________________________________________________________ |
| TypeClass InterfaceMethodImpl::getTypeClass() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return TypeClass_INTERFACE_METHOD; |
| } |
| //__________________________________________________________________________________________________ |
| OUString InterfaceMethodImpl::getName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _aTypeName; |
| } |
| |
| // XInterfaceMemberTypeDescription |
| //__________________________________________________________________________________________________ |
| sal_Int32 InterfaceMethodImpl::getPosition() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _nPosition; |
| } |
| |
| // XInterfaceMethodTypeDescription |
| //__________________________________________________________________________________________________ |
| Reference<XTypeDescription > InterfaceMethodImpl::getReturnType() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| if (!_xReturnTD.is() && _aReturnType.getLength()) |
| { |
| try |
| { |
| Reference< XTypeDescription > xReturnTD; |
| if (_xTDMgr->getByHierarchicalName( _aReturnType ) >>= xReturnTD) |
| { |
| MutexGuard aGuard( getMutex() ); |
| if (! _xReturnTD.is()) |
| _xReturnTD = xReturnTD; |
| return _xReturnTD; |
| } |
| } |
| catch (NoSuchElementException &) |
| { |
| } |
| // never try again, if no td was found |
| _aReturnType = OUString(); |
| } |
| return _xReturnTD; |
| } |
| //__________________________________________________________________________________________________ |
| sal_Bool InterfaceMethodImpl::isOneway() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _bIsOneWay; |
| } |
| //__________________________________________________________________________________________________ |
| Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Sequence< Reference< XParameter > > s1(_desc.getParameters()); |
| Sequence< Reference< XMethodParameter > > s2(s1.getLength()); |
| for (sal_Int32 i = 0; i < s1.getLength(); ++i) { |
| s2[i] = s1[i].get(); |
| } |
| return s2; |
| } |
| //__________________________________________________________________________________________________ |
| Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Sequence< Reference< XCompoundTypeDescription > > s1( |
| _desc.getExceptions()); |
| Sequence< Reference< XTypeDescription > > s2(s1.getLength()); |
| for (sal_Int32 i = 0; i < s1.getLength(); ++i) { |
| s2[i] = s1[i].get(); |
| } |
| return s2; |
| } |
| |
| |
| //################################################################################################## |
| //################################################################################################## |
| //################################################################################################## |
| |
| |
| //================================================================================================== |
| class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 > |
| { |
| Reference< XHierarchicalNameAccess > _xTDMgr; |
| |
| OUString _aTypeName; |
| OUString _aMemberName; |
| |
| OUString _aMemberTypeName; |
| Reference< XTypeDescription > _xMemberTD; |
| |
| sal_Bool _bReadOnly; |
| sal_Bool _bBound; |
| sal_Int32 _nPosition; |
| |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter; |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter; |
| |
| public: |
| InterfaceAttributeImpl( |
| const Reference< XHierarchicalNameAccess > & xTDMgr, |
| const OUString & rTypeName, |
| const OUString & rMemberName, |
| const OUString & rMemberTypeName, |
| sal_Bool bReadOnly, |
| sal_Bool bBound, |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > & |
| getter, |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > & |
| setter, |
| sal_Int32 nPosition ) |
| : _xTDMgr( xTDMgr ) |
| , _aTypeName( rTypeName ) |
| , _aMemberName( rMemberName ) |
| , _aMemberTypeName( rMemberTypeName ) |
| , _bReadOnly( bReadOnly ) |
| , _bBound( bBound ) |
| , _nPosition( nPosition ) |
| , _getter( getter ) |
| , _setter( setter ) |
| { |
| g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); |
| } |
| virtual ~InterfaceAttributeImpl(); |
| |
| // XTypeDescription |
| virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException); |
| virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException); |
| |
| // XInterfaceMemberTypeDescription |
| virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException); |
| virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException); |
| |
| // XInterfaceAttributeTypeDescription2 |
| virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException); |
| virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException); |
| |
| virtual sal_Bool SAL_CALL isBound() throw (RuntimeException) |
| { return _bBound; } |
| |
| virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL |
| getGetExceptions() throw (RuntimeException) |
| { |
| if (_getter.get() != 0) { |
| return _getter->getExceptions(); |
| } else { |
| return Sequence< Reference< XCompoundTypeDescription > >(); |
| } |
| } |
| |
| virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL |
| getSetExceptions() throw (RuntimeException) |
| { |
| if (_setter.get() != 0) { |
| return _setter->getExceptions(); |
| } else { |
| return Sequence< Reference< XCompoundTypeDescription > >(); |
| } |
| } |
| }; |
| |
| InterfaceAttributeImpl::~InterfaceAttributeImpl() |
| { |
| g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); |
| } |
| // XTypeDescription |
| //__________________________________________________________________________________________________ |
| TypeClass InterfaceAttributeImpl::getTypeClass() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return TypeClass_INTERFACE_ATTRIBUTE; |
| } |
| //__________________________________________________________________________________________________ |
| OUString InterfaceAttributeImpl::getName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _aTypeName; |
| } |
| |
| // XInterfaceMemberTypeDescription |
| //__________________________________________________________________________________________________ |
| OUString InterfaceAttributeImpl::getMemberName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _aMemberName; |
| } |
| //__________________________________________________________________________________________________ |
| sal_Int32 InterfaceAttributeImpl::getPosition() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _nPosition; |
| } |
| |
| // XInterfaceAttributeTypeDescription2 |
| //__________________________________________________________________________________________________ |
| sal_Bool InterfaceAttributeImpl::isReadOnly() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _bReadOnly; |
| } |
| //__________________________________________________________________________________________________ |
| Reference<XTypeDescription > InterfaceAttributeImpl::getType() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| if (!_xMemberTD.is() && _aMemberTypeName.getLength()) |
| { |
| try |
| { |
| Reference< XTypeDescription > xMemberTD; |
| if (_xTDMgr->getByHierarchicalName( _aMemberTypeName ) >>= xMemberTD) |
| { |
| MutexGuard aGuard( getMutex() ); |
| if (! _xMemberTD.is()) |
| _xMemberTD = xMemberTD; |
| return _xMemberTD; |
| } |
| } |
| catch (NoSuchElementException &) |
| { |
| } |
| // never try again, if no td was found |
| _aMemberTypeName = OUString(); |
| } |
| return _xMemberTD; |
| } |
| |
| |
| //################################################################################################## |
| //################################################################################################## |
| //################################################################################################## |
| |
| void InterfaceTypeDescriptionImpl::checkInterfaceType( |
| Reference< XTypeDescription > const & type) |
| { |
| if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) { |
| throw RuntimeException( |
| OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "Interface base is not an interface type")), |
| static_cast< OWeakObject * >(this)); |
| } |
| } |
| |
| namespace { |
| |
| class BaseOffset { |
| public: |
| BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc); |
| |
| sal_Int32 get() const { return offset; } |
| |
| private: |
| void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc); |
| |
| void calculate(Reference< XInterfaceTypeDescription2 > const & desc); |
| |
| std::set< rtl::OUString > set; |
| sal_Int32 offset; |
| }; |
| |
| BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) { |
| offset = 0; |
| calculateBases(desc); |
| } |
| |
| void BaseOffset::calculateBases( |
| Reference< XInterfaceTypeDescription2 > const & desc) |
| { |
| Sequence< Reference < XTypeDescription > > bases(desc->getBaseTypes()); |
| for (sal_Int32 i = 0; i < bases.getLength(); ++i) { |
| calculate( |
| Reference< XInterfaceTypeDescription2 >( |
| resolveTypedefs(bases[i]), UNO_QUERY_THROW)); |
| } |
| } |
| |
| void BaseOffset::calculate(Reference< XInterfaceTypeDescription2 > const & desc) |
| { |
| if (set.insert(desc->getName()).second) { |
| calculateBases(desc); |
| offset += desc->getMembers().getLength(); |
| } |
| } |
| |
| } |
| |
| //__________________________________________________________________________________________________ |
| InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl( |
| const Reference< XHierarchicalNameAccess > & xTDMgr, |
| const OUString & rName, const Sequence< OUString > & rBaseTypes, |
| const Sequence< OUString > & rOptionalBaseTypes, |
| const Sequence< sal_Int8 > & rBytes, bool published ) |
| : _xTDMgr( xTDMgr ) |
| , _aBytes( rBytes ) |
| , _aName( rName ) |
| , _aBaseTypes( rBaseTypes ) |
| , _aOptionalBaseTypes( rOptionalBaseTypes ) |
| , _membersInit( false ) |
| , _published( published ) |
| { |
| g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); |
| } |
| //__________________________________________________________________________________________________ |
| InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl() |
| { |
| g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); |
| } |
| |
| // XTypeDescription |
| //__________________________________________________________________________________________________ |
| TypeClass InterfaceTypeDescriptionImpl::getTypeClass() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return TypeClass_INTERFACE; |
| } |
| //__________________________________________________________________________________________________ |
| OUString InterfaceTypeDescriptionImpl::getName() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return _aName; |
| } |
| |
| // XInterfaceTypeDescription2 |
| //__________________________________________________________________________________________________ |
| Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| Sequence< Reference< XTypeDescription > > aBaseTypes(getBaseTypes()); |
| return aBaseTypes.getLength() >= 1 ? aBaseTypes[0] : 0; |
| } |
| //__________________________________________________________________________________________________ |
| Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| return Uik(); |
| } |
| //__________________________________________________________________________________________________ |
| Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers() |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| osl::MutexGuard guard(getMutex()); |
| if (!_membersInit) { |
| _nBaseOffset = BaseOffset(this).get(); |
| typereg::Reader reader( |
| _aBytes.getConstArray(), _aBytes.getLength(), false, |
| TYPEREG_VERSION_1); |
| sal_Int32 count = 0; |
| sal_uInt16 methodCount = reader.getMethodCount(); |
| {for (sal_uInt16 i = 0; i < methodCount; ++i) { |
| RTMethodMode flags = reader.getMethodFlags(i); |
| if (flags != RT_MODE_ATTRIBUTE_GET |
| && flags != RT_MODE_ATTRIBUTE_SET) |
| { |
| ++count; |
| } |
| }} |
| sal_uInt16 fieldCount = reader.getFieldCount(); |
| count += fieldCount; |
| _members.realloc(count); |
| sal_Int32 index = 0; |
| {for (sal_uInt16 i = 0; i < fieldCount; ++i) { |
| rtl::OUString name(reader.getFieldName(i)); |
| rtl::OUStringBuffer typeName(getName()); |
| typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::")); |
| typeName.append(name); |
| RTFieldAccess flags = reader.getFieldFlags(i); |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > |
| getter; |
| std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > |
| setter; |
| for (sal_uInt16 j = 0; j < methodCount; ++j) { |
| if (reader.getMethodName(j) == name) { |
| switch (reader.getMethodFlags(j)) { |
| case RT_MODE_ATTRIBUTE_GET: |
| OSL_ASSERT(getter.get() == 0); |
| getter.reset( |
| new stoc::registry_tdprovider::FunctionDescription( |
| _xTDMgr, _aBytes, j)); |
| break; |
| |
| case RT_MODE_ATTRIBUTE_SET: |
| OSL_ASSERT(setter.get() == 0); |
| setter.reset( |
| new stoc::registry_tdprovider::FunctionDescription( |
| _xTDMgr, _aBytes, j)); |
| break; |
| |
| default: |
| OSL_ASSERT(false); |
| break; |
| } |
| } |
| } |
| _members[index] = new InterfaceAttributeImpl( |
| _xTDMgr, typeName.makeStringAndClear(), name, |
| reader.getFieldTypeName(i).replace('/', '.'), |
| (flags & RT_ACCESS_READONLY) != 0, |
| (flags & RT_ACCESS_BOUND) != 0, getter, setter, |
| _nBaseOffset + index); |
| ++index; |
| }} |
| {for (sal_uInt16 i = 0; i < methodCount; ++i) { |
| RTMethodMode flags = reader.getMethodFlags(i); |
| if (flags != RT_MODE_ATTRIBUTE_GET |
| && flags != RT_MODE_ATTRIBUTE_SET) |
| { |
| rtl::OUString name(reader.getMethodName(i)); |
| rtl::OUStringBuffer typeName(getName()); |
| typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::")); |
| typeName.append(name); |
| _members[index] = new InterfaceMethodImpl( |
| _xTDMgr, typeName.makeStringAndClear(), name, |
| reader.getMethodReturnTypeName(i).replace('/', '.'), |
| _aBytes, i, flags == RT_MODE_ONEWAY, _nBaseOffset + index); |
| ++index; |
| } |
| }} |
| _membersInit = true; |
| } |
| return _members; |
| } |
| |
| Sequence< Reference< XTypeDescription > > |
| InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException) { |
| MutexGuard guard(getMutex()); |
| if (_xBaseTDs.getLength() == 0 && _aBaseTypes.getLength() != 0) { |
| Sequence< Reference< XTypeDescription > > tds(_aBaseTypes.getLength()); |
| for (sal_Int32 i = 0; i < _aBaseTypes.getLength(); ++i) { |
| try { |
| _xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i]; |
| } catch (NoSuchElementException & e) { |
| throw RuntimeException( |
| (OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.container.NoSuchElementException: ")) |
| + e.Message), |
| static_cast< OWeakObject * >(this)); |
| } |
| OSL_ASSERT(tds[i].is()); |
| checkInterfaceType(tds[i]); |
| } |
| _xBaseTDs = tds; |
| } |
| return _xBaseTDs; |
| } |
| |
| Sequence< Reference< XTypeDescription > > |
| InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException) { |
| MutexGuard guard(getMutex()); |
| if (_xOptionalBaseTDs.getLength() == 0 |
| && _aOptionalBaseTypes.getLength() != 0) |
| { |
| Sequence< Reference< XTypeDescription > > tds( |
| _aOptionalBaseTypes.getLength()); |
| for (sal_Int32 i = 0; i < _aOptionalBaseTypes.getLength(); ++i) { |
| try { |
| _xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i]) |
| >>= tds[i]; |
| } catch (NoSuchElementException & e) { |
| throw RuntimeException( |
| (OUString( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.container.NoSuchElementException: ")) |
| + e.Message), |
| static_cast< OWeakObject * >(this)); |
| } |
| OSL_ASSERT(tds[i].is()); |
| checkInterfaceType(tds[i]); |
| } |
| _xOptionalBaseTDs = tds; |
| } |
| return _xOptionalBaseTDs; |
| } |
| |
| } |