summaryrefslogtreecommitdiff
path: root/comphelper/source/property
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper/source/property')
-rw-r--r--comphelper/source/property/ChainablePropertySet.cxx55
-rw-r--r--comphelper/source/property/ChainablePropertySetInfo.cxx2
-rw-r--r--comphelper/source/property/MasterPropertySet.cxx69
-rw-r--r--comphelper/source/property/MasterPropertySetInfo.cxx4
-rw-r--r--comphelper/source/property/genericpropertyset.cxx67
-rw-r--r--comphelper/source/property/opropertybag.cxx47
-rw-r--r--comphelper/source/property/opropertybag.hxx18
-rw-r--r--comphelper/source/property/propagg.cxx55
-rw-r--r--comphelper/source/property/property.cxx25
-rw-r--r--comphelper/source/property/propertybag.cxx10
-rw-r--r--comphelper/source/property/propertycontainer.cxx1
-rw-r--r--comphelper/source/property/propertycontainer2.cxx64
-rw-r--r--comphelper/source/property/propertycontainerhelper.cxx7
-rw-r--r--comphelper/source/property/propertysethelper.cxx54
-rw-r--r--comphelper/source/property/propertysetinfo.cxx76
-rw-r--r--comphelper/source/property/propertystatecontainer.cxx45
-rw-r--r--comphelper/source/property/propmultiplex2.cxx137
-rw-r--r--comphelper/source/property/propshlp.cxx855
-rw-r--r--comphelper/source/property/propstate.cxx19
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;