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

Generated by: LCOV version 1.11