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