Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <osl/diagnose.h>
21 : : #include <osl/mutex.hxx>
22 : : #include "rtl/ustrbuf.hxx"
23 : : #include <cppuhelper/factory.hxx>
24 : : #include <cppuhelper/compbase5.hxx>
25 : : #include <cppuhelper/implbase1.hxx>
26 : : #include <cppuhelper/implementationentry.hxx>
27 : : #include "tdmgr_common.hxx"
28 : : #include "tdmgr_tdenumeration.hxx"
29 : : #include "lrucache.hxx"
30 : :
31 : : #include <com/sun/star/lang/XServiceInfo.hpp>
32 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
33 : : #include <com/sun/star/lang/XEventListener.hpp>
34 : : #include <com/sun/star/lang/XTypeProvider.hpp>
35 : : #include <com/sun/star/lang/XComponent.hpp>
36 : : #include <com/sun/star/lang/XInitialization.hpp>
37 : : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
38 : : #include <com/sun/star/container/XSet.hpp>
39 : : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
40 : : #include <com/sun/star/reflection/XTypeDescription.hpp>
41 : : #include <com/sun/star/reflection/XArrayTypeDescription.hpp>
42 : : #include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
43 : : #include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
44 : : #include "com/sun/star/reflection/XStructTypeDescription.hpp"
45 : : #include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
46 : : #include <com/sun/star/registry/XRegistryKey.hpp>
47 : : #include "com/sun/star/uno/RuntimeException.hpp"
48 : :
49 : : #include <algorithm>
50 : : #include <vector>
51 : :
52 : : using namespace std;
53 : : using namespace cppu;
54 : : using namespace osl;
55 : : using namespace com::sun::star;
56 : : using namespace com::sun::star::uno;
57 : : using namespace com::sun::star::lang;
58 : : using namespace com::sun::star::reflection;
59 : : using namespace com::sun::star::container;
60 : : using namespace com::sun::star::registry;
61 : :
62 : : using ::rtl::OUString;
63 : : using ::rtl::OUStringBuffer;
64 : :
65 : : static const sal_Int32 CACHE_SIZE = 512;
66 : :
67 : : #define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager"
68 : : #define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager"
69 : :
70 : : //--------------------------------------------------------------------------------------------------
71 : : // exported via tdmgr_common.hxx
72 : : extern rtl_StandardModuleCount g_moduleCount;
73 : :
74 : : namespace stoc_bootstrap
75 : : {
76 : 1113 : Sequence< OUString > SAL_CALL tdmgr_getSupportedServiceNames()
77 : : {
78 : 1113 : Sequence< OUString > seqNames(1);
79 [ + - ][ + - ]: 1113 : seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
80 : 1113 : return seqNames;
81 : : }
82 : :
83 : 10036 : OUString SAL_CALL tdmgr_getImplementationName()
84 : : {
85 : 10036 : return OUString(RTL_CONSTASCII_USTRINGPARAM(IMPLNAME));
86 : : }
87 : : }
88 : :
89 : : namespace stoc_tdmgr
90 : : {
91 : : typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector;
92 : :
93 : : class EnumerationImpl;
94 : : class ManagerImpl;
95 : :
96 : : //==================================================================================================
97 : : class EventListenerImpl : public ImplHelper1< XEventListener >
98 : : {
99 : : ManagerImpl * _pMgr;
100 : :
101 : : public:
102 : 756 : EventListenerImpl( ManagerImpl * pMgr )
103 : 756 : : _pMgr( pMgr )
104 : : {
105 [ + - ]: 756 : ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
106 : 756 : }
107 : : virtual ~EventListenerImpl();
108 : :
109 : : // lifetime delegated to manager
110 : : virtual void SAL_CALL acquire() throw();
111 : : virtual void SAL_CALL release() throw();
112 : :
113 : : // XEventListener
114 : : virtual void SAL_CALL disposing( const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
115 : : };
116 : :
117 : 138 : EventListenerImpl::~EventListenerImpl()
118 : : {
119 [ + - ]: 138 : ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
120 [ - + ]: 138 : }
121 : :
122 : : //==================================================================================================
123 : : class ManagerImpl
124 : : : public WeakComponentImplHelper5< XServiceInfo,
125 : : XSet,
126 : : XHierarchicalNameAccess,
127 : : XTypeDescriptionEnumerationAccess,
128 : : XInitialization >
129 : : {
130 : : friend class EnumerationImpl;
131 : : friend class EventListenerImpl;
132 : :
133 : : Mutex _aComponentMutex;
134 : : Reference< XComponentContext > _xContext;
135 : : EventListenerImpl _aEventListener;
136 : :
137 : : // elements
138 : : sal_Bool _bCaching;
139 : : LRU_CacheAnyByOUString _aElements;
140 : : // provider chain
141 : : ProviderVector _aProviders;
142 : :
143 : : inline Any getSimpleType( const OUString & rName );
144 : :
145 : : Reference< XTypeDescription > getInstantiatedStruct(OUString const & name);
146 : :
147 : : protected:
148 : : virtual void SAL_CALL disposing();
149 : :
150 : : public:
151 : : ManagerImpl( Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize );
152 : : virtual ~ManagerImpl();
153 : :
154 : : // XInitialization
155 : : virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
156 : :
157 : : // XServiceInfo
158 : : virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
159 : : virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
160 : : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
161 : :
162 : : // XElementAccess
163 : : virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
164 : : virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
165 : :
166 : : // XEnumerationAccess
167 : : virtual Reference< XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
168 : :
169 : : // XSet
170 : : virtual sal_Bool SAL_CALL has( const Any & rElement ) throw(::com::sun::star::uno::RuntimeException);
171 : : virtual void SAL_CALL insert( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
172 : : virtual void SAL_CALL remove( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
173 : :
174 : : // XHierarchicalNameAccess
175 : : virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
176 : : virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
177 : :
178 : : // XTypeDescriptionEnumerationAccess
179 : : virtual ::com::sun::star::uno::Reference<
180 : : ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
181 : : createTypeDescriptionEnumeration(
182 : : const ::rtl::OUString& moduleName,
183 : : const ::com::sun::star::uno::Sequence<
184 : : ::com::sun::star::uno::TypeClass >& types,
185 : : ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
186 : : throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
187 : : ::com::sun::star::reflection::InvalidTypeNameException,
188 : : ::com::sun::star::uno::RuntimeException );
189 : : };
190 : :
191 : : //==================================================================================================
192 : : class EnumerationImpl
193 : : : public WeakImplHelper1< XEnumeration >
194 : : {
195 : : ManagerImpl * _pMgr;
196 : : size_t _nPos;
197 : :
198 : : public:
199 : : EnumerationImpl( ManagerImpl * pManager );
200 : : virtual ~EnumerationImpl();
201 : :
202 : : // XEnumeration
203 : : virtual sal_Bool SAL_CALL hasMoreElements() throw(::com::sun::star::uno::RuntimeException);
204 : : virtual Any SAL_CALL nextElement() throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
205 : : };
206 : :
207 : : //##################################################################################################
208 : :
209 : : // lifetime delegated to manager
210 : : //__________________________________________________________________________________________________
211 : 2244 : void EventListenerImpl::acquire() throw()
212 : : {
213 : 2244 : _pMgr->acquire();
214 : 2244 : }
215 : : //__________________________________________________________________________________________________
216 : 1732 : void EventListenerImpl::release() throw()
217 : : {
218 : 1732 : _pMgr->release();
219 : 1732 : }
220 : :
221 : : // XEventListener
222 : : //__________________________________________________________________________________________________
223 : 244 : void EventListenerImpl::disposing( const EventObject & rEvt )
224 : : throw(::com::sun::star::uno::RuntimeException)
225 : : {
226 [ + - ]: 244 : _pMgr->remove( makeAny( rEvt.Source ) );
227 : 244 : }
228 : :
229 : : //##################################################################################################
230 : :
231 : : //__________________________________________________________________________________________________
232 : 0 : EnumerationImpl::EnumerationImpl( ManagerImpl * pManager )
233 : : : _pMgr( pManager )
234 : 0 : , _nPos( 0 )
235 : : {
236 : 0 : _pMgr->acquire();
237 : 0 : }
238 : : //__________________________________________________________________________________________________
239 : 0 : EnumerationImpl::~EnumerationImpl()
240 : : {
241 : 0 : _pMgr->release();
242 [ # # ]: 0 : }
243 : :
244 : : // XEnumeration
245 : : //__________________________________________________________________________________________________
246 : 0 : sal_Bool EnumerationImpl::hasMoreElements()
247 : : throw(::com::sun::star::uno::RuntimeException)
248 : : {
249 [ # # ]: 0 : MutexGuard aGuard( _pMgr->_aComponentMutex );
250 [ # # ]: 0 : return (_nPos < _pMgr->_aProviders.size());
251 : : }
252 : : //__________________________________________________________________________________________________
253 : 0 : Any EnumerationImpl::nextElement()
254 : : throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
255 : : {
256 [ # # ]: 0 : MutexGuard aGuard( _pMgr->_aComponentMutex );
257 [ # # ]: 0 : if (_nPos >= _pMgr->_aProviders.size())
258 : : {
259 : : throw NoSuchElementException(
260 : : OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ),
261 [ # # ][ # # ]: 0 : (XWeak *)(OWeakObject *)this );
[ # # ]
262 : : }
263 [ # # ][ # # ]: 0 : return makeAny( _pMgr->_aProviders[_nPos++] );
264 : : }
265 : :
266 : : //##################################################################################################
267 : :
268 : : //__________________________________________________________________________________________________
269 : 756 : ManagerImpl::ManagerImpl(
270 : : Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize )
271 : : : WeakComponentImplHelper5<
272 : : XServiceInfo, XSet, XHierarchicalNameAccess,
273 : : XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
274 : : , _xContext( xContext )
275 : : , _aEventListener( this )
276 : : , _bCaching( sal_True )
277 [ + - ][ + - ]: 756 : , _aElements( nCacheSize )
[ + - ][ + - ]
278 : : {
279 [ + - ]: 756 : ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
280 : 756 : }
281 : : //__________________________________________________________________________________________________
282 [ + - ][ + - ]: 138 : ManagerImpl::~ManagerImpl()
[ + - ]
283 : : {
284 : : OSL_ENSURE( _aProviders.empty(), "### still providers left!" );
285 : : OSL_TRACE( "> TypeDescriptionManager shut down. <" );
286 [ + - ]: 138 : ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
287 [ - + ]: 276 : }
288 : : //__________________________________________________________________________________________________
289 : 360 : void ManagerImpl::disposing()
290 : : {
291 : : // called on disposing the tdmgr instance (supposedly from context)
292 : 360 : _bCaching = sal_False;
293 : 360 : _aElements.clear();
294 : 360 : _xContext.clear();
295 : 360 : _aProviders.clear();
296 : 360 : }
297 : :
298 : : // XInitialization
299 : : //__________________________________________________________________________________________________
300 : 0 : void ManagerImpl::initialize(
301 : : const Sequence< Any > & args )
302 : : throw (Exception, RuntimeException)
303 : : {
304 : : // additional providers
305 : 0 : Any const * pProviders = args.getConstArray();
306 [ # # ]: 0 : for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
307 : : {
308 [ # # ]: 0 : Reference< XHierarchicalNameAccess > xHA( pProviders[ nPos ], UNO_QUERY );
309 : : OSL_ENSURE( xHA.is(), "### no td provider!" );
310 : :
311 [ # # ]: 0 : if (xHA.is())
312 : : {
313 : : try
314 : : {
315 [ # # ][ # # ]: 0 : insert( makeAny( xHA ) );
[ # # # ]
316 : : }
317 [ # # ]: 0 : catch (IllegalArgumentException &)
318 : : {
319 : : }
320 [ # # ]: 0 : catch (ElementExistException &)
321 : : {
322 : : }
323 : : }
324 : 0 : }
325 : 0 : }
326 : :
327 : : // XServiceInfo
328 : : //__________________________________________________________________________________________________
329 : 0 : OUString ManagerImpl::getImplementationName()
330 : : throw(::com::sun::star::uno::RuntimeException)
331 : : {
332 : 0 : return stoc_bootstrap::tdmgr_getImplementationName();
333 : : }
334 : : //__________________________________________________________________________________________________
335 : 0 : sal_Bool ManagerImpl::supportsService( const OUString & rServiceName )
336 : : throw(::com::sun::star::uno::RuntimeException)
337 : : {
338 : 0 : const Sequence< OUString > & rSNL = getSupportedServiceNames();
339 : 0 : const OUString * pArray = rSNL.getConstArray();
340 [ # # ]: 0 : for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
341 : : {
342 [ # # ]: 0 : if (pArray[nPos] == rServiceName)
343 : 0 : return sal_True;
344 : : }
345 : 0 : return sal_False;
346 : : }
347 : : //__________________________________________________________________________________________________
348 : 0 : Sequence< OUString > ManagerImpl::getSupportedServiceNames()
349 : : throw(::com::sun::star::uno::RuntimeException)
350 : : {
351 : 0 : return stoc_bootstrap::tdmgr_getSupportedServiceNames();
352 : : }
353 : :
354 : : // XElementAccess
355 : : //__________________________________________________________________________________________________
356 : 0 : Type ManagerImpl::getElementType()
357 : : throw(::com::sun::star::uno::RuntimeException)
358 : : {
359 : 0 : return ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 );
360 : : }
361 : : //__________________________________________________________________________________________________
362 : 0 : sal_Bool ManagerImpl::hasElements()
363 : : throw(::com::sun::star::uno::RuntimeException)
364 : : {
365 [ # # ]: 0 : MutexGuard aGuard( _aComponentMutex );
366 [ # # ]: 0 : return (!_aProviders.empty());
367 : : }
368 : :
369 : : // XEnumerationAccess
370 : : //__________________________________________________________________________________________________
371 : 0 : Reference< XEnumeration > ManagerImpl::createEnumeration()
372 : : throw(::com::sun::star::uno::RuntimeException)
373 : : {
374 [ # # ][ # # ]: 0 : return new EnumerationImpl( this );
375 : : }
376 : :
377 : : // XSet
378 : : //__________________________________________________________________________________________________
379 : 0 : sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement )
380 : : throw(::com::sun::star::uno::RuntimeException)
381 : : {
382 : 0 : Reference< XHierarchicalNameAccess > xElem;
383 [ # # ][ # # ]: 0 : if (rElement >>= xElem)
384 : : {
385 [ # # ]: 0 : MutexGuard aGuard( _aComponentMutex );
386 [ # # ][ # # ]: 0 : return (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end());
[ # # ]
387 : : }
388 : 0 : return sal_False;
389 : : }
390 : :
391 : : //__________________________________________________________________________________________________
392 : 756 : void SAL_CALL ManagerImpl::insert( const Any & rElement )
393 : : throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
394 : : {
395 : 756 : Reference< XHierarchicalNameAccess > xElem;
396 [ + - ][ - + ]: 756 : if (! (rElement >>= xElem) || !xElem.is())
[ - + ][ + - ]
397 : : {
398 : : throw IllegalArgumentException(
399 : : OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
400 [ # # ][ # # ]: 0 : (XWeak *)(OWeakObject *)this, 0 );
[ # # ]
401 : : }
402 : :
403 [ + - ]: 756 : MutexGuard aGuard( _aComponentMutex );
404 [ + - ][ + - ]: 756 : if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end())
[ - + ]
405 : : {
406 : : throw ElementExistException(
407 : : OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
408 [ # # ][ # # ]: 0 : (XWeak *)(OWeakObject *)this );
[ # # ]
409 : : }
410 : :
411 [ - + ]: 756 : if (! _aProviders.empty())
412 : : {
413 : : // check whether all types are compatible, if possible:
414 : : Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
415 [ # # ]: 0 : xElem, UNO_QUERY );
416 : : OSL_ENSURE( xTDEnumAccess.is(),
417 : : "### providers ought to implement "
418 : : "reflection::XTypeDescriptionEnumerationAccess!" );
419 [ # # ]: 0 : if (xTDEnumAccess.is())
420 : : {
421 : : try
422 : : {
423 : : TypeClass ar [] = {
424 : : TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
425 : : TypeClass_STRUCT, TypeClass_EXCEPTION,
426 : : /* TypeClass_UNION, TypeClass_ARRAY not supported */
427 : : TypeClass_INTERFACE,
428 : : TypeClass_SERVICE,
429 : : TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
430 : : TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
431 : : TypeClass_SINGLETON
432 : 0 : };
433 : : Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
434 [ # # ]: 0 : xTDEnumAccess->createTypeDescriptionEnumeration(
435 : : OUString() /* all modules */,
436 : : Sequence<TypeClass>( ar, ARLEN(ar) ),
437 [ # # ][ # # ]: 0 : reflection::TypeDescriptionSearchDepth_INFINITE ) );
[ # # ]
438 : :
439 [ # # ][ # # ]: 0 : while (xTDEnum->hasMoreElements())
[ # # ]
440 : : {
441 : 0 : Reference<reflection::XTypeDescription> xNewTD;
442 : : try
443 : : {
444 [ # # ][ # # ]: 0 : xNewTD = xTDEnum->nextTypeDescription();
[ # # ]
445 : : }
446 [ # # ]: 0 : catch (const container::NoSuchElementException & exc)
447 : : {
448 : : throw lang::IllegalArgumentException(
449 : : OUSTR("NoSuchElementException occurred: ") +
450 : : exc.Message, static_cast<OWeakObject *>(this),
451 [ # # # # : 0 : -1 /* unknown */ );
# # ]
452 : : }
453 : :
454 : : try
455 : : {
456 [ # # ][ # # ]: 0 : OUString newName( xNewTD->getName() );
457 : : Reference<reflection::XTypeDescription> xExistingTD(
458 [ # # ][ # # ]: 0 : getByHierarchicalName( newName ), UNO_QUERY );
459 : : OSL_ASSERT( xExistingTD.is() );
460 : : // existing, check whether compatible:
461 [ # # ]: 0 : if (xExistingTD.is())
462 : : {
463 : : try
464 : : {
465 [ # # ]: 0 : check( xNewTD, xExistingTD );
466 : : }
467 [ # # ]: 0 : catch (const IncompatibleTypeException & exc)
468 : : {
469 : : throw lang::IllegalArgumentException(
470 : : OUSTR("Rejecting types due to "
471 : : "incompatibility! ") + exc.m_cause,
472 [ # # # # : 0 : static_cast<OWeakObject *>(this), 0 );
# # ]
473 : : }
474 [ # # ]: 0 : }
475 : : }
476 [ # # ]: 0 : catch (container::NoSuchElementException &)
477 : : {
478 : : // type not in: ok
479 : : }
480 : 0 : }
481 : : }
482 : 0 : catch (const reflection::NoSuchTypeNameException & exc)
483 : : {
484 : : throw lang::IllegalArgumentException(
485 : : OUSTR("NoSuchTypeNameException occurred: ") + exc.Message,
486 [ # # # # : 0 : static_cast<OWeakObject *>(this), -1 /* unknown */ );
# # ]
487 : : }
488 [ # # # ]: 0 : catch (const reflection::InvalidTypeNameException & exc)
489 : : {
490 : : throw lang::IllegalArgumentException(
491 : : OUSTR("InvalidTypeNameException occurred: ") + exc.Message,
492 [ # # # # : 0 : static_cast<OWeakObject *>(this), -1 /* unknown */ );
# # ]
493 : : }
494 : 0 : }
495 : : }
496 : :
497 [ + - ]: 756 : _aProviders.push_back( xElem );
498 [ + - ]: 756 : Reference< XComponent > xComp( xElem, UNO_QUERY );
499 [ + - ]: 756 : if (xComp.is())
500 [ + - ][ + - ]: 756 : xComp->addEventListener( &_aEventListener );
[ + - ][ + - ]
501 : 756 : }
502 : : //__________________________________________________________________________________________________
503 : 244 : void SAL_CALL ManagerImpl::remove( const Any & rElement )
504 : : throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
505 : : {
506 [ + - ][ - + ]: 244 : if (!rBHelper.bDisposed && !rBHelper.bInDispose)
507 : : {
508 : 0 : Reference< XHierarchicalNameAccess > xElem;
509 [ # # ][ # # ]: 0 : if (! (rElement >>= xElem))
510 : : {
511 : : throw IllegalArgumentException(
512 : : OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ),
513 [ # # ][ # # ]: 0 : (XWeak *)(OWeakObject *)this, 0 );
[ # # ]
514 : : }
515 : :
516 [ # # ]: 0 : MutexGuard aGuard( _aComponentMutex );
517 [ # # ]: 0 : ProviderVector::iterator iFind( find( _aProviders.begin(), _aProviders.end(), xElem ) );
518 [ # # ][ # # ]: 0 : if (iFind == _aProviders.end())
519 : : {
520 : : throw NoSuchElementException(
521 : : OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ),
522 [ # # ][ # # ]: 0 : (XWeak *)(OWeakObject *)this );
[ # # ]
523 : : }
524 [ # # ][ # # ]: 0 : _aProviders.erase( iFind );
525 : : }
526 : :
527 : 244 : Reference< XComponent > xComp;
528 [ + - ][ + - ]: 244 : if (rElement >>= xComp)
529 [ + - ][ + - ]: 244 : xComp->removeEventListener( &_aEventListener );
[ + - ]
530 : 244 : }
531 : :
532 : : // XTypeDescriptionEnumerationAccess
533 : : //__________________________________________________________________________________________________
534 : : // virtual
535 : : Reference< XTypeDescriptionEnumeration > SAL_CALL
536 : 7 : ManagerImpl::createTypeDescriptionEnumeration(
537 : : const OUString & moduleName,
538 : : const Sequence< TypeClass > & types,
539 : : TypeDescriptionSearchDepth depth )
540 : : throw ( NoSuchTypeNameException,
541 : : InvalidTypeNameException,
542 : : RuntimeException )
543 : : {
544 [ + - ]: 7 : MutexGuard aGuard( _aComponentMutex );
545 : :
546 [ + - ][ + - ]: 7 : TDEnumerationAccessStack aStack;
547 [ + - ]: 7 : ProviderVector::const_iterator it = _aProviders.begin();
548 [ + - ]: 7 : const ProviderVector::const_iterator end = _aProviders.end();
549 [ + - ][ + + ]: 14 : while ( it != end )
550 : : {
551 : : Reference< XTypeDescriptionEnumerationAccess >xEnumAccess(
552 [ + - ]: 7 : (*it), UNO_QUERY );
553 : : OSL_ENSURE( xEnumAccess.is(),
554 : : "### no XTypeDescriptionEnumerationAccess!" );
555 [ + - ]: 7 : if ( xEnumAccess.is() )
556 [ + - ]: 7 : aStack.push( xEnumAccess );
557 : :
558 : 7 : ++it;
559 : 7 : }
560 : :
561 : : return Reference< XTypeDescriptionEnumeration >(
562 : : new TypeDescriptionEnumerationImpl( moduleName,
563 : : types,
564 : : depth,
565 [ + - ][ + - ]: 7 : aStack ) );
[ + - ][ + - ]
566 : : }
567 : :
568 : :
569 : : //##################################################################################################
570 : : //##################################################################################################
571 : : //##################################################################################################
572 : :
573 : :
574 : : //==================================================================================================
575 [ - + ]: 5014 : class SimpleTypeDescriptionImpl
576 : : : public WeakImplHelper1< XTypeDescription >
577 : : {
578 : : TypeClass _eTC;
579 : : OUString _aName;
580 : :
581 : : public:
582 : 2910 : SimpleTypeDescriptionImpl( TypeClass eTC, const OUString & rName )
583 : : : _eTC( eTC )
584 : 2910 : , _aName( rName )
585 : 2910 : {}
586 : :
587 : : // XTypeDescription
588 : : virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
589 : : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
590 : : };
591 : :
592 : : // XTypeDescription
593 : : //__________________________________________________________________________________________________
594 : 92638 : TypeClass SimpleTypeDescriptionImpl::getTypeClass()
595 : : throw(::com::sun::star::uno::RuntimeException)
596 : : {
597 : 92638 : return _eTC;
598 : : }
599 : : //__________________________________________________________________________________________________
600 : 125985 : OUString SimpleTypeDescriptionImpl::getName()
601 : : throw(::com::sun::star::uno::RuntimeException)
602 : : {
603 : 125985 : return _aName;
604 : : }
605 : :
606 : : //==================================================================================================
607 [ - + ]: 5300 : class SequenceTypeDescriptionImpl
608 : : : public WeakImplHelper1< XIndirectTypeDescription >
609 : : {
610 : : Reference< XTypeDescription > _xElementTD;
611 : :
612 : : public:
613 : 2871 : SequenceTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD )
614 : 2871 : : _xElementTD( xElementTD )
615 : 2871 : {}
616 : :
617 : : // XTypeDescription
618 : : virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
619 : : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
620 : :
621 : : // XIndirectTypeDescription
622 : : virtual Reference< XTypeDescription > SAL_CALL getReferencedType() throw(::com::sun::star::uno::RuntimeException);
623 : : };
624 : :
625 : : // XTypeDescription
626 : : //__________________________________________________________________________________________________
627 : 9179 : TypeClass SequenceTypeDescriptionImpl::getTypeClass()
628 : : throw(::com::sun::star::uno::RuntimeException)
629 : : {
630 : 9179 : return TypeClass_SEQUENCE;
631 : : }
632 : : //__________________________________________________________________________________________________
633 : 9028 : OUString SequenceTypeDescriptionImpl::getName()
634 : : throw(::com::sun::star::uno::RuntimeException)
635 : : {
636 [ + - ]: 9028 : return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD->getName());
637 : : }
638 : :
639 : : // XIndirectTypeDescription
640 : : //__________________________________________________________________________________________________
641 : 316 : Reference< XTypeDescription > SequenceTypeDescriptionImpl::getReferencedType()
642 : : throw(::com::sun::star::uno::RuntimeException)
643 : : {
644 : 316 : return _xElementTD;
645 : : }
646 : :
647 : : //==================================================================================================
648 : : class ArrayTypeDescriptionImpl
649 : : : public WeakImplHelper1< XArrayTypeDescription >
650 : : {
651 : : Reference< XTypeDescription > _xElementTD;
652 : : Mutex _aDimensionMutex;
653 : : sal_Int32 _nDimensions;
654 : : Sequence< sal_Int32 > _seqDimensions;
655 : : OUString _sDimensions;
656 : :
657 : : void initDimensions(const OUString& rSDimensions);
658 : : public:
659 : 0 : ArrayTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD,
660 : : sal_Int32 nDimensions, const OUString& rSDimensions )
661 : : : _xElementTD( xElementTD )
662 : : , _nDimensions( nDimensions )
663 : : , _seqDimensions( Sequence< sal_Int32 >(nDimensions) )
664 [ # # ][ # # ]: 0 : , _sDimensions( rSDimensions )
665 : : {
666 [ # # ]: 0 : initDimensions( rSDimensions );
667 : 0 : }
668 [ # # ][ # # ]: 0 : virtual ~ArrayTypeDescriptionImpl() {}
[ # # ]
669 : :
670 : : // XTypeDescription
671 : : virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
672 : : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
673 : :
674 : : // XArrayTypeDescription
675 : : virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
676 : : virtual sal_Int32 SAL_CALL getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException);
677 : : virtual Sequence< sal_Int32 > SAL_CALL getDimensions() throw(::com::sun::star::uno::RuntimeException);
678 : : };
679 : : //__________________________________________________________________________________________________
680 : 0 : static sal_Int32 unicodeToInteger( sal_Int8 base, const sal_Unicode *s )
681 : : {
682 : 0 : sal_Int32 r = 0;
683 : 0 : sal_Int32 negative = 0;
684 : :
685 [ # # ]: 0 : if (*s == '-')
686 : : {
687 : 0 : negative = 1;
688 : 0 : s++;
689 : : }
690 [ # # ][ # # ]: 0 : if (base == 8 && *s == '0')
691 : 0 : s++;
692 [ # # ][ # # ]: 0 : else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
[ # # ][ # # ]
693 : 0 : s += 2;
694 : :
695 [ # # ]: 0 : for (; *s; s++)
696 : : {
697 [ # # ][ # # ]: 0 : if (*s <= '9' && *s >= '0')
698 : 0 : r = (r * base) + (*s - '0');
699 [ # # ][ # # ]: 0 : else if (base > 10 && *s <= 'f' && *s >= 'a')
[ # # ]
700 : 0 : r = (r * base) + (*s - 'a' + 10);
701 [ # # ][ # # ]: 0 : else if (base > 10 && *s <= 'F' && *s >= 'A')
[ # # ]
702 : 0 : r = (r * base) + (*s - 'A' + 10);
703 : : else
704 : 0 : break;
705 : : }
706 [ # # ]: 0 : if (negative) r *= -1;
707 : 0 : return r;
708 : : }
709 : : //__________________________________________________________________________________________________
710 : 0 : void ArrayTypeDescriptionImpl::initDimensions(const OUString& rSDimensions)
711 : : {
712 [ # # ]: 0 : MutexGuard aGuard( _aDimensionMutex );
713 : :
714 [ # # ]: 0 : sal_Int32 * pDimensions = _seqDimensions.getArray();
715 : 0 : OUString tmp(rSDimensions);
716 : 0 : sal_Unicode* p = (sal_Unicode*)tmp.getStr()+1;
717 : 0 : sal_Unicode* pOffset = p;
718 : 0 : sal_Int32 len = tmp.getLength() - 1 ;
719 : 0 : sal_Int32 i = 0;
720 : :
721 [ # # ]: 0 : while ( len > 0)
722 : : {
723 : 0 : pOffset++;
724 [ # # ]: 0 : if (*pOffset == ']')
725 : : {
726 : 0 : *pOffset = '\0';
727 : 0 : pOffset += 2;
728 : 0 : len -= 3;
729 : 0 : pDimensions[i++] = unicodeToInteger(10, p);
730 : 0 : p = pOffset;
731 : : } else
732 : 0 : len--;
733 [ # # ]: 0 : }
734 : 0 : }
735 : :
736 : : // XTypeDescription
737 : : //__________________________________________________________________________________________________
738 : 0 : TypeClass ArrayTypeDescriptionImpl::getTypeClass()
739 : : throw(::com::sun::star::uno::RuntimeException)
740 : : {
741 : 0 : return TypeClass_ARRAY;
742 : : }
743 : : //__________________________________________________________________________________________________
744 : 0 : OUString ArrayTypeDescriptionImpl::getName()
745 : : throw(::com::sun::star::uno::RuntimeException)
746 : : {
747 : 0 : return (_xElementTD->getName() + _sDimensions);
748 : : }
749 : :
750 : : // XArrayTypeDescription
751 : : //__________________________________________________________________________________________________
752 : 0 : Reference< XTypeDescription > ArrayTypeDescriptionImpl::getType()
753 : : throw(::com::sun::star::uno::RuntimeException)
754 : : {
755 : 0 : return _xElementTD;
756 : : }
757 : :
758 : : //__________________________________________________________________________________________________
759 : 0 : sal_Int32 ArrayTypeDescriptionImpl::getNumberOfDimensions()
760 : : throw(::com::sun::star::uno::RuntimeException)
761 : : {
762 : 0 : return _nDimensions;
763 : : }
764 : :
765 : : //__________________________________________________________________________________________________
766 : 0 : Sequence< sal_Int32 > ArrayTypeDescriptionImpl::getDimensions()
767 : : throw(::com::sun::star::uno::RuntimeException)
768 : : {
769 : 0 : return _seqDimensions;
770 : : }
771 : :
772 : : //##################################################################################################
773 : : //##################################################################################################
774 : : //##################################################################################################
775 : :
776 : :
777 : : //__________________________________________________________________________________________________
778 : 3005 : inline Any ManagerImpl::getSimpleType( const OUString & rName )
779 : : {
780 : 3005 : Any aRet;
781 : :
782 [ + + ]: 3005 : if ( rName == "string" )
783 [ + - ][ + - ]: 331 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) );
[ + - ][ + - ]
784 [ + + ]: 2674 : else if ( rName == "long" )
785 [ + - ][ + - ]: 286 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) );
[ + - ][ + - ]
786 [ + + ]: 2388 : else if ( rName == "unsigned long" )
787 [ + - ][ + - ]: 64 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) );
[ + - ][ + - ]
788 [ + + ]: 2324 : else if ( rName == "boolean" )
789 [ + - ][ + - ]: 281 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) );
[ + - ][ + - ]
790 [ + + ]: 2043 : else if ( rName == "char" )
791 [ + - ][ + - ]: 62 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) );
[ + - ][ + - ]
792 [ + + ]: 1981 : else if ( rName == "byte" )
793 [ + - ][ + - ]: 157 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) );
[ + - ][ + - ]
794 [ + + ]: 1824 : else if ( rName == "short" )
795 [ + - ][ + - ]: 258 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) );
[ + - ][ + - ]
796 [ + + ]: 1566 : else if ( rName == "unsigned short" )
797 [ + - ][ + - ]: 271 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) );
[ + - ][ + - ]
798 [ + + ]: 1295 : else if ( rName == "hyper" )
799 [ + - ][ + - ]: 154 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) );
[ + - ][ + - ]
800 [ + + ]: 1141 : else if ( rName == "unsigned hyper" )
801 [ + - ][ + - ]: 5 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) );
[ + - ][ + - ]
802 [ + + ]: 1136 : else if ( rName == "float" )
803 [ + - ][ + - ]: 112 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) );
[ + - ][ + - ]
804 [ + + ]: 1024 : else if ( rName == "double" )
805 [ + - ][ + - ]: 76 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) );
[ + - ][ + - ]
806 [ + + ]: 948 : else if ( rName == "any" )
807 [ + - ][ + - ]: 331 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) );
[ + - ][ + - ]
808 [ + + ]: 617 : else if ( rName == "void" )
809 [ + - ][ + - ]: 239 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) );
[ + - ][ + - ]
810 [ + + ]: 378 : else if ( rName == "type" )
811 [ + - ][ + - ]: 283 : aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) );
[ + - ][ + - ]
812 : :
813 : 3005 : return aRet;
814 : : }
815 : :
816 : : namespace {
817 : :
818 : 500 : Reference< XTypeDescription > resolveTypedefs(
819 : : Reference< XTypeDescription > const & type)
820 : : {
821 : 500 : Reference< XTypeDescription > resolved(type);
822 [ + - ][ + - ]: 500 : while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
[ - + ]
823 : : resolved = Reference< XIndirectTypeDescription >(
824 [ # # ][ # # ]: 0 : type, UNO_QUERY_THROW)->getReferencedType();
[ # # ][ # # ]
825 : : }
826 : 500 : return resolved;
827 : : }
828 : :
829 : 500 : bool isNonVoidNonExceptionType(Reference< XTypeDescription > const & type) {
830 [ + - ]: 500 : switch (type->getTypeClass()) {
831 : : case TypeClass_BOOLEAN:
832 : : case TypeClass_BYTE:
833 : : case TypeClass_SHORT:
834 : : case TypeClass_UNSIGNED_SHORT:
835 : : case TypeClass_LONG:
836 : : case TypeClass_UNSIGNED_LONG:
837 : : case TypeClass_HYPER:
838 : : case TypeClass_UNSIGNED_HYPER:
839 : : case TypeClass_FLOAT:
840 : : case TypeClass_DOUBLE:
841 : : case TypeClass_CHAR:
842 : : case TypeClass_STRING:
843 : : case TypeClass_TYPE:
844 : : case TypeClass_ANY:
845 : : case TypeClass_SEQUENCE:
846 : : case TypeClass_ENUM:
847 : : case TypeClass_STRUCT:
848 : : case TypeClass_INTERFACE:
849 : 500 : return true;
850 : :
851 : : default:
852 : 500 : return false;
853 : : }
854 : : }
855 : :
856 [ + - ][ - + ]: 734 : class InstantiatedStruct: public WeakImplHelper1< XStructTypeDescription > {
857 : : public:
858 : : InstantiatedStruct(
859 : : Reference< XStructTypeDescription > const & structType,
860 : : std::vector< Reference< XTypeDescription > > const & arguments);
861 : :
862 : 629 : virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException)
863 : 629 : { return TypeClass_STRUCT; }
864 : :
865 : : virtual OUString SAL_CALL getName() throw (RuntimeException);
866 : :
867 : 421 : virtual Reference< XTypeDescription > SAL_CALL getBaseType()
868 : : throw (RuntimeException)
869 : 421 : { return m_struct->getBaseType(); }
870 : :
871 : : virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes()
872 : : throw (RuntimeException);
873 : :
874 : 421 : virtual Sequence< OUString > SAL_CALL getMemberNames()
875 : : throw (RuntimeException)
876 : 421 : { return m_struct->getMemberNames(); }
877 : :
878 : 421 : virtual Sequence< OUString > SAL_CALL getTypeParameters()
879 : : throw (RuntimeException)
880 : 421 : { return Sequence< OUString >(); }
881 : :
882 : : virtual Sequence< Reference< XTypeDescription > > SAL_CALL
883 : 0 : getTypeArguments() throw (RuntimeException)
884 : 0 : { return m_arguments; }
885 : :
886 : : private:
887 : : Reference< XStructTypeDescription > m_struct;
888 : : Sequence< Reference< XTypeDescription > > m_arguments;
889 : : };
890 : :
891 : 423 : InstantiatedStruct::InstantiatedStruct(
892 : : Reference< XStructTypeDescription > const & structType,
893 : : std::vector< Reference< XTypeDescription > > const & arguments):
894 : : m_struct(structType),
895 [ + - ]: 423 : m_arguments(static_cast< sal_Int32 >(arguments.size()))
896 : : {
897 [ + + ]: 1846 : for (std::vector< Reference< XTypeDescription > >::size_type i = 0;
898 : 923 : i < arguments.size(); ++i)
899 : : {
900 [ + - ][ + - ]: 500 : m_arguments[static_cast< sal_Int32 >(i)] = arguments[i];
901 : : }
902 : 423 : }
903 : :
904 : 637 : OUString InstantiatedStruct::getName() throw (RuntimeException) {
905 [ + - ][ + - ]: 637 : OUStringBuffer buf(m_struct->getName());
[ + - ]
906 [ + - ]: 637 : buf.append(static_cast< sal_Unicode >('<'));
907 [ + + ]: 1441 : for (sal_Int32 i = 0; i < m_arguments.getLength(); ++i) {
908 [ + + ]: 804 : if (i != 0) {
909 [ + - ]: 167 : buf.append(static_cast< sal_Unicode >(','));
910 : : }
911 [ + - ][ + - ]: 804 : buf.append(m_arguments[i]->getName());
[ + - ][ + - ]
912 : : }
913 [ + - ]: 637 : buf.append(static_cast< sal_Unicode >('>'));
914 [ + - ]: 637 : return buf.makeStringAndClear();
915 : : }
916 : :
917 : 421 : Sequence< Reference< XTypeDescription > > InstantiatedStruct::getMemberTypes()
918 : : throw (RuntimeException)
919 : : {
920 : 421 : Sequence< Reference< XTypeDescription > > types(m_struct->getMemberTypes());
921 [ + + ]: 1083 : for (sal_Int32 i = 0; i < types.getLength(); ++i) {
922 [ + - ][ + - ]: 662 : if (types[i]->getTypeClass() == TypeClass_UNKNOWN) {
[ + - ][ + + ]
923 [ + - ][ + - ]: 500 : Sequence< OUString > parameters(m_struct->getTypeParameters());
924 : : OSL_ASSERT(parameters.getLength() == m_arguments.getLength());
925 [ + - ]: 579 : for (sal_Int32 j = 0; j < parameters.getLength(); ++j) {
926 [ + - ][ + - ]: 579 : if (parameters[j] == types[i]->getName()) {
[ + - ][ + - ]
[ + + ]
927 [ + - ][ + - ]: 500 : types[i] = m_arguments[j];
[ + - ]
928 : 500 : break;
929 : : }
930 [ + - ]: 500 : }
931 : : }
932 : : }
933 : 421 : return types;
934 : : }
935 : :
936 : : }
937 : :
938 : 423 : Reference< XTypeDescription > ManagerImpl::getInstantiatedStruct(
939 : : OUString const & name)
940 : : {
941 : 423 : sal_Int32 i = name.indexOf('<');
942 : : OSL_ASSERT(i >= 0);
943 : : Reference< XStructTypeDescription > structType(
944 [ + - ][ + - ]: 423 : getByHierarchicalName(name.copy(0, i)), UNO_QUERY);
945 [ + - ]: 423 : std::vector< Reference< XTypeDescription > > args;
946 : 423 : bool good = structType.is();
947 [ + - ]: 423 : if (good) {
948 [ + + ]: 1000 : do {
[ + - + + ]
949 : 500 : ++i; // skip '<' or ','
950 : 500 : sal_Int32 j = i;
951 [ + - ]: 7185 : for (sal_Int32 level = 0; j != name.getLength(); ++j) {
952 : 7185 : sal_Unicode c = name[j];
953 [ + + ]: 7185 : if (c == ',') {
954 [ + + ]: 117 : if (level == 0) {
955 : 77 : break;
956 : : }
957 [ + + ]: 7068 : } else if (c == '<') {
958 : 67 : ++level;
959 [ + + ]: 7001 : } else if (c == '>') {
960 [ + + ]: 490 : if (level == 0) {
961 : 423 : break;
962 : : }
963 : 67 : --level;
964 : : }
965 : : }
966 [ + - ]: 500 : if (j != name.getLength()) {
967 : : Reference< XTypeDescription > type(
968 [ + - ][ + - ]: 500 : getByHierarchicalName(name.copy(i, j - i)), UNO_QUERY);
969 [ + - ][ + - ]: 500 : if (isNonVoidNonExceptionType(resolveTypedefs(type))) {
[ + - ]
970 [ + - ]: 500 : args.push_back(type);
971 : : } else {
972 : 500 : good = false;
973 : : break;
974 [ + - ]: 500 : }
975 : : }
976 : 500 : i = j;
977 : 1000 : } while (i != name.getLength() && name[i] != '>');
978 : 423 : good = good && i == name.getLength() - 1
979 [ + - + - ]: 846 : && name[i] == '>' && !args.empty();
[ + - ][ + - ]
980 : : }
981 : : // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at
982 : : // least one position within an rtl::OUString (which is no longer than
983 : : // SAL_MAX_INT32):
984 [ + - - + ]: 1269 : if (!good
[ - + ]
985 : 423 : || (args.size()
986 : : != sal::static_int_cast< sal_uInt32 >(
987 [ + - ][ + - ]: 846 : structType->getTypeParameters().getLength())))
[ + - ][ # # ]
[ + - ]
988 : : {
989 [ # # ][ # # ]: 0 : throw NoSuchElementException(name, static_cast< OWeakObject * >(this));
990 : : }
991 [ + - ][ + - ]: 423 : return new InstantiatedStruct(structType, args);
[ + - ]
992 : : }
993 : :
994 : : // XHierarchicalNameAccess
995 : : //__________________________________________________________________________________________________
996 : 291407 : Any ManagerImpl::getByHierarchicalName( const OUString & rName )
997 : : throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
998 : : {
999 : 291407 : Any aRet;
1000 [ + - ]: 291407 : if (_bCaching)
1001 [ + - ]: 291407 : aRet = _aElements.getValue( rName );
1002 [ + - ][ + + ]: 291407 : if (!rName.isEmpty() && !aRet.hasValue())
[ + + ]
1003 : : {
1004 : : sal_Int32 nIndex;
1005 [ + + ]: 106816 : if (rName[0] == '[') // test for sequence
1006 : : {
1007 : : Reference< XTypeDescription > xElemType(
1008 : 2871 : getByHierarchicalName( rName.copy( 2 ) ),
1009 [ + - ][ + - ]: 2871 : UNO_QUERY_THROW );
1010 : : aRet <<= Reference< XTypeDescription >(
1011 [ + - ][ + - ]: 2871 : new SequenceTypeDescriptionImpl( xElemType ) );
[ + - ][ + - ]
1012 : : }
1013 [ - + ]: 103945 : else if (rName[rName.getLength()-1] == ']') // test for array
1014 : : {
1015 : 0 : sal_Int32 nIndex2 = 0, nTokens = 0;
1016 [ # # ]: 0 : do { rName.getToken( 0, '[', nIndex2 ); nTokens++; } while( nIndex2 != -1 );
1017 : 0 : sal_Int32 nDims = nTokens - 1;
1018 : 0 : sal_Int32 dimOffset = rName.indexOf('[');
1019 : : Reference< XTypeDescription > xElemType(
1020 : 0 : getByHierarchicalName( rName.copy( 0, dimOffset ) ),
1021 [ # # ][ # # ]: 0 : UNO_QUERY_THROW );
1022 : : aRet <<= Reference< XTypeDescription >(
1023 : : new ArrayTypeDescriptionImpl(
1024 [ # # ][ # # ]: 0 : xElemType, nDims, rName.copy(dimOffset) ) );
[ # # ][ # # ]
1025 : : }
1026 : : // test for interface member names:
1027 [ + + ]: 103945 : else if ((nIndex = rName.indexOf( ':' )) >= 0)
1028 : : {
1029 : : Reference< XInterfaceTypeDescription > xIfaceTD(
1030 : 34822 : getByHierarchicalName( rName.copy( 0, nIndex ) ),
1031 [ + - ][ + - ]: 34822 : UNO_QUERY_THROW );
1032 : : const Sequence< Reference< XInterfaceMemberTypeDescription > > &
1033 [ + - ][ + - ]: 34822 : rMembers = xIfaceTD->getMembers();
1034 : : const Reference< XInterfaceMemberTypeDescription > * pMembers =
1035 : 34822 : rMembers.getConstArray();
1036 : :
1037 [ + - ]: 176974 : for ( sal_Int32 nPos = rMembers.getLength(); nPos--; )
1038 : : {
1039 [ + - ][ + - ]: 176974 : if (rName == pMembers[nPos]->getName())
[ + + ]
1040 : : {
1041 : : aRet <<= Reference< XTypeDescription >(
1042 [ + - ][ + - ]: 34822 : pMembers[nPos], UNO_QUERY_THROW );
1043 : 34822 : break;
1044 : : }
1045 : : }
1046 [ - + ]: 34822 : if (! aRet.hasValue())
1047 : : {
1048 : : // member not found:
1049 : : throw NoSuchElementException(
1050 [ # # ][ # # ]: 0 : rName, static_cast< OWeakObject * >(this) );
1051 [ + - ]: 34822 : }
1052 : : }
1053 : : // test for instantiated polymorphic struct types:
1054 [ + + ]: 69123 : else if (rName.indexOf('<') >= 0)
1055 : : {
1056 [ + - ][ + - ]: 423 : aRet <<= getInstantiatedStruct(rName);
1057 : : }
1058 [ + + ]: 68700 : else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types
1059 : : {
1060 [ + - ]: 3005 : aRet = getSimpleType( rName );
1061 : : }
1062 : :
1063 [ + + ]: 106816 : if (! aRet.hasValue())
1064 : : {
1065 : : // last, try callback chain
1066 [ + - ][ + - ]: 197556 : for ( ProviderVector::const_iterator iPos( _aProviders.begin() );
[ + + ][ - + ]
1067 : 65883 : iPos != _aProviders.end(); ++iPos )
1068 : : {
1069 : : try
1070 : : {
1071 [ + - + - ]: 131487 : if ((aRet = (*iPos)->getByHierarchicalName(
1072 [ + + ]: 65790 : rName )).hasValue())
1073 : : {
1074 : 65697 : break;
1075 : : }
1076 : : }
1077 [ + - ]: 93 : catch (NoSuchElementException &)
1078 : : {
1079 : : }
1080 : : }
1081 : : }
1082 : :
1083 : : // update cache
1084 [ + - ][ + + ]: 106816 : if (_bCaching && aRet.hasValue())
[ + + ]
1085 [ + - ]: 106723 : _aElements.setValue( rName, aRet );
1086 : : }
1087 : :
1088 [ + + ]: 291407 : if (! aRet.hasValue())
1089 : : {
1090 : : throw NoSuchElementException(
1091 [ + - ][ + - ]: 93 : rName, static_cast< OWeakObject * >(this) );
1092 : : }
1093 : 291407 : return aRet;
1094 : : }
1095 : : //__________________________________________________________________________________________________
1096 : 103 : sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName )
1097 : : throw(::com::sun::star::uno::RuntimeException)
1098 : : {
1099 : : try
1100 : : {
1101 [ + + ][ - + ]: 196 : return getByHierarchicalName( rName ).hasValue();
1102 : : }
1103 : 93 : catch (NoSuchElementException &)
1104 : : {
1105 : : }
1106 : 93 : return sal_False;
1107 : : }
1108 : : }
1109 : :
1110 : : namespace stoc_bootstrap
1111 : : {
1112 : : //==================================================================================================
1113 : 756 : Reference< XInterface > SAL_CALL ManagerImpl_create(
1114 : : Reference< XComponentContext > const & xContext )
1115 : : SAL_THROW( (::com::sun::star::uno::Exception) )
1116 : : {
1117 : 756 : sal_Int32 nCacheSize = CACHE_SIZE;
1118 [ + - ]: 756 : if (xContext.is()) {
1119 [ + - ]: 756 : xContext->getValueByName(
1120 : : OUString(
1121 : : RTL_CONSTASCII_USTRINGPARAM(
1122 : 756 : "/implementations/" IMPLNAME "/CacheSize"))) >>=
1123 [ + - ][ + - ]: 756 : nCacheSize;
1124 : : }
1125 : :
1126 [ + - ][ + - ]: 756 : return Reference< XInterface >( *new stoc_tdmgr::ManagerImpl( xContext, nCacheSize ) );
1127 : : }
1128 : :
1129 : : }
1130 : :
1131 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|