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

Generated by: LCOV version 1.10