LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/cppuhelper/source - propshlp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 417 491 84.9 %
Date: 2013-07-09 Functions: 48 55 87.3 %
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        3143 : IPropertyArrayHelper::~IPropertyArrayHelper()
      42             : {
      43        3143 : }
      44             : 
      45       36047 : inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW(())
      46             : {
      47       36047 :     return ::getCppuType( (Reference< XPropertyChangeListener > *)0 );
      48             : }
      49       34789 : inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW(())
      50             : {
      51       34789 :     return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 );
      52             : }
      53        1321 : inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW(())
      54             : {
      55        1321 :     return ::getCppuType( (Reference< XVetoableChangeListener > *)0 );
      56             : }
      57             : 
      58             : extern "C" {
      59             : 
      60     6047297 : static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 )
      61             :     SAL_THROW_EXTERN_C()
      62             : {
      63     6047297 :    return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name );
      64             : }
      65             : 
      66             : }
      67             : 
      68             : /**
      69             :  * The class which implements the PropertySetInfo interface.
      70             :  */
      71             : 
      72       76272 : 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       38137 : OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
      91             :     IPropertyArrayHelper & rHelper_ )
      92             :     SAL_THROW(())
      93       38137 :     :aInfos( rHelper_.getProperties() )
      94             : {
      95       38137 : }
      96             : 
      97             : /**
      98             :  * Return the sequence of properties, which are provided throug the constructor.
      99             :  */
     100        5957 : Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException)
     101             : 
     102             : {
     103        5957 :     return aInfos;
     104             : }
     105             : 
     106             : /**
     107             :  * Return the sequence of properties, which are provided throug the constructor.
     108             :  */
     109      110349 : Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
     110             : {
     111             :     Property * pR;
     112      220698 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     113             :                               sizeof( Property ),
     114      220698 :                               compare_OUString_Property_Impl );
     115      110349 :     if( !pR ) {
     116          19 :         throw UnknownPropertyException();
     117             :     }
     118             : 
     119      110330 :     return *pR;
     120             : }
     121             : 
     122             : /**
     123             :  * Return the sequence of properties, which are provided throug the constructor.
     124             :  */
     125      242954 : sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException)
     126             : {
     127             :     Property * pR;
     128      485908 :     pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(),
     129             :                               sizeof( Property ),
     130      485908 :                               compare_OUString_Property_Impl );
     131      242954 :     return pR != NULL;
     132             : }
     133             : 
     134             : //  ----------------------------------------------------
     135             : //  class PropertySetHelper_Impl
     136             : //  ----------------------------------------------------
     137       67925 : class OPropertySetHelper::Impl {
     138             : 
     139             : public:
     140       68241 :     Impl(   bool i_bIgnoreRuntimeExceptionsWhileFiring,
     141             :             IEventNotificationHook *i_pFireEvents
     142             :         )
     143             :         :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring )
     144             :         ,m_bFireEvents(true)
     145       68241 :         ,m_pFireEvents( i_pFireEvents )
     146             :     {
     147       68241 :     }
     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       66936 : OPropertySetHelper::OPropertySetHelper(
     163             :     OBroadcastHelper  & rBHelper_ ) SAL_THROW(())
     164             :     : rBHelper( rBHelper_ ),
     165             :       aBoundLC( rBHelper_.rMutex ),
     166             :       aVetoableLC( rBHelper_.rMutex ),
     167       66936 :       m_pReserved( new Impl(false, 0) )
     168             : {
     169       66936 : }
     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        1305 : 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        1305 :         new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) )
     188             : {
     189        1305 : }
     190             : 
     191        1305 : OPropertySetHelper2::OPropertySetHelper2(
     192             :         OBroadcastHelper & irBHelper,
     193             :         IEventNotificationHook *i_pFireEvents,
     194             :         bool bIgnoreRuntimeExceptionsWhileFiring)
     195        1305 :             :OPropertySetHelper( irBHelper, i_pFireEvents, bIgnoreRuntimeExceptionsWhileFiring )
     196             : {
     197        1305 : }
     198             : 
     199             : /**
     200             :  * You must call disposing before.
     201             :  */
     202       67925 : OPropertySetHelper::~OPropertySetHelper() SAL_THROW(())
     203             : {
     204       67925 : }
     205        1224 : OPropertySetHelper2::~OPropertySetHelper2() SAL_THROW(())
     206             : {
     207        1224 : }
     208             : 
     209             : // XInterface
     210      133840 : 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      133840 :         static_cast< XFastPropertySet * >( this ) );
     218             : }
     219             : 
     220       86452 : Any OPropertySetHelper2::queryInterface( const ::com::sun::star::uno::Type & rType )
     221             :     throw (RuntimeException)
     222             : {
     223       86452 :     Any cnd(cppu::queryInterface(rType, static_cast< XPropertySetOption * >(this)));
     224       86452 :     if ( cnd.hasValue() )
     225         198 :         return cnd;
     226             :     else
     227       86254 :         return OPropertySetHelper::queryInterface(rType);
     228             : }
     229             : 
     230             : /**
     231             :  * called from the derivee's XTypeProvider::getTypes implementation
     232             :  */
     233         127 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes()
     234             :     throw (RuntimeException)
     235             : {
     236         127 :     Sequence< ::com::sun::star::uno::Type > aTypes( 4 );
     237         127 :     aTypes[ 0 ] = XPropertySet::static_type();
     238         127 :     aTypes[ 1 ] = XPropertySetOption::static_type();
     239         127 :     aTypes[ 2 ] = XMultiPropertySet::static_type();
     240         127 :     aTypes[ 3 ] = XFastPropertySet::static_type();
     241         127 :     return aTypes;
     242             : }
     243             : 
     244             : // ComponentHelper
     245        5738 : void OPropertySetHelper::disposing() SAL_THROW(())
     246             : {
     247             :     // Create an event with this as sender
     248        5738 :     Reference < XPropertySet  > rSource( (static_cast< XPropertySet *  >(this)) , UNO_QUERY );
     249       11476 :     EventObject aEvt;
     250        5738 :     aEvt.Source = rSource;
     251             : 
     252             :     // inform all listeners to release this object
     253             :     // The listener containers are automatically cleared
     254        5738 :     aBoundLC.disposeAndClear( aEvt );
     255       11476 :     aVetoableLC.disposeAndClear( aEvt );
     256        5738 : }
     257             : 
     258       38137 : Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo(
     259             :     IPropertyArrayHelper & rProperties ) SAL_THROW(())
     260             : {
     261       38137 :     return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) );
     262             : }
     263             : 
     264             : // XPropertySet
     265      117915 : 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      117915 :     IPropertyArrayHelper & rPH = getInfoHelper();
     271             :     // map the name to the handle
     272      117915 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     273             :     // call the method of the XFastPropertySet interface
     274      117915 :     setFastPropertyValue( nHandle, rValue );
     275      117794 : }
     276             : 
     277             : // XPropertySet
     278      770138 : 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      770138 :     IPropertyArrayHelper & rPH = getInfoHelper();
     284             :     // map the name to the handle
     285      770137 :     sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     286             :     // call the method of the XFastPropertySet interface
     287      770138 :     return getFastPropertyValue( nHandle );
     288             : }
     289             : 
     290             : // XPropertySet
     291        9147 : 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        9147 :     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        9147 :     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        9147 :         if( !rPropertyName.isEmpty() )
     306             :         {
     307             :             // get the map table
     308        7985 :             IPropertyArrayHelper & rPH = getInfoHelper();
     309             :             // map the name to the handle
     310        7985 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     311        7985 :             if( nHandle == -1 ) {
     312             :                 // property not known throw exception
     313           0 :                 throw  UnknownPropertyException() ;
     314             :             }
     315             : 
     316             :             sal_Int16 nAttributes;
     317        7985 :             rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
     318        7985 :             if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) )
     319             :             {
     320             :                 OSL_FAIL( "add listener to an unbound property" );
     321             :                 // silent ignore this
     322        9147 :                 return;
     323             :             }
     324             :             // add the change listener to the helper container
     325             : 
     326        7985 :             aBoundLC.addInterface( (sal_Int32)nHandle, rxListener );
     327             :         }
     328             :         else
     329             :             // add the change listener to the helper container
     330             :             rBHelper.aLC.addInterface(
     331        1162 :                             getPropertyTypeIdentifier(  ),
     332             :                             rxListener
     333        2324 :                                      );
     334        9147 :     }
     335             : }
     336             : 
     337             : 
     338             : // XPropertySet
     339        5768 : 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        5768 :     MutexGuard aGuard( rBHelper.rMutex );
     347             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     348             :     // all listeners are automaticly released in a dispose call
     349        5768 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     350             :     {
     351        5514 :         if( !rPropertyName.isEmpty() )
     352             :         {
     353             :             // get the map table
     354        4871 :             IPropertyArrayHelper & rPH = getInfoHelper();
     355             :             // map the name to the handle
     356        4871 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     357        4871 :             if( nHandle == -1 )
     358             :                 // property not known throw exception
     359           0 :                 throw UnknownPropertyException();
     360        4871 :             aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener );
     361             :         }
     362             :         else {
     363             :             // remove the change listener to the helper container
     364             :             rBHelper.aLC.removeInterface(
     365         643 :                             getPropertyTypeIdentifier(  ),
     366             :                             rxListener
     367        1286 :                                         );
     368             :         }
     369        5768 :     }
     370        5768 : }
     371             : 
     372             : // XPropertySet
     373         598 : 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         598 :     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         598 :     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         598 :         if( !rPropertyName.isEmpty() )
     388             :         {
     389             :             // get the map table
     390          31 :             IPropertyArrayHelper & rPH = getInfoHelper();
     391             :             // map the name to the handle
     392          31 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     393          31 :             if( nHandle == -1 ) {
     394             :                 // property not known throw exception
     395           0 :                 throw UnknownPropertyException();
     396             :             }
     397             : 
     398             :             sal_Int16 nAttributes;
     399          31 :             rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle );
     400          31 :             if( !(nAttributes & PropertyAttribute::CONSTRAINED) )
     401             :             {
     402             :                 OSL_FAIL( "addVetoableChangeListener, and property is not constrained" );
     403             :                 // silent ignore this
     404         598 :                 return;
     405             :             }
     406             :             // add the vetoable listener to the helper container
     407          31 :             aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener );
     408             :         }
     409             :         else
     410             :             // add the vetoable listener to the helper container
     411             :             rBHelper.aLC.addInterface(
     412         567 :                                 getVetoableTypeIdentifier(  ),
     413             :                                 rxListener
     414        1134 :                                      );
     415         598 :     }
     416             : }
     417             : 
     418             : // XPropertySet
     419         517 : 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         517 :     MutexGuard aGuard( rBHelper.rMutex );
     427             :     OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
     428             :     // all listeners are automaticly released in a dispose call
     429         517 :     if( !rBHelper.bInDispose && !rBHelper.bDisposed )
     430             :     {
     431         517 :         if( !rPropertyName.isEmpty() )
     432             :         {
     433             :             // get the map table
     434           1 :             IPropertyArrayHelper & rPH = getInfoHelper();
     435             :             // map the name to the handle
     436           1 :             sal_Int32 nHandle = rPH.getHandleByName( rPropertyName );
     437           1 :             if( nHandle == -1 ) {
     438             :                 // property not known throw exception
     439           0 :                 throw UnknownPropertyException();
     440             :             }
     441             :             // remove the vetoable listener to the helper container
     442           1 :             aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener );
     443             :         }
     444             :         else
     445             :             // add the vetoable listener to the helper container
     446             :             rBHelper.aLC.removeInterface(
     447         516 :                                 getVetoableTypeIdentifier( ),
     448             :                                 rxListener
     449        1032 :                                         );
     450         517 :     }
     451         517 : }
     452             : 
     453         187 : 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         187 :     sal_Int16 nAttributes(0);
     459         187 :     IPropertyArrayHelper& rInfo = getInfoHelper();
     460         187 :     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         249 :     Any aConverted, aOld;
     469         187 :     sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value );
     470         187 :     if ( !bChanged )
     471         312 :         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          62 :         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          62 :     m_pReserved->m_handles.push_back( i_handle );
     500          62 :     m_pReserved->m_newValues.push_back( aConverted );   // TODO: setFastPropertyValue notifies the unconverted value here ...?
     501         124 :     m_pReserved->m_oldValues.push_back( aOld );
     502             : }
     503             : 
     504             : // XFastPropertySet
     505      116288 : 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      116288 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     516             :     sal_Int16 nAttributes;
     517      116288 :     if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) {
     518             :         // unknown property
     519          69 :         throw UnknownPropertyException();
     520             :     }
     521      116219 :     if( nAttributes & PropertyAttribute::READONLY )
     522          32 :         throw PropertyVetoException();
     523             : 
     524      116187 :     Any aConvertedVal;
     525      232374 :     Any aOldVal;
     526             : 
     527             :     // Will the property change?
     528             :     sal_Bool bChanged;
     529             :     {
     530      116187 :         MutexGuard aGuard( rBHelper.rMutex );
     531      116191 :         bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue );
     532             :         // release guard to fire events
     533             :     }
     534      116183 :     if( bChanged )
     535             :     {
     536             :         // Is it a constrained property?
     537       20650 :         if( nAttributes & PropertyAttribute::CONSTRAINED )
     538             :         {
     539             :             // In aValue is the converted rValue
     540             :             // fire a constarined event
     541             :             // second parameter NULL means constrained
     542         238 :             fire( &nHandle, &rValue, &aOldVal, 1, sal_True );
     543             :         }
     544             : 
     545             :         {
     546       20650 :             MutexGuard aGuard( rBHelper.rMutex );
     547             :             try
     548             :             {
     549             :                 // set the property to the new value
     550       20650 :                 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       20650 :             }
     566             : 
     567             :             // release guard to fire events
     568             :         }
     569             :         // file a change event, if the value changed
     570       20650 :         impl_fireAll( &nHandle, &rValue, &aOldVal, 1 );
     571      116187 :     }
     572      116183 : }
     573             : 
     574             : // XFastPropertySet
     575      824195 : 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      824195 :     IPropertyArrayHelper & rInfo = getInfoHelper();
     582      824195 :     if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) )
     583             :         // unknown property
     584        1190 :         throw UnknownPropertyException();
     585             : 
     586      823005 :     Any aRet;
     587     1646010 :     MutexGuard aGuard( rBHelper.rMutex );
     588      823005 :     getFastPropertyValue( aRet, nHandle );
     589     1646010 :     return aRet;
     590             : }
     591             : 
     592             : //--------------------------------------------------------------------------
     593       30545 : void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count )
     594             : {
     595       30545 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     596       30545 :     if ( m_pReserved->m_handles.empty() )
     597             :     {
     598       30487 :         aGuard.clear();
     599       30487 :         fire( i_handles, i_newValues, i_oldValues, i_count, sal_False );
     600       61032 :         return;
     601             :     }
     602             : 
     603          58 :     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         116 :     ::std::vector< sal_Int32 > allHandles( additionalEvents + i_count );
     609          58 :     ::std::copy( m_pReserved->m_handles.begin(), m_pReserved->m_handles.end(), allHandles.begin() );
     610          58 :     ::std::copy( i_handles, i_handles + i_count, allHandles.begin() + additionalEvents );
     611             : 
     612         116 :     ::std::vector< Any > allNewValues( additionalEvents + i_count );
     613          58 :     ::std::copy( m_pReserved->m_newValues.begin(), m_pReserved->m_newValues.end(), allNewValues.begin() );
     614          58 :     ::std::copy( i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents );
     615             : 
     616         116 :     ::std::vector< Any > allOldValues( additionalEvents + i_count );
     617          58 :     ::std::copy( m_pReserved->m_oldValues.begin(), m_pReserved->m_oldValues.end(), allOldValues.begin() );
     618          58 :     ::std::copy( i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents );
     619             : 
     620          58 :     m_pReserved->m_handles.clear();
     621          58 :     m_pReserved->m_newValues.clear();
     622          58 :     m_pReserved->m_oldValues.clear();
     623             : 
     624          58 :     aGuard.clear();
     625         116 :     fire( &allHandles[0], &allNewValues[0], &allOldValues[0], additionalEvents + i_count, sal_False );
     626             : }
     627             : 
     628             : //--------------------------------------------------------------------------
     629       49143 : 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       49143 :     if (! m_pReserved->m_bFireEvents)
     641       49218 :         return;
     642             : 
     643       49068 :     if (m_pReserved->m_pFireEvents) {
     644          24 :         m_pReserved->m_pFireEvents->fireEvents(
     645             :             pnHandles, nHandles, bVetoable,
     646          24 :             m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring);
     647             :     }
     648             : 
     649             :     // Only fire, if one or more properties changed
     650       49068 :     if( nHandles )
     651             :     {
     652             :         // create the event sequence of all changed properties
     653       43352 :         Sequence< PropertyChangeEvent > aEvts( nHandles );
     654       43352 :         PropertyChangeEvent * pEvts = aEvts.getArray();
     655       86704 :         Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
     656             :         sal_Int32 i;
     657       43352 :         sal_Int32 nChangesLen = 0;
     658             :         // Loop over all changed properties to fill the event struct
     659       92685 :         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       49333 :             IPropertyArrayHelper & rInfo = getInfoHelper();
     664             :             sal_Int16   nAttributes;
     665       49333 :             OUString aPropName;
     666       49333 :             rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] );
     667             : 
     668       49333 :             if(
     669       11200 :                (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) ||
     670       38133 :                (!bVetoable && (nAttributes & PropertyAttribute::BOUND))
     671             :               )
     672             :             {
     673       34480 :                 pEvts[nChangesLen].Source = xSource;
     674       34480 :                 pEvts[nChangesLen].PropertyName = aPropName;
     675       34480 :                 pEvts[nChangesLen].PropertyHandle = pnHandles[i];
     676       34480 :                 pEvts[nChangesLen].OldValue = pOldValues[i];
     677       34480 :                 pEvts[nChangesLen].NewValue = pNewValues[i];
     678       34480 :                 nChangesLen++;
     679             :             }
     680       49333 :         }
     681             : 
     682             :         bool bIgnoreRuntimeExceptionsWhileFiring =
     683       43352 :                 m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring;
     684             : 
     685             :         // fire the events for all changed properties
     686       77832 :         for( i = 0; i < nChangesLen; i++ )
     687             :         {
     688             :             // get the listener container for the property name
     689             :             OInterfaceContainerHelper * pLC;
     690       34480 :             if( bVetoable ) // fire change Events?
     691         238 :                 pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle );
     692             :             else
     693       34242 :                 pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle );
     694       34480 :             if( pLC )
     695             :             {
     696             :                 // Iterate over all listeners and send events
     697        2812 :                 OInterfaceIteratorHelper aIt( *pLC);
     698        7879 :                 while( aIt.hasMoreElements() )
     699             :                 {
     700        2255 :                     XInterface * pL = aIt.next();
     701             :                     try
     702             :                     {
     703             :                         try
     704             :                         {
     705        2255 :                             if( bVetoable ) // fire change Events?
     706             :                             {
     707             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     708           0 :                                     pEvts[i] );
     709             :                             }
     710             :                             else
     711             :                             {
     712             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     713        2255 :                                     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        2812 :                 }
     738             :             }
     739             :             // broadcast to all listeners with "" property name
     740       34480 :             if( bVetoable ){
     741             :                 // fire change Events?
     742             :                 pLC = rBHelper.aLC.getContainer(
     743         238 :                             getVetoableTypeIdentifier()
     744         238 :                                                 );
     745             :             }
     746             :             else {
     747             :                 pLC = rBHelper.aLC.getContainer(
     748       34242 :                             getPropertyTypeIdentifier(  )
     749       34242 :                                                 );
     750             :             }
     751       34480 :             if( pLC )
     752             :             {
     753             :                 // Iterate over all listeners and send events.
     754        7211 :                 OInterfaceIteratorHelper aIt( *pLC);
     755       26840 :                 while( aIt.hasMoreElements() )
     756             :                 {
     757       12418 :                     XInterface * pL = aIt.next();
     758             :                     try
     759             :                     {
     760             :                         try
     761             :                         {
     762       12418 :                             if( bVetoable ) // fire change Events?
     763             :                             {
     764             :                                 ((XVetoableChangeListener *)pL)->vetoableChange(
     765           0 :                                     pEvts[i] );
     766             :                             }
     767             :                             else
     768             :                             {
     769             :                                 ((XPropertyChangeListener *)pL)->propertyChange(
     770       12418 :                                     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        7211 :                 }
     795             :             }
     796             :         }
     797             : 
     798             :         // reduce array to changed properties
     799       43352 :         aEvts.realloc( nChangesLen );
     800             : 
     801       43352 :         if( !bVetoable )
     802             :         {
     803       34789 :             OInterfaceContainerHelper * pCont = 0;
     804             :             pCont = rBHelper.aLC.getContainer(
     805       34789 :                                 getPropertiesTypeIdentifier(  )
     806       34789 :                                              );
     807       34789 :             if( pCont )
     808             :             {
     809             :                 // Here is a Bug, unbound properties are also fired
     810       10456 :                 OInterfaceIteratorHelper aIt( *pCont );
     811       32391 :                 while( aIt.hasMoreElements() )
     812             :                 {
     813             :                     XPropertiesChangeListener * pL =
     814       11479 :                         (XPropertiesChangeListener *)aIt.next();
     815             :                     try
     816             :                     {
     817             :                         try
     818             :                         {
     819             :                             // fire the hole event sequence to the
     820             :                             // XPropertiesChangeListener's
     821       11479 :                             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       10456 :                 }
     845             :             }
     846       43352 :         }
     847             :     }
     848             : }
     849             : 
     850             : // OPropertySetHelper
     851        9919 : 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        9919 :     Any * pConvertedValues = NULL;
     862        9919 :     Any * pOldValues = NULL;
     863             : 
     864             :     try
     865             :     {
     866             :         // get the map table
     867        9919 :         IPropertyArrayHelper & rPH = getInfoHelper();
     868             : 
     869        9919 :         pConvertedValues = new Any[ nHitCount ];
     870        9919 :         pOldValues = new Any[ nHitCount ];
     871        9919 :         sal_Int32 n = 0;
     872             :         sal_Int32 i;
     873             : 
     874             :         {
     875             :         // must lock the mutex outside the loop. So all values are consistent.
     876        9919 :         MutexGuard aGuard( rBHelper.rMutex );
     877       67527 :         for( i = 0; i < nSeqLen; i++ )
     878             :         {
     879       57632 :             if( pHandles[i] != -1 )
     880             :             {
     881             :                 sal_Int16 nAttributes;
     882       39517 :                 rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
     883       39517 :                 if( nAttributes & PropertyAttribute::READONLY ) {
     884           0 :                     throw PropertyVetoException();
     885             :                 }
     886             :                 // Will the property change?
     887      118527 :                 if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n],
     888      118551 :                                             pHandles[i], pValues[i] ) )
     889             :                 {
     890             :                     // only increment if the property really change
     891       10444 :                     pHandles[n]         = pHandles[i];
     892       10444 :                     n++;
     893             :                 }
     894             :             }
     895        9919 :         }
     896             :         // release guard to fire events
     897             :         }
     898             : 
     899             :         // fire vetoable events
     900        9895 :         fire( pHandles, pConvertedValues, pOldValues, n, sal_True );
     901             : 
     902             :         {
     903             :         // must lock the mutex outside the loop.
     904        9895 :         MutexGuard aGuard( rBHelper.rMutex );
     905             :         // Loop over all changed properties
     906       20335 :         for( i = 0; i < n; i++ )
     907             :         {
     908             :             // Will the property change?
     909       10440 :             setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
     910        9895 :         }
     911             :         // release guard to fire events
     912             :         }
     913             : 
     914             :         // fire change events
     915        9895 :         impl_fireAll( pHandles, pConvertedValues, pOldValues, n );
     916             :     }
     917          24 :     catch( ... )
     918             :     {
     919          24 :         delete [] pOldValues;
     920          24 :         delete [] pConvertedValues;
     921          24 :         throw;
     922             :     }
     923        9895 :     delete [] pOldValues;
     924        9895 :     delete [] pConvertedValues;
     925        9895 : }
     926             : 
     927             : // XMultiPropertySet
     928             : /**
     929             :  * The sequence may be conatain not known properties. The implementation
     930             :  * must ignore these properties.
     931             :  */
     932        2136 : 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        2136 :     sal_Int32 * pHandles = NULL;
     938             :     try
     939             :     {
     940        2136 :         sal_Int32   nSeqLen = rPropertyNames.getLength();
     941        2136 :         pHandles = new sal_Int32[ nSeqLen ];
     942             :         // get the map table
     943        2136 :         IPropertyArrayHelper & rPH = getInfoHelper();
     944             :         // fill the handle array
     945        2136 :         sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames );
     946        2136 :         if( nHitCount != 0 )
     947        1736 :             setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount );
     948             :     }
     949           3 :     catch( ... )
     950             :     {
     951           3 :         delete [] pHandles;
     952           3 :         throw;
     953             :     }
     954        2133 :     delete [] pHandles;
     955        2133 : }
     956             : 
     957             : // XMultiPropertySet
     958        3392 : Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames )
     959             :     throw(::com::sun::star::uno::RuntimeException)
     960             : {
     961        3392 :     sal_Int32   nSeqLen = rPropertyNames.getLength();
     962        3392 :     sal_Int32 * pHandles = new sal_Int32[ nSeqLen ];
     963        3392 :     Sequence< Any > aValues( nSeqLen );
     964             : 
     965             :     // get the map table
     966        3392 :     IPropertyArrayHelper & rPH = getInfoHelper();
     967             :     // fill the handle array
     968        3392 :     rPH.fillHandles( pHandles, rPropertyNames );
     969             : 
     970        3392 :     Any * pValues = aValues.getArray();
     971             : 
     972        6784 :     MutexGuard aGuard( rBHelper.rMutex );
     973             :     // fill the sequence with the values
     974       67484 :     for( sal_Int32 i = 0; i < nSeqLen; i++ )
     975       64092 :         getFastPropertyValue( pValues[i], pHandles[i] );
     976             : 
     977        3392 :     delete [] pHandles;
     978        6784 :     return aValues;
     979             : }
     980             : 
     981             : // XMultiPropertySet
     982        1463 : void OPropertySetHelper::addPropertiesChangeListener(
     983             :     const Sequence<OUString> & ,
     984             :     const Reference < XPropertiesChangeListener > & rListener )
     985             :     throw(::com::sun::star::uno::RuntimeException)
     986             : {
     987        1463 :     rBHelper.addListener( getCppuType(&rListener) , rListener );
     988        1463 : }
     989             : 
     990             : // XMultiPropertySet
     991        1382 : void OPropertySetHelper::removePropertiesChangeListener(
     992             :     const Reference < XPropertiesChangeListener > & rListener )
     993             :     throw(::com::sun::star::uno::RuntimeException)
     994             : {
     995        1382 :     rBHelper.removeListener( getCppuType(&rListener) , rListener );
     996        1382 : }
     997             : 
     998             : // XMultiPropertySet
     999         411 : void OPropertySetHelper::firePropertiesChangeEvent(
    1000             :     const Sequence<OUString>& rPropertyNames,
    1001             :     const Reference < XPropertiesChangeListener >& rListener )
    1002             :     throw(::com::sun::star::uno::RuntimeException)
    1003             : {
    1004         411 :     sal_Int32 nLen = rPropertyNames.getLength();
    1005         411 :     sal_Int32 * pHandles = new sal_Int32[nLen];
    1006         411 :     IPropertyArrayHelper & rPH = getInfoHelper();
    1007         411 :     rPH.fillHandles( pHandles, rPropertyNames );
    1008         411 :     const OUString* pNames = rPropertyNames.getConstArray();
    1009             : 
    1010             :     // get the count of matching properties
    1011         411 :     sal_Int32 nFireLen = 0;
    1012             :     sal_Int32 i;
    1013       28290 :     for( i = 0; i < nLen; i++ )
    1014       27879 :         if( pHandles[i] != -1 )
    1015       27879 :             nFireLen++;
    1016             : 
    1017         411 :     Sequence<PropertyChangeEvent> aChanges( nFireLen );
    1018         411 :     PropertyChangeEvent* pChanges = aChanges.getArray();
    1019             : 
    1020             :     {
    1021             :     // must lock the mutex outside the loop. So all values are consistent.
    1022         411 :     MutexGuard aGuard( rBHelper.rMutex );
    1023         822 :     Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY );
    1024         411 :     sal_Int32 nFirePos = 0;
    1025       28290 :     for( i = 0; i < nLen; i++ )
    1026             :     {
    1027       27879 :         if( pHandles[i] != -1 )
    1028             :         {
    1029       27879 :             pChanges[nFirePos].Source = xSource;
    1030       27879 :             pChanges[nFirePos].PropertyName = pNames[i];
    1031       27879 :             pChanges[nFirePos].PropertyHandle = pHandles[i];
    1032       27879 :             getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] );
    1033       27879 :             pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue;
    1034       27879 :             nFirePos++;
    1035             :         }
    1036         411 :     }
    1037             :     // release guard to fire events
    1038             :     }
    1039         411 :     if( nFireLen )
    1040         411 :         rListener->propertiesChange( aChanges );
    1041             : 
    1042         411 :     delete [] pHandles;
    1043         411 : }
    1044             : 
    1045         198 : void OPropertySetHelper2::enableChangeListenerNotification( sal_Bool bEnable )
    1046             :     throw(::com::sun::star::uno::RuntimeException)
    1047             : {
    1048         198 :     m_pReserved->m_bFireEvents = bEnable;
    1049         198 : }
    1050             : 
    1051             : //========================================================================
    1052             : //== OPropertyArrayHelper ================================================
    1053             : //========================================================================
    1054             : 
    1055             : extern "C" {
    1056             : 
    1057       76929 : static int compare_Property_Impl( const void *arg1, const void *arg2 )
    1058             :     SAL_THROW_EXTERN_C()
    1059             : {
    1060       76929 :    return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name );
    1061             : }
    1062             : 
    1063             : }
    1064             : 
    1065        2461 : void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW(())
    1066             : {
    1067        2461 :     sal_Int32 i, nElements = aInfos.getLength();
    1068        2461 :     const Property* pProperties = aInfos.getConstArray();
    1069             : 
    1070       49339 :     for( i = 1; i < nElements; i++ )
    1071             :     {
    1072       47425 :         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         547 :             qsort( aInfos.getArray(), nElements, sizeof( Property ),
    1079        1094 :                     compare_Property_Impl );
    1080         547 :             break;
    1081             :         }
    1082             :     }
    1083             :     // may be that the array is resorted
    1084        2461 :     pProperties = aInfos.getConstArray();
    1085        2585 :     for( i = 0; i < nElements; i++ )
    1086        2453 :         if( pProperties[i].Handle != i )
    1087        4790 :             return;
    1088             :     // The handle is the index
    1089         132 :     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        2461 : OPropertyArrayHelper::OPropertyArrayHelper(
    1104             :     const Sequence< Property > & aProps,
    1105             :     sal_Bool bSorted )
    1106             :     SAL_THROW(())
    1107             :     : aInfos(aProps)
    1108        2461 :     , bRightOrdered( sal_False )
    1109             : {
    1110        2461 :     init( bSorted );
    1111        2461 : }
    1112             : 
    1113             : //========================================================================
    1114           0 : sal_Int32 OPropertyArrayHelper::getCount() const
    1115             : {
    1116           0 :     return aInfos.getLength();
    1117             : }
    1118             : 
    1119             : //========================================================================
    1120      935127 : sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle
    1121             : (
    1122             :     OUString * pPropName,
    1123             :     sal_Int16 * pAttributes,
    1124             :     sal_Int32 nHandle
    1125             : )
    1126             : {
    1127      935127 :     const Property* pProperties = aInfos.getConstArray();
    1128      935127 :     sal_Int32 nElements = aInfos.getLength();
    1129             : 
    1130      935127 :     if( bRightOrdered )
    1131             :     {
    1132         169 :         if( nHandle < 0 || nHandle >= nElements )
    1133           0 :             return sal_False;
    1134         169 :         if( pPropName )
    1135           1 :             *pPropName = pProperties[ nHandle ].Name;
    1136         169 :         if( pAttributes )
    1137           2 :             *pAttributes = pProperties[ nHandle ].Attributes;
    1138         169 :         return sal_True;
    1139             :     }
    1140             :     else
    1141             :     {
    1142             :         // normally the array is sorted
    1143    27865154 :         for( sal_Int32 i = 0; i < nElements; i++ )
    1144             :         {
    1145    27864068 :             if( pProperties[i].Handle == nHandle )
    1146             :             {
    1147      933872 :                 if( pPropName )
    1148       45994 :                     *pPropName = pProperties[ i ].Name;
    1149      933872 :                 if( pAttributes )
    1150      178796 :                     *pAttributes = pProperties[ i ].Attributes;
    1151      933872 :                 return sal_True;
    1152             :             }
    1153             :         }
    1154             :     }
    1155        1086 :     return sal_False;
    1156             : }
    1157             : 
    1158             : //========================================================================
    1159       15481 : Sequence< Property > OPropertyArrayHelper::getProperties(void)
    1160             : {
    1161       15481 :     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      914878 : sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName )
    1190             : {
    1191             :     Property * pR;
    1192     1829756 :     pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(),
    1193             :                               sizeof( Property ),
    1194     1829756 :                               compare_OUString_Property_Impl );
    1195      914878 :     return pR ? pR->Handle : -1;
    1196             : }
    1197             : 
    1198             : //========================================================================
    1199        2239 : sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames )
    1200             : {
    1201        2239 :     sal_Int32 nHitCount = 0;
    1202        2239 :     const OUString * pReqProps = rPropNames.getConstArray();
    1203        2239 :     sal_Int32 nReqLen = rPropNames.getLength();
    1204        2239 :     const Property * pCur = aInfos.getConstArray();
    1205        2239 :     const Property * pEnd = pCur + aInfos.getLength();
    1206             : 
    1207       15673 :     for( sal_Int32 i = 0; i < nReqLen; i++ )
    1208             :     {
    1209             :         // Calculate logarithm
    1210       13434 :         sal_Int32 n = (sal_Int32)(pEnd - pCur);
    1211       13434 :         sal_Int32 nLog = 0;
    1212       99203 :         while( n )
    1213             :         {
    1214       72335 :             nLog += 1;
    1215       72335 :             n = n >> 1;
    1216             :         }
    1217             : 
    1218             :         // Number of properties to search for * Log2 of the number of remaining
    1219             :         // properties to search in.
    1220       13434 :         if( (nReqLen - i) * nLog >= pEnd - pCur )
    1221             :         {
    1222             :             // linear search is better
    1223       24011 :             while( pCur < pEnd && pReqProps[i] > pCur->Name )
    1224             :             {
    1225        8105 :                 pCur++;
    1226             :             }
    1227        7953 :             if( pCur < pEnd && pReqProps[i] == pCur->Name )
    1228             :             {
    1229        7945 :                 pHandles[i] = pCur->Handle;
    1230        7945 :                 nHitCount++;
    1231             :             }
    1232             :             else
    1233           8 :                 pHandles[i] = -1;
    1234             :         }
    1235             :         else
    1236             :         {
    1237             :             // binary search is better
    1238        5481 :             sal_Int32   nCompVal = 1;
    1239        5481 :             const Property * pOldEnd = pEnd--;
    1240        5481 :             const Property * pMid = pCur;
    1241             : 
    1242       36748 :             while( nCompVal != 0 && pCur <= pEnd )
    1243             :             {
    1244       25786 :                 pMid = (pEnd - pCur) / 2 + pCur;
    1245             : 
    1246       25786 :                 nCompVal = pReqProps[i].compareTo( pMid->Name );
    1247             : 
    1248       25786 :                 if( nCompVal > 0 )
    1249        6405 :                     pCur = pMid + 1;
    1250             :                 else
    1251       19381 :                     pEnd = pMid - 1;
    1252             :             }
    1253             : 
    1254        5481 :             if( nCompVal == 0 )
    1255             :             {
    1256        5481 :                 pHandles[i] = pMid->Handle;
    1257        5481 :                 nHitCount++;
    1258        5481 :                 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        5481 :             pEnd = pOldEnd;
    1271             :         }
    1272             :     }
    1273        2239 :     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