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