diff options
Diffstat (limited to 'comphelper/source/property')
19 files changed, 1291 insertions, 319 deletions
diff --git a/comphelper/source/property/ChainablePropertySet.cxx b/comphelper/source/property/ChainablePropertySet.cxx index 65a53e62479f..dfb5c2b3f80d 100644 --- a/comphelper/source/property/ChainablePropertySet.cxx +++ b/comphelper/source/property/ChainablePropertySet.cxx @@ -23,6 +23,7 @@ #include <memory> +#include <optional> using namespace ::comphelper; using namespace ::com::sun::star; @@ -51,9 +52,9 @@ Reference< XPropertySetInfo > SAL_CALL ChainablePropertySet::getPropertySetInfo( void SAL_CALL ChainablePropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); PropertyInfoHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName ); @@ -68,9 +69,9 @@ void SAL_CALL ChainablePropertySet::setPropertyValue( const OUString& rPropertyN Any SAL_CALL ChainablePropertySet::getPropertyValue( const OUString& rPropertyName ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); PropertyInfoHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName ); @@ -109,31 +110,27 @@ void SAL_CALL ChainablePropertySet::removeVetoableChangeListener( const OUString void SAL_CALL ChainablePropertySet::setPropertyValues(const Sequence< OUString >& rPropertyNames, const Sequence< Any >& rValues) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); const sal_Int32 nCount = rPropertyNames.getLength(); if( nCount != rValues.getLength() ) - throw IllegalArgumentException("lengths do not match", static_cast<cppu::OWeakObject*>(this), -1); + throw IllegalArgumentException(u"lengths do not match"_ustr, static_cast<cppu::OWeakObject*>(this), -1); if( !nCount ) return; _preSetValues(); - const Any * pAny = rValues.getConstArray(); - const OUString * pString = rPropertyNames.getConstArray(); - PropertyInfoHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; - - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); - if ( aIter == aEnd ) - throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) ); + auto aIter = mxInfo->maMap.find(rPropertyNames[i]); + if (aIter == mxInfo->maMap.end()) + throw RuntimeException(rPropertyNames[i], static_cast<XPropertySet*>(this)); - _setSingleValue ( *((*aIter).second), *pAny ); + _setSingleValue(*((*aIter).second), rValues[i]); } _postSetValues(); @@ -142,9 +139,9 @@ void SAL_CALL ChainablePropertySet::setPropertyValues(const Sequence< OUString > Sequence< Any > SAL_CALL ChainablePropertySet::getPropertyValues(const Sequence< OUString >& rPropertyNames) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); const sal_Int32 nCount = rPropertyNames.getLength(); @@ -155,16 +152,13 @@ Sequence< Any > SAL_CALL ChainablePropertySet::getPropertyValues(const Sequence< _preGetValues(); Any * pAny = aValues.getArray(); - const OUString * pString = rPropertyNames.getConstArray(); - PropertyInfoHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; - - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); - if ( aIter == aEnd ) - throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) ); + auto aIter = mxInfo->maMap.find(rPropertyNames[i]); + if (aIter == mxInfo->maMap.end()) + throw RuntimeException(rPropertyNames[i], static_cast<XPropertySet*>(this)); - _getSingleValue ( *((*aIter).second), *pAny ); + _getSingleValue(*((*aIter).second), pAny[i]); } _postGetValues(); @@ -205,14 +199,15 @@ Sequence< PropertyState > SAL_CALL ChainablePropertySet::getPropertyStates( cons if( nCount ) { PropertyState * pState = aStates.getArray(); - const OUString * pString = rPropertyNames.getConstArray(); PropertyInfoHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); + aIter = mxInfo->maMap.find(rPropertyNames[i]); if ( aIter == aEnd ) - throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + throw UnknownPropertyException(rPropertyNames[i], static_cast<XPropertySet*>(this)); + + pState[i] = PropertyState_AMBIGUOUS_VALUE; } } return aStates; diff --git a/comphelper/source/property/ChainablePropertySetInfo.cxx b/comphelper/source/property/ChainablePropertySetInfo.cxx index 10b4d5fda622..4515e5c4314b 100644 --- a/comphelper/source/property/ChainablePropertySetInfo.cxx +++ b/comphelper/source/property/ChainablePropertySetInfo.cxx @@ -31,7 +31,7 @@ ChainablePropertySetInfo::ChainablePropertySetInfo( PropertyInfo const * pMap ) for( ; !pMap->maName.isEmpty(); ++pMap ) { SAL_WARN_IF( - maMap.find(pMap->maName) != maMap.end(), + maMap.contains(pMap->maName), "comphelper", "Duplicate property name \"" << pMap->maName << "\""); maMap[pMap->maName] = pMap; } diff --git a/comphelper/source/property/MasterPropertySet.cxx b/comphelper/source/property/MasterPropertySet.cxx index 3f6f0119dbb6..bd5ce83eaa16 100644 --- a/comphelper/source/property/MasterPropertySet.cxx +++ b/comphelper/source/property/MasterPropertySet.cxx @@ -27,17 +27,18 @@ #include <memory> #include <vector> +#include <optional> namespace { class AutoOGuardArray { - std::vector<std::unique_ptr< osl::Guard< comphelper::SolarMutex > >> maGuardArray; + std::vector<std::optional< osl::Guard< comphelper::SolarMutex > >> maGuardArray; public: explicit AutoOGuardArray( sal_Int32 nNumElements ); - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; } + std::optional< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; } }; } @@ -91,9 +92,9 @@ void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet ) void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName ); @@ -111,9 +112,9 @@ void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get(); // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard2; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2; if (pSlave->mpMutex) - xMutexGuard2.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) ); + xMutexGuard2.emplace( pSlave->mpMutex ); pSlave->_preSetValues(); pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue ); @@ -124,9 +125,9 @@ void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName ); @@ -145,9 +146,9 @@ Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get(); // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard2; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2; if (pSlave->mpMutex) - xMutexGuard2.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) ); + xMutexGuard2.emplace( pSlave->mpMutex ); pSlave->_preGetValues(); pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny ); @@ -180,9 +181,9 @@ void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const OUString&, void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); const sal_Int32 nCount = aPropertyNames.getLength(); @@ -194,8 +195,6 @@ void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& _preSetValues(); - const Any * pAny = aValues.getConstArray(); - const OUString * pString = aPropertyNames.getConstArray(); PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; //!! have a unique_ptr to an array of OGuards in order to have the @@ -205,14 +204,14 @@ void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& //!! the acquired locks properly released. AutoOGuardArray aOGuardArray( nCount ); - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); + aIter = mxInfo->maMap.find(aPropertyNames[i]); if ( aIter == aEnd ) - throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) ); + throw RuntimeException(aPropertyNames[i], static_cast<XPropertySet*>(this)); if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! - _setSingleValue( *((*aIter).second->mpInfo), *pAny ); + _setSingleValue(*((*aIter).second->mpInfo), aValues[i]); else { SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]; @@ -220,12 +219,12 @@ void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). if (pSlave->mxSlave->mpMutex) - aOGuardArray[i].reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mxSlave->mpMutex) ); + aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex ); pSlave->mxSlave->_preSetValues(); pSlave->SetInit ( true ); } - pSlave->mxSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny ); + pSlave->mxSlave->_setSingleValue(*((*aIter).second->mpInfo), aValues[i]); } } @@ -243,9 +242,9 @@ void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames ) { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(mpMutex) ); + xMutexGuard.emplace( mpMutex ); const sal_Int32 nCount = aPropertyNames.getLength(); @@ -256,7 +255,6 @@ Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< O _preGetValues(); Any * pAny = aValues.getArray(); - const OUString * pString = aPropertyNames.getConstArray(); PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; //!! have a unique_ptr to an array of OGuards in order to have the @@ -266,14 +264,14 @@ Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< O //!! the acquired locks properly released. AutoOGuardArray aOGuardArray( nCount ); - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); + aIter = mxInfo->maMap.find(aPropertyNames[i]); if ( aIter == aEnd ) - throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) ); + throw RuntimeException(aPropertyNames[i], static_cast<XPropertySet*>(this)); if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours ! - _getSingleValue( *((*aIter).second->mpInfo), *pAny ); + _getSingleValue(*((*aIter).second->mpInfo), pAny[i]); else { SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]; @@ -281,12 +279,12 @@ Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< O { // acquire mutex in c-tor and releases it in the d-tor (exception safe!). if (pSlave->mxSlave->mpMutex) - aOGuardArray[i].reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mxSlave->mpMutex) ); + aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex ); pSlave->mxSlave->_preGetValues(); pSlave->SetInit ( true ); } - pSlave->mxSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny ); + pSlave->mxSlave->_getSingleValue(*((*aIter).second->mpInfo), pAny[i]); } } @@ -331,9 +329,9 @@ PropertyState SAL_CALL MasterPropertySet::getPropertyState( const OUString& Prop ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get(); // acquire mutex in c-tor and releases it in the d-tor (exception safe!). - std::unique_ptr< osl::Guard< comphelper::SolarMutex > > xMutexGuard; + std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard; if (pSlave->mpMutex) - xMutexGuard.reset( new osl::Guard< comphelper::SolarMutex >(pSlave->mpMutex) ); + xMutexGuard.emplace( pSlave->mpMutex ); } return PropertyState_AMBIGUOUS_VALUE; @@ -347,14 +345,13 @@ Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const S if( nCount ) { PropertyState * pState = aStates.getArray(); - const OUString * pString = rPropertyNames.getConstArray(); PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter; - for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState ) + for (sal_Int32 i = 0; i < nCount; ++i) { - aIter = mxInfo->maMap.find ( *pString ); + aIter = mxInfo->maMap.find(rPropertyNames[i]); if ( aIter == aEnd ) - throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) ); + throw UnknownPropertyException(rPropertyNames[i], static_cast<XPropertySet*>(this)); // 0 means it's one of ours ! if ( (*aIter).second->mnMapId != 0 ) @@ -365,6 +362,8 @@ Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const S pSlave->SetInit ( true ); } } + + pState[i] = PropertyState_AMBIGUOUS_VALUE; } for( const auto& rSlave : maSlaveMap ) { diff --git a/comphelper/source/property/MasterPropertySetInfo.cxx b/comphelper/source/property/MasterPropertySetInfo.cxx index db8ddb769975..4040b479a05c 100644 --- a/comphelper/source/property/MasterPropertySetInfo.cxx +++ b/comphelper/source/property/MasterPropertySetInfo.cxx @@ -31,7 +31,7 @@ MasterPropertySetInfo::MasterPropertySetInfo( PropertyInfo const * pMap ) for ( ; !pMap->maName.isEmpty(); ++pMap ) { SAL_WARN_IF( - maMap.find(pMap->maName) != maMap.end(), + maMap.contains(pMap->maName), "comphelper", "Duplicate property name \"" << pMap->maName << "\""); maMap[pMap->maName] = new PropertyData ( 0, pMap ); } @@ -52,7 +52,7 @@ void MasterPropertySetInfo::add( PropertyInfoHash &rHash, sal_uInt8 nMapId ) for( const auto& rObj : rHash ) { SAL_WARN_IF( - maMap.find(rObj.first) != maMap.end(), + maMap.contains(rObj.first), "comphelper", "Duplicate property name \"" << rObj.first << "\""); maMap[rObj.first] = new PropertyData ( nMapId, rObj.second ); } diff --git a/comphelper/source/property/genericpropertyset.cxx b/comphelper/source/property/genericpropertyset.cxx index 68ae7a3353b4..c33ed391ec96 100644 --- a/comphelper/source/property/genericpropertyset.cxx +++ b/comphelper/source/property/genericpropertyset.cxx @@ -25,14 +25,13 @@ #include <com/sun/star/lang/XTypeProvider.hpp> #include <cppuhelper/weakagg.hxx> #include <cppuhelper/supportsservice.hxx> -#include <comphelper/multiinterfacecontainer2.hxx> +#include <comphelper/multiinterfacecontainer4.hxx> #include <comphelper/propertysethelper.hxx> -#include <osl/mutex.hxx> +#include <mutex> #include <rtl/ref.hxx> #include <comphelper/genericpropertyset.hxx> #include <comphelper/propertysetinfo.hxx> -using namespace ::osl; using namespace ::cppu; using namespace ::comphelper; using namespace ::com::sun::star; @@ -44,20 +43,15 @@ namespace comphelper { namespace { - struct IMPL_GenericPropertySet_MutexContainer - { - Mutex maMutex; - }; - - class GenericPropertySet : public OWeakAggObject, + class GenericPropertySet : public OWeakObject, public XServiceInfo, public XTypeProvider, - public PropertySetHelper, - private IMPL_GenericPropertySet_MutexContainer + public PropertySetHelper { private: std::map<OUString, Any> maAnyMap; - comphelper::OMultiTypeInterfaceContainerHelperVar2<OUString> m_aListener; + std::mutex maMutex; + comphelper::OMultiTypeInterfaceContainerHelperVar4<OUString, XPropertyChangeListener> m_aListener; protected: virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) override; @@ -67,7 +61,6 @@ namespace comphelper explicit GenericPropertySet( PropertySetInfo* pInfo ) noexcept; // XInterface - virtual Any SAL_CALL queryAggregation( const Type & rType ) override; virtual Any SAL_CALL queryInterface( const Type & rType ) override; virtual void SAL_CALL acquire() noexcept override; virtual void SAL_CALL release() noexcept override; @@ -92,7 +85,6 @@ namespace comphelper GenericPropertySet::GenericPropertySet( PropertySetInfo* pInfo ) noexcept : PropertySetHelper( pInfo ) -,m_aListener(maMutex) { } @@ -102,53 +94,47 @@ void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& aPr if ( !xInfo.is() ) return; + std::unique_lock aGuard(maMutex); if ( aPropertyName.isEmpty() ) { - Sequence< Property> aSeq = xInfo->getProperties(); - const Property* pIter = aSeq.getConstArray(); - const Property* pEnd = pIter + aSeq.getLength(); - for( ; pIter != pEnd ; ++pIter) + for (auto& prop : xInfo->getProperties()) { - m_aListener.addInterface(pIter->Name,xListener); + m_aListener.addInterface(aGuard, prop.Name, xListener); } } else if ( xInfo->hasPropertyByName(aPropertyName) ) - m_aListener.addInterface(aPropertyName,xListener); + m_aListener.addInterface(aGuard, aPropertyName,xListener); else throw UnknownPropertyException( aPropertyName, *this ); } void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) { - ClearableMutexGuard aGuard( maMutex ); Reference < XPropertySetInfo > xInfo = getPropertySetInfo( ); - aGuard.clear(); if ( !xInfo.is() ) return; + std::unique_lock aGuard(maMutex); if ( aPropertyName.isEmpty() ) { - Sequence< Property> aSeq = xInfo->getProperties(); - const Property* pIter = aSeq.getConstArray(); - const Property* pEnd = pIter + aSeq.getLength(); - for( ; pIter != pEnd ; ++pIter) + for (auto& prop : xInfo->getProperties()) { - m_aListener.removeInterface(pIter->Name,xListener); + m_aListener.removeInterface(aGuard, prop.Name, xListener); } } else if ( xInfo->hasPropertyByName(aPropertyName) ) - m_aListener.removeInterface(aPropertyName,xListener); + m_aListener.removeInterface(aGuard, aPropertyName,xListener); else throw UnknownPropertyException( aPropertyName, *this ); } void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) { - ResettableMutexGuard aGuard( maMutex ); + std::unique_lock aGuard(maMutex); while( *ppEntries ) { - OInterfaceContainerHelper2 * pHelper = m_aListener.getContainer((*ppEntries)->maName); + OInterfaceContainerHelper4<XPropertyChangeListener> * pHelper = m_aListener.getContainer(aGuard, (*ppEntries)->maName); maAnyMap[ (*ppEntries)->maName ] = *pValues; @@ -157,9 +143,7 @@ void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, PropertyChangeEvent aEvt; aEvt.PropertyName = (*ppEntries)->maName; aEvt.NewValue = *pValues; - aGuard.clear(); - pHelper->notifyEach( &XPropertyChangeListener::propertyChange, aEvt ); - aGuard.reset(); + pHelper->notifyEach( aGuard, &XPropertyChangeListener::propertyChange, aEvt ); } ppEntries++; @@ -169,7 +153,7 @@ void GenericPropertySet::_setPropertyValues( const PropertyMapEntry** ppEntries, void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, Any* pValue ) { - MutexGuard aGuard( maMutex ); + std::unique_lock aGuard(maMutex); while( *ppEntries ) { @@ -184,11 +168,6 @@ void GenericPropertySet::_getPropertyValues( const comphelper::PropertyMapEntry* Any SAL_CALL GenericPropertySet::queryInterface( const Type & rType ) { - return OWeakAggObject::queryInterface( rType ); -} - -Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType ) -{ Any aAny; if( rType == cppu::UnoType<XServiceInfo>::get()) @@ -200,19 +179,19 @@ Any SAL_CALL GenericPropertySet::queryAggregation( const Type & rType ) else if( rType == cppu::UnoType<XMultiPropertySet>::get()) aAny <<= Reference< XMultiPropertySet >(this); else - aAny = OWeakAggObject::queryAggregation( rType ); + aAny = OWeakObject::queryInterface( rType ); return aAny; } void SAL_CALL GenericPropertySet::acquire() noexcept { - OWeakAggObject::acquire(); + OWeakObject::acquire(); } void SAL_CALL GenericPropertySet::release() noexcept { - OWeakAggObject::release(); + OWeakObject::release(); } uno::Sequence< uno::Type > SAL_CALL GenericPropertySet::getTypes() @@ -238,12 +217,12 @@ sal_Bool SAL_CALL GenericPropertySet::supportsService( const OUString& ServiceN OUString SAL_CALL GenericPropertySet::getImplementationName() { - return "com.sun.star.comp.comphelper.GenericPropertySet"; + return u"com.sun.star.comp.comphelper.GenericPropertySet"_ustr; } Sequence< OUString > SAL_CALL GenericPropertySet::getSupportedServiceNames( ) { - return { "com.sun.star.beans.XPropertySet" }; + return { u"com.sun.star.beans.XPropertySet"_ustr }; } css::uno::Reference< css::beans::XPropertySet > comphelper::GenericPropertySet_CreateInstance( comphelper::PropertySetInfo* pInfo ) diff --git a/comphelper/source/property/opropertybag.cxx b/comphelper/source/property/opropertybag.cxx index e0b389c19199..eec379ffd761 100644 --- a/comphelper/source/property/opropertybag.cxx +++ b/comphelper/source/property/opropertybag.cxx @@ -89,11 +89,11 @@ namespace comphelper } else { ::comphelper::NamedValueCollection aArguments( _rArguments ); - if ( aArguments.get_ensureType( "AllowedTypes", aTypes ) ) + if ( aArguments.get_ensureType( u"AllowedTypes"_ustr, aTypes ) ) m_aAllowedTypes.insert(std::cbegin(aTypes), std::cend(aTypes)); - aArguments.get_ensureType( "AutomaticAddition", m_bAutoAddProperties ); - aArguments.get_ensureType( "AllowEmptyPropertyName", + aArguments.get_ensureType( u"AutomaticAddition"_ustr, m_bAutoAddProperties ); + aArguments.get_ensureType( u"AllowEmptyPropertyName"_ustr, AllowEmptyPropertyName ); } if (AllowEmptyPropertyName) { @@ -104,7 +104,7 @@ namespace comphelper OUString SAL_CALL OPropertyBag::getImplementationName() { - return "com.sun.star.comp.comphelper.OPropertyBag"; + return u"com.sun.star.comp.comphelper.OPropertyBag"_ustr; } sal_Bool SAL_CALL OPropertyBag::supportsService( const OUString& rServiceName ) @@ -114,7 +114,7 @@ namespace comphelper Sequence< OUString > SAL_CALL OPropertyBag::getSupportedServiceNames( ) { - return { "com.sun.star.beans.PropertyBag" }; + return { u"com.sun.star.beans.PropertyBag"_ustr }; } void OPropertyBag::fireEvents( @@ -197,7 +197,7 @@ namespace comphelper // If we ever have a smarter XPropertyContainer::addProperty interface, we can remove this, ehm, well, hack. Property aProperty; if ( !( _element >>= aProperty ) ) - throw IllegalArgumentException( "element is not Property", *this, 1 ); + throw IllegalArgumentException( u"element is not Property"_ustr, *this, 1 ); { osl::MutexGuard g(m_aMutex); @@ -206,7 +206,7 @@ namespace comphelper // by m_aDynamicProperties if (!m_aAllowedTypes.empty() && m_aAllowedTypes.find(aProperty.Type) == m_aAllowedTypes.end()) - throw IllegalArgumentException("not in list of allowed types", *this, 1); + throw IllegalArgumentException(u"not in list of allowed types"_ustr, *this, 1); m_aDynamicProperties.addVoidProperty(aProperty.Name, aProperty.Type, findFreeHandle(), aProperty.Attributes); @@ -389,7 +389,7 @@ namespace comphelper { aValues = OPropertyBag_PBase::getPropertyValues( aNames ); if ( aValues.getLength() != aNames.getLength() ) - throw RuntimeException(); + throw RuntimeException(u"property name and value counts out of sync"_ustr); } catch( const RuntimeException& ) { @@ -404,17 +404,14 @@ namespace comphelper ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); Sequence< PropertyValue > aPropertyValues( aNames.getLength() ); - const OUString* pName = aNames.getConstArray(); - const OUString* pNamesEnd = aNames.getConstArray() + aNames.getLength(); - const Any* pValue = aValues.getArray(); PropertyValue* pPropertyValue = aPropertyValues.getArray(); - for ( ; pName != pNamesEnd; ++pName, ++pValue, ++pPropertyValue ) + for (sal_Int32 i = 0; i < aNames.getLength(); ++i) { - pPropertyValue->Name = *pName; - pPropertyValue->Handle = rPropInfo.getHandleByName( *pName ); - pPropertyValue->Value = *pValue; - pPropertyValue->State = getPropertyStateByHandle( pPropertyValue->Handle ); + pPropertyValue[i].Name = aNames[i]; + pPropertyValue[i].Handle = rPropInfo.getHandleByName(aNames[i]); + pPropertyValue[i].Value = aValues[i]; + pPropertyValue[i].State = getPropertyStateByHandle(pPropertyValue[i].Handle); } return aPropertyValues; @@ -452,16 +449,12 @@ namespace comphelper sal_Int32 nCount = aNames.getLength(); Sequence< sal_Int32 > aHandles( nCount ); - sal_Int32* pHandle = aHandles.getArray(); - const PropertyValue* pProperty = aProperties.getConstArray(); - for ( const OUString* pName = aNames.getConstArray(); - pName != aNames.getConstArray() + aNames.getLength(); - ++pName, ++pHandle, ++pProperty - ) + sal_Int32* pHandles = aHandles.getArray(); + for (sal_Int32 i = 0; i < nCount; ++i) { ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); - *pHandle = rPropInfo.getHandleByName( *pName ); - if ( *pHandle != -1 ) + pHandles[i] = rPropInfo.getHandleByName(aNames[i]); + if (pHandles[i] != -1) continue; // there's a property requested which we do not know @@ -469,12 +462,12 @@ namespace comphelper { // add the property sal_Int16 const nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVABLE | PropertyAttribute::MAYBEDEFAULT; - addProperty( *pName, nAttributes, pProperty->Value ); + addProperty(aNames[i], nAttributes, aProperties[i].Value); continue; } // no way out - throw UnknownPropertyException( *pName, *this ); + throw UnknownPropertyException(aNames[i], *this); } // a sequence of values @@ -486,7 +479,7 @@ namespace comphelper ExtractPropertyValue() ); - setFastPropertyValues( nCount, aHandles.getArray(), aValues.getConstArray(), nCount ); + setFastPropertyValues(nCount, pHandles, aValues.getConstArray(), nCount); } catch( const PropertyVetoException& ) { throw; } catch( const IllegalArgumentException& ) { throw; } diff --git a/comphelper/source/property/opropertybag.hxx b/comphelper/source/property/opropertybag.hxx index 73957e51a39f..66c38d870c10 100644 --- a/comphelper/source/property/opropertybag.hxx +++ b/comphelper/source/property/opropertybag.hxx @@ -25,8 +25,8 @@ #include <com/sun/star/beans/XPropertyBag.hpp> #include <com/sun/star/container/XSet.hpp> -#include <cppuhelper/implbase5.hxx> -#include <comphelper/interfacecontainer2.hxx> +#include <cppuhelper/implbase.hxx> +#include <comphelper/interfacecontainer3.hxx> #include <comphelper/propstate.hxx> #include <comphelper/broadcasthelper.hxx> #include <comphelper/propertybag.hxx> @@ -55,12 +55,12 @@ namespace comphelper typedef std::map< sal_Int32, css::uno::Any > MapInt2Any; typedef std::set< css::uno::Type, UnoTypeLess > TypeBag; - typedef ::cppu::WeakAggImplHelper5 < css::beans::XPropertyBag - , css::util::XModifiable - , css::lang::XServiceInfo - , css::lang::XInitialization - , css::container::XSet - > OPropertyBag_Base; + typedef ::cppu::WeakImplHelper < css::beans::XPropertyBag + , css::util::XModifiable + , css::lang::XServiceInfo + , css::lang::XInitialization + , css::container::XSet + > OPropertyBag_Base; typedef ::comphelper::OPropertyStateHelper OPropertyBag_PBase; class OPropertyBag final : public ::comphelper::OMutexAndBroadcastHelper // must be before OPropertyBag_PBase @@ -80,7 +80,7 @@ namespace comphelper bool m_bAutoAddProperties; /// for notification - ::comphelper::OInterfaceContainerHelper2 m_NotifyListeners; + ::comphelper::OInterfaceContainerHelper3<css::util::XModifyListener> m_NotifyListeners; /// modify flag bool m_isModified; diff --git a/comphelper/source/property/propagg.cxx b/comphelper/source/property/propagg.cxx index a93c82c98fae..f84649b3bf19 100644 --- a/comphelper/source/property/propagg.cxx +++ b/comphelper/source/property/propagg.cxx @@ -27,6 +27,7 @@ #include <o3tl/sorted_vector.hxx> #include <typeinfo> #include <algorithm> +#include <cstddef> #include <unordered_set> #include <memory> @@ -83,12 +84,13 @@ OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper( std::unordered_set< sal_Int32 > existingHandles; existingHandles.reserve( m_aProperties.size() ); sal_Int32 nAggregateHandle = _nFirstAggregateId; - for ( sal_Int32 nMPLoop = 0; nMPLoop < static_cast< sal_Int32 >( m_aProperties.size() ); ++nMPLoop ) + for ( std::size_t nMPLoop = 0; nMPLoop < m_aProperties.size(); ++nMPLoop ) { auto &prop = m_aProperties[ nMPLoop ]; if ( aDelegatorProps.find( prop.Name ) != aDelegatorProps.end() ) { - m_aPropertyAccessors[ prop.Handle ] = OPropertyAccessor( -1, nMPLoop, false ); + m_aPropertyAccessors.insert_or_assign( + prop.Handle, OPropertyAccessor( -1, nMPLoop, false )); existingHandles.insert( prop.Handle ); } else @@ -111,7 +113,8 @@ OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper( } // remember the accessor for this property - m_aPropertyAccessors[ nHandle ] = OPropertyAccessor( prop.Handle, nMPLoop, true ); + m_aPropertyAccessors.insert_or_assign( + nHandle, OPropertyAccessor( prop.Handle, nMPLoop, true )); prop.Handle = nHandle; } } @@ -126,7 +129,7 @@ OPropertyArrayAggregationHelper::PropertyOrigin OPropertyArrayAggregationHelper: if ( pPropertyDescriptor ) { // look up the handle for this name - ConstPropertyAccessorMapIterator aPos = m_aPropertyAccessors.find( pPropertyDescriptor->Handle ); + auto aPos = m_aPropertyAccessors.find( pPropertyDescriptor->Handle ); OSL_ENSURE( m_aPropertyAccessors.end() != aPos, "OPropertyArrayAggregationHelper::classifyProperty: should have this handle in my map!" ); if ( m_aPropertyAccessors.end() != aPos ) { @@ -170,7 +173,7 @@ sal_Int32 OPropertyArrayAggregationHelper::getHandleByName(const OUString& _rPro sal_Bool OPropertyArrayAggregationHelper::fillPropertyMembersByHandle( OUString* _pPropName, sal_Int16* _pAttributes, sal_Int32 _nHandle) { - ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle); + auto i = m_aPropertyAccessors.find(_nHandle); bool bRet = i != m_aPropertyAccessors.end(); if (bRet) { @@ -186,7 +189,7 @@ sal_Bool OPropertyArrayAggregationHelper::fillPropertyMembersByHandle( bool OPropertyArrayAggregationHelper::getPropertyByHandle( sal_Int32 _nHandle, Property& _rProperty ) const { - ConstPropertyAccessorMapIterator pos = m_aPropertyAccessors.find(_nHandle); + auto pos = m_aPropertyAccessors.find(_nHandle); if ( pos != m_aPropertyAccessors.end() ) { _rProperty = m_aProperties[ pos->second.nPos ]; @@ -199,7 +202,7 @@ bool OPropertyArrayAggregationHelper::getPropertyByHandle( sal_Int32 _nHandle, P bool OPropertyArrayAggregationHelper::fillAggregatePropertyInfoByHandle( OUString* _pPropName, sal_Int32* _pOriginalHandle, sal_Int32 _nHandle) const { - ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle); + auto i = m_aPropertyAccessors.find(_nHandle); bool bRet = i != m_aPropertyAccessors.end() && (*i).second.bAggregate; if (bRet) { @@ -207,7 +210,7 @@ bool OPropertyArrayAggregationHelper::fillAggregatePropertyInfoByHandle( *_pOriginalHandle = (*i).second.nOriginalHandle; if (_pPropName) { - OSL_ENSURE((*i).second.nPos < static_cast<sal_Int32>(m_aProperties.size()),"Invalid index for sequence!"); + OSL_ENSURE((*i).second.nPos < m_aProperties.size(),"Invalid index for sequence!"); const css::beans::Property& rProperty = m_aProperties[(*i).second.nPos]; *_pPropName = rProperty.Name; } @@ -226,15 +229,13 @@ sal_Int32 OPropertyArrayAggregationHelper::fillHandles( sal_Int32* _pHandles, const css::uno::Sequence< OUString >& _rPropNames ) { sal_Int32 nHitCount = 0; - const OUString* pReqProps = _rPropNames.getConstArray(); - sal_Int32 nReqLen = _rPropNames.getLength(); Property aNameProp; - for( sal_Int32 i = 0; i < nReqLen; ++i ) + for (sal_Int32 i = 0; i < _rPropNames.getLength(); ++i) { - aNameProp.Name = pReqProps[i]; + aNameProp.Name = _rPropNames[i]; auto findIter = std::lower_bound(m_aProperties.begin(), m_aProperties.end(), aNameProp, PropertyCompareByName()); - if ( findIter != m_aProperties.end() && findIter->Name == pReqProps[i] ) + if (findIter != m_aProperties.end() && findIter->Name == _rPropNames[i]) { _pHandles[i] = findIter->Handle; nHitCount++; @@ -383,7 +384,7 @@ void SAL_CALL OPropertySetAggregationHelper::propertiesChange(const css::uno::Se if (1 == nLen) { - const css::beans::PropertyChangeEvent& evt = _rEvents.getConstArray()[0]; + const css::beans::PropertyChangeEvent& evt = _rEvents[0]; OSL_ENSURE(!evt.PropertyName.isEmpty(), "OPropertySetAggregationHelper::propertiesChange : invalid event !"); // we had a bug where this assertion would have us saved a whole day :) (72514) sal_Int32 nHandle = rPH.getHandleByName( evt.PropertyName ); @@ -586,6 +587,9 @@ void SAL_CALL OPropertySetAggregationHelper::setPropertyValues( OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues); else if (_rPropertyNames.getLength() == 1) // use the more efficient way { + if (_rValues.getLength() != 1) + throw IllegalArgumentException(u"lengths do not match"_ustr, static_cast<XPropertySet*>(this), + -1); try { setPropertyValue( _rPropertyNames[0], _rValues[0] ); @@ -628,9 +632,9 @@ void SAL_CALL OPropertySetAggregationHelper::setPropertyValues( // mixed else { - const css::uno::Any* pValues = _rValues.getConstArray(); - - // dividing the Names and _rValues + if (_rValues.getLength() != nLen) + throw IllegalArgumentException(u"lengths do not match"_ustr, + static_cast<XPropertySet*>(this), -1); // aggregate's names Sequence< OUString > AggPropertyNames( nAggCount ); @@ -647,23 +651,20 @@ void SAL_CALL OPropertySetAggregationHelper::setPropertyValues( Sequence< Any > DelValues( nLen - nAggCount ); Any* pDelValues = DelValues.getArray(); - for ( const OUString& rName : _rPropertyNames ) + for (sal_Int32 i = 0; i < nLen; ++i) { - if ( OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate == rPH.classifyProperty( rName ) ) + if ( OPropertyArrayAggregationHelper::PropertyOrigin::Aggregate == rPH.classifyProperty( _rPropertyNames[i] ) ) { - *pAggNames++ = rName; - *pAggValues++ = *pValues++; + *pAggNames++ = _rPropertyNames[i]; + *pAggValues++ = _rValues[i]; } else { - *pDelNames++ = rName; - *pDelValues++ = *pValues++; + *pDelNames++ = _rPropertyNames[i]; + *pDelValues++ = _rValues[i]; } } - // reset, needed below - pDelValues = DelValues.getArray(); - std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[ nLen - nAggCount ]); // get the map table @@ -691,7 +692,7 @@ void SAL_CALL OPropertySetAggregationHelper::setPropertyValues( throw css::beans::PropertyVetoException(); // Will the property change? if( convertFastPropertyValue( pConvertedValues[ nHitCount ], pOldValues[nHitCount], - pHandles[i], pDelValues[i] ) ) + pHandles[i], DelValues[i] ) ) { // only increment if the property really change pHandles[nHitCount] = pHandles[i]; diff --git a/comphelper/source/property/property.cxx b/comphelper/source/property/property.cxx index 49a7a108f09a..7d57baeb39cb 100644 --- a/comphelper/source/property/property.cxx +++ b/comphelper/source/property/property.cxx @@ -21,6 +21,7 @@ #include <comphelper/sequence.hxx> #include <osl/diagnose.h> #include <sal/log.hxx> +#include <comphelper/diagnose_ex.hxx> #if OSL_DEBUG_LEVEL > 0 #include <cppuhelper/exc_hlp.hxx> @@ -87,10 +88,12 @@ void copyProperties(const Reference<XPropertySet>& _rxSource, catch (Exception&) { #if OSL_DEBUG_LEVEL > 0 - OUStringBuffer aBuffer; - aBuffer.append( "::comphelper::copyProperties: could not copy property '" ); - aBuffer.append(rSourceProp.Name ); - aBuffer.append( "' to the destination set (a '" ); + TOOLS_WARN_EXCEPTION("comphelper", "Caught exception copying properties"); + + OUStringBuffer aBuffer( + "::comphelper::copyProperties: could not copy property '" + + rSourceProp.Name + + "' to the destination set (a '" ); Reference< XServiceInfo > xSI( _rxDest, UNO_QUERY ); if ( xSI.is() ) @@ -99,21 +102,21 @@ void copyProperties(const Reference<XPropertySet>& _rxSource, } else { - aBuffer.append( OUString::createFromAscii(typeid( *_rxDest ).name()) ); + aBuffer.appendAscii( typeid( *_rxDest ).name() ); } aBuffer.append( "' implementation).\n" ); Any aException( ::cppu::getCaughtException() ); - aBuffer.append( "Caught an exception of type '" ); - aBuffer.append( aException.getValueTypeName() ); - aBuffer.append( "'" ); + aBuffer.append( "Caught an exception of type '" + + aException.getValueTypeName() + + "'" ); Exception aBaseException; if ( ( aException >>= aBaseException ) && !aBaseException.Message.isEmpty() ) { - aBuffer.append( ", saying '" ); - aBuffer.append( aBaseException.Message ); - aBuffer.append( "'" ); + aBuffer.append( ", saying '" + + aBaseException.Message + + "'" ); } aBuffer.append( "." ); diff --git a/comphelper/source/property/propertybag.cxx b/comphelper/source/property/propertybag.cxx index 02e6f78c1287..b85786705cf0 100644 --- a/comphelper/source/property/propertybag.cxx +++ b/comphelper/source/property/propertybag.cxx @@ -70,7 +70,7 @@ namespace comphelper { if ( !_allowEmpty && _name.empty() ) throw IllegalArgumentException( - "The property name must not be empty.", + u"The property name must not be empty."_ustr, // TODO: resource nullptr, 1 @@ -81,7 +81,7 @@ namespace comphelper { if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) ) throw PropertyExistException( - "Property name or handle already used.", + u"Property name or handle already used."_ustr, nullptr ); } @@ -90,7 +90,7 @@ namespace comphelper { if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) ) throw ElementExistException( - "Property name or handle already used.", + u"Property name or handle already used."_ustr, nullptr ); } @@ -102,7 +102,7 @@ namespace comphelper { if ( _rType.getTypeClass() == TypeClass_VOID ) throw IllegalArgumentException( - "Illegal property type: VOID", + u"Illegal property type: VOID"_ustr, // TODO: resource nullptr, 1 @@ -127,7 +127,7 @@ namespace comphelper const Type& aPropertyType = _rInitialValue.getValueType(); if ( aPropertyType.getTypeClass() == TypeClass_VOID ) throw IllegalTypeException( - "The initial value must be non-NULL to determine the property type.", + u"The initial value must be non-NULL to determine the property type."_ustr, // TODO: resource nullptr ); diff --git a/comphelper/source/property/propertycontainer.cxx b/comphelper/source/property/propertycontainer.cxx index 2b5685405604..ad24c5f30aa7 100644 --- a/comphelper/source/property/propertycontainer.cxx +++ b/comphelper/source/property/propertycontainer.cxx @@ -26,7 +26,6 @@ namespace comphelper using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; OPropertyContainer::OPropertyContainer(::cppu::OBroadcastHelper& _rBHelper) diff --git a/comphelper/source/property/propertycontainer2.cxx b/comphelper/source/property/propertycontainer2.cxx new file mode 100644 index 000000000000..5a3bfa4be285 --- /dev/null +++ b/comphelper/source/property/propertycontainer2.cxx @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <comphelper/propertycontainer2.hxx> +#include <cppuhelper/typeprovider.hxx> + +namespace comphelper +{ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +OPropertyContainer2::OPropertyContainer2() {} + +OPropertyContainer2::~OPropertyContainer2() {} + +Sequence<Type> OPropertyContainer2::getBaseTypes() +{ + // just the types from our one and only base class + ::cppu::OTypeCollection aTypes(cppu::UnoType<XPropertySet>::get(), + cppu::UnoType<XFastPropertySet>::get(), + cppu::UnoType<XMultiPropertySet>::get()); + return aTypes.getTypes(); +} + +bool OPropertyContainer2::convertFastPropertyValue(std::unique_lock<std::mutex>& /*rGuard*/, + Any& _rConvertedValue, Any& _rOldValue, + sal_Int32 _nHandle, const Any& _rValue) +{ + return OPropertyContainerHelper::convertFastPropertyValue(_rConvertedValue, _rOldValue, + _nHandle, _rValue); +} + +void OPropertyContainer2::setFastPropertyValue_NoBroadcast(std::unique_lock<std::mutex>& /*rGuard*/, + sal_Int32 _nHandle, const Any& _rValue) +{ + OPropertyContainerHelper::setFastPropertyValue(_nHandle, _rValue); +} + +void OPropertyContainer2::getFastPropertyValue(std::unique_lock<std::mutex>& /*rGuard*/, + Any& _rValue, sal_Int32 _nHandle) const +{ + OPropertyContainerHelper::getFastPropertyValue(_rValue, _nHandle); +} + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertycontainerhelper.cxx b/comphelper/source/property/propertycontainerhelper.cxx index 5fd6053ce100..ee81100ae617 100644 --- a/comphelper/source/property/propertycontainerhelper.cxx +++ b/comphelper/source/property/propertycontainerhelper.cxx @@ -26,6 +26,7 @@ #include <com/sun/star/beans/UnknownPropertyException.hpp> #include <algorithm> +#include <utility> namespace comphelper @@ -51,7 +52,7 @@ namespace struct PropertyDescriptionNameMatch { OUString const m_rCompare; - explicit PropertyDescriptionNameMatch( const OUString& _rCompare ) : m_rCompare( _rCompare ) { } + explicit PropertyDescriptionNameMatch( OUString _aCompare ) : m_rCompare(std::move( _aCompare )) { } bool operator() (const PropertyDescription& x ) const { @@ -269,7 +270,7 @@ bool OPropertyContainerHelper::convertFastPropertyValue( if (PropertyDescription::LocationType::HoldMyself == aPos->eLocated) { - OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < static_cast<sal_Int32>(m_aHoldProperties.size()), + OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < m_aHoldProperties.size(), "OPropertyContainerHelper::convertFastPropertyValue: invalid position !"); auto aIter = m_aHoldProperties.begin() + aPos->aLocation.nOwnClassVectorIndex; pPropContainer = &(*aIter); @@ -407,7 +408,7 @@ void OPropertyContainerHelper::getFastPropertyValue(Any& _rValue, sal_Int32 _nHa switch (aPos->eLocated) { case PropertyDescription::LocationType::HoldMyself: - OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < static_cast<sal_Int32>(m_aHoldProperties.size()), + OSL_ENSURE(aPos->aLocation.nOwnClassVectorIndex < m_aHoldProperties.size(), "OPropertyContainerHelper::convertFastPropertyValue: invalid position !"); _rValue = m_aHoldProperties[aPos->aLocation.nOwnClassVectorIndex]; break; diff --git a/comphelper/source/property/propertysethelper.cxx b/comphelper/source/property/propertysethelper.cxx index 1568aca9b49d..5172fbb17b8f 100644 --- a/comphelper/source/property/propertysethelper.cxx +++ b/comphelper/source/property/propertysethelper.cxx @@ -23,6 +23,7 @@ #include <rtl/ref.hxx> #include <memory> +#include <utility> using namespace ::comphelper; using namespace ::com::sun::star; @@ -41,8 +42,8 @@ static PropertyMapEntry const * find( const rtl::Reference<PropertySetInfo>& mxI } -PropertySetHelper::PropertySetHelper( rtl::Reference<comphelper::PropertySetInfo> const & xInfo ) noexcept - : mxInfo(xInfo) +PropertySetHelper::PropertySetHelper( rtl::Reference<comphelper::PropertySetInfo> xInfo ) noexcept + : mxInfo(std::move(xInfo)) { } @@ -111,28 +112,22 @@ void SAL_CALL PropertySetHelper::setPropertyValues( const Sequence< OUString >& const sal_Int32 nCount = rPropertyNames.getLength(); if( nCount != rValues.getLength() ) - throw IllegalArgumentException("lengths do not match", uno::Reference<uno::XInterface>(), -1); + throw IllegalArgumentException("lengths do not match", static_cast<XPropertySet*>(this), -1); if( !nCount ) return; std::unique_ptr<PropertyMapEntry const *[]> pEntries(new PropertyMapEntry const *[nCount+1]); pEntries[nCount] = nullptr; - const OUString* pNames = rPropertyNames.getConstArray(); - bool bUnknown = false; - sal_Int32 n; - for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + for (sal_Int32 n = 0; n < nCount; n++) { - pEntries[n] = find( mxInfo, *pNames ); - bUnknown = nullptr == pEntries[n]; + pEntries[n] = find(mxInfo, rPropertyNames[n]); + if (!pEntries[n]) + throw UnknownPropertyException(rPropertyNames[n], static_cast<XPropertySet*>(this)); } - if( !bUnknown ) - _setPropertyValues( pEntries.get(), rValues.getConstArray() ); - - if( bUnknown ) - throw RuntimeException( *pNames, static_cast< XPropertySet* >( this ) ); + _setPropertyValues(pEntries.get(), rValues.getConstArray()); } Sequence< Any > SAL_CALL PropertySetHelper::getPropertyValues(const Sequence< OUString >& rPropertyNames) @@ -143,22 +138,16 @@ Sequence< Any > SAL_CALL PropertySetHelper::getPropertyValues(const Sequence< OU return Sequence< Any >(); std::unique_ptr<PropertyMapEntry const *[]> pEntries(new PropertyMapEntry const *[nCount+1]); - const OUString* pNames = rPropertyNames.getConstArray(); - bool bUnknown = false; - sal_Int32 n; - for( n = 0; !bUnknown && ( n < nCount ); n++, pNames++ ) + for (sal_Int32 n = 0; n < nCount; n++) { - pEntries[n] = find( mxInfo, *pNames ); - bUnknown = nullptr == pEntries[n]; + pEntries[n] = find(mxInfo, rPropertyNames[n]); + if (!pEntries[n]) + throw UnknownPropertyException(rPropertyNames[n], static_cast<XPropertySet*>(this)); } - if( bUnknown ) - throw RuntimeException( *pNames, static_cast< XPropertySet* >( this ) ); - pEntries[nCount] = nullptr; Sequence< Any > aValues(nCount); - aValues.realloc(nCount); _getPropertyValues( pEntries.get(), aValues.getArray() ); return aValues; @@ -204,26 +193,19 @@ Sequence< PropertyState > SAL_CALL PropertySetHelper::getPropertyStates( const S if( nCount ) { - const OUString* pNames = aPropertyName.getConstArray(); - - bool bUnknown = false; - std::unique_ptr<PropertyMapEntry const *[]> pEntries(new PropertyMapEntry const *[nCount+1]); sal_Int32 n; - for( n = 0; !bUnknown && (n < nCount); n++, pNames++ ) + for (n = 0; n < nCount; n++) { - pEntries[n] = find( mxInfo, *pNames ); - bUnknown = nullptr == pEntries[n]; + pEntries[n] = find(mxInfo, aPropertyName[n]); + if (!pEntries[n]) + throw UnknownPropertyException(aPropertyName[n], static_cast<XPropertySet*>(this)); } pEntries[nCount] = nullptr; - if( !bUnknown ) - _getPropertyStates( pEntries.get(), aStates.getArray() ); - - if( bUnknown ) - throw UnknownPropertyException( *pNames, static_cast< XPropertySet* >( this ) ); + _getPropertyStates(pEntries.get(), aStates.getArray()); } return aStates; diff --git a/comphelper/source/property/propertysetinfo.cxx b/comphelper/source/property/propertysetinfo.cxx index f21afe3951cd..1d4ad2be8d25 100644 --- a/comphelper/source/property/propertysetinfo.cxx +++ b/comphelper/source/property/propertysetinfo.cxx @@ -20,78 +20,58 @@ #include <comphelper/propertysetinfo.hxx> #include <comphelper/sequence.hxx> -#include <vector> using namespace ::comphelper; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::lang; - -void PropertySetInfo::addImpl(PropertyMapEntry const * pMap) noexcept -{ - while (!pMap->maName.isEmpty()) - { - // check for duplicates - assert(maPropertyMap.find(pMap->maName) == maPropertyMap.end()); - - maPropertyMap[pMap->maName] = pMap; - - maProperties.clear(); - - ++pMap; - } -} PropertySetInfo::PropertySetInfo() noexcept { } -PropertySetInfo::PropertySetInfo( PropertyMapEntry const * pMap ) noexcept +PropertySetInfo::PropertySetInfo( std::span<const PropertyMapEntry> pMap ) noexcept { - while (!pMap->maName.isEmpty()) + maPropertyMap.reserve(pMap.size()); + for (const auto & rEntry : pMap) { // check for duplicates - assert(maPropertyMap.find(pMap->maName) == maPropertyMap.end()); + assert(maPropertyMap.find(rEntry.maName) == maPropertyMap.end()); + // Make sure there are no accidental empty entries left at the end of the array from + // when this method used to take a empty-terminated array. + assert(!rEntry.maName.isEmpty()); - maPropertyMap[pMap->maName] = pMap; - - ++pMap; + maPropertyMap.emplace(rEntry.maName, &rEntry); } } -PropertySetInfo::PropertySetInfo(uno::Sequence<beans::Property> const& rProps) noexcept -{ - PropertyMapEntry * pEntries(new PropertyMapEntry[rProps.getLength() + 1]); - PropertyMapEntry * pEntry(&pEntries[0]); - for (auto const& it : rProps) - { - pEntry->maName = it.Name; - pEntry->mnHandle = it.Handle; - pEntry->maType = it.Type; - pEntry->mnAttributes = it.Attributes; - pEntry->mnMemberId = 0; - ++pEntry; - } - pEntry->maName = OUString(); - - addImpl(pEntries); -} - PropertySetInfo::~PropertySetInfo() noexcept { } -void PropertySetInfo::add( PropertyMapEntry const * pMap ) noexcept +void PropertySetInfo::add( std::span<PropertyMapEntry const> pMap ) noexcept { - addImpl( pMap ); + maPropertyMap.reserve(maPropertyMap.size() + pMap.size()); + for (const auto & rEntry : pMap) + { + // check for duplicates + assert(maPropertyMap.find(rEntry.maName) == maPropertyMap.end()); + // Make sure there are no accidental empty entries left at the end of the array from + // when this method used to take a empty-terminated array. + assert(!rEntry.maName.isEmpty()); + + maPropertyMap.emplace(rEntry.maName, &rEntry); + } + + // clear cache + maProperties.realloc(0); } void PropertySetInfo::remove( const OUString& aName ) noexcept { maPropertyMap.erase( aName ); - maProperties.clear(); + maProperties.realloc(0); } Sequence< css::beans::Property > SAL_CALL PropertySetInfo::getProperties() @@ -101,8 +81,8 @@ Sequence< css::beans::Property > SAL_CALL PropertySetInfo::getProperties() // to getProperties if( maProperties.size() != maPropertyMap.size() ) { - maProperties.resize( maPropertyMap.size() ); - auto propIter = maProperties.begin(); + maProperties.realloc( maPropertyMap.size() ); + auto propIter = maProperties.getArray(); for( const auto& rProperty : maPropertyMap ) { @@ -116,7 +96,7 @@ Sequence< css::beans::Property > SAL_CALL PropertySetInfo::getProperties() ++propIter; } } - return comphelper::containerToSequence(maProperties); + return maProperties; } Property SAL_CALL PropertySetInfo::getPropertyByName( const OUString& aName ) @@ -133,7 +113,7 @@ Property SAL_CALL PropertySetInfo::getPropertyByName( const OUString& aName ) sal_Bool SAL_CALL PropertySetInfo::hasPropertyByName( const OUString& aName ) { - return maPropertyMap.find( aName ) != maPropertyMap.end(); + return maPropertyMap.contains( aName ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propertystatecontainer.cxx b/comphelper/source/property/propertystatecontainer.cxx index e19e78733689..9ab7f534dc02 100644 --- a/comphelper/source/property/propertystatecontainer.cxx +++ b/comphelper/source/property/propertystatecontainer.cxx @@ -30,7 +30,6 @@ namespace comphelper using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; - using namespace ::com::sun::star::lang; namespace { @@ -90,46 +89,34 @@ namespace comphelper #ifdef DBG_UTIL // precondition: property sequence is sorted (the algorithm below relies on this) - { - const OUString* pNames = _rPropertyNames.getConstArray(); - const OUString* pNamesCompare = pNames + 1; - const OUString* pNamesEnd = _rPropertyNames.getConstArray() + _rPropertyNames.getLength(); - for ( ; pNamesCompare != pNamesEnd; ++pNames, ++pNamesCompare ) - OSL_PRECOND( pNames->compareTo( *pNamesCompare ) < 0, + OSL_PRECOND(std::is_sorted(_rPropertyNames.begin(), _rPropertyNames.end(), + [](auto& lhs, auto& rhs) { return lhs.compareTo(rhs) < 0; }), "OPropertyStateContainer::getPropertyStates: property sequence not sorted!" ); - } #endif - const OUString* pLookup = _rPropertyNames.getConstArray(); - const OUString* pLookupEnd = pLookup + nProperties; PropertyState* pStates = aStates.getArray(); cppu::IPropertyArrayHelper& rHelper = getInfoHelper(); Sequence< Property> aAllProperties = rHelper.getProperties(); - sal_Int32 nAllProperties = aAllProperties.getLength(); - const Property* pAllProperties = aAllProperties.getConstArray(); - const Property* pAllPropertiesEnd = pAllProperties + nAllProperties; +#ifdef DBG_UTIL + OSL_ENSURE(std::is_sorted(aAllProperties.begin(), aAllProperties.end(), + [](auto& lhs, auto& rhs) + { return lhs.Name.compareTo(rhs.Name) < 0; }), + "OPropertyStateContainer::getPropertyStates: all-properties not sorted!"); +#endif + auto it = aAllProperties.begin(); + const auto end = aAllProperties.end(); osl::MutexGuard aGuard( rBHelper.rMutex ); - for ( ; ( pAllProperties != pAllPropertiesEnd ) && ( pLookup != pLookupEnd ); ++pAllProperties ) + for (auto& propName : _rPropertyNames) { -#ifdef DBG_UTIL - if ( pAllProperties < pAllPropertiesEnd - 1 ) - OSL_ENSURE( pAllProperties->Name.compareTo( (pAllProperties + 1)->Name ) < 0, - "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" ); -#endif - if ( pAllProperties->Name == *pLookup ) - { - *pStates++ = getPropertyState( *pLookup ); - ++pLookup; - } + it = std::find_if(it, end, [&propName](auto& prop) { return prop.Name == propName; }); + if (it == end) + throw UnknownPropertyException(lcl_getUnknownPropertyErrorMessage(propName), + static_cast<XPropertyState*>(this)); + *pStates++ = getPropertyStateByHandle(it->Handle); } - if ( pLookup != pLookupEnd ) - // we run out of properties from the IPropertyArrayHelper, but still have properties to lookup - // -> we were asked for a nonexistent property - throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( *pLookup ), static_cast< XPropertyState* >( this ) ); - return aStates; } diff --git a/comphelper/source/property/propmultiplex2.cxx b/comphelper/source/property/propmultiplex2.cxx new file mode 100644 index 000000000000..b9d7719c4e1d --- /dev/null +++ b/comphelper/source/property/propmultiplex2.cxx @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <comphelper/propmultiplex2.hxx> +#include <osl/diagnose.h> + +namespace comphelper +{ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; + +OPropertyChangeListener2::~OPropertyChangeListener2() +{ + if (m_xAdapter.is()) + m_xAdapter->onListenerDestruction(); +} + +void OPropertyChangeListener2::disposeAdapter(std::unique_lock<std::mutex>& rGuard) +{ + if (m_xAdapter.is()) + m_xAdapter->dispose(rGuard); + + // will automatically set a new adapter + OSL_ENSURE(!m_xAdapter.is(), "OPropertyChangeListener::disposeAdapter: what did dispose do?"); +} + +void OPropertyChangeListener2::setAdapter(std::unique_lock<std::mutex>& /*rGuard*/, + OPropertyChangeMultiplexer2* pAdapter) +{ + m_xAdapter = pAdapter; +} + +OPropertyChangeMultiplexer2::OPropertyChangeMultiplexer2(std::mutex& rMutex, + std::unique_lock<std::mutex>& rGuard, + OPropertyChangeListener2* _pListener, + const Reference<XPropertySet>& _rxSet) + : m_rMutex(rMutex) + , m_xSet(_rxSet) + , m_pListener(_pListener) + , m_nLockCount(0) + , m_bListening(false) +{ + m_pListener->setAdapter(rGuard, this); +} + +OPropertyChangeMultiplexer2::~OPropertyChangeMultiplexer2() {} + +void OPropertyChangeMultiplexer2::lock() { ++m_nLockCount; } + +void OPropertyChangeMultiplexer2::unlock() { --m_nLockCount; } + +void OPropertyChangeMultiplexer2::dispose(std::unique_lock<std::mutex>& rGuard) +{ + if (!m_bListening) + return; + + Reference<XPropertyChangeListener> xPreventDelete(this); + + for (const OUString& rProp : m_aProperties) + m_xSet->removePropertyChangeListener(rProp, static_cast<XPropertyChangeListener*>(this)); + + m_pListener->setAdapter(rGuard, nullptr); + + m_pListener = nullptr; + m_bListening = false; + + m_xSet = nullptr; +} + +void OPropertyChangeMultiplexer2::onListenerDestruction() +{ + if (!m_bListening) + return; + + Reference<XPropertyChangeListener> xPreventDelete(this); + + for (const OUString& rProp : m_aProperties) + m_xSet->removePropertyChangeListener(rProp, static_cast<XPropertyChangeListener*>(this)); +} + +// XEventListener + +void SAL_CALL OPropertyChangeMultiplexer2::disposing(const EventObject& /*_rSource*/) +{ + std::unique_lock g(m_rMutex); + if (m_pListener) + { + // disconnect the listener + if (m_pListener) // may have been reset whilst calling into _disposing + m_pListener->setAdapter(g, nullptr); + } + + m_pListener = nullptr; + m_bListening = false; + + m_xSet = nullptr; +} + +// XPropertyChangeListener + +void SAL_CALL OPropertyChangeMultiplexer2::propertyChange(const PropertyChangeEvent& _rEvent) +{ + if (m_pListener && !locked()) + m_pListener->_propertyChanged(_rEvent); +} + +void OPropertyChangeMultiplexer2::addProperty(const OUString& _sPropertyName) +{ + if (m_xSet.is()) + { + m_xSet->addPropertyChangeListener(_sPropertyName, + static_cast<XPropertyChangeListener*>(this)); + m_aProperties.push_back(_sPropertyName); + m_bListening = true; + } +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propshlp.cxx b/comphelper/source/property/propshlp.cxx new file mode 100644 index 000000000000..b0139c747969 --- /dev/null +++ b/comphelper/source/property/propshlp.cxx @@ -0,0 +1,855 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <osl/diagnose.h> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/propshlp.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <memory> +#include <sal/log.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace cppu; + +namespace comphelper +{ +extern "C" { + +static int compare_OUString_Property_Impl(const void* arg1, const void* arg2) SAL_THROW_EXTERN_C() +{ + return static_cast<OUString const*>(arg1)->compareTo(static_cast<Property const*>(arg2)->Name); +} +} + +/** + * The class which implements the PropertySetInfo interface. + */ + +namespace +{ +class OPropertySetHelperInfo_Impl : public WeakImplHelper<css::beans::XPropertySetInfo> +{ + Sequence<Property> aInfos; + +public: + explicit OPropertySetHelperInfo_Impl(IPropertyArrayHelper& rHelper_); + + // XPropertySetInfo-methods + virtual Sequence<Property> SAL_CALL getProperties() override; + virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) override; + virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) override; +}; +} + +/** + * Create an object that implements XPropertySetInfo IPropertyArrayHelper. + */ +OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(IPropertyArrayHelper& rHelper_) + : aInfos(rHelper_.getProperties()) +{ +} + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +Sequence<Property> OPropertySetHelperInfo_Impl::getProperties() { return aInfos; } + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +Property OPropertySetHelperInfo_Impl::getPropertyByName(const OUString& PropertyName) +{ + Property* pR + = static_cast<Property*>(bsearch(&PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof(Property), compare_OUString_Property_Impl)); + if (!pR) + throw UnknownPropertyException(PropertyName); + + return *pR; +} + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName(const OUString& PropertyName) +{ + Property* pR + = static_cast<Property*>(bsearch(&PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof(Property), compare_OUString_Property_Impl)); + return pR != nullptr; +} + +OPropertySetHelper::OPropertySetHelper() {} + +OPropertySetHelper::OPropertySetHelper(bool bIgnoreRuntimeExceptionsWhileFiring) + : m_bIgnoreRuntimeExceptionsWhileFiring(bIgnoreRuntimeExceptionsWhileFiring) +{ +} + +/** + * You must call disposing before. + */ +OPropertySetHelper::~OPropertySetHelper() {} + +// XInterface +Any OPropertySetHelper::queryInterface(const css::uno::Type& rType) +{ + return ::cppu::queryInterface(rType, static_cast<XPropertySet*>(this), + static_cast<XMultiPropertySet*>(this), + static_cast<XFastPropertySet*>(this)); +} + +/** + * called from the derivee's XTypeProvider::getTypes implementation + */ +css::uno::Sequence<css::uno::Type> OPropertySetHelper::getTypes() +{ + return { UnoType<css::beans::XPropertySet>::get(), + UnoType<css::beans::XMultiPropertySet>::get(), + UnoType<css::beans::XFastPropertySet>::get() }; +} + +// ComponentHelper +void OPropertySetHelper::disposing(std::unique_lock<std::mutex>& rGuard) +{ + // Create an event with this as sender + Reference<XPropertySet> rSource = this; + EventObject aEvt; + aEvt.Source = rSource; + + // inform all listeners to release this object + // The listener containers are automatically cleared + aBoundLC.disposeAndClear(rGuard, aEvt); + aVetoableLC.disposeAndClear(rGuard, aEvt); +} + +Reference<XPropertySetInfo> +OPropertySetHelper::createPropertySetInfo(IPropertyArrayHelper& rProperties) +{ + return new OPropertySetHelperInfo_Impl(rProperties); +} + +// XPropertySet +void OPropertySetHelper::setPropertyValue(const OUString& rPropertyName, const Any& rValue) +{ + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + std::unique_lock aGuard(m_aMutex); + setFastPropertyValueImpl(aGuard, nHandle, rValue); +} + +// XPropertySet +Any OPropertySetHelper::getPropertyValue(const OUString& rPropertyName) +{ + std::unique_lock aGuard(m_aMutex); + return getPropertyValueImpl(aGuard, rPropertyName); +} + +Any OPropertySetHelper::getPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + const OUString& rPropertyName) +{ + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + // call the method of the XFastPropertySet interface + Any aAny; + getFastPropertyValue(rGuard, aAny, nHandle); + return aAny; +} + +// XPropertySet +void OPropertySetHelper::addPropertyChangeListener( + const OUString& rPropertyName, const Reference<XPropertyChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + if (m_bDisposed) + return; + + // only add listeners if you are not disposed + // a listener with no name means all properties + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle); + if (!(nAttributes & css::beans::PropertyAttribute::BOUND)) + { + OSL_FAIL("add listener to an unbound property"); + // silent ignore this + return; + } + // add the change listener to the helper container + aBoundLC.addInterface(aGuard, nHandle, rxListener); + } + else + // add the change listener to the helper container + maPropertyChangeListeners.addInterface(aGuard, rxListener); +} + +// XPropertySet +void OPropertySetHelper::removePropertyChangeListener( + const OUString& rPropertyName, const Reference<XPropertyChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + // all listeners are automatically released in a dispose call + if (m_bDisposed) + return; + + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + aBoundLC.removeInterface(aGuard, nHandle, rxListener); + } + else + { + // remove the change listener to the helper container + maPropertyChangeListeners.removeInterface(aGuard, rxListener); + } +} + +// XPropertySet +void OPropertySetHelper::addVetoableChangeListener( + const OUString& rPropertyName, const Reference<XVetoableChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + if (m_bDisposed) + return; + + // only add listeners if you are not disposed + // a listener with no name means all properties + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle); + if (!(nAttributes & PropertyAttribute::CONSTRAINED)) + { + OSL_FAIL("addVetoableChangeListener, and property is not constrained"); + // silent ignore this + return; + } + // add the vetoable listener to the helper container + aVetoableLC.addInterface(aGuard, nHandle, rxListener); + } + else + // add the vetoable listener to the helper container + maVetoableChangeListeners.addInterface(aGuard, rxListener); +} + +// XPropertySet +void OPropertySetHelper::removeVetoableChangeListener( + const OUString& rPropertyName, const Reference<XVetoableChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + // all listeners are automatically released in a dispose call + if (m_bDisposed) + return; + + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + // remove the vetoable listener to the helper container + aVetoableLC.removeInterface(aGuard, nHandle, rxListener); + } + else + // add the vetoable listener to the helper container + maVetoableChangeListeners.removeInterface(aGuard, rxListener); +} + +void OPropertySetHelper::setDependentFastPropertyValue(std::unique_lock<std::mutex>& rGuard, + sal_Int32 i_handle, + const css::uno::Any& i_value) +{ + sal_Int16 nAttributes(0); + IPropertyArrayHelper& rInfo = getInfoHelper(); + if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, i_handle)) + // unknown property + throw UnknownPropertyException(OUString::number(i_handle)); + + // no need to check for READONLY-ness of the property. The method is intended to be called internally, which + // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed + // to change their value. + + Any aConverted, aOld; + bool bChanged = convertFastPropertyValue(rGuard, aConverted, aOld, i_handle, i_value); + if (!bChanged) + return; + + // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be + // a good idea. The caller is responsible for not invoking this for constrained properties. + OSL_ENSURE((nAttributes & PropertyAttribute::CONSTRAINED) == 0, + "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained " + "properties!"); + + // actually set the new value + try + { + setFastPropertyValue_NoBroadcast(rGuard, i_handle, aConverted); + } + catch (const UnknownPropertyException&) + { + throw; /* allowed to leave */ + } + catch (const PropertyVetoException&) + { + throw; /* allowed to leave */ + } + catch (const IllegalArgumentException&) + { + throw; /* allowed to leave */ + } + catch (const WrappedTargetException&) + { + throw; /* allowed to leave */ + } + catch (const RuntimeException&) + { + throw; /* allowed to leave */ + } + catch (const Exception&) + { + // not allowed to leave this method + WrappedTargetException aWrapped; + aWrapped.TargetException = ::cppu::getCaughtException(); + aWrapped.Context = static_cast<XPropertySet*>(this); + throw aWrapped; + } + + // remember the handle/values, for the events to be fired later + m_handles.push_back(i_handle); + m_newValues.push_back( + aConverted); // TODO: setFastPropertyValue notifies the unconverted value here ...? + m_oldValues.push_back(aOld); +} + +// XFastPropertySet +void OPropertySetHelper::setFastPropertyValue(sal_Int32 nHandle, const Any& rValue) +{ + std::unique_lock aGuard(m_aMutex); + setFastPropertyValueImpl(aGuard, nHandle, rValue); +} + +void OPropertySetHelper::setFastPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + sal_Int32 nHandle, const Any& rValue) +{ + OSL_ENSURE(!m_bDisposed, "object is disposed"); + + IPropertyArrayHelper& rInfo = getInfoHelper(); + sal_Int16 nAttributes; + if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle)) + { + // unknown property + throw UnknownPropertyException(OUString::number(nHandle)); + } + if (nAttributes & PropertyAttribute::READONLY) + throw PropertyVetoException(); + + Any aConvertedVal; + Any aOldVal; + + // Will the property change? + bool bChanged = convertFastPropertyValue(rGuard, aConvertedVal, aOldVal, nHandle, rValue); + if (!bChanged) + return; + + // Is it a constrained property? + if (nAttributes & PropertyAttribute::CONSTRAINED) + { + // In aValue is the converted rValue + // fire a constrained event + // second parameter NULL means constrained + fire(rGuard, &nHandle, &rValue, &aOldVal, 1, true); + } + + try + { + // set the property to the new value + setFastPropertyValue_NoBroadcast(rGuard, nHandle, aConvertedVal); + } + catch (const css::beans::UnknownPropertyException&) + { + throw; /* allowed to leave */ + } + catch (const css::beans::PropertyVetoException&) + { + throw; /* allowed to leave */ + } + catch (const css::lang::IllegalArgumentException&) + { + throw; /* allowed to leave */ + } + catch (const css::lang::WrappedTargetException&) + { + throw; /* allowed to leave */ + } + catch (const css::uno::RuntimeException&) + { + throw; /* allowed to leave */ + } + catch (const css::uno::Exception& e) + { + // not allowed to leave this method + css::lang::WrappedTargetException aWrap; + aWrap.Context = static_cast<css::beans::XPropertySet*>(this); + aWrap.TargetException <<= e; + + throw aWrap; + } + + // file a change event, if the value changed + impl_fireAll(rGuard, &nHandle, &rValue, &aOldVal, 1); +} + +// XFastPropertySet +Any OPropertySetHelper::getFastPropertyValue(sal_Int32 nHandle) +{ + IPropertyArrayHelper& rInfo = getInfoHelper(); + if (!rInfo.fillPropertyMembersByHandle(nullptr, nullptr, nHandle)) + // unknown property + throw UnknownPropertyException(OUString::number(nHandle)); + + Any aRet; + std::unique_lock aGuard(m_aMutex); + getFastPropertyValue(aGuard, aRet, nHandle); + return aRet; +} + +void OPropertySetHelper::impl_fireAll(std::unique_lock<std::mutex>& rGuard, sal_Int32* i_handles, + const Any* i_newValues, const Any* i_oldValues, + sal_Int32 i_count) +{ + if (m_handles.empty()) + { + fire(rGuard, i_handles, i_newValues, i_oldValues, i_count, false); + return; + } + + const size_t additionalEvents = m_handles.size(); + OSL_ENSURE(additionalEvents == m_newValues.size() && additionalEvents == m_oldValues.size(), + "OPropertySetHelper::impl_fireAll: inconsistency!"); + + std::vector<sal_Int32> allHandles(additionalEvents + i_count); + std::copy(m_handles.begin(), m_handles.end(), allHandles.begin()); + std::copy(i_handles, i_handles + i_count, allHandles.begin() + additionalEvents); + + std::vector<Any> allNewValues(additionalEvents + i_count); + std::copy(m_newValues.begin(), m_newValues.end(), allNewValues.begin()); + std::copy(i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents); + + std::vector<Any> allOldValues(additionalEvents + i_count); + std::copy(m_oldValues.begin(), m_oldValues.end(), allOldValues.begin()); + std::copy(i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents); + + m_handles.clear(); + m_newValues.clear(); + m_oldValues.clear(); + + fire(rGuard, allHandles.data(), allNewValues.data(), allOldValues.data(), + additionalEvents + i_count, false); +} + +void OPropertySetHelper::fire(std::unique_lock<std::mutex>& rGuard, sal_Int32* pnHandles, + const Any* pNewValues, const Any* pOldValues, + sal_Int32 nHandles, // This is the Count of the array + bool bVetoable) +{ + // Only fire, if one or more properties changed + if (!nHandles) + return; + + // create the event sequence of all changed properties + Sequence<PropertyChangeEvent> aEvts(nHandles); + PropertyChangeEvent* pEvts = aEvts.getArray(); + Reference<XInterface> xSource(static_cast<XPropertySet*>(this), UNO_QUERY); + sal_Int32 i; + sal_Int32 nChangesLen = 0; + // Loop over all changed properties to fill the event struct + for (i = 0; i < nHandles; i++) + { + // Vetoable fire and constrained attribute set or + // Change fire and Changed and bound attribute set + IPropertyArrayHelper& rInfo = getInfoHelper(); + sal_Int16 nAttributes; + OUString aPropName; + rInfo.fillPropertyMembersByHandle(&aPropName, &nAttributes, pnHandles[i]); + + if ((bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) + || (!bVetoable && (nAttributes & PropertyAttribute::BOUND))) + { + pEvts[nChangesLen].Source = xSource; + pEvts[nChangesLen].PropertyName = aPropName; + pEvts[nChangesLen].PropertyHandle = pnHandles[i]; + pEvts[nChangesLen].OldValue = pOldValues[i]; + pEvts[nChangesLen].NewValue = pNewValues[i]; + nChangesLen++; + } + } + + bool bIgnoreRuntimeExceptionsWhileFiring = m_bIgnoreRuntimeExceptionsWhileFiring; + + // fire the events for all changed properties + for (i = 0; i < nChangesLen; i++) + { + if (bVetoable) // fire change Events? + fireVetoableChangeListeners( + rGuard, aVetoableLC.getContainer(rGuard, pEvts[i].PropertyHandle), pEvts[i]); + else + // get the listener container for the property name + firePropertyChangeListeners( + rGuard, aBoundLC.getContainer(rGuard, pEvts[i].PropertyHandle), pEvts[i]); + + // broadcast to all listeners with "" property name + if (bVetoable) + // fire change Events? + fireVetoableChangeListeners(rGuard, &maVetoableChangeListeners, pEvts[i]); + else + firePropertyChangeListeners(rGuard, &maPropertyChangeListeners, pEvts[i]); + } + + // reduce array to changed properties + aEvts.realloc(nChangesLen); + + if (bVetoable) + return; + + if (!maPropertiesChangeListeners.getLength(rGuard)) + return; + + // Here is a Bug, unbound properties are also fired + OInterfaceIteratorHelper4 aIt(rGuard, maPropertiesChangeListeners); + rGuard.unlock(); + while (aIt.hasMoreElements()) + { + XPropertiesChangeListener* pL = aIt.next().get(); + try + { + try + { + // fire the whole event sequence to the + // XPropertiesChangeListener's + pL->propertiesChange(aEvts); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + } + rGuard.lock(); +} + +void OPropertySetHelper::fireVetoableChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent) +{ + if (!pListeners || !pListeners->getLength(rGuard)) + return; + // Iterate over all listeners and send events + OInterfaceIteratorHelper4 aIt(rGuard, *pListeners); + rGuard.unlock(); + while (aIt.hasMoreElements()) + { + XVetoableChangeListener* pL = aIt.next().get(); + try + { + try + { + pL->vetoableChange(rChangeEvent); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!m_bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + } + rGuard.lock(); +} + +void OPropertySetHelper::firePropertyChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent) +{ + if (!pListeners || !pListeners->getLength(rGuard)) + return; + // Iterate over all listeners and send events + OInterfaceIteratorHelper4 aIt(rGuard, *pListeners); + rGuard.unlock(); + while (aIt.hasMoreElements()) + { + XPropertyChangeListener* pL = aIt.next().get(); + try + { + try + { + pL->propertyChange(rChangeEvent); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!m_bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + } + rGuard.lock(); +} + +// OPropertySetHelper +void OPropertySetHelper::setFastPropertyValues(std::unique_lock<std::mutex>& rGuard, + sal_Int32 nSeqLen, sal_Int32* pHandles, + const Any* pValues, sal_Int32 nHitCount) +{ + OSL_ENSURE(!m_bDisposed, "object is disposed"); + + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + + std::unique_ptr<Any[]> pConvertedValues(new Any[nHitCount]); + std::unique_ptr<Any[]> pOldValues(new Any[nHitCount]); + sal_Int32 n = 0; + sal_Int32 i; + + for (i = 0; i < nSeqLen; i++) + { + if (pHandles[i] != -1) + { + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, pHandles[i]); + if (nAttributes & PropertyAttribute::READONLY) + throw PropertyVetoException(); + // Will the property change? + if (convertFastPropertyValue(rGuard, pConvertedValues[n], pOldValues[n], pHandles[i], + pValues[i])) + { + // only increment if the property really change + pHandles[n] = pHandles[i]; + n++; + } + } + } + + // fire vetoable events + fire(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), n, true); + + // Loop over all changed properties + for (i = 0; i < n; i++) + { + // Will the property change? + setFastPropertyValue_NoBroadcast(rGuard, pHandles[i], pConvertedValues[i]); + } + + // fire change events + impl_fireAll(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), n); +} + +// XMultiPropertySet +/** + * The sequence may be contain not known properties. The implementation + * must ignore these properties. + */ +void OPropertySetHelper::setPropertyValues(const Sequence<OUString>& rPropertyNames, + const Sequence<Any>& rValues) +{ + sal_Int32 nSeqLen = rPropertyNames.getLength(); + if (nSeqLen != rValues.getLength()) + throw IllegalArgumentException(u"lengths do not match"_ustr, + static_cast<XPropertySet*>(this), -1); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]); + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // fill the handle array + sal_Int32 nHitCount = rPH.fillHandles(pHandles.get(), rPropertyNames); + if (nHitCount == 0) + return; + std::unique_lock aGuard(m_aMutex); + setFastPropertyValues(aGuard, nSeqLen, pHandles.get(), rValues.getConstArray(), nHitCount); +} + +// XMultiPropertySet +Sequence<Any> OPropertySetHelper::getPropertyValues(const Sequence<OUString>& rPropertyNames) +{ + sal_Int32 nSeqLen = rPropertyNames.getLength(); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]); + Sequence<Any> aValues(nSeqLen); + + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // fill the handle array + rPH.fillHandles(pHandles.get(), rPropertyNames); + + Any* pValues = aValues.getArray(); + + std::unique_lock aGuard(m_aMutex); + // fill the sequence with the values + for (sal_Int32 i = 0; i < nSeqLen; i++) + getFastPropertyValue(aGuard, pValues[i], pHandles[i]); + + return aValues; +} + +// XMultiPropertySet +void OPropertySetHelper::addPropertiesChangeListener( + const Sequence<OUString>&, const Reference<XPropertiesChangeListener>& rListener) +{ + std::unique_lock g(m_aMutex); + maPropertiesChangeListeners.addInterface(g, rListener); +} + +// XMultiPropertySet +void OPropertySetHelper::removePropertiesChangeListener( + const Reference<XPropertiesChangeListener>& rListener) +{ + std::unique_lock g(m_aMutex); + maPropertiesChangeListeners.removeInterface(g, rListener); +} + +// XMultiPropertySet +void OPropertySetHelper::firePropertiesChangeEvent( + const Sequence<OUString>& rPropertyNames, const Reference<XPropertiesChangeListener>& rListener) +{ + sal_Int32 nLen = rPropertyNames.getLength(); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nLen]); + IPropertyArrayHelper& rPH = getInfoHelper(); + rPH.fillHandles(pHandles.get(), rPropertyNames); + + // get the count of matching properties + sal_Int32 nFireLen = 0; + sal_Int32 i; + for (i = 0; i < nLen; i++) + if (pHandles[i] != -1) + nFireLen++; + + Sequence<PropertyChangeEvent> aChanges(nFireLen); + PropertyChangeEvent* pChanges = aChanges.getArray(); + + { + // must lock the mutex outside the loop. So all values are consistent. + std::unique_lock aGuard(m_aMutex); + Reference<XInterface> xSource(static_cast<XPropertySet*>(this), UNO_QUERY); + sal_Int32 nFirePos = 0; + for (i = 0; i < nLen; i++) + { + if (pHandles[i] != -1) + { + pChanges[nFirePos].Source = xSource; + pChanges[nFirePos].PropertyName = rPropertyNames[i]; + pChanges[nFirePos].PropertyHandle = pHandles[i]; + getFastPropertyValue(aGuard, pChanges[nFirePos].OldValue, pHandles[i]); + pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue; + nFirePos++; + } + } + // release guard to fire events + } + if (nFireLen) + rListener->propertiesChange(aChanges); +} + +UnoImplBase::~UnoImplBase() {} + +} // end namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/comphelper/source/property/propstate.cxx b/comphelper/source/property/propstate.cxx index 183f51efcedf..20deab1963ee 100644 --- a/comphelper/source/property/propstate.cxx +++ b/comphelper/source/property/propstate.cxx @@ -115,25 +115,22 @@ namespace comphelper sal_Int32 nLen = _rPropertyNames.getLength(); css::uno::Sequence< css::beans::PropertyState> aRet(nLen); css::beans::PropertyState* pValues = aRet.getArray(); - const OUString* pNames = _rPropertyNames.getConstArray(); cppu::IPropertyArrayHelper& rHelper = getInfoHelper(); css::uno::Sequence< css::beans::Property> aProps = rHelper.getProperties(); - const css::beans::Property* pProps = aProps.getConstArray(); - sal_Int32 nPropCount = aProps.getLength(); + auto it = aProps.begin(); + const auto end = aProps.end(); osl::MutexGuard aGuard(rBHelper.rMutex); - for (sal_Int32 i=0, j=0; i<nPropCount && j<nLen; ++i, ++pProps) + // Assumption is that both _rPropertyNames and aProps are sorted + for (auto& propName : _rPropertyNames) { // get the values only for valid properties - if (pProps->Name == *pNames) - { - *pValues = getPropertyState(*pNames); - ++pValues; - ++pNames; - ++j; - } + it = std::find_if(it, end, [&propName](auto& prop) { return prop.Name == propName; }); + if (it == end) + break; + *pValues++ = getPropertyStateByHandle(it->Handle); } return aRet; |