1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cppuhelper.hxx"
26 #include <osl/diagnose.h>
27 #include <osl/mutex.hxx>
28 #include <cppuhelper/weak.hxx>
29 #include <cppuhelper/component.hxx>
30 #include <cppuhelper/factory.hxx>
31 #ifndef _CPPUHELPER_IMPLBASE3_HXX
32 #include <cppuhelper/implbase3.hxx>
33 #endif
34 #include <cppuhelper/typeprovider.hxx>
35 #include <rtl/unload.h>
36
37 #include "cppuhelper/propshlp.hxx"
38
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
41 #include <com/sun/star/lang/XSingleComponentFactory.hpp>
42 #include <com/sun/star/lang/XInitialization.hpp>
43 #include <com/sun/star/loader/XImplementationLoader.hpp>
44 #include <com/sun/star/lang/XComponent.hpp>
45 #include <com/sun/star/lang/IllegalArgumentException.hpp>
46 #include <com/sun/star/uno/XUnloadingPreference.hpp>
47 #include "com/sun/star/beans/PropertyAttribute.hpp"
48
49 #include <memory>
50
51 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
52
53
54 using namespace osl;
55 using namespace rtl;
56 using namespace com::sun::star;
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::lang;
59 using namespace com::sun::star::loader;
60 using namespace com::sun::star::registry;
61
62 namespace cppu
63 {
64
65 //-----------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------
67 //-----------------------------------------------------------------------------
68 class OSingleFactoryHelper
69 : public XServiceInfo
70 , public XSingleServiceFactory
71 , public lang::XSingleComponentFactory
72 , public XUnloadingPreference
73 {
74 public:
OSingleFactoryHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_,ComponentInstantiation pCreateFunction_,ComponentFactoryFunc fptr,const Sequence<OUString> * pServiceNames_)75 OSingleFactoryHelper(
76 const Reference<XMultiServiceFactory > & rServiceManager,
77 const OUString & rImplementationName_,
78 ComponentInstantiation pCreateFunction_,
79 ComponentFactoryFunc fptr,
80 const Sequence< OUString > * pServiceNames_ )
81 SAL_THROW( () )
82 : xSMgr( rServiceManager )
83 , pCreateFunction( pCreateFunction_ )
84 , m_fptr( fptr )
85 , aImplementationName( rImplementationName_ )
86 {
87 if( pServiceNames_ )
88 aServiceNames = *pServiceNames_;
89 }
90
91 // old function, only for backward compatibility
OSingleFactoryHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_)92 OSingleFactoryHelper(
93 const Reference<XMultiServiceFactory > & rServiceManager,
94 const OUString & rImplementationName_ )
95 SAL_THROW( () )
96 : xSMgr( rServiceManager )
97 , pCreateFunction( NULL )
98 , m_fptr( 0 )
99 , aImplementationName( rImplementationName_ )
100 {}
101
102 virtual ~OSingleFactoryHelper();
103
104 // XInterface
105 Any SAL_CALL queryInterface( const Type & rType )
106 throw(::com::sun::star::uno::RuntimeException);
107
108 // XSingleServiceFactory
109 Reference<XInterface > SAL_CALL createInstance()
110 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
111 virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
112 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
113 // XSingleComponentFactory
114 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
115 Reference< XComponentContext > const & xContext )
116 throw (Exception, RuntimeException);
117 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
118 Sequence< Any > const & rArguments,
119 Reference< XComponentContext > const & xContext )
120 throw (Exception, RuntimeException);
121
122 // XServiceInfo
123 OUString SAL_CALL getImplementationName()
124 throw(::com::sun::star::uno::RuntimeException);
125 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
126 throw(::com::sun::star::uno::RuntimeException);
127 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
128 throw(::com::sun::star::uno::RuntimeException);
129
130 protected:
131 /**
132 * Create an instance specified by the factory. The one instance logic is implemented
133 * in the createInstance and createInstanceWithArguments methods.
134 * @return the newly created instance. Do not return a previous (one instance) instance.
135 */
136 virtual Reference<XInterface > createInstanceEveryTime(
137 Reference< XComponentContext > const & xContext )
138 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
139
140 Reference<XMultiServiceFactory > xSMgr;
141 ComponentInstantiation pCreateFunction;
142 ComponentFactoryFunc m_fptr;
143 Sequence< OUString > aServiceNames;
144 OUString aImplementationName;
145 };
~OSingleFactoryHelper()146 OSingleFactoryHelper::~OSingleFactoryHelper()
147 {
148 }
149
150
151 //-----------------------------------------------------------------------------
queryInterface(const Type & rType)152 Any OSingleFactoryHelper::queryInterface( const Type & rType )
153 throw(::com::sun::star::uno::RuntimeException)
154 {
155 return ::cppu::queryInterface(
156 rType,
157 static_cast< XSingleComponentFactory * >( this ),
158 static_cast< XSingleServiceFactory * >( this ),
159 static_cast< XServiceInfo * >( this ) ,
160 static_cast< XUnloadingPreference * >( this ));
161 }
162
163 // OSingleFactoryHelper
createInstanceEveryTime(Reference<XComponentContext> const & xContext)164 Reference<XInterface > OSingleFactoryHelper::createInstanceEveryTime(
165 Reference< XComponentContext > const & xContext )
166 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
167 {
168 if (m_fptr)
169 {
170 return (*m_fptr)( xContext );
171 }
172 else if( pCreateFunction )
173 {
174 if (xContext.is())
175 {
176 Reference< lang::XMultiServiceFactory > xContextMgr(
177 xContext->getServiceManager(), UNO_QUERY );
178 if (xContextMgr.is())
179 return (*pCreateFunction)( xContextMgr );
180 }
181 return (*pCreateFunction)( xSMgr );
182 }
183 else
184 {
185 return Reference< XInterface >();
186 }
187 }
188
189 // XSingleServiceFactory
createInstance()190 Reference<XInterface > OSingleFactoryHelper::createInstance()
191 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
192 {
193 return createInstanceWithContext( Reference< XComponentContext >() );
194 }
195
196 // XSingleServiceFactory
createInstanceWithArguments(const Sequence<Any> & Arguments)197 Reference<XInterface > OSingleFactoryHelper::createInstanceWithArguments(
198 const Sequence<Any>& Arguments )
199 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
200 {
201 return createInstanceWithArgumentsAndContext(
202 Arguments, Reference< XComponentContext >() );
203 }
204
205 // XSingleComponentFactory
206 //__________________________________________________________________________________________________
createInstanceWithContext(Reference<XComponentContext> const & xContext)207 Reference< XInterface > OSingleFactoryHelper::createInstanceWithContext(
208 Reference< XComponentContext > const & xContext )
209 throw (Exception, RuntimeException)
210 {
211 return createInstanceEveryTime( xContext );
212 }
213 //__________________________________________________________________________________________________
createInstanceWithArgumentsAndContext(Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)214 Reference< XInterface > OSingleFactoryHelper::createInstanceWithArgumentsAndContext(
215 Sequence< Any > const & rArguments,
216 Reference< XComponentContext > const & xContext )
217 throw (Exception, RuntimeException)
218 {
219 Reference< XInterface > xRet( createInstanceWithContext( xContext ) );
220
221 Reference< lang::XInitialization > xInit( xRet, UNO_QUERY );
222 // always call initialize, even if there are no arguments.
223 // #i63511# / 2006-03-27 / frank.schoenheit@sun.com
224 if (xInit.is())
225 {
226 xInit->initialize( rArguments );
227 }
228 else
229 {
230 if ( rArguments.getLength() )
231 {
232 // dispose the here created UNO object before throwing out exception
233 // to avoid risk of memory leaks #i113722#
234 Reference<XComponent> xComp( xRet, UNO_QUERY );
235 if (xComp.is())
236 xComp->dispose();
237
238 throw lang::IllegalArgumentException(
239 OUString( RTL_CONSTASCII_USTRINGPARAM("cannot pass arguments to component => no XInitialization implemented!") ),
240 Reference< XInterface >(), 0 );
241 }
242 }
243
244 return xRet;
245 }
246
247 // XServiceInfo
getImplementationName()248 OUString OSingleFactoryHelper::getImplementationName()
249 throw(::com::sun::star::uno::RuntimeException)
250 {
251 return aImplementationName;
252 }
253
254 // XServiceInfo
supportsService(const OUString & ServiceName)255 sal_Bool OSingleFactoryHelper::supportsService(
256 const OUString& ServiceName )
257 throw(::com::sun::star::uno::RuntimeException)
258 {
259 Sequence< OUString > seqServices = getSupportedServiceNames();
260 const OUString * pServices = seqServices.getConstArray();
261 for( sal_Int32 i = 0; i < seqServices.getLength(); i++ )
262 if( pServices[i] == ServiceName )
263 return sal_True;
264
265 return sal_False;
266 }
267
268 // XServiceInfo
getSupportedServiceNames(void)269 Sequence< OUString > OSingleFactoryHelper::getSupportedServiceNames(void)
270 throw(::com::sun::star::uno::RuntimeException)
271 {
272 return aServiceNames;
273 }
274
275
276 //----------------------------------------------------------------------
277 //----------------------------------------------------------------------
278 //----------------------------------------------------------------------
279 struct OFactoryComponentHelper_Mutex
280 {
281 Mutex aMutex;
282 };
283
284 class OFactoryComponentHelper
285 : public OFactoryComponentHelper_Mutex
286 , public OComponentHelper
287 , public OSingleFactoryHelper
288 {
289 public:
OFactoryComponentHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_,ComponentInstantiation pCreateFunction_,ComponentFactoryFunc fptr,const Sequence<OUString> * pServiceNames_,sal_Bool bOneInstance_=sal_False)290 OFactoryComponentHelper(
291 const Reference<XMultiServiceFactory > & rServiceManager,
292 const OUString & rImplementationName_,
293 ComponentInstantiation pCreateFunction_,
294 ComponentFactoryFunc fptr,
295 const Sequence< OUString > * pServiceNames_,
296 sal_Bool bOneInstance_ = sal_False )
297 SAL_THROW( () )
298 : OComponentHelper( aMutex )
299 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
300 , bOneInstance( bOneInstance_ )
301 , pModuleCount(0)
302 {
303 }
304
305 // Used by the createXXXFactory functions. The argument pModCount is used to prevent the unloading of the module
306 // which contains pCreateFunction_
OFactoryComponentHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_,ComponentInstantiation pCreateFunction_,ComponentFactoryFunc fptr,const Sequence<OUString> * pServiceNames_,rtl_ModuleCount * pModCount,sal_Bool bOneInstance_=sal_False)307 OFactoryComponentHelper(
308 const Reference<XMultiServiceFactory > & rServiceManager,
309 const OUString & rImplementationName_,
310 ComponentInstantiation pCreateFunction_,
311 ComponentFactoryFunc fptr,
312 const Sequence< OUString > * pServiceNames_,
313 rtl_ModuleCount * pModCount,
314 sal_Bool bOneInstance_ = sal_False )
315 SAL_THROW( () )
316 : OComponentHelper( aMutex )
317 , OSingleFactoryHelper( rServiceManager, rImplementationName_, pCreateFunction_, fptr, pServiceNames_ )
318 , bOneInstance( bOneInstance_ )
319 , pModuleCount(pModCount)
320 {
321 if(pModuleCount)
322 pModuleCount->acquire( pModuleCount);
323 }
324
325 // old function, only for backward compatibility
OFactoryComponentHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_,sal_Bool bOneInstance_=sal_False)326 OFactoryComponentHelper(
327 const Reference<XMultiServiceFactory > & rServiceManager,
328 const OUString & rImplementationName_,
329 sal_Bool bOneInstance_ = sal_False )
330 SAL_THROW( () )
331 : OComponentHelper( aMutex )
332 , OSingleFactoryHelper( rServiceManager, rImplementationName_ )
333 , bOneInstance( bOneInstance_ )
334 , pModuleCount(0)
335 {
336 }
337
~OFactoryComponentHelper()338 ~OFactoryComponentHelper()
339 {
340 if(pModuleCount)
341 pModuleCount->release( pModuleCount);
342 }
343
344 // XInterface
345 Any SAL_CALL queryInterface( const Type & rType )
346 throw(::com::sun::star::uno::RuntimeException);
acquire()347 void SAL_CALL acquire() throw()
348 { OComponentHelper::acquire(); }
release()349 void SAL_CALL release() throw()
350 { OComponentHelper::release(); }
351
352 // XSingleServiceFactory
353 Reference<XInterface > SAL_CALL createInstance()
354 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
355 Reference<XInterface > SAL_CALL createInstanceWithArguments( const Sequence<Any>& Arguments )
356 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
357 // XSingleComponentFactory
358 virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
359 Reference< XComponentContext > const & xContext )
360 throw (Exception, RuntimeException);
361 virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
362 Sequence< Any > const & rArguments,
363 Reference< XComponentContext > const & xContext )
364 throw (Exception, RuntimeException);
365
366 // XTypeProvider
367 virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
368 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
369
370 // XAggregation
371 Any SAL_CALL queryAggregation( const Type & rType )
372 throw(::com::sun::star::uno::RuntimeException);
373
374 // XUnloadingPreference
375 virtual sal_Bool SAL_CALL releaseOnNotification()
376 throw(::com::sun::star::uno::RuntimeException);
377
378 // OComponentHelper
379 void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
380
381 private:
382 Reference<XInterface > xTheInstance;
383 sal_Bool bOneInstance;
384 rtl_ModuleCount * pModuleCount;
385 protected:
386 // needed for implementing XUnloadingPreference in inheriting classes
isOneInstance()387 sal_Bool isOneInstance() {return bOneInstance;}
isInstance()388 sal_Bool isInstance() {return xTheInstance.is();}
389 };
390
391
queryInterface(const Type & rType)392 Any SAL_CALL OFactoryComponentHelper::queryInterface( const Type & rType )
393 throw(::com::sun::star::uno::RuntimeException)
394 {
395 if( rType == ::getCppuType( (Reference<XUnloadingPreference>*)0))
396 {
397 return makeAny(
398 Reference< XUnloadingPreference >(
399 static_cast< XUnloadingPreference * >(this) ) );
400 }
401 return OComponentHelper::queryInterface( rType );
402 }
403
404 // XAggregation
queryAggregation(const Type & rType)405 Any OFactoryComponentHelper::queryAggregation( const Type & rType )
406 throw(::com::sun::star::uno::RuntimeException)
407 {
408 Any aRet( OComponentHelper::queryAggregation( rType ) );
409 return (aRet.hasValue() ? aRet : OSingleFactoryHelper::queryInterface( rType ));
410 }
411
412 // XTypeProvider
getTypes()413 Sequence< Type > OFactoryComponentHelper::getTypes()
414 throw (::com::sun::star::uno::RuntimeException)
415 {
416 Type ar[ 4 ];
417 ar[ 0 ] = ::getCppuType( (const Reference< XSingleServiceFactory > *)0 );
418 ar[ 1 ] = ::getCppuType( (const Reference< XServiceInfo > *)0 );
419 ar[ 2 ] = ::getCppuType( (const Reference< XUnloadingPreference > *)0 );
420
421 if (m_fptr)
422 ar[ 3 ] = ::getCppuType( (const Reference< XSingleComponentFactory > *)0 );
423
424 return Sequence< Type >( ar, m_fptr ? 4 : 3 );
425 }
426
getImplementationId()427 Sequence< sal_Int8 > OFactoryComponentHelper::getImplementationId()
428 throw (::com::sun::star::uno::RuntimeException)
429 {
430 static OImplementationId * pId = 0;
431 if (! pId)
432 {
433 MutexGuard aGuard( Mutex::getGlobalMutex() );
434 if (! pId)
435 {
436 static OImplementationId aId;
437 pId = &aId;
438 }
439 }
440 return pId->getImplementationId();
441 }
442
443 // XSingleServiceFactory
createInstance()444 Reference<XInterface > OFactoryComponentHelper::createInstance()
445 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
446 {
447 if( bOneInstance )
448 {
449 if( !xTheInstance.is() )
450 {
451 MutexGuard aGuard( aMutex );
452 if( !xTheInstance.is() )
453 xTheInstance = OSingleFactoryHelper::createInstance();
454 }
455 return xTheInstance;
456 }
457 return OSingleFactoryHelper::createInstance();
458 }
459
createInstanceWithArguments(const Sequence<Any> & Arguments)460 Reference<XInterface > OFactoryComponentHelper::createInstanceWithArguments(
461 const Sequence<Any>& Arguments )
462 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
463 {
464 if( bOneInstance )
465 {
466 if( !xTheInstance.is() )
467 {
468 MutexGuard aGuard( aMutex );
469 // OSL_ENSURE( !xTheInstance.is(), "### arguments will be ignored!" );
470 if( !xTheInstance.is() )
471 xTheInstance = OSingleFactoryHelper::createInstanceWithArguments( Arguments );
472 }
473 return xTheInstance;
474 }
475 return OSingleFactoryHelper::createInstanceWithArguments( Arguments );
476 }
477
478 // XSingleComponentFactory
479 //__________________________________________________________________________________________________
createInstanceWithContext(Reference<XComponentContext> const & xContext)480 Reference< XInterface > OFactoryComponentHelper::createInstanceWithContext(
481 Reference< XComponentContext > const & xContext )
482 throw (Exception, RuntimeException)
483 {
484 if( bOneInstance )
485 {
486 if( !xTheInstance.is() )
487 {
488 MutexGuard aGuard( aMutex );
489 // OSL_ENSURE( !xTheInstance.is(), "### context will be ignored!" );
490 if( !xTheInstance.is() )
491 xTheInstance = OSingleFactoryHelper::createInstanceWithContext( xContext );
492 }
493 return xTheInstance;
494 }
495 return OSingleFactoryHelper::createInstanceWithContext( xContext );
496 }
497 //__________________________________________________________________________________________________
createInstanceWithArgumentsAndContext(Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)498 Reference< XInterface > OFactoryComponentHelper::createInstanceWithArgumentsAndContext(
499 Sequence< Any > const & rArguments,
500 Reference< XComponentContext > const & xContext )
501 throw (Exception, RuntimeException)
502 {
503 if( bOneInstance )
504 {
505 if( !xTheInstance.is() )
506 {
507 MutexGuard aGuard( aMutex );
508 // OSL_ENSURE( !xTheInstance.is(), "### context and arguments will be ignored!" );
509 if( !xTheInstance.is() )
510 xTheInstance = OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
511 }
512 return xTheInstance;
513 }
514 return OSingleFactoryHelper::createInstanceWithArgumentsAndContext( rArguments, xContext );
515 }
516
517
518 // OComponentHelper
dispose()519 void OFactoryComponentHelper::dispose()
520 throw(::com::sun::star::uno::RuntimeException)
521 {
522 OComponentHelper::dispose();
523
524 Reference<XInterface > x;
525 {
526 // do not delete in the guard section
527 MutexGuard aGuard( aMutex );
528 x = xTheInstance;
529 xTheInstance = Reference<XInterface >();
530 }
531 // if it is a component call dispose at the component
532 Reference<XComponent > xComp( x, UNO_QUERY );
533 if( xComp.is() )
534 xComp->dispose();
535 }
536
537 // XUnloadingPreference
538 // This class is used for single factories, component factories and
539 // one-instance factories. Depending on the usage this function has
540 // to return different values.
541 // one-instance factory: sal_False
542 // single factory: sal_True
543 // component factory: sal_True
releaseOnNotification()544 sal_Bool SAL_CALL OFactoryComponentHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
545 {
546 if( bOneInstance)
547 return sal_False;
548 return sal_True;
549 }
550
551
552 //-----------------------------------------------------------------------------
553 //-----------------------------------------------------------------------------
554 //-----------------------------------------------------------------------------
555 class ORegistryFactoryHelper : public OFactoryComponentHelper,
556 public OPropertySetHelper
557
558 {
559 public:
ORegistryFactoryHelper(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName_,const Reference<XRegistryKey> & xImplementationKey_,sal_Bool bOneInstance_=sal_False)560 ORegistryFactoryHelper(
561 const Reference<XMultiServiceFactory > & rServiceManager,
562 const OUString & rImplementationName_,
563 const Reference<XRegistryKey > & xImplementationKey_,
564 sal_Bool bOneInstance_ = sal_False ) SAL_THROW( () )
565 : OFactoryComponentHelper(
566 rServiceManager, rImplementationName_, 0, 0, 0, bOneInstance_ ),
567 OPropertySetHelper( OComponentHelper::rBHelper ),
568 xImplementationKey( xImplementationKey_ )
569 {}
570
571 // XInterface
572 virtual Any SAL_CALL queryInterface( Type const & type )
573 throw (RuntimeException);
574 virtual void SAL_CALL acquire() throw ();
575 virtual void SAL_CALL release() throw ();
576 // XTypeProvider
577 virtual Sequence< Type > SAL_CALL getTypes()
578 throw (RuntimeException);
579 // XPropertySet
580 virtual Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
581 throw (RuntimeException);
582
583 // OPropertySetHelper
584 virtual IPropertyArrayHelper & SAL_CALL getInfoHelper();
585 virtual sal_Bool SAL_CALL convertFastPropertyValue(
586 Any & rConvertedValue, Any & rOldValue,
587 sal_Int32 nHandle, Any const & rValue )
588 throw (lang::IllegalArgumentException);
589 virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
590 sal_Int32 nHandle, Any const & rValue )
591 throw (Exception);
592 using OPropertySetHelper::getFastPropertyValue;
593 virtual void SAL_CALL getFastPropertyValue(
594 Any & rValue, sal_Int32 nHandle ) const;
595
596 // OSingleFactoryHelper
597 Reference<XInterface > createInstanceEveryTime(
598 Reference< XComponentContext > const & xContext )
599 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
600
601 // XSingleServiceFactory
602 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
603 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
604 // XSingleComponentFactory
605 Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
606 Sequence< Any > const & rArguments,
607 Reference< XComponentContext > const & xContext )
608 throw (Exception, RuntimeException);
609
610 // XServiceInfo
611 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
612 throw(::com::sun::star::uno::RuntimeException);
613 // XUnloadingPreference
614 sal_Bool SAL_CALL releaseOnNotification()
615 throw( RuntimeException);
616
617
618 private:
619 Reference< XInterface > createModuleFactory()
620 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
621
622 /** The registry key of the implementation section */
623 Reference<XRegistryKey > xImplementationKey;
624 /** The factory created with the loader. */
625 Reference<XSingleComponentFactory > xModuleFactory;
626 Reference<XSingleServiceFactory > xModuleFactoryDepr;
627 Reference< beans::XPropertySetInfo > m_xInfo;
628 ::std::auto_ptr< IPropertyArrayHelper > m_property_array_helper;
629 protected:
630 using OPropertySetHelper::getTypes;
631 };
632
633 // XInterface
634 //______________________________________________________________________________
queryInterface(Type const & type)635 Any SAL_CALL ORegistryFactoryHelper::queryInterface(
636 Type const & type ) throw (RuntimeException)
637 {
638 Any ret( OFactoryComponentHelper::queryInterface( type ) );
639 if (ret.hasValue())
640 return ret;
641 else
642 return OPropertySetHelper::queryInterface( type );
643 }
644
645 //______________________________________________________________________________
acquire()646 void ORegistryFactoryHelper::acquire() throw ()
647 {
648 OFactoryComponentHelper::acquire();
649 }
650
651 //______________________________________________________________________________
release()652 void ORegistryFactoryHelper::release() throw ()
653 {
654 OFactoryComponentHelper::release();
655 }
656
657 // XTypeProvider
658 //______________________________________________________________________________
getTypes()659 Sequence< Type > ORegistryFactoryHelper::getTypes() throw (RuntimeException)
660 {
661 Sequence< Type > types( OFactoryComponentHelper::getTypes() );
662 sal_Int32 pos = types.getLength();
663 types.realloc( pos + 3 );
664 Type * p = types.getArray();
665 p[ pos++ ] = ::getCppuType(
666 reinterpret_cast< Reference< beans::XMultiPropertySet > const * >(0) );
667 p[ pos++ ] = ::getCppuType(
668 reinterpret_cast< Reference< beans::XFastPropertySet > const * >(0) );
669 p[ pos++ ] = ::getCppuType(
670 reinterpret_cast< Reference< beans::XPropertySet > const * >(0) );
671 return types;
672 }
673
674 // XPropertySet
675 //______________________________________________________________________________
676 Reference< beans::XPropertySetInfo >
getPropertySetInfo()677 ORegistryFactoryHelper::getPropertySetInfo() throw (RuntimeException)
678 {
679 ::osl::MutexGuard guard( aMutex );
680 if (! m_xInfo.is())
681 m_xInfo = createPropertySetInfo( getInfoHelper() );
682 return m_xInfo;
683 }
684
685 // OPropertySetHelper
686 //______________________________________________________________________________
getInfoHelper()687 IPropertyArrayHelper & ORegistryFactoryHelper::getInfoHelper()
688 {
689 ::osl::MutexGuard guard( aMutex );
690 if (m_property_array_helper.get() == 0)
691 {
692 beans::Property prop(
693 OUSTR("ImplementationKey") /* name */,
694 0 /* handle */,
695 ::getCppuType( &xImplementationKey ),
696 beans::PropertyAttribute::READONLY |
697 beans::PropertyAttribute::OPTIONAL );
698 m_property_array_helper.reset(
699 new ::cppu::OPropertyArrayHelper( &prop, 1 ) );
700 }
701 return *m_property_array_helper.get();
702 }
703
704 //______________________________________________________________________________
convertFastPropertyValue(Any &,Any &,sal_Int32,Any const &)705 sal_Bool ORegistryFactoryHelper::convertFastPropertyValue(
706 Any &, Any &, sal_Int32, Any const & )
707 throw (lang::IllegalArgumentException)
708 {
709 OSL_ENSURE( 0, "unexpected!" );
710 return false;
711 }
712
713 //______________________________________________________________________________
setFastPropertyValue_NoBroadcast(sal_Int32,Any const &)714 void ORegistryFactoryHelper::setFastPropertyValue_NoBroadcast(
715 sal_Int32, Any const & )
716 throw (Exception)
717 {
718 throw beans::PropertyVetoException(
719 OUSTR("unexpected: only readonly properties!"),
720 static_cast< OWeakObject * >(this) );
721 }
722
723 //______________________________________________________________________________
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const724 void ORegistryFactoryHelper::getFastPropertyValue(
725 Any & rValue, sal_Int32 nHandle ) const
726 {
727 if (nHandle == 0)
728 {
729 rValue <<= xImplementationKey;
730 }
731 else
732 {
733 rValue.clear();
734 throw beans::UnknownPropertyException(
735 OUSTR("unknown property!"), static_cast< OWeakObject * >(
736 const_cast< ORegistryFactoryHelper * >(this) ) );
737 }
738 }
739
createInstanceEveryTime(Reference<XComponentContext> const & xContext)740 Reference<XInterface > ORegistryFactoryHelper::createInstanceEveryTime(
741 Reference< XComponentContext > const & xContext )
742 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
743 {
744 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
745 {
746 Reference< XInterface > x( createModuleFactory() );
747 if (x.is())
748 {
749 MutexGuard aGuard( aMutex );
750 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
751 {
752 xModuleFactory.set( x, UNO_QUERY );
753 xModuleFactoryDepr.set( x, UNO_QUERY );
754 }
755 }
756 }
757 if( xModuleFactory.is() )
758 {
759 return xModuleFactory->createInstanceWithContext( xContext );
760 }
761 else if( xModuleFactoryDepr.is() )
762 {
763 return xModuleFactoryDepr->createInstance();
764 }
765
766 return Reference<XInterface >();
767 }
768
createInstanceWithArguments(const Sequence<Any> & Arguments)769 Reference<XInterface > SAL_CALL ORegistryFactoryHelper::createInstanceWithArguments(
770 const Sequence<Any>& Arguments )
771 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
772 {
773 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
774 {
775 Reference< XInterface > x( createModuleFactory() );
776 if (x.is())
777 {
778 MutexGuard aGuard( aMutex );
779 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
780 {
781 xModuleFactory.set( x, UNO_QUERY );
782 xModuleFactoryDepr.set( x, UNO_QUERY );
783 }
784 }
785 }
786 if( xModuleFactoryDepr.is() )
787 {
788 return xModuleFactoryDepr->createInstanceWithArguments( Arguments );
789 }
790 else if( xModuleFactory.is() )
791 {
792 #if OSL_DEBUG_LEVEL > 1
793 OSL_TRACE( "### no context ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" );
794 #endif
795 return xModuleFactory->createInstanceWithArgumentsAndContext( Arguments, Reference< XComponentContext >() );
796 }
797
798 return Reference<XInterface >();
799 }
800
createInstanceWithArgumentsAndContext(Sequence<Any> const & rArguments,Reference<XComponentContext> const & xContext)801 Reference< XInterface > ORegistryFactoryHelper::createInstanceWithArgumentsAndContext(
802 Sequence< Any > const & rArguments,
803 Reference< XComponentContext > const & xContext )
804 throw (Exception, RuntimeException)
805 {
806 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
807 {
808 Reference< XInterface > x( createModuleFactory() );
809 if (x.is())
810 {
811 MutexGuard aGuard( aMutex );
812 if( !xModuleFactory.is() && !xModuleFactoryDepr.is() )
813 {
814 xModuleFactory.set( x, UNO_QUERY );
815 xModuleFactoryDepr.set( x, UNO_QUERY );
816 }
817 }
818 }
819 if( xModuleFactory.is() )
820 {
821 return xModuleFactory->createInstanceWithArgumentsAndContext( rArguments, xContext );
822 }
823 else if( xModuleFactoryDepr.is() )
824 {
825 #if OSL_DEBUG_LEVEL > 1
826 if (xContext.is())
827 {
828 OSL_TRACE( "### ignoring context calling ORegistryFactoryHelper::createInstanceWithArgumentsAndContext()!\n" );
829 }
830 #endif
831 return xModuleFactoryDepr->createInstanceWithArguments( rArguments );
832 }
833
834 return Reference<XInterface >();
835 }
836
837
838 // OSingleFactoryHelper
createModuleFactory()839 Reference< XInterface > ORegistryFactoryHelper::createModuleFactory()
840 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
841 {
842 OUString aActivatorUrl;
843 OUString aActivatorName;
844 OUString aLocation;
845
846 Reference<XRegistryKey > xActivatorKey = xImplementationKey->openKey(
847 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") ) );
848 if( xActivatorKey.is() && xActivatorKey->getValueType() == RegistryValueType_ASCII )
849 {
850 aActivatorUrl = xActivatorKey->getAsciiValue();
851
852 OUString tmpActivator(aActivatorUrl.getStr());
853 sal_Int32 nIndex = 0;
854 aActivatorName = tmpActivator.getToken(0, ':', nIndex );
855
856 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
857 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") ) );
858 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
859 aLocation = xLocationKey->getAsciiValue();
860 }
861 else
862 {
863 // old style"url"
864 // the location of the program code of the implementation
865 Reference<XRegistryKey > xLocationKey = xImplementationKey->openKey(
866 OUString( RTL_CONSTASCII_USTRINGPARAM("/UNO/URL") ) );
867 // is the key of the right type ?
868 if( xLocationKey.is() && xLocationKey->getValueType() == RegistryValueType_ASCII )
869 {
870 // one implementation found -> try to activate
871 aLocation = xLocationKey->getAsciiValue();
872
873 // search protocol delemitter
874 sal_Int32 nPos = aLocation.indexOf(
875 OUString( RTL_CONSTASCII_USTRINGPARAM("://") ) );
876 if( nPos != -1 )
877 {
878 aActivatorName = aLocation.copy( 0, nPos );
879 if( aActivatorName.compareToAscii( "java" ) == 0 )
880 aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") );
881 else if( aActivatorName.compareToAscii( "module" ) == 0 )
882 aActivatorName = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") );
883 aLocation = aLocation.copy( nPos + 3 );
884 }
885 }
886 }
887
888 Reference< XInterface > xFactory;
889 if( aActivatorName.getLength() != 0 )
890 {
891 Reference<XInterface > x = xSMgr->createInstance( aActivatorName );
892 Reference<XImplementationLoader > xLoader( x, UNO_QUERY );
893 Reference<XInterface > xMF;
894 if (xLoader.is())
895 {
896 xFactory = xLoader->activate( aImplementationName, aActivatorUrl, aLocation, xImplementationKey );
897 }
898 }
899 return xFactory;
900 }
901
902 // XServiceInfo
getSupportedServiceNames(void)903 Sequence< OUString > ORegistryFactoryHelper::getSupportedServiceNames(void)
904 throw(::com::sun::star::uno::RuntimeException)
905 {
906 MutexGuard aGuard( aMutex );
907 if( aServiceNames.getLength() == 0 )
908 {
909 // not yet loaded
910 try
911 {
912 Reference<XRegistryKey > xKey = xImplementationKey->openKey(
913 OUString( RTL_CONSTASCII_USTRINGPARAM("UNO/SERVICES") ) );
914
915 if (xKey.is())
916 {
917 // length of prefix. +1 for the '/' at the end
918 sal_Int32 nPrefixLen = xKey->getKeyName().getLength() + 1;
919
920 // Full qualified names like "IMPLEMENTATIONS/TEST/UNO/SERVICES/com.sun.star..."
921 Sequence<OUString> seqKeys = xKey->getKeyNames();
922 OUString* pKeys = seqKeys.getArray();
923 for( sal_Int32 i = 0; i < seqKeys.getLength(); i++ )
924 pKeys[i] = pKeys[i].copy(nPrefixLen);
925
926 aServiceNames = seqKeys;
927 }
928 }
929 catch (InvalidRegistryException &)
930 {
931 }
932 }
933 return aServiceNames;
934 }
935
releaseOnNotification()936 sal_Bool SAL_CALL ORegistryFactoryHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
937 {
938 sal_Bool retVal= sal_True;
939 if( isOneInstance() && isInstance())
940 {
941 retVal= sal_False;
942 }
943 else if( ! isOneInstance())
944 {
945 // try to delegate
946 if( xModuleFactory.is())
947 {
948 Reference<XUnloadingPreference> xunloading( xModuleFactory, UNO_QUERY);
949 if( xunloading.is())
950 retVal= xunloading->releaseOnNotification();
951 }
952 else if( xModuleFactoryDepr.is())
953 {
954 Reference<XUnloadingPreference> xunloading( xModuleFactoryDepr, UNO_QUERY);
955 if( xunloading.is())
956 retVal= xunloading->releaseOnNotification();
957 }
958 }
959 return retVal;
960 }
961
962 //-----------------------------------------------------------------------------
963 //-----------------------------------------------------------------------------
964 //-----------------------------------------------------------------------------
965
966 class OFactoryProxyHelper : public WeakImplHelper3< XServiceInfo, XSingleServiceFactory,
967 XUnloadingPreference >
968 {
969 Reference<XSingleServiceFactory > xFactory;
970
971 public:
972
OFactoryProxyHelper(const Reference<XMultiServiceFactory> &,const Reference<XSingleServiceFactory> & rFactory)973 OFactoryProxyHelper(
974 const Reference<XMultiServiceFactory > & /*rServiceManager*/,
975 const Reference<XSingleServiceFactory > & rFactory )
976 SAL_THROW( () )
977 : xFactory( rFactory )
978 {}
979
980 // XSingleServiceFactory
981 Reference<XInterface > SAL_CALL createInstance()
982 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
983 Reference<XInterface > SAL_CALL createInstanceWithArguments(const Sequence<Any>& Arguments)
984 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
985
986 // XServiceInfo
987 OUString SAL_CALL getImplementationName()
988 throw(::com::sun::star::uno::RuntimeException);
989 sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
990 throw(::com::sun::star::uno::RuntimeException);
991 Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
992 throw(::com::sun::star::uno::RuntimeException);
993 //XUnloadingPreference
994 sal_Bool SAL_CALL releaseOnNotification()
995 throw(::com::sun::star::uno::RuntimeException);
996
997 };
998
999 // XSingleServiceFactory
createInstance()1000 Reference<XInterface > OFactoryProxyHelper::createInstance()
1001 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1002 {
1003 return xFactory->createInstance();
1004 }
1005
1006 // XSingleServiceFactory
createInstanceWithArguments(const Sequence<Any> & Arguments)1007 Reference<XInterface > OFactoryProxyHelper::createInstanceWithArguments
1008 (
1009 const Sequence<Any>& Arguments
1010 )
1011 throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1012 {
1013 return xFactory->createInstanceWithArguments( Arguments );
1014 }
1015
1016 // XServiceInfo
getImplementationName()1017 OUString OFactoryProxyHelper::getImplementationName()
1018 throw(::com::sun::star::uno::RuntimeException)
1019 {
1020 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
1021 if( xInfo.is() )
1022 return xInfo->getImplementationName();
1023 return OUString();
1024 }
1025
1026 // XServiceInfo
supportsService(const OUString & ServiceName)1027 sal_Bool OFactoryProxyHelper::supportsService(const OUString& ServiceName)
1028 throw(::com::sun::star::uno::RuntimeException)
1029 {
1030 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
1031 if( xInfo.is() )
1032 return xInfo->supportsService( ServiceName );
1033 return sal_False;
1034 }
1035
1036 // XServiceInfo
getSupportedServiceNames(void)1037 Sequence< OUString > OFactoryProxyHelper::getSupportedServiceNames(void)
1038 throw(::com::sun::star::uno::RuntimeException)
1039 {
1040 Reference<XServiceInfo > xInfo( xFactory, UNO_QUERY );
1041 if( xInfo.is() )
1042 return xInfo->getSupportedServiceNames();
1043 return Sequence< OUString >();
1044 }
1045
releaseOnNotification()1046 sal_Bool SAL_CALL OFactoryProxyHelper::releaseOnNotification() throw(::com::sun::star::uno::RuntimeException)
1047 {
1048
1049 Reference<XUnloadingPreference> pref( xFactory, UNO_QUERY);
1050 if( pref.is())
1051 return pref->releaseOnNotification();
1052 return sal_True;
1053 }
1054
1055
1056 //-----------------------------------------------------------------------------
1057 //-----------------------------------------------------------------------------
1058 //-----------------------------------------------------------------------------
1059 // global function
createSingleFactory(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName,ComponentInstantiation pCreateFunction,const Sequence<OUString> & rServiceNames,rtl_ModuleCount * pModCount)1060 Reference<XSingleServiceFactory > SAL_CALL createSingleFactory(
1061 const Reference<XMultiServiceFactory > & rServiceManager,
1062 const OUString & rImplementationName,
1063 ComponentInstantiation pCreateFunction,
1064 const Sequence< OUString > & rServiceNames,
1065 rtl_ModuleCount *pModCount )
1066 SAL_THROW( () )
1067 {
1068 return new OFactoryComponentHelper(
1069 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_False );
1070 }
1071
1072 // global function
createFactoryProxy(const Reference<XMultiServiceFactory> & rServiceManager,const Reference<XSingleServiceFactory> & rFactory)1073 Reference<XSingleServiceFactory > SAL_CALL createFactoryProxy(
1074 const Reference<XMultiServiceFactory > & rServiceManager,
1075 const Reference<XSingleServiceFactory > & rFactory )
1076 SAL_THROW( () )
1077 {
1078 return new OFactoryProxyHelper(
1079 rServiceManager, rFactory );
1080 }
1081
1082 // global function
createOneInstanceFactory(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName,ComponentInstantiation pCreateFunction,const Sequence<OUString> & rServiceNames,rtl_ModuleCount * pModCount)1083 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceFactory(
1084 const Reference<XMultiServiceFactory > & rServiceManager,
1085 const OUString & rImplementationName,
1086 ComponentInstantiation pCreateFunction,
1087 const Sequence< OUString > & rServiceNames,
1088 rtl_ModuleCount *pModCount )
1089 SAL_THROW( () )
1090 {
1091 return new OFactoryComponentHelper(
1092 rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True );
1093 // return new OFactoryUnloadableComponentHelper(
1094 // rServiceManager, rImplementationName, pCreateFunction, 0, &rServiceNames, pModCount, sal_True );
1095 }
1096
1097 // global function
createSingleRegistryFactory(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName,const Reference<XRegistryKey> & rImplementationKey)1098 Reference<XSingleServiceFactory > SAL_CALL createSingleRegistryFactory(
1099 const Reference<XMultiServiceFactory > & rServiceManager,
1100 const OUString & rImplementationName,
1101 const Reference<XRegistryKey > & rImplementationKey )
1102 SAL_THROW( () )
1103 {
1104 return new ORegistryFactoryHelper(
1105 rServiceManager, rImplementationName, rImplementationKey, sal_False );
1106 }
1107
1108 // global function
createOneInstanceRegistryFactory(const Reference<XMultiServiceFactory> & rServiceManager,const OUString & rImplementationName,const Reference<XRegistryKey> & rImplementationKey)1109 Reference<XSingleServiceFactory > SAL_CALL createOneInstanceRegistryFactory(
1110 const Reference<XMultiServiceFactory > & rServiceManager,
1111 const OUString & rImplementationName,
1112 const Reference<XRegistryKey > & rImplementationKey )
1113 SAL_THROW( () )
1114 {
1115 return new ORegistryFactoryHelper(
1116 rServiceManager, rImplementationName, rImplementationKey, sal_True );
1117 }
1118
1119 //##################################################################################################
createSingleComponentFactory(ComponentFactoryFunc fptr,OUString const & rImplementationName,Sequence<OUString> const & rServiceNames,rtl_ModuleCount * pModCount)1120 Reference< lang::XSingleComponentFactory > SAL_CALL createSingleComponentFactory(
1121 ComponentFactoryFunc fptr,
1122 OUString const & rImplementationName,
1123 Sequence< OUString > const & rServiceNames,
1124 rtl_ModuleCount * pModCount)
1125 SAL_THROW( () )
1126 {
1127 return new OFactoryComponentHelper(
1128 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_False );
1129 }
1130
createOneInstanceComponentFactory(ComponentFactoryFunc fptr,OUString const & rImplementationName,Sequence<OUString> const & rServiceNames,rtl_ModuleCount * pModCount)1131 Reference< lang::XSingleComponentFactory > SAL_CALL createOneInstanceComponentFactory(
1132 ComponentFactoryFunc fptr,
1133 OUString const & rImplementationName,
1134 Sequence< OUString > const & rServiceNames,
1135 rtl_ModuleCount * pModCount)
1136 SAL_THROW( () )
1137 {
1138 return new OFactoryComponentHelper(
1139 Reference< XMultiServiceFactory >(), rImplementationName, 0, fptr, &rServiceNames, pModCount, sal_True );
1140 }
1141
1142 }
1143
1144
1145