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

Generated by: LCOV version 1.10