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