| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_cppuhelper.hxx" |
| |
| #include "osl/diagnose.h" |
| #include "cppuhelper/implbase1.hxx" |
| #include "cppuhelper/weak.hxx" |
| #include "cppuhelper/propshlp.hxx" |
| #include "cppuhelper/exc_hlp.hxx" |
| #include "com/sun/star/beans/PropertyAttribute.hpp" |
| #include "com/sun/star/lang/DisposedException.hpp" |
| |
| |
| using namespace osl; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::lang; |
| using namespace rtl; |
| using namespace cppu; |
| |
| namespace cppu { |
| |
| IPropertyArrayHelper::~IPropertyArrayHelper() |
| { |
| } |
| |
| inline const ::com::sun::star::uno::Type & getPropertyTypeIdentifier( ) SAL_THROW( () ) |
| { |
| return ::getCppuType( (Reference< XPropertyChangeListener > *)0 ); |
| } |
| inline const ::com::sun::star::uno::Type & getPropertiesTypeIdentifier() SAL_THROW( () ) |
| { |
| return ::getCppuType( (Reference< XPropertiesChangeListener > *)0 ); |
| } |
| inline const ::com::sun::star::uno::Type & getVetoableTypeIdentifier() SAL_THROW( () ) |
| { |
| return ::getCppuType( (Reference< XVetoableChangeListener > *)0 ); |
| } |
| |
| extern "C" { |
| |
| static int compare_OUString_Property_Impl( const void *arg1, const void *arg2 ) |
| SAL_THROW_EXTERN_C() |
| { |
| return ((OUString *)arg1)->compareTo( ((Property *)arg2)->Name ); |
| } |
| |
| } |
| |
| /** |
| * The class which implements the PropertySetInfo interface. |
| */ |
| |
| class OPropertySetHelperInfo_Impl |
| : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > |
| { |
| Sequence < Property > aInfos; |
| |
| public: |
| OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW( () ); |
| |
| // XPropertySetInfo-Methoden |
| virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException); |
| virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); |
| virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException); |
| }; |
| |
| |
| /** |
| * Create an object that implements XPropertySetInfo IPropertyArrayHelper. |
| */ |
| OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl( |
| IPropertyArrayHelper & rHelper_ ) |
| SAL_THROW( () ) |
| :aInfos( rHelper_.getProperties() ) |
| { |
| } |
| |
| /** |
| * Return the sequence of properties, which are provided throug the constructor. |
| */ |
| Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException) |
| |
| { |
| return aInfos; |
| } |
| |
| /** |
| * Return the sequence of properties, which are provided throug the constructor. |
| */ |
| Property OPropertySetHelperInfo_Impl::getPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) |
| { |
| Property * pR; |
| pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), |
| sizeof( Property ), |
| compare_OUString_Property_Impl ); |
| if( !pR ) { |
| throw UnknownPropertyException(); |
| } |
| |
| return *pR; |
| } |
| |
| /** |
| * Return the sequence of properties, which are provided throug the constructor. |
| */ |
| sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| Property * pR; |
| pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), |
| sizeof( Property ), |
| compare_OUString_Property_Impl ); |
| return pR != NULL; |
| } |
| |
| // ---------------------------------------------------- |
| // class PropertySetHelper_Impl |
| // ---------------------------------------------------- |
| class OPropertySetHelper::Impl { |
| |
| public: |
| Impl( bool i_bIgnoreRuntimeExceptionsWhileFiring, |
| IEventNotificationHook *i_pFireEvents |
| ) |
| :m_bIgnoreRuntimeExceptionsWhileFiring( i_bIgnoreRuntimeExceptionsWhileFiring ) |
| ,m_pFireEvents( i_pFireEvents ) |
| { |
| } |
| |
| bool m_bIgnoreRuntimeExceptionsWhileFiring; |
| class IEventNotificationHook * const m_pFireEvents; |
| |
| ::std::vector< sal_Int32 > m_handles; |
| ::std::vector< Any > m_newValues; |
| ::std::vector< Any > m_oldValues; |
| }; |
| |
| |
| // ---------------------------------------------------- |
| // class PropertySetHelper |
| // ---------------------------------------------------- |
| OPropertySetHelper::OPropertySetHelper( |
| OBroadcastHelper & rBHelper_ ) SAL_THROW( () ) |
| : rBHelper( rBHelper_ ), |
| aBoundLC( rBHelper_.rMutex ), |
| aVetoableLC( rBHelper_.rMutex ), |
| m_pReserved( new Impl(false, 0) ) |
| { |
| } |
| |
| OPropertySetHelper::OPropertySetHelper( |
| OBroadcastHelper & rBHelper_, bool bIgnoreRuntimeExceptionsWhileFiring ) |
| : rBHelper( rBHelper_ ), |
| aBoundLC( rBHelper_.rMutex ), |
| aVetoableLC( rBHelper_.rMutex ), |
| m_pReserved( new Impl( bIgnoreRuntimeExceptionsWhileFiring, 0 ) ) |
| { |
| } |
| |
| OPropertySetHelper::OPropertySetHelper( |
| OBroadcastHelper & rBHelper_, IEventNotificationHook * i_pFireEvents, |
| bool bIgnoreRuntimeExceptionsWhileFiring) |
| : rBHelper( rBHelper_ ), |
| aBoundLC( rBHelper_.rMutex ), |
| aVetoableLC( rBHelper_.rMutex ), |
| m_pReserved( |
| new Impl( bIgnoreRuntimeExceptionsWhileFiring, i_pFireEvents) ) |
| { |
| } |
| |
| /** |
| * You must call disposing before. |
| */ |
| OPropertySetHelper::~OPropertySetHelper() SAL_THROW( () ) |
| { |
| } |
| |
| /** |
| * These method is called from queryInterface, if no delegator is set. |
| * Otherwise this method is called from the delegator. |
| */ |
| // XAggregation |
| Any OPropertySetHelper::queryInterface( const ::com::sun::star::uno::Type & rType ) |
| throw (RuntimeException) |
| { |
| return ::cppu::queryInterface( |
| rType, |
| static_cast< XPropertySet * >( this ), |
| static_cast< XMultiPropertySet * >( this ), |
| static_cast< XFastPropertySet * >( this ) ); |
| } |
| |
| /** |
| * called from the derivee's XTypeProvider::getTypes implementation |
| */ |
| ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > OPropertySetHelper::getTypes() |
| throw (RuntimeException) |
| { |
| Sequence< ::com::sun::star::uno::Type > aTypes( 3 ); |
| aTypes[ 0 ] = XPropertySet::static_type(); |
| aTypes[ 1 ] = XMultiPropertySet::static_type(); |
| aTypes[ 2 ] = XFastPropertySet::static_type(); |
| return aTypes; |
| } |
| |
| // ComponentHelper |
| void OPropertySetHelper::disposing() SAL_THROW( () ) |
| { |
| // Create an event with this as sender |
| Reference < XPropertySet > rSource( SAL_STATIC_CAST( XPropertySet * , this ) , UNO_QUERY ); |
| EventObject aEvt; |
| aEvt.Source = rSource; |
| |
| // inform all listeners to reelease this object |
| // The listener container are automatically cleared |
| aBoundLC.disposeAndClear( aEvt ); |
| aVetoableLC.disposeAndClear( aEvt ); |
| } |
| |
| Reference < XPropertySetInfo > OPropertySetHelper::createPropertySetInfo( |
| IPropertyArrayHelper & rProperties ) SAL_THROW( () ) |
| { |
| return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) ); |
| } |
| |
| // XPropertySet |
| void OPropertySetHelper::setPropertyValue( |
| const OUString& rPropertyName, const Any& rValue ) |
| 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) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| // call the method of the XFastPropertySet interface |
| setFastPropertyValue( nHandle, rValue ); |
| } |
| |
| // XPropertySet |
| Any OPropertySetHelper::getPropertyValue( |
| const OUString& rPropertyName ) |
| throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| // call the method of the XFastPropertySet interface |
| return getFastPropertyValue( nHandle ); |
| } |
| |
| // XPropertySet |
| void OPropertySetHelper::addPropertyChangeListener( |
| const OUString& rPropertyName, |
| const Reference < XPropertyChangeListener > & rxListener ) |
| throw(::com::sun::star::beans::UnknownPropertyException, |
| ::com::sun::star::lang::WrappedTargetException, |
| ::com::sun::star::uno::RuntimeException) |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| OSL_ENSURE( !rBHelper.bInDispose, "do not addPropertyChangeListener in the dispose call" ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| if( !rBHelper.bInDispose && !rBHelper.bDisposed ) |
| { |
| // only add listeners if you are not disposed |
| // a listener with no name means all properties |
| if( rPropertyName.getLength() ) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| if( nHandle == -1 ) { |
| // property not known throw exception |
| throw UnknownPropertyException() ; |
| } |
| |
| sal_Int16 nAttributes; |
| rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); |
| if( !(nAttributes & ::com::sun::star::beans::PropertyAttribute::BOUND) ) |
| { |
| OSL_ENSURE( sal_False, "add listener to an unbound property" ); |
| // silent ignore this |
| return; |
| } |
| // add the change listener to the helper container |
| |
| aBoundLC.addInterface( (sal_Int32)nHandle, rxListener ); |
| } |
| else |
| // add the change listener to the helper container |
| rBHelper.aLC.addInterface( |
| getPropertyTypeIdentifier( ), |
| rxListener |
| ); |
| } |
| } |
| |
| |
| // XPropertySet |
| void OPropertySetHelper::removePropertyChangeListener( |
| const OUString& rPropertyName, |
| const Reference < XPropertyChangeListener >& rxListener ) |
| throw(::com::sun::star::beans::UnknownPropertyException, |
| ::com::sun::star::lang::WrappedTargetException, |
| ::com::sun::star::uno::RuntimeException) |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| // all listeners are automatically released in a dispose call |
| if( !rBHelper.bInDispose && !rBHelper.bDisposed ) |
| { |
| if( rPropertyName.getLength() ) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| if( nHandle == -1 ) |
| // property not known throw exception |
| throw UnknownPropertyException(); |
| aBoundLC.removeInterface( (sal_Int32)nHandle, rxListener ); |
| } |
| else { |
| // remove the change listener to the helper container |
| rBHelper.aLC.removeInterface( |
| getPropertyTypeIdentifier( ), |
| rxListener |
| ); |
| } |
| } |
| } |
| |
| // XPropertySet |
| void OPropertySetHelper::addVetoableChangeListener( |
| const OUString& rPropertyName, |
| const Reference< XVetoableChangeListener > & rxListener ) |
| throw(::com::sun::star::beans::UnknownPropertyException, |
| ::com::sun::star::lang::WrappedTargetException, |
| ::com::sun::star::uno::RuntimeException) |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| OSL_ENSURE( !rBHelper.bInDispose, "do not addVetoableChangeListener in the dispose call" ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| if( !rBHelper.bInDispose && !rBHelper.bDisposed ) |
| { |
| // only add listeners if you are not disposed |
| // a listener with no name means all properties |
| if( rPropertyName.getLength() ) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| if( nHandle == -1 ) { |
| // property not known throw exception |
| throw UnknownPropertyException(); |
| } |
| |
| sal_Int16 nAttributes; |
| rPH.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ); |
| if( !(nAttributes & PropertyAttribute::CONSTRAINED) ) |
| { |
| OSL_ENSURE( sal_False, "addVetoableChangeListener, and property is not constrained" ); |
| // silent ignore this |
| return; |
| } |
| // add the vetoable listener to the helper container |
| aVetoableLC.addInterface( (sal_Int32)nHandle, rxListener ); |
| } |
| else |
| // add the vetoable listener to the helper container |
| rBHelper.aLC.addInterface( |
| getVetoableTypeIdentifier( ), |
| rxListener |
| ); |
| } |
| } |
| |
| // XPropertySet |
| void OPropertySetHelper::removeVetoableChangeListener( |
| const OUString& rPropertyName, |
| const Reference < XVetoableChangeListener > & rxListener ) |
| throw(::com::sun::star::beans::UnknownPropertyException, |
| ::com::sun::star::lang::WrappedTargetException, |
| ::com::sun::star::uno::RuntimeException) |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| // all listeners are automatically released in a dispose call |
| if( !rBHelper.bInDispose && !rBHelper.bDisposed ) |
| { |
| if( rPropertyName.getLength() ) |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // map the name to the handle |
| sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); |
| if( nHandle == -1 ) { |
| // property not known throw exception |
| throw UnknownPropertyException(); |
| } |
| // remove the vetoable listener to the helper container |
| aVetoableLC.removeInterface( (sal_Int32)nHandle, rxListener ); |
| } |
| else |
| // add the vetoable listener to the helper container |
| rBHelper.aLC.removeInterface( |
| getVetoableTypeIdentifier( ), |
| rxListener |
| ); |
| } |
| } |
| |
| void OPropertySetHelper::setDependentFastPropertyValue( sal_Int32 i_handle, const ::com::sun::star::uno::Any& i_value ) |
| { |
| //OSL_PRECOND( rBHelper.rMutex.isAcquired(), "OPropertySetHelper::setDependentFastPropertyValue: to be called with a locked mutex only!" ); |
| // there is no such thing as Mutex.isAcquired, sadly ... |
| |
| sal_Int16 nAttributes(0); |
| IPropertyArrayHelper& rInfo = getInfoHelper(); |
| if ( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, i_handle ) ) |
| // unknown property |
| throw UnknownPropertyException(); |
| |
| // no need to check for READONLY-ness of the property. The method is intended to be called internally, which |
| // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed |
| // to change their value. |
| |
| Any aConverted, aOld; |
| sal_Bool bChanged = convertFastPropertyValue( aConverted, aOld, i_handle, i_value ); |
| if ( !bChanged ) |
| return; |
| |
| // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be |
| // a good idea. The caler is responsible for not invoking this for constrained properties. |
| OSL_ENSURE( ( nAttributes & PropertyAttribute::CONSTRAINED ) == 0, |
| "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained properties!" ); |
| (void)nAttributes; |
| |
| // actually set the new value |
| try |
| { |
| setFastPropertyValue_NoBroadcast( i_handle, aConverted ); |
| } |
| catch (const UnknownPropertyException& ) { throw; /* allowed to leave */ } |
| catch (const PropertyVetoException& ) { throw; /* allowed to leave */ } |
| catch (const IllegalArgumentException& ) { throw; /* allowed to leave */ } |
| catch (const WrappedTargetException& ) { throw; /* allowed to leave */ } |
| catch (const RuntimeException& ) { throw; /* allowed to leave */ } |
| catch (const Exception& ) |
| { |
| // not allowed to leave this meathod |
| WrappedTargetException aWrapped; |
| aWrapped.TargetException <<= ::cppu::getCaughtException(); |
| aWrapped.Context = static_cast< XPropertySet* >( this ); |
| throw aWrapped; |
| } |
| |
| // remember the handle/values, for the events to be fired later |
| m_pReserved->m_handles.push_back( i_handle ); |
| m_pReserved->m_newValues.push_back( aConverted ); // TODO: setFastPropertyValue notifies the unconverted value here ...? |
| m_pReserved->m_oldValues.push_back( aOld ); |
| } |
| |
| // XFastPropertySet |
| void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue ) |
| 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) |
| { |
| OSL_ENSURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| |
| IPropertyArrayHelper & rInfo = getInfoHelper(); |
| sal_Int16 nAttributes; |
| if( !rInfo.fillPropertyMembersByHandle( NULL, &nAttributes, nHandle ) ) { |
| // unknown property |
| throw UnknownPropertyException(); |
| } |
| if( nAttributes & PropertyAttribute::READONLY ) |
| throw PropertyVetoException(); |
| |
| Any aConvertedVal; |
| Any aOldVal; |
| |
| // Will the property change? |
| sal_Bool bChanged; |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue ); |
| // release guard to fire events |
| } |
| if( bChanged ) |
| { |
| // Is it a constrained property? |
| if( nAttributes & PropertyAttribute::CONSTRAINED ) |
| { |
| // In aValue is the converted rValue |
| // fire a constarined event |
| // second parameter NULL means constrained |
| fire( &nHandle, &rValue, &aOldVal, 1, sal_True ); |
| } |
| |
| { |
| MutexGuard aGuard( rBHelper.rMutex ); |
| try |
| { |
| // set the property to the new value |
| setFastPropertyValue_NoBroadcast( nHandle, aConvertedVal ); |
| } |
| catch (const ::com::sun::star::beans::UnknownPropertyException& ) { throw; /* allowed to leave */ } |
| catch (const ::com::sun::star::beans::PropertyVetoException& ) { throw; /* allowed to leave */ } |
| catch (const ::com::sun::star::lang::IllegalArgumentException& ) { throw; /* allowed to leave */ } |
| catch (const ::com::sun::star::lang::WrappedTargetException& ) { throw; /* allowed to leave */ } |
| catch (const ::com::sun::star::uno::RuntimeException& ) { throw; /* allowed to leave */ } |
| catch (const ::com::sun::star::uno::Exception& e ) |
| { |
| // not allowed to leave this meathod |
| ::com::sun::star::lang::WrappedTargetException aWrap; |
| aWrap.Context = static_cast< ::com::sun::star::beans::XPropertySet* >( this ); |
| aWrap.TargetException <<= e; |
| |
| throw ::com::sun::star::lang::WrappedTargetException( aWrap ); |
| } |
| |
| // release guard to fire events |
| } |
| // file a change event, if the value changed |
| impl_fireAll( &nHandle, &rValue, &aOldVal, 1 ); |
| } |
| } |
| |
| // XFastPropertySet |
| Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle ) |
| throw(::com::sun::star::beans::UnknownPropertyException, |
| ::com::sun::star::lang::WrappedTargetException, |
| ::com::sun::star::uno::RuntimeException) |
| |
| { |
| IPropertyArrayHelper & rInfo = getInfoHelper(); |
| if( !rInfo.fillPropertyMembersByHandle( NULL, NULL, nHandle ) ) |
| // unknown property |
| throw UnknownPropertyException(); |
| |
| Any aRet; |
| MutexGuard aGuard( rBHelper.rMutex ); |
| getFastPropertyValue( aRet, nHandle ); |
| return aRet; |
| } |
| |
| //-------------------------------------------------------------------------- |
| void OPropertySetHelper::impl_fireAll( sal_Int32* i_handles, const Any* i_newValues, const Any* i_oldValues, sal_Int32 i_count ) |
| { |
| ClearableMutexGuard aGuard( rBHelper.rMutex ); |
| if ( m_pReserved->m_handles.empty() ) |
| { |
| aGuard.clear(); |
| fire( i_handles, i_newValues, i_oldValues, i_count, sal_False ); |
| return; |
| } |
| |
| const size_t additionalEvents = m_pReserved->m_handles.size(); |
| OSL_ENSURE( additionalEvents == m_pReserved->m_newValues.size() |
| && additionalEvents == m_pReserved->m_oldValues.size(), |
| "OPropertySetHelper::impl_fireAll: inconsistency!" ); |
| |
| ::std::vector< sal_Int32 > allHandles( additionalEvents + i_count ); |
| ::std::copy( m_pReserved->m_handles.begin(), m_pReserved->m_handles.end(), allHandles.begin() ); |
| ::std::copy( i_handles, i_handles + i_count, allHandles.begin() + additionalEvents ); |
| |
| ::std::vector< Any > allNewValues( additionalEvents + i_count ); |
| ::std::copy( m_pReserved->m_newValues.begin(), m_pReserved->m_newValues.end(), allNewValues.begin() ); |
| ::std::copy( i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents ); |
| |
| ::std::vector< Any > allOldValues( additionalEvents + i_count ); |
| ::std::copy( m_pReserved->m_oldValues.begin(), m_pReserved->m_oldValues.end(), allOldValues.begin() ); |
| ::std::copy( i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents ); |
| |
| m_pReserved->m_handles.clear(); |
| m_pReserved->m_newValues.clear(); |
| m_pReserved->m_oldValues.clear(); |
| |
| aGuard.clear(); |
| fire( &allHandles[0], &allNewValues[0], &allOldValues[0], additionalEvents + i_count, sal_False ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| void OPropertySetHelper::fire |
| ( |
| sal_Int32 * pnHandles, |
| const Any * pNewValues, |
| const Any * pOldValues, |
| sal_Int32 nHandles, // These is the Count of the array |
| sal_Bool bVetoable |
| ) |
| { |
| OSL_ENSURE( m_pReserved.get(), "No OPropertySetHelper::Impl" ); |
| if (m_pReserved->m_pFireEvents) { |
| m_pReserved->m_pFireEvents->fireEvents( |
| pnHandles, nHandles, bVetoable, |
| m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring); |
| } |
| |
| // Only fire, if one or more properties changed |
| if( nHandles ) |
| { |
| // create the event sequence of all changed properties |
| Sequence< PropertyChangeEvent > aEvts( nHandles ); |
| PropertyChangeEvent * pEvts = aEvts.getArray(); |
| Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); |
| sal_Int32 i; |
| sal_Int32 nChangesLen = 0; |
| // Loop over all changed properties to fill the event struct |
| for( i = 0; i < nHandles; i++ ) |
| { |
| // Vetoable fire and constrained attribute set or |
| // Change fire and Changed and bound attribute set |
| IPropertyArrayHelper & rInfo = getInfoHelper(); |
| sal_Int16 nAttributes; |
| OUString aPropName; |
| rInfo.fillPropertyMembersByHandle( &aPropName, &nAttributes, pnHandles[i] ); |
| |
| if( |
| (bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) || |
| (!bVetoable && (nAttributes & PropertyAttribute::BOUND)) |
| ) |
| { |
| pEvts[nChangesLen].Source = xSource; |
| pEvts[nChangesLen].PropertyName = aPropName; |
| pEvts[nChangesLen].PropertyHandle = pnHandles[i]; |
| pEvts[nChangesLen].OldValue = pOldValues[i]; |
| pEvts[nChangesLen].NewValue = pNewValues[i]; |
| nChangesLen++; |
| } |
| } |
| |
| bool bIgnoreRuntimeExceptionsWhileFiring = |
| m_pReserved->m_bIgnoreRuntimeExceptionsWhileFiring; |
| |
| // fire the events for all changed properties |
| for( i = 0; i < nChangesLen; i++ ) |
| { |
| // get the listener container for the property name |
| OInterfaceContainerHelper * pLC; |
| if( bVetoable ) // fire change Events? |
| pLC = aVetoableLC.getContainer( pEvts[i].PropertyHandle ); |
| else |
| pLC = aBoundLC.getContainer( pEvts[i].PropertyHandle ); |
| if( pLC ) |
| { |
| // Ueber alle Listener iterieren und Events senden |
| OInterfaceIteratorHelper aIt( *pLC); |
| while( aIt.hasMoreElements() ) |
| { |
| XInterface * pL = aIt.next(); |
| try |
| { |
| try |
| { |
| if( bVetoable ) // fire change Events? |
| { |
| ((XVetoableChangeListener *)pL)->vetoableChange( |
| pEvts[i] ); |
| } |
| else |
| { |
| ((XPropertyChangeListener *)pL)->propertyChange( |
| pEvts[i] ); |
| } |
| } |
| catch (DisposedException & exc) |
| { |
| OSL_ENSURE( exc.Context.is(), |
| "DisposedException without Context!" ); |
| if (exc.Context == pL) |
| aIt.remove(); |
| else |
| throw; |
| } |
| } |
| catch (RuntimeException & exc) |
| { |
| OSL_TRACE( |
| OUStringToOString( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "caught RuntimeException while " |
| "firing listeners: ") ) + |
| exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| if (! bIgnoreRuntimeExceptionsWhileFiring) |
| throw; |
| } |
| } |
| } |
| // broadcast to all listeners with "" property name |
| if( bVetoable ){ |
| // fire change Events? |
| pLC = rBHelper.aLC.getContainer( |
| getVetoableTypeIdentifier() |
| ); |
| } |
| else { |
| pLC = rBHelper.aLC.getContainer( |
| getPropertyTypeIdentifier( ) |
| ); |
| } |
| if( pLC ) |
| { |
| // Ueber alle Listener iterieren und Events senden |
| OInterfaceIteratorHelper aIt( *pLC); |
| while( aIt.hasMoreElements() ) |
| { |
| XInterface * pL = aIt.next(); |
| try |
| { |
| try |
| { |
| if( bVetoable ) // fire change Events? |
| { |
| ((XVetoableChangeListener *)pL)->vetoableChange( |
| pEvts[i] ); |
| } |
| else |
| { |
| ((XPropertyChangeListener *)pL)->propertyChange( |
| pEvts[i] ); |
| } |
| } |
| catch (DisposedException & exc) |
| { |
| OSL_ENSURE( exc.Context.is(), |
| "DisposedException without Context!" ); |
| if (exc.Context == pL) |
| aIt.remove(); |
| else |
| throw; |
| } |
| } |
| catch (RuntimeException & exc) |
| { |
| OSL_TRACE( |
| OUStringToOString( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "caught RuntimeException while " |
| "firing listeners: ") ) + |
| exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| if (! bIgnoreRuntimeExceptionsWhileFiring) |
| throw; |
| } |
| } |
| } |
| } |
| |
| // reduce array to changed properties |
| aEvts.realloc( nChangesLen ); |
| |
| if( !bVetoable ) |
| { |
| OInterfaceContainerHelper * pCont = 0; |
| pCont = rBHelper.aLC.getContainer( |
| getPropertiesTypeIdentifier( ) |
| ); |
| if( pCont ) |
| { |
| // Here is a Bug, unbound properties are also fired |
| OInterfaceIteratorHelper aIt( *pCont ); |
| while( aIt.hasMoreElements() ) |
| { |
| XPropertiesChangeListener * pL = |
| (XPropertiesChangeListener *)aIt.next(); |
| try |
| { |
| try |
| { |
| // fire the hole event sequence to the |
| // XPropertiesChangeListener's |
| pL->propertiesChange( aEvts ); |
| } |
| catch (DisposedException & exc) |
| { |
| OSL_ENSURE( exc.Context.is(), |
| "DisposedException without Context!" ); |
| if (exc.Context == pL) |
| aIt.remove(); |
| else |
| throw; |
| } |
| } |
| catch (RuntimeException & exc) |
| { |
| OSL_TRACE( |
| OUStringToOString( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "caught RuntimeException while " |
| "firing listeners: ") ) + |
| exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| if (! bIgnoreRuntimeExceptionsWhileFiring) |
| throw; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // OPropertySetHelper |
| void OPropertySetHelper::setFastPropertyValues( |
| sal_Int32 nSeqLen, |
| sal_Int32 * pHandles, |
| const Any * pValues, |
| sal_Int32 nHitCount ) |
| SAL_THROW( (::com::sun::star::uno::Exception) ) |
| { |
| OSL_ENSURE( !rBHelper.bInDispose, "do not getFastPropertyValue in the dispose call" ); |
| OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); |
| |
| Any * pConvertedValues = NULL; |
| Any * pOldValues = NULL; |
| |
| try |
| { |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| |
| pConvertedValues = new Any[ nHitCount ]; |
| pOldValues = new Any[ nHitCount ]; |
| sal_Int32 n = 0; |
| sal_Int32 i; |
| |
| { |
| // must lock the mutex outside the loop. So all values are consistent. |
| MutexGuard aGuard( rBHelper.rMutex ); |
| for( i = 0; i < nSeqLen; i++ ) |
| { |
| if( pHandles[i] != -1 ) |
| { |
| sal_Int16 nAttributes; |
| rPH.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] ); |
| if( nAttributes & PropertyAttribute::READONLY ) { |
| throw PropertyVetoException(); |
| } |
| // Will the property change? |
| if( convertFastPropertyValue( pConvertedValues[ n ], pOldValues[n], |
| pHandles[i], pValues[i] ) ) |
| { |
| // only increment if the property really change |
| pHandles[n] = pHandles[i]; |
| n++; |
| } |
| } |
| } |
| // release guard to fire events |
| } |
| |
| // fire vetoable events |
| fire( pHandles, pConvertedValues, pOldValues, n, sal_True ); |
| |
| { |
| // must lock the mutex outside the loop. |
| MutexGuard aGuard( rBHelper.rMutex ); |
| // Loop over all changed properties |
| for( i = 0; i < n; i++ ) |
| { |
| // Will the property change? |
| setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] ); |
| } |
| // release guard to fire events |
| } |
| |
| // fire change events |
| impl_fireAll( pHandles, pConvertedValues, pOldValues, n ); |
| } |
| catch( ... ) |
| { |
| delete [] pOldValues; |
| delete [] pConvertedValues; |
| throw; |
| } |
| delete [] pOldValues; |
| delete [] pConvertedValues; |
| } |
| |
| // XMultiPropertySet |
| /** |
| * The sequence may be conatain not known properties. The implementation |
| * must ignore these properties. |
| */ |
| void OPropertySetHelper::setPropertyValues( |
| const Sequence<OUString>& rPropertyNames, |
| const Sequence<Any>& rValues ) |
| throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) |
| { |
| sal_Int32 * pHandles = NULL; |
| try |
| { |
| sal_Int32 nSeqLen = rPropertyNames.getLength(); |
| pHandles = new sal_Int32[ nSeqLen ]; |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // fill the handle array |
| sal_Int32 nHitCount = rPH.fillHandles( pHandles, rPropertyNames ); |
| if( nHitCount != 0 ) |
| setFastPropertyValues( nSeqLen, pHandles, rValues.getConstArray(), nHitCount ); |
| } |
| catch( ... ) |
| { |
| delete [] pHandles; |
| throw; |
| } |
| delete [] pHandles; |
| } |
| |
| // XMultiPropertySet |
| Sequence<Any> OPropertySetHelper::getPropertyValues( const Sequence<OUString>& rPropertyNames ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| sal_Int32 nSeqLen = rPropertyNames.getLength(); |
| sal_Int32 * pHandles = new sal_Int32[ nSeqLen ]; |
| Sequence< Any > aValues( nSeqLen ); |
| |
| // get the map table |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| // fill the handle array |
| rPH.fillHandles( pHandles, rPropertyNames ); |
| |
| Any * pValues = aValues.getArray(); |
| |
| MutexGuard aGuard( rBHelper.rMutex ); |
| // fill the sequence with the values |
| for( sal_Int32 i = 0; i < nSeqLen; i++ ) |
| getFastPropertyValue( pValues[i], pHandles[i] ); |
| |
| delete [] pHandles; |
| return aValues; |
| } |
| |
| // XMultiPropertySet |
| void OPropertySetHelper::addPropertiesChangeListener( |
| const Sequence<OUString> & , |
| const Reference < XPropertiesChangeListener > & rListener ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| rBHelper.addListener( getCppuType(&rListener) , rListener ); |
| } |
| |
| // XMultiPropertySet |
| void OPropertySetHelper::removePropertiesChangeListener( |
| const Reference < XPropertiesChangeListener > & rListener ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| rBHelper.removeListener( getCppuType(&rListener) , rListener ); |
| } |
| |
| // XMultiPropertySet |
| void OPropertySetHelper::firePropertiesChangeEvent( |
| const Sequence<OUString>& rPropertyNames, |
| const Reference < XPropertiesChangeListener >& rListener ) |
| throw(::com::sun::star::uno::RuntimeException) |
| { |
| sal_Int32 nLen = rPropertyNames.getLength(); |
| sal_Int32 * pHandles = new sal_Int32[nLen]; |
| IPropertyArrayHelper & rPH = getInfoHelper(); |
| rPH.fillHandles( pHandles, rPropertyNames ); |
| const OUString* pNames = rPropertyNames.getConstArray(); |
| |
| // get the count of matching properties |
| sal_Int32 nFireLen = 0; |
| sal_Int32 i; |
| for( i = 0; i < nLen; i++ ) |
| if( pHandles[i] != -1 ) |
| nFireLen++; |
| |
| Sequence<PropertyChangeEvent> aChanges( nFireLen ); |
| PropertyChangeEvent* pChanges = aChanges.getArray(); |
| |
| sal_Int32 nFirePos = 0; |
| { |
| // must lock the mutex outside the loop. So all values are consistent. |
| MutexGuard aGuard( rBHelper.rMutex ); |
| Reference < XInterface > xSource( (XPropertySet *)this, UNO_QUERY ); |
| for( i = 0; i < nLen; i++ ) |
| { |
| if( pHandles[i] != -1 ) |
| { |
| pChanges[nFirePos].Source = xSource; |
| pChanges[nFirePos].PropertyName = pNames[i]; |
| pChanges[nFirePos].PropertyHandle = pHandles[i]; |
| getFastPropertyValue( pChanges[nFirePos].OldValue, pHandles[i] ); |
| pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue; |
| nFirePos++; |
| } |
| } |
| // release guard to fire events |
| } |
| if( nFireLen ) |
| rListener->propertiesChange( aChanges ); |
| |
| delete [] pHandles; |
| } |
| |
| #ifdef xdvnsdfln |
| // XPropertyState |
| PropertyState OPropertySetHelper::getPropertyState( const OUString& PropertyName ) |
| { |
| PropertyState aState; |
| return aState; |
| } |
| |
| // XPropertyState |
| Sequence< PropertyState > OPropertySetHelper::getPropertyStates( const Sequence< OUString >& PropertyNames ) |
| { |
| ULONG nNames = PropertyNames.getLength(); |
| const OUString* pNames = PropertyNames.getConstArray(); |
| |
| Sequence< PropertyState > aStates( nNames ); |
| return aStates; |
| |
| } |
| |
| void OPropertySetHelper::setPropertyToDefault( const OUString& aPropertyName ) |
| { |
| setPropertyValue( aPropertyName, Any() ); |
| } |
| |
| Any OPropertySetHelper::getPropertyDefault( const OUString& aPropertyName ) const |
| { |
| return Any(); |
| } |
| |
| void OPropertySetHelper::addPropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) |
| { |
| } |
| |
| void OPropertySetHelper::removePropertyStateChangeListener( const OUString& aPropertyName, const XPropertyStateChangeListenerRef& Listener ) |
| { |
| } |
| #endif |
| |
| //======================================================================== |
| //== OPropertyArrayHelper ================================================ |
| //======================================================================== |
| |
| //======================================================================== |
| |
| // static OUString makeOUString( sal_Char *p ) |
| // { |
| // sal_Int32 nLen = strlen(p); |
| // sal_Unicode *pw = new sal_Unicode[nLen]; |
| |
| // for( int i = 0 ; i < nLen ; i ++ ) { |
| |
| // // Only ascii strings allowed with this helper ! |
| // OSL_ASSERT( p[i] < 127 ); |
| // pw[i] = p[i]; |
| // } |
| // OUString ow( pw , nLen ); |
| // delete pw; |
| // return ow; |
| // } |
| |
| extern "C" { |
| |
| static int compare_Property_Impl( const void *arg1, const void *arg2 ) |
| SAL_THROW_EXTERN_C() |
| { |
| return ((Property *)arg1)->Name.compareTo( ((Property *)arg2)->Name ); |
| } |
| |
| } |
| |
| void OPropertyArrayHelper::init( sal_Bool bSorted ) SAL_THROW( () ) |
| { |
| sal_Int32 i, nElements = aInfos.getLength(); |
| const Property* pProperties = aInfos.getConstArray(); |
| |
| for( i = 1; i < nElements; i++ ) |
| { |
| if( pProperties[i-1].Name >= pProperties[i].Name ) |
| { |
| #ifndef OS2 // YD disabled, too many troubles with debug builds! |
| if (bSorted) { |
| OSL_ENSURE( false, "Property array is not sorted" ); |
| } |
| #endif |
| // not sorted |
| qsort( aInfos.getArray(), nElements, sizeof( Property ), |
| compare_Property_Impl ); |
| break; |
| } |
| } |
| // may be that the array is resorted |
| pProperties = aInfos.getConstArray(); |
| for( i = 0; i < nElements; i++ ) |
| if( pProperties[i].Handle != i ) |
| return; |
| // The handle is the index |
| bRightOrdered = sal_True; |
| } |
| |
| OPropertyArrayHelper::OPropertyArrayHelper( |
| Property * pProps, |
| sal_Int32 nEle, |
| sal_Bool bSorted ) |
| SAL_THROW( () ) |
| : aInfos(pProps, nEle) |
| , bRightOrdered( sal_False ) |
| { |
| init( bSorted ); |
| } |
| |
| OPropertyArrayHelper::OPropertyArrayHelper( |
| const Sequence< Property > & aProps, |
| sal_Bool bSorted ) |
| SAL_THROW( () ) |
| : aInfos(aProps) |
| , bRightOrdered( sal_False ) |
| { |
| init( bSorted ); |
| } |
| |
| //======================================================================== |
| sal_Int32 OPropertyArrayHelper::getCount() const |
| { |
| return aInfos.getLength(); |
| } |
| |
| //======================================================================== |
| sal_Bool OPropertyArrayHelper::fillPropertyMembersByHandle |
| ( |
| OUString * pPropName, |
| sal_Int16 * pAttributes, |
| sal_Int32 nHandle |
| ) |
| { |
| const Property* pProperties = aInfos.getConstArray(); |
| sal_Int32 nElements = aInfos.getLength(); |
| |
| if( bRightOrdered ) |
| { |
| if( nHandle < 0 || nHandle >= nElements ) |
| return sal_False; |
| if( pPropName ) |
| *pPropName = pProperties[ nHandle ].Name; |
| if( pAttributes ) |
| *pAttributes = pProperties[ nHandle ].Attributes; |
| return sal_True; |
| } |
| else |
| { |
| // normally the array is sorted |
| for( sal_Int32 i = 0; i < nElements; i++ ) |
| { |
| if( pProperties[i].Handle == nHandle ) |
| { |
| if( pPropName ) |
| *pPropName = pProperties[ i ].Name; |
| if( pAttributes ) |
| *pAttributes = pProperties[ i ].Attributes; |
| return sal_True; |
| } |
| } |
| } |
| return sal_False; |
| } |
| |
| //======================================================================== |
| Sequence< Property > OPropertyArrayHelper::getProperties(void) |
| { |
| /*if( aInfos.getLength() != nElements ) |
| { |
| ((OPropertyArrayHelper *)this)->aInfos.realloc( nElements ); |
| Property * pProps = ((OPropertyArrayHelper *)this)->aInfos.getArray(); |
| for( sal_Int32 i = 0; i < nElements; i++ ) |
| { |
| pProps[i].Name = pProperties[i].Name; |
| pProps[i].Handle = pProperties[i].Handle; |
| pProps[i].Type = pProperties[i].Type; |
| pProps[i].Attributes = pProperties[i].Attributes; |
| } |
| }*/ |
| return aInfos; |
| } |
| |
| //======================================================================== |
| Property OPropertyArrayHelper::getPropertyByName(const OUString& aPropertyName) |
| throw (UnknownPropertyException) |
| { |
| Property * pR; |
| pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), |
| sizeof( Property ), |
| compare_OUString_Property_Impl ); |
| if( !pR ) { |
| throw UnknownPropertyException(); |
| } |
| |
| /*Property aProp; |
| aProp.Name = pR->Name; |
| aProp.Handle = pR->Handle; |
| aProp.Type = pR->Type; |
| aProp.Attributes = pR->Attributes; |
| return aProp;*/ |
| return *pR; |
| } |
| |
| //======================================================================== |
| sal_Bool OPropertyArrayHelper::hasPropertyByName(const OUString& aPropertyName) |
| { |
| Property * pR; |
| pR = (Property *)bsearch( &aPropertyName, aInfos.getConstArray(), aInfos.getLength(), |
| sizeof( Property ), |
| compare_OUString_Property_Impl ); |
| return pR != NULL; |
| } |
| |
| //======================================================================== |
| sal_Int32 OPropertyArrayHelper::getHandleByName( const OUString & rPropName ) |
| { |
| Property * pR; |
| pR = (Property *)bsearch( &rPropName, aInfos.getConstArray(), aInfos.getLength(), |
| sizeof( Property ), |
| compare_OUString_Property_Impl ); |
| return pR ? pR->Handle : -1; |
| } |
| |
| //======================================================================== |
| sal_Int32 OPropertyArrayHelper::fillHandles( sal_Int32 * pHandles, const Sequence< OUString > & rPropNames ) |
| { |
| sal_Int32 nHitCount = 0; |
| const OUString * pReqProps = rPropNames.getConstArray(); |
| sal_Int32 nReqLen = rPropNames.getLength(); |
| const Property * pCur = aInfos.getConstArray(); |
| const Property * pEnd = pCur + aInfos.getLength(); |
| |
| for( sal_Int32 i = 0; i < nReqLen; i++ ) |
| { |
| // Logarithmus ermitteln |
| sal_Int32 n = (sal_Int32)(pEnd - pCur); |
| sal_Int32 nLog = 0; |
| while( n ) |
| { |
| nLog += 1; |
| n = n >> 1; |
| } |
| |
| // Anzahl der noch zu suchenden Properties * dem Log2 der verbleibenden |
| // zu dursuchenden Properties. |
| if( (nReqLen - i) * nLog >= pEnd - pCur ) |
| { |
| // linear search is better |
| while( pCur < pEnd && pReqProps[i] > pCur->Name ) |
| { |
| pCur++; |
| } |
| if( pCur < pEnd && pReqProps[i] == pCur->Name ) |
| { |
| pHandles[i] = pCur->Handle; |
| nHitCount++; |
| } |
| else |
| pHandles[i] = -1; |
| } |
| else |
| { |
| // binary search is better |
| sal_Int32 nCompVal = 1; |
| const Property * pOldEnd = pEnd--; |
| const Property * pMid = pCur; |
| |
| while( nCompVal != 0 && pCur <= pEnd ) |
| { |
| pMid = (pEnd - pCur) / 2 + pCur; |
| |
| nCompVal = pReqProps[i].compareTo( pMid->Name ); |
| |
| if( nCompVal > 0 ) |
| pCur = pMid + 1; |
| else |
| pEnd = pMid - 1; |
| } |
| |
| if( nCompVal == 0 ) |
| { |
| pHandles[i] = pMid->Handle; |
| nHitCount++; |
| pCur = pMid +1; |
| } |
| else if( nCompVal > 0 ) |
| { |
| pHandles[i] = -1; |
| pCur = pMid +1; |
| } |
| else |
| { |
| pHandles[i] = -1; |
| pCur = pMid; |
| } |
| pEnd = pOldEnd; |
| } |
| } |
| return nHitCount; |
| } |
| |
| } // end namespace cppu |
| |
| |
| |