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