LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - propshlp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 361 489 73.8 %
Date: 2012-12-17 Functions: 47 55 85.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "osl/diagnose.h"
      22             : #include "cppuhelper/implbase1.hxx"
      23             : #include "cppuhelper/weak.hxx"
      24             : #include "cppuhelper/propshlp.hxx"
      25             : #include "cppuhelper/exc_hlp.hxx"
      26             : #include "com/sun/star/beans/PropertyAttribute.hpp"
      27             : #include "com/sun/star/lang/DisposedException.hpp"
      28             : 
      29             : 
      30             : using namespace osl;
      31             : using namespace com::sun::star::uno;
      32             : using namespace com::sun::star::beans;
      33             : using namespace com::sun::star::lang;
      34             : using namespace cppu;
      35             : 
      36             : using ::rtl::OUString;
      37             : using ::rtl::OUStringToOString;
      38             : 
      39             : namespace cppu {
      40             : 
      41         462 : IPropertyArrayHelper::~IPropertyArrayHelper()
      42             : {
      43         462 : }
      44             : 
      45        9485 : inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW(())
      46             : {
      47        9485 :     return ::getCppuType( (Reference< XPropertyChangeListener > *)0 );
      48             : }
      49        8219 : inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW(())
      50             : {
      51        8219 :     return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 );
      52             : }
      53          73 : inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW(())
      54             : {
      55          73 :     return ::getCppuType( (Reference< XVetoableChangeListener > *)0 );
      56             : }
      57             : 
      58             : extern "C" {
      59             : 
      60      723384 : static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 )
      61             :     SAL_THROW_EXTERN_C()
      62             : {
      63      723384 :    return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name );
      64             : }
      65             : 
      66             : }
      67             : 
      68             : /**
      69             :  * The class which implements the PropertySetInfo interface.
      70             :  */
      71             : 
      72        1928 : class OPropertySetHelperInfo_Impl
      73             :     : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
      74             : {
      75             :     Sequence < Property > aInfos;
      76             : 
      77             : public:
      78             :     OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW(());
      79             : 
      80             :     // XPropertySetInfo-methods
      81             :     virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException);
      82             :     virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
      83             :     virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException);
      84             : };
      85             : 
      86             : 
      87             : /**
      88             :  * Create an object that implements XPropertySetInfo IPropertyArrayHelper.
      89             :  */
      90         964 : OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
      91             :     IPropertyArrayHelper & rHelper_ )
      92             :     SAL_THROW(())
      93         964 :     :aInfos( rHelper_.getProperties() )
      94             : {
      95         964 : }
      96             : 
      97             : /**
      98             :  * Return the sequence of properties, which are provided throug the constructor.
      99             :  */
     100         610 : Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException)
     101             : 
     102             : {
     103         610 :     return aInfos;
     104             : }
     105             : 
     106             : /**
     107             :  * Return the sequence of properties, which are provided throug the constructor.
     108             :  */
     109       11394 : Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
     110             : {
     111             :     Property * pR;
     112       22788 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     113             :                               sizeof( Property ),
     114       22788 :                               compare_OUString_Property_Impl );
     115       11394 :     if( !pR ) {
     116           0 :         throw UnknownPropertyException();
     117             :     }
     118             : 
     119       11394 :     return *pR;
     120             : }
     121             : 
     122             : /**
     123             :  * Return the sequence of properties, which are provided throug the constructor.
     124             :  */
     125       21519 : sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException)
     126             : {
     127             :     Property * pR;
     128       43038 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     129             :                               sizeof( Property ),
     130       43038 :                               compare_OUString_Property_Impl );
     131       21519 :     return pR != NULL;
     132             : }
     133             : 
     134             : //  ----------------------------------------------------
     135             : //  class PropertySetHelper_Impl
     136             : //  ----------------------------------------------------
     137        7621 : class OPropertySetHelper::Impl {
     138             : 
     139             : public:
     140       15075 :     Impl(   bool i_bIgnoreRuntimeExceptionsWhileFiring,
     141             :             IEventNotificationHook *i_pFireEvents
     142             :         )
     143             :         :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring )
     144             :         ,m_bFireEvents(true)
     145       15075 :         ,m_pFireEvents( i_pFireEvents )
     146             :     {
     147       15075 :     }
     148             : 
     149             :     bool m_bIgnoreRuntimeExceptionsWhileFiring;
     150             :     bool m_bFireEvents;
     151             :     class IEventNotificationHook * const m_pFireEvents;
     152             : 
     153             :     ::std::vector< sal_Int32 >  m_handles;
     154             :     ::std::vector< Any >        m_newValues;
     155             :     ::std::vector< Any >        m_oldValues;
     156             : };
     157             : 
     158             : 
     159             : //  ----------------------------------------------------
     160             : //  class PropertySetHelper
     161             : //  ----------------------------------------------------
     162       14677 : OPropertySetHelper::OPropertySetHelper(
     163             :     OBroadcastHelper  & rBHelper_ ) SAL_THROW(())
     164             :     : rBHelper( rBHelper_ ),
     165             :       aBoundLC( rBHelper_.rMutex ),
     166             :       aVetoableLC( rBHelper_.rMutex ),
     167       14677 :       m_pReserved( new Impl(false, 0) )
     168             : {
     169       14677 : }
     170             : 
     171           0 : OPropertySetHelper::OPropertySetHelper(
     172             :     OBroadcastHelper  & rBHelper_, bool bIgnoreRuntimeExceptionsWhileFiring )
     173             :     : rBHelper( rBHelper_ ),
     174             :       aBoundLC( rBHelper_.rMutex ),
     175             :       aVetoableLC( rBHelper_.rMutex ),
     176           0 :       m_pReserved( new Impl( bIgnoreRuntimeExceptionsWhileFiring, 0 ) )
     177             : {
     178           0 : }
     179             : 
     180         398 : OPropertySetHelper::OPropertySetHelper(
     181             :     OBroadcastHelper  & rBHelper_, IEventNotificationHook * i_pFireEvents,
     182             :     bool bIgnoreRuntimeExceptionsWhileFiring)
     183             :     : rBHelper( rBHelper_ ),
     184             :       aBoundLC( rBHelper_.rMutex ),
     185             :       aVetoableLC( rBHelper_.rMutex ),
     186             :       m_pReserved(
     187         398 :         new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) )
     188             : {
     189         398 : }
     190             : 
     191         398 : OPropertySetHelper2::OPropertySetHelper2(
     192             :         OBroadcastHelper & irBHelper,
     193             :         IEventNotificationHook *i_pFireEvents,
     194             :         bool bIgnoreRuntimeExceptionsWhileFiring)
     195         398 :             :OPropertySetHelper( irBHelper, i_pFireEvents, bIgnoreRuntimeExceptionsWhileFiring )
     196             : {
     197         398 : }
     198             : 
     199             : /**
     200             :  * You must call disposing before.
     201             :  */
     202        7621 : OPropertySetHelper::~OPropertySetHelper() SAL_THROW(())
     203             : {
     204        7621 : }
     205         194 : OPropertySetHelper2::~OPropertySetHelper2() SAL_THROW(())
     206             : {
     207         194 : }
     208             : 
     209             : // XInterface
     210        6659 : Any OPropertySetHelper::queryInterface( const ::com::sun::star::uno::Type & rType )
     211             :     throw (RuntimeException)
     212             : {
     213             :     return ::cppu::queryInterface(
     214             :         rType,
     215             :         static_cast< XPropertySet * >( this ),
     216             :         static_cast< XMultiPropertySet * >( this ),
     217        6659 :         static_cast< XFastPropertySet * >( this ) );
     218             : }
     219             : 
     220        3017 : Any OPropertySetHelper2::queryInterface( const ::com::sun::star::uno::Type & rType )
     221             :     throw (RuntimeException)
     222             : {
     223        3017 :     Any cnd(cppu::queryInterface(rType, static_cast< XPropertySetOption * >(this)));
     224        3017 :     if ( cnd.hasValue() )
     225         116 :         return cnd;
     226             :     else
     227        2901 :         return OPropertySetHelper::queryInterface(rType);
     228             : }
     229             : 
     230             : /**
     231             :  * called from the derivee's XTypeProvider::getTypes implementation
     232             :  */
     233           8 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes()
     234             :     throw (RuntimeException)
     235             : {
     236           8 :     Sequence< ::com::sun::star::uno::Type > aTypes( 4 );
     237           8 :     aTypes[ 0 ] = XPropertySet::static_type();
     238           8 :     aTypes[ 1 ] = XPropertySetOption::static_type();
     239           8 :     aTypes[ 2 ] = XMultiPropertySet::static_type();
     240           8 :     aTypes[ 3 ] = XFastPropertySet::static_type();
     241           8 :     return aTypes;
     242             : }
     243             : 
     244             : // ComponentHelper
     245         240 : void OPropertySetHelper::disposing() SAL_THROW(())
     246             : {
     247             :     // Create an event with this as sender
     248         240 :     Reference < XPropertySet  > rSource( (static_cast< XPropertySet *  >(this)) , UNO_QUERY );
     249         240 :     EventObject aEvt;
     250         240 :     aEvt.Source = rSource;
     251             : 
     252             :     // inform all listeners to release this object
     253             :     // The listener containers are automatically cleared
     254         240 :     aBoundLC.disposeAndClear( aEvt );
     255         240 :     aVetoableLC.disposeAndClear( aEvt );
     256         240 : }
     257             : 
     258         964 : Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo(
     259             :     IPropertyArrayHelper & rProperties ) SAL_THROW(())
     260             : {
     261         964 :     return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
     262             : }
     263             : 
     264             : // XPropertySet
     265       19524 : void OPropertySetHelper::setPropertyValue(
     266             :     const OUString& rPropertyName, const Any& rValue )
     267             :     throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
     268             : {
     269             :     // get the map table
     270       19524 :     IPropertyArrayHelper & rPH = getInfoHelper();
     271             :     // map the name to the handle
     272       19524 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     273             :     // call the method of the XFastPropertySet interface
     274       19524 :     setFastPropertyValue( nHandle, rValue );
     275       19442 : }
     276             : 
     277             : // XPropertySet
     278       81535 : Any OPropertySetHelper::getPropertyValue(
     279             :     const OUString& rPropertyName )
     280             :     throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
     281             : {
     282             :     // get the map table
     283       81535 :     IPropertyArrayHelper & rPH = getInfoHelper();
     284             :     // map the name to the handle
     285       81535 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     286             :     // call the method of the XFastPropertySet interface
     287       81535 :     return getFastPropertyValue( nHandle );
     288             : }
     289             : 
     290             : // XPropertySet
     291         250 : void OPropertySetHelper::addPropertyChangeListener(
     292             :     const OUString& rPropertyName,
     293             :     const Reference < XPropertyChangeListener > & rxListener )
     294             :      throw(::com::sun::star::beans::UnknownPropertyException,
     295             :            ::com::sun::star::lang::WrappedTargetException,
     296             :            ::com::sun::star::uno::RuntimeException)
     297             : {
     298         250 :     MutexGuard aGuard( rBHelper.rMutex );
     299             :     OSL_ENSURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" );
     300             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     301         250 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     302             :     {
     303             :         // only add listeners if you are not disposed
     304             :         // a listener with no name means all properties
     305         250 :         if( !rPropertyName.isEmpty() )
     306             :         {
     307             :             // get the map table
     308         209 :             IPropertyArrayHelper & rPH = getInfoHelper();
     309             :             // map the name to the handle
     310         209 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     311         209 :             if( nHandle == -1 ) {
     312             :                 // property not known throw exception
     313           0 :                 throw  UnknownPropertyException() ;
     314             :             }
     315             : 
     316             :             sal_Int16 nAttributes;
     317         209 :             rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
     318         209 :             if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) )
     319             :             {
     320             :                 OSL_FAIL( "add listener to an unbound property" );
     321             :                 // silent ignore this
     322         250 :                 return;
     323             :             }
     324             :             // add the change listener to the helper container
     325             : 
     326         209 :             aBoundLC.addInterface( (sal_Int32)nHandle, rxListener );
     327             :         }
     328             :         else
     329             :             // add the change listener to the helper container
     330             :             rBHelper.aLC.addInterface(
     331          41 :                             getPropertyTypeIdentifier(  ),
     332             :                             rxListener
     333          82 :                                      );
     334         250 :     }
     335             : }
     336             : 
     337             : 
     338             : // XPropertySet
     339         122 : void OPropertySetHelper::removePropertyChangeListener(
     340             :     const OUString& rPropertyName,
     341             :     const Reference < XPropertyChangeListener >& rxListener )
     342             :     throw(::com::sun::star::beans::UnknownPropertyException,
     343             :           ::com::sun::star::lang::WrappedTargetException,
     344             :           ::com::sun::star::uno::RuntimeException)
     345             : {
     346         122 :     MutexGuard aGuard( rBHelper.rMutex );
     347             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     348             :     // all listeners are automaticly released in a dispose call
     349         122 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     350             :     {
     351         122 :         if( !rPropertyName.isEmpty() )
     352             :         {
     353             :             // get the map table
     354          89 :             IPropertyArrayHelper & rPH = getInfoHelper();
     355             :             // map the name to the handle
     356          89 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     357          89 :             if( nHandle == -1 )
     358             :                 // property not known throw exception
     359           0 :                 throw UnknownPropertyException();
     360          89 :             aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener );
     361             :         }
     362             :         else {
     363             :             // remove the change listener to the helper container
     364             :             rBHelper.aLC.removeInterface(
     365          33 :                             getPropertyTypeIdentifier(  ),
     366             :                             rxListener
     367          66 :                                         );
     368             :         }
     369         122 :     }
     370         122 : }
     371             : 
     372             : // XPropertySet
     373          39 : void OPropertySetHelper::addVetoableChangeListener(
     374             :     const OUString& rPropertyName,
     375             :     const Reference< XVetoableChangeListener > & rxListener )
     376             :     throw(::com::sun::star::beans::UnknownPropertyException,
     377             :           ::com::sun::star::lang::WrappedTargetException,
     378             :           ::com::sun::star::uno::RuntimeException)
     379             : {
     380          39 :     MutexGuard aGuard( rBHelper.rMutex );
     381             :     OSL_ENSURE( !rBHelper.bInDispose, "do not addVetoableChangeListener in the dispose call" );
     382             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     383          39 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     384             :     {
     385             :         // only add listeners if you are not disposed
     386             :         // a listener with no name means all properties
     387          39 :         if( !rPropertyName.isEmpty() )
     388             :         {
     389             :             // get the map table
     390           0 :             IPropertyArrayHelper & rPH = getInfoHelper();
     391             :             // map the name to the handle
     392           0 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     393           0 :             if( nHandle == -1 ) {
     394             :                 // property not known throw exception
     395           0 :                 throw UnknownPropertyException();
     396             :             }
     397             : 
     398             :             sal_Int16 nAttributes;
     399           0 :             rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
     400           0 :             if( !(nAttributes & PropertyAttribute::CONSTRAINED) )
     401             :             {
     402             :                 OSL_FAIL( "addVetoableChangeListener, and property is not constrained" );
     403             :                 // silent ignore this
     404          39 :                 return;
     405             :             }
     406             :             // add the vetoable listener to the helper container
     407           0 :             aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener );
     408             :         }
     409             :         else
     410             :             // add the vetoable listener to the helper container
     411             :             rBHelper.aLC.addInterface(
     412          39 :                                 getVetoableTypeIdentifier(  ),
     413             :                                 rxListener
     414          78 :                                      );
     415          39 :     }
     416             : }
     417             : 
     418             : // XPropertySet
     419          31 : void OPropertySetHelper::removeVetoableChangeListener(
     420             :     const OUString& rPropertyName,
     421             :     const Reference < XVetoableChangeListener > & rxListener )
     422             :     throw(::com::sun::star::beans::UnknownPropertyException,
     423             :           ::com::sun::star::lang::WrappedTargetException,
     424             :           ::com::sun::star::uno::RuntimeException)
     425             : {
     426          31 :     MutexGuard aGuard( rBHelper.rMutex );
     427             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     428             :     // all listeners are automaticly released in a dispose call
     429          31 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     430             :     {
     431          31 :         if( !rPropertyName.isEmpty() )
     432             :         {
     433             :             // get the map table
     434           0 :             IPropertyArrayHelper & rPH = getInfoHelper();
     435             :             // map the name to the handle
     436           0 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     437           0 :             if( nHandle == -1 ) {
     438             :                 // property not known throw exception
     439           0 :                 throw UnknownPropertyException();
     440             :             }
     441             :             // remove the vetoable listener to the helper container
     442           0 :             aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener );
     443             :         }
     444             :         else
     445             :             // add the vetoable listener to the helper container
     446             :             rBHelper.aLC.removeInterface(
     447          31 :                                 getVetoableTypeIdentifier( ),
     448             :                                 rxListener
     449          62 :                                         );
     450          31 :     }
     451          31 : }
     452             : 
     453          22 : void OPropertySetHelper::setDependentFastPropertyValue( sal_Int32 i_handle, const ::com::sun::star::uno::Any& i_value )
     454             : {
     455             :     //OSL_PRECOND( rBHelper.rMutex.isAcquired(), "OPropertySetHelper::setDependentFastPropertyValue: to be called with a locked mutex only!" );
     456             :         // there is no such thing as Mutex.isAcquired, sadly ...
     457             : 
     458          22 :     sal_Int16 nAttributes(0);
     459          22 :     IPropertyArrayHelper& rInfo = getInfoHelper();
     460          22 :     if ( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, i_handle ) )
     461             :         // unknown property
     462           0 :         throw UnknownPropertyException();
     463             : 
     464             :     // no need to check for READONLY-ness of the property. The method is intended to be called internally, which
     465             :     // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed
     466             :     // to change their value.
     467             : 
     468          22 :     Any aConverted, aOld;
     469          22 :     sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value );
     470          22 :     if ( !bChanged )
     471          22 :         return;
     472             : 
     473             :     // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be
     474             :     // a good idea. The caler is responsible for not invoking this for constrained properties.
     475             :     OSL_ENSURE( ( nAttributes & PropertyAttribute::CONSTRAINED ) == 0,
     476             :         "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained properties!" );
     477             :     (void)nAttributes;
     478             : 
     479             :     // actually set the new value
     480             :     try
     481             :     {
     482           0 :         setFastPropertyValue_NoBroadcast( i_handle, aConverted );
     483             :     }
     484           0 :     catch (const UnknownPropertyException& )    { throw;    /* allowed to leave */ }
     485           0 :     catch (const PropertyVetoException& )       { throw;    /* allowed to leave */ }
     486           0 :     catch (const IllegalArgumentException& )    { throw;    /* allowed to leave */ }
     487           0 :     catch (const WrappedTargetException& )      { throw;    /* allowed to leave */ }
     488           0 :     catch (const RuntimeException& )            { throw;    /* allowed to leave */ }
     489           0 :     catch (const Exception& )
     490             :     {
     491             :         // not allowed to leave this meathod
     492           0 :         WrappedTargetException aWrapped;
     493           0 :         aWrapped.TargetException <<= ::cppu::getCaughtException();
     494           0 :         aWrapped.Context = static_cast< XPropertySet* >( this );
     495           0 :         throw aWrapped;
     496             :     }
     497             : 
     498             :     // remember the handle/values, for the events to be fired later
     499           0 :     m_pReserved->m_handles.push_back( i_handle );
     500           0 :     m_pReserved->m_newValues.push_back( aConverted );   // TODO: setFastPropertyValue notifies the unconverted value here ...?
     501           0 :     m_pReserved->m_oldValues.push_back( aOld );
     502             : }
     503             : 
     504             : // XFastPropertySet
     505       19424 : void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
     506             :      throw(::com::sun::star::beans::UnknownPropertyException,
     507             :            ::com::sun::star::beans::PropertyVetoException,
     508             :            ::com::sun::star::lang::IllegalArgumentException,
     509             :            ::com::sun::star::lang::WrappedTargetException,
     510             :            ::com::sun::star::uno::RuntimeException)
     511             : {
     512             :     OSL_ENSURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" );
     513             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     514             : 
     515       19424 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     516             :     sal_Int16 nAttributes;
     517       19424 :     if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) {
     518             :         // unknown property
     519          82 :         throw UnknownPropertyException();
     520             :     }
     521       19342 :     if( nAttributes & PropertyAttribute::READONLY )
     522           0 :         throw PropertyVetoException();
     523             : 
     524       19342 :     Any aConvertedVal;
     525       19342 :     Any aOldVal;
     526             : 
     527             :     // Will the property change?
     528             :     sal_Bool bChanged;
     529             :     {
     530       19342 :         MutexGuard aGuard( rBHelper.rMutex );
     531       19342 :         bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue );
     532             :         // release guard to fire events
     533             :     }
     534       19342 :     if( bChanged )
     535             :     {
     536             :         // Is it a constrained property?
     537        5826 :         if( nAttributes & PropertyAttribute::CONSTRAINED )
     538             :         {
     539             :             // In aValue is the converted rValue
     540             :             // fire a constarined event
     541             :             // second parameter NULL means constrained
     542           3 :             fire( &nHandle, &rValue, &aOldVal, 1, sal_True );
     543             :         }
     544             : 
     545             :         {
     546        5826 :             MutexGuard aGuard( rBHelper.rMutex );
     547             :             try
     548             :             {
     549             :                 // set the property to the new value
     550        5826 :                 setFastPropertyValue_NoBroadcast( nHandle, aConvertedVal );
     551             :             }
     552           0 :             catch (const ::com::sun::star::beans::UnknownPropertyException& )   { throw;    /* allowed to leave */ }
     553           0 :             catch (const ::com::sun::star::beans::PropertyVetoException& )      { throw;    /* allowed to leave */ }
     554           0 :             catch (const ::com::sun::star::lang::IllegalArgumentException& )    { throw;    /* allowed to leave */ }
     555           0 :             catch (const ::com::sun::star::lang::WrappedTargetException& )      { throw;    /* allowed to leave */ }
     556           0 :             catch (const ::com::sun::star::uno::RuntimeException& )             { throw;    /* allowed to leave */ }
     557           0 :             catch (const ::com::sun::star::uno::Exception& e )
     558             :             {
     559             :                 // not allowed to leave this meathod
     560           0 :                 ::com::sun::star::lang::WrappedTargetException aWrap;
     561           0 :                 aWrap.Context = static_cast< ::com::sun::star::beans::XPropertySet* >( this );
     562           0 :                 aWrap.TargetException <<= e;
     563             : 
     564           0 :                 throw ::com::sun::star::lang::WrappedTargetException( aWrap );
     565        5826 :             }
     566             : 
     567             :             // release guard to fire events
     568             :         }
     569             :         // file a change event, if the value changed
     570        5826 :         impl_fireAll( &nHandle, &rValue, &aOldVal, 1 );
     571       19342 :     }
     572       19342 : }
     573             : 
     574             : // XFastPropertySet
     575       90092 : Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle )
     576             :      throw(::com::sun::star::beans::UnknownPropertyException,
     577             :            ::com::sun::star::lang::WrappedTargetException,
     578             :            ::com::sun::star::uno::RuntimeException)
     579             : 
     580             : {
     581       90092 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     582       90092 :     if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
     583             :         // unknown property
     584         257 :         throw UnknownPropertyException();
     585             : 
     586       89835 :     Any aRet;
     587       89835 :     MutexGuard aGuard( rBHelper.rMutex );
     588       89835 :     getFastPropertyValue( aRet, nHandle );
     589       89835 :     return aRet;
     590             : }
     591             : 
     592             : //--------------------------------------------------------------------------
     593        8611 : void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count )
     594             : {
     595        8611 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     596        8611 :     if ( m_pReserved->m_handles.empty() )
     597             :     {
     598        8611 :         aGuard.clear();
     599        8611 :         fire( i_handles, i_newValues, i_oldValues, i_count, sal_False );
     600        8611 :         return;
     601             :     }
     602             : 
     603           0 :     const size_t additionalEvents = m_pReserved->m_handles.size();
     604             :     OSL_ENSURE( additionalEvents == m_pReserved->m_newValues.size()
     605             :             &&  additionalEvents == m_pReserved->m_oldValues.size(),
     606             :             "OPropertySetHelper::impl_fireAll: inconsistency!" );
     607             : 
     608           0 :     ::std::vector< sal_Int32 > allHandles( additionalEvents + i_count );
     609           0 :     ::std::copy( m_pReserved->m_handles.begin(), m_pReserved->m_handles.end(), allHandles.begin() );
     610           0 :     ::std::copy( i_handles, i_handles + i_count, allHandles.begin() + additionalEvents );
     611             : 
     612           0 :     ::std::vector< Any > allNewValues( additionalEvents + i_count );
     613           0 :     ::std::copy( m_pReserved->m_newValues.begin(), m_pReserved->m_newValues.end(), allNewValues.begin() );
     614           0 :     ::std::copy( i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents );
     615             : 
     616           0 :     ::std::vector< Any > allOldValues( additionalEvents + i_count );
     617           0 :     ::std::copy( m_pReserved->m_oldValues.begin(), m_pReserved->m_oldValues.end(), allOldValues.begin() );
     618           0 :     ::std::copy( i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents );
     619             : 
     620           0 :     m_pReserved->m_handles.clear();
     621           0 :     m_pReserved->m_newValues.clear();
     622           0 :     m_pReserved->m_oldValues.clear();
     623             : 
     624           0 :     aGuard.clear();
     625           0 :     fire( &allHandles[0], &allNewValues[0], &allOldValues[0], additionalEvents + i_count, sal_False );
     626             : }
     627             : 
     628             : //--------------------------------------------------------------------------
     629       11615 : void OPropertySetHelper::fire
     630             : (
     631             :     sal_Int32 * pnHandles,
     632             :     const Any * pNewValues,
     633             :     const Any * pOldValues,
     634             :     sal_Int32 nHandles, // These is the Count of the array
     635             :     sal_Bool bVetoable
     636             : )
     637             : {
     638             :     OSL_ENSURE( m_pReserved.get(), "No OPropertySetHelper::Impl" );
     639             : 
     640       11615 :     if (! m_pReserved->m_bFireEvents)
     641       11713 :         return;
     642             : 
     643       11517 :     if (m_pReserved->m_pFireEvents) {
     644           0 :         m_pReserved->m_pFireEvents->fireEvents(
     645             :             pnHandles, nHandles, bVetoable,
     646           0 :             m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring);
     647             :     }
     648             : 
     649             :     // Only fire, if one or more properties changed
     650       11517 :     if( nHandles )
     651             :     {
     652             :         // create the event sequence of all changed properties
     653       10587 :         Sequence< PropertyChangeEvent > aEvts( nHandles );
     654       10587 :         PropertyChangeEvent * pEvts = aEvts.getArray();
     655       10587 :         Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
     656             :         sal_Int32 i;
     657       10587 :         sal_Int32 nChangesLen = 0;
     658             :         // Loop over all changed properties to fill the event struct
     659       25288 :         for( i = 0; i < nHandles; i++ )
     660             :         {
     661             :             // Vetoable fire and constrained attribute set or
     662             :             // Change fire and Changed and bound attribute set
     663       14701 :             IPropertyArrayHelper & rInfo = getInfoHelper();
     664             :             sal_Int16   nAttributes;
     665       14701 :             OUString aPropName;
     666       14701 :             rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] );
     667             : 
     668       14701 :             if(
     669             :                (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) ||
     670             :                (!bVetoable && (nAttributes & PropertyAttribute::BOUND))
     671             :               )
     672             :             {
     673        9414 :                 pEvts[nChangesLen].Source = xSource;
     674        9414 :                 pEvts[nChangesLen].PropertyName = aPropName;
     675        9414 :                 pEvts[nChangesLen].PropertyHandle = pnHandles[i];
     676        9414 :                 pEvts[nChangesLen].OldValue = pOldValues[i];
     677        9414 :                 pEvts[nChangesLen].NewValue = pNewValues[i];
     678        9414 :                 nChangesLen++;
     679             :             }
     680       14701 :         }
     681             : 
     682             :         bool bIgnoreRuntimeExceptionsWhileFiring =
     683       10587 :                 m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring;
     684             : 
     685             :         // fire the events for all changed properties
     686       20001 :         for( i = 0; i < nChangesLen; i++ )
     687             :         {
     688             :             // get the listener container for the property name
     689             :             OInterfaceContainerHelper * pLC;
     690        9414 :             if( bVetoable ) // fire change Events?
     691           3 :                 pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle );
     692             :             else
     693        9411 :                 pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle );
     694        9414 :             if( pLC )
     695             :             {
     696             :                 // Iterate over all listeners and send events
     697          21 :                 OInterfaceIteratorHelper aIt( *pLC);
     698          65 :                 while( aIt.hasMoreElements() )
     699             :                 {
     700          23 :                     XInterface * pL = aIt.next();
     701             :                     try
     702             :                     {
     703             :                         try
     704             :                         {
     705          23 :                             if( bVetoable ) // fire change Events?
     706             :                             {
     707             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     708           0 :                                     pEvts[i] );
     709             :                             }
     710             :                             else
     711             :                             {
     712             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     713          23 :                                     pEvts[i] );
     714             :                             }
     715             :                         }
     716           0 :                         catch (DisposedException & exc)
     717             :                         {
     718             :                             OSL_ENSURE( exc.Context.is(),
     719             :                                         "DisposedException without Context!" );
     720           0 :                             if (exc.Context == pL)
     721           0 :                                 aIt.remove();
     722             :                             else
     723           0 :                                 throw;
     724             :                         }
     725             :                     }
     726           0 :                     catch (RuntimeException & exc)
     727             :                     {
     728             :                         OSL_TRACE(
     729             :                             OUStringToOString(
     730             :                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
     731             :                                               "caught RuntimeException while "
     732             :                                               "firing listeners: ") ) +
     733             :                                 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
     734           0 :                         if (! bIgnoreRuntimeExceptionsWhileFiring)
     735           0 :                             throw;
     736             :                     }
     737          21 :                 }
     738             :             }
     739             :             // broadcast to all listeners with "" property name
     740        9414 :             if( bVetoable ){
     741             :                 // fire change Events?
     742             :                 pLC = rBHelper.aLC.getContainer(
     743           3 :                             getVetoableTypeIdentifier()
     744           3 :                                                 );
     745             :             }
     746             :             else {
     747             :                 pLC = rBHelper.aLC.getContainer(
     748        9411 :                             getPropertyTypeIdentifier(  )
     749        9411 :                                                 );
     750             :             }
     751        9414 :             if( pLC )
     752             :             {
     753             :                 // Iterate over all listeners and send events.
     754          55 :                 OInterfaceIteratorHelper aIt( *pLC);
     755         162 :                 while( aIt.hasMoreElements() )
     756             :                 {
     757          52 :                     XInterface * pL = aIt.next();
     758             :                     try
     759             :                     {
     760             :                         try
     761             :                         {
     762          52 :                             if( bVetoable ) // fire change Events?
     763             :                             {
     764             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     765           0 :                                     pEvts[i] );
     766             :                             }
     767             :                             else
     768             :                             {
     769             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     770          52 :                                     pEvts[i] );
     771             :                             }
     772             :                         }
     773           0 :                         catch (DisposedException & exc)
     774             :                         {
     775             :                             OSL_ENSURE( exc.Context.is(),
     776             :                                         "DisposedException without Context!" );
     777           0 :                             if (exc.Context == pL)
     778           0 :                                 aIt.remove();
     779             :                             else
     780           0 :                                 throw;
     781             :                         }
     782             :                     }
     783           0 :                     catch (RuntimeException & exc)
     784             :                     {
     785             :                         OSL_TRACE(
     786             :                             OUStringToOString(
     787             :                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
     788             :                                               "caught RuntimeException while "
     789             :                                               "firing listeners: ") ) +
     790             :                                 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
     791           0 :                         if (! bIgnoreRuntimeExceptionsWhileFiring)
     792           0 :                             throw;
     793             :                     }
     794          55 :                 }
     795             :             }
     796             :         }
     797             : 
     798             :         // reduce array to changed properties
     799       10587 :         aEvts.realloc( nChangesLen );
     800             : 
     801       10587 :         if( !bVetoable )
     802             :         {
     803        8219 :             OInterfaceContainerHelper * pCont = 0;
     804             :             pCont = rBHelper.aLC.getContainer(
     805        8219 :                                 getPropertiesTypeIdentifier(  )
     806        8219 :                                              );
     807        8219 :             if( pCont )
     808             :             {
     809             :                 // Here is a Bug, unbound properties are also fired
     810         107 :                 OInterfaceIteratorHelper aIt( *pCont );
     811         321 :                 while( aIt.hasMoreElements() )
     812             :                 {
     813             :                     XPropertiesChangeListener * pL =
     814         107 :                         (XPropertiesChangeListener *)aIt.next();
     815             :                     try
     816             :                     {
     817             :                         try
     818             :                         {
     819             :                             // fire the hole event sequence to the
     820             :                             // XPropertiesChangeListener's
     821         107 :                             pL->propertiesChange( aEvts );
     822             :                         }
     823           0 :                         catch (DisposedException & exc)
     824             :                         {
     825             :                             OSL_ENSURE( exc.Context.is(),
     826             :                                         "DisposedException without Context!" );
     827           0 :                             if (exc.Context == pL)
     828           0 :                                 aIt.remove();
     829             :                             else
     830           0 :                                 throw;
     831             :                         }
     832             :                     }
     833           0 :                     catch (RuntimeException & exc)
     834             :                     {
     835             :                         OSL_TRACE(
     836             :                             OUStringToOString(
     837             :                                 OUString( RTL_CONSTASCII_USTRINGPARAM(
     838             :                                               "caught RuntimeException while "
     839             :                                               "firing listeners: ") ) +
     840             :                                 exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
     841           0 :                         if (! bIgnoreRuntimeExceptionsWhileFiring)
     842           0 :                             throw;
     843             :                     }
     844         107 :                 }
     845             :             }
     846       10587 :         }
     847             :     }
     848             : }
     849             : 
     850             : // OPropertySetHelper
     851        2785 : void OPropertySetHelper::setFastPropertyValues(
     852             :     sal_Int32 nSeqLen,
     853             :     sal_Int32 * pHandles,
     854             :     const Any * pValues,
     855             :     sal_Int32 nHitCount )
     856             :     SAL_THROW( (::com::sun::star::uno::Exception) )
     857             : {
     858             :     OSL_ENSURE( !rBHelper.bInDispose, "do not getFastPropertyValue in the dispose call" );
     859             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     860             : 
     861        2785 :     Any * pConvertedValues = NULL;
     862        2785 :     Any * pOldValues = NULL;
     863             : 
     864             :     try
     865             :     {
     866             :         // get the map table
     867        2785 :         IPropertyArrayHelper & rPH = getInfoHelper();
     868             : 
     869        2785 :         pConvertedValues = new Any[ nHitCount ];
     870        2785 :         pOldValues = new Any[ nHitCount ];
     871        2785 :         sal_Int32 n = 0;
     872             :         sal_Int32 i;
     873             : 
     874             :         {
     875             :         // must lock the mutex outside the loop. So all values are consistent.
     876        2785 :         MutexGuard aGuard( rBHelper.rMutex );
     877       13640 :         for( i = 0; i < nSeqLen; i++ )
     878             :         {
     879       10855 :             if( pHandles[i] != -1 )
     880             :             {
     881             :                 sal_Int16 nAttributes;
     882       10713 :                 rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
     883       10713 :                 if( nAttributes & PropertyAttribute::READONLY ) {
     884           0 :                     throw PropertyVetoException();
     885             :                 }
     886             :                 // Will the property change?
     887       32139 :                 if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n],
     888       32139 :                                             pHandles[i], pValues[i] ) )
     889             :                 {
     890             :                     // only increment if the property really change
     891        4389 :                     pHandles[n]         = pHandles[i];
     892        4389 :                     n++;
     893             :                 }
     894             :             }
     895        2785 :         }
     896             :         // release guard to fire events
     897             :         }
     898             : 
     899             :         // fire vetoable events
     900        2785 :         fire( pHandles, pConvertedValues, pOldValues, n, sal_True );
     901             : 
     902             :         {
     903             :         // must lock the mutex outside the loop.
     904        2785 :         MutexGuard aGuard( rBHelper.rMutex );
     905             :         // Loop over all changed properties
     906        7174 :         for( i = 0; i < n; i++ )
     907             :         {
     908             :             // Will the property change?
     909        4389 :             setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
     910        2785 :         }
     911             :         // release guard to fire events
     912             :         }
     913             : 
     914             :         // fire change events
     915        2785 :         impl_fireAll( pHandles, pConvertedValues, pOldValues, n );
     916             :     }
     917           0 :     catch( ... )
     918             :     {
     919           0 :         delete [] pOldValues;
     920           0 :         delete [] pConvertedValues;
     921           0 :         throw;
     922             :     }
     923        2785 :     delete [] pOldValues;
     924        2785 :     delete [] pConvertedValues;
     925        2785 : }
     926             : 
     927             : // XMultiPropertySet
     928             : /**
     929             :  * The sequence may be conatain not known properties. The implementation
     930             :  * must ignore these properties.
     931             :  */
     932        2593 : void OPropertySetHelper::setPropertyValues(
     933             :     const Sequence<OUString>& rPropertyNames,
     934             :     const Sequence<Any>& rValues )
     935             :     throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
     936             : {
     937        2593 :     sal_Int32 * pHandles = NULL;
     938             :     try
     939             :     {
     940        2593 :         sal_Int32   nSeqLen = rPropertyNames.getLength();
     941        2593 :         pHandles = new sal_Int32[ nSeqLen ];
     942             :         // get the map table
     943        2593 :         IPropertyArrayHelper & rPH = getInfoHelper();
     944             :         // fill the handle array
     945        2593 :         sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames );
     946        2593 :         if( nHitCount != 0 )
     947        2593 :             setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount );
     948             :     }
     949           0 :     catch( ... )
     950             :     {
     951           0 :         delete [] pHandles;
     952           0 :         throw;
     953             :     }
     954        2593 :     delete [] pHandles;
     955        2593 : }
     956             : 
     957             : // XMultiPropertySet
     958           0 : Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames )
     959             :     throw(::com::sun::star::uno::RuntimeException)
     960             : {
     961           0 :     sal_Int32   nSeqLen = rPropertyNames.getLength();
     962           0 :     sal_Int32 * pHandles = new sal_Int32[ nSeqLen ];
     963           0 :     Sequence< Any > aValues( nSeqLen );
     964             : 
     965             :     // get the map table
     966           0 :     IPropertyArrayHelper & rPH = getInfoHelper();
     967             :     // fill the handle array
     968           0 :     rPH.fillHandles( pHandles, rPropertyNames );
     969             : 
     970           0 :     Any * pValues = aValues.getArray();
     971             : 
     972           0 :     MutexGuard aGuard( rBHelper.rMutex );
     973             :     // fill the sequence with the values
     974           0 :     for( sal_Int32 i = 0; i < nSeqLen; i++ )
     975           0 :         getFastPropertyValue( pValues[i], pHandles[i] );
     976             : 
     977           0 :     delete [] pHandles;
     978           0 :     return aValues;
     979             : }
     980             : 
     981             : // XMultiPropertySet
     982         138 : void OPropertySetHelper::addPropertiesChangeListener(
     983             :     const Sequence<OUString> & ,
     984             :     const Reference < XPropertiesChangeListener > & rListener )
     985             :     throw(::com::sun::star::uno::RuntimeException)
     986             : {
     987         138 :     rBHelper.addListener( getCppuType(&rListener) , rListener );
     988         138 : }
     989             : 
     990             : // XMultiPropertySet
     991          96 : void OPropertySetHelper::removePropertiesChangeListener(
     992             :     const Reference < XPropertiesChangeListener > & rListener )
     993             :     throw(::com::sun::star::uno::RuntimeException)
     994             : {
     995          96 :     rBHelper.removeListener( getCppuType(&rListener) , rListener );
     996          96 : }
     997             : 
     998             : // XMultiPropertySet
     999          12 : void OPropertySetHelper::firePropertiesChangeEvent(
    1000             :     const Sequence<OUString>& rPropertyNames,
    1001             :     const Reference < XPropertiesChangeListener >& rListener )
    1002             :     throw(::com::sun::star::uno::RuntimeException)
    1003             : {
    1004          12 :     sal_Int32 nLen = rPropertyNames.getLength();
    1005          12 :     sal_Int32 * pHandles = new sal_Int32[nLen];
    1006          12 :     IPropertyArrayHelper & rPH = getInfoHelper();
    1007          12 :     rPH.fillHandles( pHandles, rPropertyNames );
    1008          12 :     const OUString* pNames = rPropertyNames.getConstArray();
    1009             : 
    1010             :     // get the count of matching properties
    1011          12 :     sal_Int32 nFireLen = 0;
    1012             :     sal_Int32 i;
    1013        1098 :     for( i = 0; i < nLen; i++ )
    1014        1086 :         if( pHandles[i] != -1 )
    1015        1086 :             nFireLen++;
    1016             : 
    1017          12 :     Sequence<PropertyChangeEvent> aChanges( nFireLen );
    1018          12 :     PropertyChangeEvent* pChanges = aChanges.getArray();
    1019             : 
    1020             :     {
    1021             :     // must lock the mutex outside the loop. So all values are consistent.
    1022          12 :     MutexGuard aGuard( rBHelper.rMutex );
    1023          12 :     Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
    1024          12 :     sal_Int32 nFirePos = 0;
    1025        1098 :     for( i = 0; i < nLen; i++ )
    1026             :     {
    1027        1086 :         if( pHandles[i] != -1 )
    1028             :         {
    1029        1086 :             pChanges[nFirePos].Source = xSource;
    1030        1086 :             pChanges[nFirePos].PropertyName = pNames[i];
    1031        1086 :             pChanges[nFirePos].PropertyHandle = pHandles[i];
    1032        1086 :             getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] );
    1033        1086 :             pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue;
    1034        1086 :             nFirePos++;
    1035             :         }
    1036          12 :     }
    1037             :     // release guard to fire events
    1038             :     }
    1039          12 :     if( nFireLen )
    1040          12 :         rListener->propertiesChange( aChanges );
    1041             : 
    1042          12 :     delete [] pHandles;
    1043          12 : }
    1044             : 
    1045         116 : void OPropertySetHelper2::enableChangeListenerNotification( sal_Bool bEnable )
    1046             :     throw(::com::sun::star::uno::RuntimeException)
    1047             : {
    1048         116 :     m_pReserved->m_bFireEvents = bEnable;
    1049         116 : }
    1050             : 
    1051             : //========================================================================
    1052             : //== OPropertyArrayHelper ================================================
    1053             : //========================================================================
    1054             : 
    1055             : extern "C" {
    1056             : 
    1057       30312 : static int compare_Property_Impl( const void *arg1, const void *arg2 )
    1058             :     SAL_THROW_EXTERN_C()
    1059             : {
    1060       30312 :    return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name );
    1061             : }
    1062             : 
    1063             : }
    1064             : 
    1065         507 : void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW(())
    1066             : {
    1067         507 :     sal_Int32 i, nElements = aInfos.getLength();
    1068         507 :     const Property* pProperties = aInfos.getConstArray();
    1069             : 
    1070       13878 :     for( i = 1; i < nElements; i++ )
    1071             :     {
    1072       13443 :         if(  pProperties[i-1].Name >= pProperties[i].Name )
    1073             :         {
    1074             :             if (bSorted) {
    1075             :                 OSL_FAIL( "Property array is not sorted" );
    1076             :             }
    1077             :             // not sorted
    1078          72 :             qsort( aInfos.getArray(), nElements, sizeof( Property ),
    1079         144 :                     compare_Property_Impl );
    1080          72 :             break;
    1081             :         }
    1082             :     }
    1083             :     // may be that the array is resorted
    1084         507 :     pProperties = aInfos.getConstArray();
    1085         591 :     for( i = 0; i < nElements; i++ )
    1086         477 :         if( pProperties[i].Handle != i )
    1087         900 :             return;
    1088             :     // The handle is the index
    1089         114 :     bRightOrdered = sal_True;
    1090             : }
    1091             : 
    1092           0 : OPropertyArrayHelper::OPropertyArrayHelper(
    1093             :     Property * pProps,
    1094             :     sal_Int32 nEle,
    1095             :     sal_Bool bSorted )
    1096             :     SAL_THROW(())
    1097             :     : aInfos(pProps, nEle)
    1098           0 :     , bRightOrdered( sal_False )
    1099             : {
    1100           0 :     init( bSorted );
    1101           0 : }
    1102             : 
    1103         507 : OPropertyArrayHelper::OPropertyArrayHelper(
    1104             :     const Sequence< Property > & aProps,
    1105             :     sal_Bool bSorted )
    1106             :     SAL_THROW(())
    1107             :     : aInfos(aProps)
    1108         507 :     , bRightOrdered( sal_False )
    1109             : {
    1110         507 :     init( bSorted );
    1111         507 : }
    1112             : 
    1113             : //========================================================================
    1114           0 : sal_Int32 OPropertyArrayHelper::getCount() const
    1115             : {
    1116           0 :     return aInfos.getLength();
    1117             : }
    1118             : 
    1119             : //========================================================================
    1120      132720 : sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle
    1121             : (
    1122             :     OUString * pPropName,
    1123             :     sal_Int16 * pAttributes,
    1124             :     sal_Int32 nHandle
    1125             : )
    1126             : {
    1127      132720 :     const Property* pProperties = aInfos.getConstArray();
    1128      132720 :     sal_Int32 nElements = aInfos.getLength();
    1129             : 
    1130      132720 :     if( bRightOrdered )
    1131             :     {
    1132          74 :         if( nHandle < 0 || nHandle >= nElements )
    1133           0 :             return sal_False;
    1134          74 :         if( pPropName )
    1135           0 :             *pPropName = pProperties[ nHandle ].Name;
    1136          74 :         if( pAttributes )
    1137          74 :             *pAttributes = pProperties[ nHandle ].Attributes;
    1138          74 :         return sal_True;
    1139             :     }
    1140             :     else
    1141             :     {
    1142             :         // normally the array is sorted
    1143     4714623 :         for( sal_Int32 i = 0; i < nElements; i++ )
    1144             :         {
    1145     4714295 :             if( pProperties[i].Handle == nHandle )
    1146             :             {
    1147      132318 :                 if( pPropName )
    1148       14140 :                     *pPropName = pProperties[ i ].Name;
    1149      132318 :                 if( pAttributes )
    1150       43715 :                     *pAttributes = pProperties[ i ].Attributes;
    1151      132318 :                 return sal_True;
    1152             :             }
    1153             :         }
    1154             :     }
    1155         328 :     return sal_False;
    1156             : }
    1157             : 
    1158             : //========================================================================
    1159         313 : Sequence< Property > OPropertyArrayHelper::getProperties(void)
    1160             : {
    1161         313 :     return aInfos;
    1162             : }
    1163             : 
    1164             : //========================================================================
    1165           0 : Property OPropertyArrayHelper::getPropertyByName(const OUString& aPropertyName)
    1166             :         throw (UnknownPropertyException)
    1167             : {
    1168             :     Property * pR;
    1169           0 :     pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(),
    1170             :                               sizeof( Property ),
    1171           0 :                               compare_OUString_Property_Impl );
    1172           0 :     if( !pR ) {
    1173           0 :         throw UnknownPropertyException();
    1174             :     }
    1175           0 :     return *pR;
    1176             : }
    1177             : 
    1178             : //========================================================================
    1179           0 : sal_Bool OPropertyArrayHelper::hasPropertyByName(const OUString& aPropertyName)
    1180             : {
    1181             :     Property * pR;
    1182           0 :     pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(),
    1183             :                               sizeof( Property ),
    1184           0 :                               compare_OUString_Property_Impl );
    1185           0 :     return pR != NULL;
    1186             : }
    1187             : 
    1188             : //========================================================================
    1189      108763 : sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName )
    1190             : {
    1191             :     Property * pR;
    1192      217526 :     pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(),
    1193             :                               sizeof( Property ),
    1194      217526 :                               compare_OUString_Property_Impl );
    1195      108763 :     return pR ? pR->Handle : -1;
    1196             : }
    1197             : 
    1198             : //========================================================================
    1199        2591 : sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames )
    1200             : {
    1201        2591 :     sal_Int32 nHitCount = 0;
    1202        2591 :     const OUString * pReqProps = rPropNames.getConstArray();
    1203        2591 :     sal_Int32 nReqLen = rPropNames.getLength();
    1204        2591 :     const Property * pCur = aInfos.getConstArray();
    1205        2591 :     const Property * pEnd = pCur + aInfos.getLength();
    1206             : 
    1207       12986 :     for( sal_Int32 i = 0; i < nReqLen; i++ )
    1208             :     {
    1209             :         // Calculate logarithm
    1210       10395 :         sal_Int32 n = (sal_Int32)(pEnd - pCur);
    1211       10395 :         sal_Int32 nLog = 0;
    1212       82446 :         while( n )
    1213             :         {
    1214       61656 :             nLog += 1;
    1215       61656 :             n = n >> 1;
    1216             :         }
    1217             : 
    1218             :         // Number of properties to search for * Log2 of the number of remaining
    1219             :         // properties to search in.
    1220       10395 :         if( (nReqLen - i) * nLog >= pEnd - pCur )
    1221             :         {
    1222             :             // linear search is better
    1223        1884 :             while( pCur < pEnd && pReqProps[i] > pCur->Name )
    1224             :             {
    1225         740 :                 pCur++;
    1226             :             }
    1227         572 :             if( pCur < pEnd && pReqProps[i] == pCur->Name )
    1228             :             {
    1229         572 :                 pHandles[i] = pCur->Handle;
    1230         572 :                 nHitCount++;
    1231             :             }
    1232             :             else
    1233           0 :                 pHandles[i] = -1;
    1234             :         }
    1235             :         else
    1236             :         {
    1237             :             // binary search is better
    1238        9823 :             sal_Int32   nCompVal = 1;
    1239        9823 :             const Property * pOldEnd = pEnd--;
    1240        9823 :             const Property * pMid = pCur;
    1241             : 
    1242       66208 :             while( nCompVal != 0 && pCur <= pEnd )
    1243             :             {
    1244       46562 :                 pMid = (pEnd - pCur) / 2 + pCur;
    1245             : 
    1246       46562 :                 nCompVal = pReqProps[i].compareTo( pMid->Name );
    1247             : 
    1248       46562 :                 if( nCompVal > 0 )
    1249       11689 :                     pCur = pMid + 1;
    1250             :                 else
    1251       34873 :                     pEnd = pMid - 1;
    1252             :             }
    1253             : 
    1254        9823 :             if( nCompVal == 0 )
    1255             :             {
    1256        9823 :                 pHandles[i] = pMid->Handle;
    1257        9823 :                 nHitCount++;
    1258        9823 :                 pCur = pMid +1;
    1259             :             }
    1260           0 :             else if( nCompVal > 0 )
    1261             :             {
    1262           0 :                 pHandles[i] = -1;
    1263           0 :                 pCur = pMid +1;
    1264             :             }
    1265             :             else
    1266             :             {
    1267           0 :                 pHandles[i] = -1;
    1268           0 :                 pCur = pMid;
    1269             :             }
    1270        9823 :             pEnd = pOldEnd;
    1271             :         }
    1272             :     }
    1273        2591 :     return nHitCount;
    1274             : }
    1275             : 
    1276             : } // end namespace cppu
    1277             : 
    1278             : 
    1279             : 
    1280             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10