LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - propshlp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 322 489 65.8 %
Date: 2012-12-27 Functions: 45 55 81.8 %
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         168 : IPropertyArrayHelper::~IPropertyArrayHelper()
      42             : {
      43         168 : }
      44             : 
      45        4646 : inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW(())
      46             : {
      47        4646 :     return ::getCppuType( (Reference< XPropertyChangeListener > *)0 );
      48             : }
      49        3997 : inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW(())
      50             : {
      51        3997 :     return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 );
      52             : }
      53          22 : inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW(())
      54             : {
      55          22 :     return ::getCppuType( (Reference< XVetoableChangeListener > *)0 );
      56             : }
      57             : 
      58             : extern "C" {
      59             : 
      60      358654 : static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 )
      61             :     SAL_THROW_EXTERN_C()
      62             : {
      63      358654 :    return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name );
      64             : }
      65             : 
      66             : }
      67             : 
      68             : /**
      69             :  * The class which implements the PropertySetInfo interface.
      70             :  */
      71             : 
      72         488 : 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         244 : OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
      91             :     IPropertyArrayHelper & rHelper_ )
      92             :     SAL_THROW(())
      93         244 :     :aInfos( rHelper_.getProperties() )
      94             : {
      95         244 : }
      96             : 
      97             : /**
      98             :  * Return the sequence of properties, which are provided throug the constructor.
      99             :  */
     100         191 : Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException)
     101             : 
     102             : {
     103         191 :     return aInfos;
     104             : }
     105             : 
     106             : /**
     107             :  * Return the sequence of properties, which are provided throug the constructor.
     108             :  */
     109        5673 : Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
     110             : {
     111             :     Property * pR;
     112       11346 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     113             :                               sizeof( Property ),
     114       11346 :                               compare_OUString_Property_Impl );
     115        5673 :     if( !pR ) {
     116           0 :         throw UnknownPropertyException();
     117             :     }
     118             : 
     119        5673 :     return *pR;
     120             : }
     121             : 
     122             : /**
     123             :  * Return the sequence of properties, which are provided throug the constructor.
     124             :  */
     125       10515 : sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException)
     126             : {
     127             :     Property * pR;
     128       21030 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     129             :                               sizeof( Property ),
     130       21030 :                               compare_OUString_Property_Impl );
     131       10515 :     return pR != NULL;
     132             : }
     133             : 
     134             : //  ----------------------------------------------------
     135             : //  class PropertySetHelper_Impl
     136             : //  ----------------------------------------------------
     137        3532 : class OPropertySetHelper::Impl {
     138             : 
     139             : public:
     140        6194 :     Impl(   bool i_bIgnoreRuntimeExceptionsWhileFiring,
     141             :             IEventNotificationHook *i_pFireEvents
     142             :         )
     143             :         :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring )
     144             :         ,m_bFireEvents(true)
     145        6194 :         ,m_pFireEvents( i_pFireEvents )
     146             :     {
     147        6194 :     }
     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        6050 : OPropertySetHelper::OPropertySetHelper(
     163             :     OBroadcastHelper  & rBHelper_ ) SAL_THROW(())
     164             :     : rBHelper( rBHelper_ ),
     165             :       aBoundLC( rBHelper_.rMutex ),
     166             :       aVetoableLC( rBHelper_.rMutex ),
     167        6050 :       m_pReserved( new Impl(false, 0) )
     168             : {
     169        6050 : }
     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         144 : 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         144 :         new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) )
     188             : {
     189         144 : }
     190             : 
     191         144 : OPropertySetHelper2::OPropertySetHelper2(
     192             :         OBroadcastHelper & irBHelper,
     193             :         IEventNotificationHook *i_pFireEvents,
     194             :         bool bIgnoreRuntimeExceptionsWhileFiring)
     195         144 :             :OPropertySetHelper( irBHelper, i_pFireEvents, bIgnoreRuntimeExceptionsWhileFiring )
     196             : {
     197         144 : }
     198             : 
     199             : /**
     200             :  * You must call disposing before.
     201             :  */
     202        3532 : OPropertySetHelper::~OPropertySetHelper() SAL_THROW(())
     203             : {
     204        3532 : }
     205          83 : OPropertySetHelper2::~OPropertySetHelper2() SAL_THROW(())
     206             : {
     207          83 : }
     208             : 
     209             : // XInterface
     210        1934 : 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        1934 :         static_cast< XFastPropertySet * >( this ) );
     218             : }
     219             : 
     220         486 : Any OPropertySetHelper2::queryInterface( const ::com::sun::star::uno::Type & rType )
     221             :     throw (RuntimeException)
     222             : {
     223         486 :     Any cnd(cppu::queryInterface(rType, static_cast< XPropertySetOption * >(this)));
     224         486 :     if ( cnd.hasValue() )
     225          52 :         return cnd;
     226             :     else
     227         434 :         return OPropertySetHelper::queryInterface(rType);
     228             : }
     229             : 
     230             : /**
     231             :  * called from the derivee's XTypeProvider::getTypes implementation
     232             :  */
     233           0 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes()
     234             :     throw (RuntimeException)
     235             : {
     236           0 :     Sequence< ::com::sun::star::uno::Type > aTypes( 4 );
     237           0 :     aTypes[ 0 ] = XPropertySet::static_type();
     238           0 :     aTypes[ 1 ] = XPropertySetOption::static_type();
     239           0 :     aTypes[ 2 ] = XMultiPropertySet::static_type();
     240           0 :     aTypes[ 3 ] = XFastPropertySet::static_type();
     241           0 :     return aTypes;
     242             : }
     243             : 
     244             : // ComponentHelper
     245         103 : void OPropertySetHelper::disposing() SAL_THROW(())
     246             : {
     247             :     // Create an event with this as sender
     248         103 :     Reference < XPropertySet  > rSource( (static_cast< XPropertySet *  >(this)) , UNO_QUERY );
     249         103 :     EventObject aEvt;
     250         103 :     aEvt.Source = rSource;
     251             : 
     252             :     // inform all listeners to release this object
     253             :     // The listener containers are automatically cleared
     254         103 :     aBoundLC.disposeAndClear( aEvt );
     255         103 :     aVetoableLC.disposeAndClear( aEvt );
     256         103 : }
     257             : 
     258         244 : Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo(
     259             :     IPropertyArrayHelper & rProperties ) SAL_THROW(())
     260             : {
     261         244 :     return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
     262             : }
     263             : 
     264             : // XPropertySet
     265        9677 : 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        9677 :     IPropertyArrayHelper & rPH = getInfoHelper();
     271             :     // map the name to the handle
     272        9677 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     273             :     // call the method of the XFastPropertySet interface
     274        9677 :     setFastPropertyValue( nHandle, rValue );
     275        9636 : }
     276             : 
     277             : // XPropertySet
     278       40022 : 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       40022 :     IPropertyArrayHelper & rPH = getInfoHelper();
     284             :     // map the name to the handle
     285       40022 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     286             :     // call the method of the XFastPropertySet interface
     287       40022 :     return getFastPropertyValue( nHandle );
     288             : }
     289             : 
     290             : // XPropertySet
     291          61 : 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          61 :     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          61 :     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          61 :         if( !rPropertyName.isEmpty() )
     306             :         {
     307             :             // get the map table
     308          50 :             IPropertyArrayHelper & rPH = getInfoHelper();
     309             :             // map the name to the handle
     310          50 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     311          50 :             if( nHandle == -1 ) {
     312             :                 // property not known throw exception
     313           0 :                 throw  UnknownPropertyException() ;
     314             :             }
     315             : 
     316             :             sal_Int16 nAttributes;
     317          50 :             rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
     318          50 :             if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) )
     319             :             {
     320             :                 OSL_FAIL( "add listener to an unbound property" );
     321             :                 // silent ignore this
     322          61 :                 return;
     323             :             }
     324             :             // add the change listener to the helper container
     325             : 
     326          50 :             aBoundLC.addInterface( (sal_Int32)nHandle, rxListener );
     327             :         }
     328             :         else
     329             :             // add the change listener to the helper container
     330             :             rBHelper.aLC.addInterface(
     331          11 :                             getPropertyTypeIdentifier(  ),
     332             :                             rxListener
     333          22 :                                      );
     334          61 :     }
     335             : }
     336             : 
     337             : 
     338             : // XPropertySet
     339          28 : 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          28 :     MutexGuard aGuard( rBHelper.rMutex );
     347             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     348             :     // all listeners are automaticly released in a dispose call
     349          28 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     350             :     {
     351          28 :         if( !rPropertyName.isEmpty() )
     352             :         {
     353             :             // get the map table
     354          17 :             IPropertyArrayHelper & rPH = getInfoHelper();
     355             :             // map the name to the handle
     356          17 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     357          17 :             if( nHandle == -1 )
     358             :                 // property not known throw exception
     359           0 :                 throw UnknownPropertyException();
     360          17 :             aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener );
     361             :         }
     362             :         else {
     363             :             // remove the change listener to the helper container
     364             :             rBHelper.aLC.removeInterface(
     365          11 :                             getPropertyTypeIdentifier(  ),
     366             :                             rxListener
     367          22 :                                         );
     368             :         }
     369          28 :     }
     370          28 : }
     371             : 
     372             : // XPropertySet
     373          11 : 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          11 :     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          11 :     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          11 :         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          11 :                 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          11 :                                 getVetoableTypeIdentifier(  ),
     413             :                                 rxListener
     414          22 :                                      );
     415          11 :     }
     416             : }
     417             : 
     418             : // XPropertySet
     419          11 : 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          11 :     MutexGuard aGuard( rBHelper.rMutex );
     427             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     428             :     // all listeners are automaticly released in a dispose call
     429          11 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     430             :     {
     431          11 :         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          11 :                                 getVetoableTypeIdentifier( ),
     448             :                                 rxListener
     449          22 :                                         );
     450          11 :     }
     451          11 : }
     452             : 
     453           6 : 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           6 :     sal_Int16 nAttributes(0);
     459           6 :     IPropertyArrayHelper& rInfo = getInfoHelper();
     460           6 :     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           6 :     Any aConverted, aOld;
     469           6 :     sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value );
     470           6 :     if ( !bChanged )
     471           6 :         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        9638 : 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        9638 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     516             :     sal_Int16 nAttributes;
     517        9638 :     if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) {
     518             :         // unknown property
     519          41 :         throw UnknownPropertyException();
     520             :     }
     521        9597 :     if( nAttributes & PropertyAttribute::READONLY )
     522           0 :         throw PropertyVetoException();
     523             : 
     524        9597 :     Any aConvertedVal;
     525        9597 :     Any aOldVal;
     526             : 
     527             :     // Will the property change?
     528             :     sal_Bool bChanged;
     529             :     {
     530        9597 :         MutexGuard aGuard( rBHelper.rMutex );
     531        9597 :         bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue );
     532             :         // release guard to fire events
     533             :     }
     534        9597 :     if( bChanged )
     535             :     {
     536             :         // Is it a constrained property?
     537        2849 :         if( nAttributes & PropertyAttribute::CONSTRAINED )
     538             :         {
     539             :             // In aValue is the converted rValue
     540             :             // fire a constarined event
     541             :             // second parameter NULL means constrained
     542           0 :             fire( &nHandle, &rValue, &aOldVal, 1, sal_True );
     543             :         }
     544             : 
     545             :         {
     546        2849 :             MutexGuard aGuard( rBHelper.rMutex );
     547             :             try
     548             :             {
     549             :                 // set the property to the new value
     550        2849 :                 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        2849 :             }
     566             : 
     567             :             // release guard to fire events
     568             :         }
     569             :         // file a change event, if the value changed
     570        2849 :         impl_fireAll( &nHandle, &rValue, &aOldVal, 1 );
     571        9597 :     }
     572        9597 : }
     573             : 
     574             : // XFastPropertySet
     575       43587 : 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       43587 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     582       43587 :     if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
     583             :         // unknown property
     584         125 :         throw UnknownPropertyException();
     585             : 
     586       43462 :     Any aRet;
     587       43462 :     MutexGuard aGuard( rBHelper.rMutex );
     588       43462 :     getFastPropertyValue( aRet, nHandle );
     589       43462 :     return aRet;
     590             : }
     591             : 
     592             : //--------------------------------------------------------------------------
     593        4215 : void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count )
     594             : {
     595        4215 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     596        4215 :     if ( m_pReserved->m_handles.empty() )
     597             :     {
     598        4215 :         aGuard.clear();
     599        4215 :         fire( i_handles, i_newValues, i_oldValues, i_count, sal_False );
     600        4215 :         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        5644 : 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        5644 :     if (! m_pReserved->m_bFireEvents)
     641        5692 :         return;
     642             : 
     643        5596 :     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        5596 :     if( nHandles )
     651             :     {
     652             :         // create the event sequence of all changed properties
     653        5155 :         Sequence< PropertyChangeEvent > aEvts( nHandles );
     654        5155 :         PropertyChangeEvent * pEvts = aEvts.getArray();
     655        5155 :         Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
     656             :         sal_Int32 i;
     657        5155 :         sal_Int32 nChangesLen = 0;
     658             :         // Loop over all changed properties to fill the event struct
     659       12339 :         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        7184 :             IPropertyArrayHelper & rInfo = getInfoHelper();
     664             :             sal_Int16   nAttributes;
     665        7184 :             OUString aPropName;
     666        7184 :             rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] );
     667             : 
     668        7184 :             if(
     669             :                (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) ||
     670             :                (!bVetoable && (nAttributes & PropertyAttribute::BOUND))
     671             :               )
     672             :             {
     673        4624 :                 pEvts[nChangesLen].Source = xSource;
     674        4624 :                 pEvts[nChangesLen].PropertyName = aPropName;
     675        4624 :                 pEvts[nChangesLen].PropertyHandle = pnHandles[i];
     676        4624 :                 pEvts[nChangesLen].OldValue = pOldValues[i];
     677        4624 :                 pEvts[nChangesLen].NewValue = pNewValues[i];
     678        4624 :                 nChangesLen++;
     679             :             }
     680        7184 :         }
     681             : 
     682             :         bool bIgnoreRuntimeExceptionsWhileFiring =
     683        5155 :                 m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring;
     684             : 
     685             :         // fire the events for all changed properties
     686        9779 :         for( i = 0; i < nChangesLen; i++ )
     687             :         {
     688             :             // get the listener container for the property name
     689             :             OInterfaceContainerHelper * pLC;
     690        4624 :             if( bVetoable ) // fire change Events?
     691           0 :                 pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle );
     692             :             else
     693        4624 :                 pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle );
     694        4624 :             if( pLC )
     695             :             {
     696             :                 // Iterate over all listeners and send events
     697           7 :                 OInterfaceIteratorHelper aIt( *pLC);
     698          22 :                 while( aIt.hasMoreElements() )
     699             :                 {
     700           8 :                     XInterface * pL = aIt.next();
     701             :                     try
     702             :                     {
     703             :                         try
     704             :                         {
     705           8 :                             if( bVetoable ) // fire change Events?
     706             :                             {
     707             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     708           0 :                                     pEvts[i] );
     709             :                             }
     710             :                             else
     711             :                             {
     712             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     713           8 :                                     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           7 :                 }
     738             :             }
     739             :             // broadcast to all listeners with "" property name
     740        4624 :             if( bVetoable ){
     741             :                 // fire change Events?
     742             :                 pLC = rBHelper.aLC.getContainer(
     743           0 :                             getVetoableTypeIdentifier()
     744           0 :                                                 );
     745             :             }
     746             :             else {
     747             :                 pLC = rBHelper.aLC.getContainer(
     748        4624 :                             getPropertyTypeIdentifier(  )
     749        4624 :                                                 );
     750             :             }
     751        4624 :             if( pLC )
     752             :             {
     753             :                 // Iterate over all listeners and send events.
     754          10 :                 OInterfaceIteratorHelper aIt( *pLC);
     755          30 :                 while( aIt.hasMoreElements() )
     756             :                 {
     757          10 :                     XInterface * pL = aIt.next();
     758             :                     try
     759             :                     {
     760             :                         try
     761             :                         {
     762          10 :                             if( bVetoable ) // fire change Events?
     763             :                             {
     764             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     765           0 :                                     pEvts[i] );
     766             :                             }
     767             :                             else
     768             :                             {
     769             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     770          10 :                                     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          10 :                 }
     795             :             }
     796             :         }
     797             : 
     798             :         // reduce array to changed properties
     799        5155 :         aEvts.realloc( nChangesLen );
     800             : 
     801        5155 :         if( !bVetoable )
     802             :         {
     803        3997 :             OInterfaceContainerHelper * pCont = 0;
     804             :             pCont = rBHelper.aLC.getContainer(
     805        3997 :                                 getPropertiesTypeIdentifier(  )
     806        3997 :                                              );
     807        3997 :             if( pCont )
     808             :             {
     809             :                 // Here is a Bug, unbound properties are also fired
     810          30 :                 OInterfaceIteratorHelper aIt( *pCont );
     811          90 :                 while( aIt.hasMoreElements() )
     812             :                 {
     813             :                     XPropertiesChangeListener * pL =
     814          30 :                         (XPropertiesChangeListener *)aIt.next();
     815             :                     try
     816             :                     {
     817             :                         try
     818             :                         {
     819             :                             // fire the hole event sequence to the
     820             :                             // XPropertiesChangeListener's
     821          30 :                             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          30 :                 }
     845             :             }
     846        5155 :         }
     847             :     }
     848             : }
     849             : 
     850             : // OPropertySetHelper
     851        1366 : 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        1366 :     Any * pConvertedValues = NULL;
     862        1366 :     Any * pOldValues = NULL;
     863             : 
     864             :     try
     865             :     {
     866             :         // get the map table
     867        1366 :         IPropertyArrayHelper & rPH = getInfoHelper();
     868             : 
     869        1366 :         pConvertedValues = new Any[ nHitCount ];
     870        1366 :         pOldValues = new Any[ nHitCount ];
     871        1366 :         sal_Int32 n = 0;
     872             :         sal_Int32 i;
     873             : 
     874             :         {
     875             :         // must lock the mutex outside the loop. So all values are consistent.
     876        1366 :         MutexGuard aGuard( rBHelper.rMutex );
     877        6730 :         for( i = 0; i < nSeqLen; i++ )
     878             :         {
     879        5364 :             if( pHandles[i] != -1 )
     880             :             {
     881             :                 sal_Int16 nAttributes;
     882        5300 :                 rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
     883        5300 :                 if( nAttributes & PropertyAttribute::READONLY ) {
     884           0 :                     throw PropertyVetoException();
     885             :                 }
     886             :                 // Will the property change?
     887       15900 :                 if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n],
     888       15900 :                                             pHandles[i], pValues[i] ) )
     889             :                 {
     890             :                     // only increment if the property really change
     891        2161 :                     pHandles[n]         = pHandles[i];
     892        2161 :                     n++;
     893             :                 }
     894             :             }
     895        1366 :         }
     896             :         // release guard to fire events
     897             :         }
     898             : 
     899             :         // fire vetoable events
     900        1366 :         fire( pHandles, pConvertedValues, pOldValues, n, sal_True );
     901             : 
     902             :         {
     903             :         // must lock the mutex outside the loop.
     904        1366 :         MutexGuard aGuard( rBHelper.rMutex );
     905             :         // Loop over all changed properties
     906        3527 :         for( i = 0; i < n; i++ )
     907             :         {
     908             :             // Will the property change?
     909        2161 :             setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
     910        1366 :         }
     911             :         // release guard to fire events
     912             :         }
     913             : 
     914             :         // fire change events
     915        1366 :         impl_fireAll( pHandles, pConvertedValues, pOldValues, n );
     916             :     }
     917           0 :     catch( ... )
     918             :     {
     919           0 :         delete [] pOldValues;
     920           0 :         delete [] pConvertedValues;
     921           0 :         throw;
     922             :     }
     923        1366 :     delete [] pOldValues;
     924        1366 :     delete [] pConvertedValues;
     925        1366 : }
     926             : 
     927             : // XMultiPropertySet
     928             : /**
     929             :  * The sequence may be conatain not known properties. The implementation
     930             :  * must ignore these properties.
     931             :  */
     932        1294 : 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        1294 :     sal_Int32 * pHandles = NULL;
     938             :     try
     939             :     {
     940        1294 :         sal_Int32   nSeqLen = rPropertyNames.getLength();
     941        1294 :         pHandles = new sal_Int32[ nSeqLen ];
     942             :         // get the map table
     943        1294 :         IPropertyArrayHelper & rPH = getInfoHelper();
     944             :         // fill the handle array
     945        1294 :         sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames );
     946        1294 :         if( nHitCount != 0 )
     947        1294 :             setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount );
     948             :     }
     949           0 :     catch( ... )
     950             :     {
     951           0 :         delete [] pHandles;
     952           0 :         throw;
     953             :     }
     954        1294 :     delete [] pHandles;
     955        1294 : }
     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          20 : void OPropertySetHelper::addPropertiesChangeListener(
     983             :     const Sequence<OUString> & ,
     984             :     const Reference < XPropertiesChangeListener > & rListener )
     985             :     throw(::com::sun::star::uno::RuntimeException)
     986             : {
     987          20 :     rBHelper.addListener( getCppuType(&rListener) , rListener );
     988          20 : }
     989             : 
     990             : // XMultiPropertySet
     991          13 : void OPropertySetHelper::removePropertiesChangeListener(
     992             :     const Reference < XPropertiesChangeListener > & rListener )
     993             :     throw(::com::sun::star::uno::RuntimeException)
     994             : {
     995          13 :     rBHelper.removeListener( getCppuType(&rListener) , rListener );
     996          13 : }
     997             : 
     998             : // XMultiPropertySet
     999           0 : void OPropertySetHelper::firePropertiesChangeEvent(
    1000             :     const Sequence<OUString>& rPropertyNames,
    1001             :     const Reference < XPropertiesChangeListener >& rListener )
    1002             :     throw(::com::sun::star::uno::RuntimeException)
    1003             : {
    1004           0 :     sal_Int32 nLen = rPropertyNames.getLength();
    1005           0 :     sal_Int32 * pHandles = new sal_Int32[nLen];
    1006           0 :     IPropertyArrayHelper & rPH = getInfoHelper();
    1007           0 :     rPH.fillHandles( pHandles, rPropertyNames );
    1008           0 :     const OUString* pNames = rPropertyNames.getConstArray();
    1009             : 
    1010             :     // get the count of matching properties
    1011           0 :     sal_Int32 nFireLen = 0;
    1012             :     sal_Int32 i;
    1013           0 :     for( i = 0; i < nLen; i++ )
    1014           0 :         if( pHandles[i] != -1 )
    1015           0 :             nFireLen++;
    1016             : 
    1017           0 :     Sequence<PropertyChangeEvent> aChanges( nFireLen );
    1018           0 :     PropertyChangeEvent* pChanges = aChanges.getArray();
    1019             : 
    1020             :     {
    1021             :     // must lock the mutex outside the loop. So all values are consistent.
    1022           0 :     MutexGuard aGuard( rBHelper.rMutex );
    1023           0 :     Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
    1024           0 :     sal_Int32 nFirePos = 0;
    1025           0 :     for( i = 0; i < nLen; i++ )
    1026             :     {
    1027           0 :         if( pHandles[i] != -1 )
    1028             :         {
    1029           0 :             pChanges[nFirePos].Source = xSource;
    1030           0 :             pChanges[nFirePos].PropertyName = pNames[i];
    1031           0 :             pChanges[nFirePos].PropertyHandle = pHandles[i];
    1032           0 :             getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] );
    1033           0 :             pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue;
    1034           0 :             nFirePos++;
    1035             :         }
    1036           0 :     }
    1037             :     // release guard to fire events
    1038             :     }
    1039           0 :     if( nFireLen )
    1040           0 :         rListener->propertiesChange( aChanges );
    1041             : 
    1042           0 :     delete [] pHandles;
    1043           0 : }
    1044             : 
    1045          52 : void OPropertySetHelper2::enableChangeListenerNotification( sal_Bool bEnable )
    1046             :     throw(::com::sun::star::uno::RuntimeException)
    1047             : {
    1048          52 :     m_pReserved->m_bFireEvents = bEnable;
    1049          52 : }
    1050             : 
    1051             : //========================================================================
    1052             : //== OPropertyArrayHelper ================================================
    1053             : //========================================================================
    1054             : 
    1055             : extern "C" {
    1056             : 
    1057        7578 : static int compare_Property_Impl( const void *arg1, const void *arg2 )
    1058             :     SAL_THROW_EXTERN_C()
    1059             : {
    1060        7578 :    return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name );
    1061             : }
    1062             : 
    1063             : }
    1064             : 
    1065         165 : void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW(())
    1066             : {
    1067         165 :     sal_Int32 i, nElements = aInfos.getLength();
    1068         165 :     const Property* pProperties = aInfos.getConstArray();
    1069             : 
    1070        6523 :     for( i = 1; i < nElements; i++ )
    1071             :     {
    1072        6376 :         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          18 :             qsort( aInfos.getArray(), nElements, sizeof( Property ),
    1079          36 :                     compare_Property_Impl );
    1080          18 :             break;
    1081             :         }
    1082             :     }
    1083             :     // may be that the array is resorted
    1084         165 :     pProperties = aInfos.getConstArray();
    1085         207 :     for( i = 0; i < nElements; i++ )
    1086         184 :         if( pProperties[i].Handle != i )
    1087         307 :             return;
    1088             :     // The handle is the index
    1089          23 :     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         165 : OPropertyArrayHelper::OPropertyArrayHelper(
    1104             :     const Sequence< Property > & aProps,
    1105             :     sal_Bool bSorted )
    1106             :     SAL_THROW(())
    1107             :     : aInfos(aProps)
    1108         165 :     , bRightOrdered( sal_False )
    1109             : {
    1110         165 :     init( bSorted );
    1111         165 : }
    1112             : 
    1113             : //========================================================================
    1114           0 : sal_Int32 OPropertyArrayHelper::getCount() const
    1115             : {
    1116           0 :     return aInfos.getLength();
    1117             : }
    1118             : 
    1119             : //========================================================================
    1120       65256 : sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle
    1121             : (
    1122             :     OUString * pPropName,
    1123             :     sal_Int16 * pAttributes,
    1124             :     sal_Int32 nHandle
    1125             : )
    1126             : {
    1127       65256 :     const Property* pProperties = aInfos.getConstArray();
    1128       65256 :     sal_Int32 nElements = aInfos.getLength();
    1129             : 
    1130       65256 :     if( bRightOrdered )
    1131             :     {
    1132          37 :         if( nHandle < 0 || nHandle >= nElements )
    1133           0 :             return sal_False;
    1134          37 :         if( pPropName )
    1135           0 :             *pPropName = pProperties[ nHandle ].Name;
    1136          37 :         if( pAttributes )
    1137          37 :             *pAttributes = pProperties[ nHandle ].Attributes;
    1138          37 :         return sal_True;
    1139             :     }
    1140             :     else
    1141             :     {
    1142             :         // normally the array is sorted
    1143     2334535 :         for( sal_Int32 i = 0; i < nElements; i++ )
    1144             :         {
    1145     2334371 :             if( pProperties[i].Handle == nHandle )
    1146             :             {
    1147       65055 :                 if( pPropName )
    1148        7028 :                     *pPropName = pProperties[ i ].Name;
    1149       65055 :                 if( pAttributes )
    1150       21764 :                     *pAttributes = pProperties[ i ].Attributes;
    1151       65055 :                 return sal_True;
    1152             :             }
    1153             :         }
    1154             :     }
    1155         164 :     return sal_False;
    1156             : }
    1157             : 
    1158             : //========================================================================
    1159          99 : Sequence< Property > OPropertyArrayHelper::getProperties(void)
    1160             : {
    1161          99 :     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       53755 : sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName )
    1190             : {
    1191             :     Property * pR;
    1192      107510 :     pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(),
    1193             :                               sizeof( Property ),
    1194      107510 :                               compare_OUString_Property_Impl );
    1195       53755 :     return pR ? pR->Handle : -1;
    1196             : }
    1197             : 
    1198             : //========================================================================
    1199        1294 : sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames )
    1200             : {
    1201        1294 :     sal_Int32 nHitCount = 0;
    1202        1294 :     const OUString * pReqProps = rPropNames.getConstArray();
    1203        1294 :     sal_Int32 nReqLen = rPropNames.getLength();
    1204        1294 :     const Property * pCur = aInfos.getConstArray();
    1205        1294 :     const Property * pEnd = pCur + aInfos.getLength();
    1206             : 
    1207        6490 :     for( sal_Int32 i = 0; i < nReqLen; i++ )
    1208             :     {
    1209             :         // Calculate logarithm
    1210        5196 :         sal_Int32 n = (sal_Int32)(pEnd - pCur);
    1211        5196 :         sal_Int32 nLog = 0;
    1212       41211 :         while( n )
    1213             :         {
    1214       30819 :             nLog += 1;
    1215       30819 :             n = n >> 1;
    1216             :         }
    1217             : 
    1218             :         // Number of properties to search for * Log2 of the number of remaining
    1219             :         // properties to search in.
    1220        5196 :         if( (nReqLen - i) * nLog >= pEnd - pCur )
    1221             :         {
    1222             :             // linear search is better
    1223         942 :             while( pCur < pEnd && pReqProps[i] > pCur->Name )
    1224             :             {
    1225         370 :                 pCur++;
    1226             :             }
    1227         286 :             if( pCur < pEnd && pReqProps[i] == pCur->Name )
    1228             :             {
    1229         286 :                 pHandles[i] = pCur->Handle;
    1230         286 :                 nHitCount++;
    1231             :             }
    1232             :             else
    1233           0 :                 pHandles[i] = -1;
    1234             :         }
    1235             :         else
    1236             :         {
    1237             :             // binary search is better
    1238        4910 :             sal_Int32   nCompVal = 1;
    1239        4910 :             const Property * pOldEnd = pEnd--;
    1240        4910 :             const Property * pMid = pCur;
    1241             : 
    1242       33095 :             while( nCompVal != 0 && pCur <= pEnd )
    1243             :             {
    1244       23275 :                 pMid = (pEnd - pCur) / 2 + pCur;
    1245             : 
    1246       23275 :                 nCompVal = pReqProps[i].compareTo( pMid->Name );
    1247             : 
    1248       23275 :                 if( nCompVal > 0 )
    1249        5843 :                     pCur = pMid + 1;
    1250             :                 else
    1251       17432 :                     pEnd = pMid - 1;
    1252             :             }
    1253             : 
    1254        4910 :             if( nCompVal == 0 )
    1255             :             {
    1256        4910 :                 pHandles[i] = pMid->Handle;
    1257        4910 :                 nHitCount++;
    1258        4910 :                 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        4910 :             pEnd = pOldEnd;
    1271             :         }
    1272             :     }
    1273        1294 :     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