1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "comphelper_module.hxx"
22 #include "comphelper/anytostring.hxx"
23 #include "comphelper/anycompare.hxx"
24 #include "comphelper/componentbase.hxx"
25 #include "comphelper/extract.hxx"
27 #include <com/sun/star/container/XEnumerableMap.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
30 #include <com/sun/star/beans/Pair.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <cppuhelper/compbase3.hxx>
34 #include <cppuhelper/implbase1.hxx>
35 #include <rtl/math.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <typelib/typedescription.hxx>
40 #include <boost/shared_ptr.hpp>
42 //........................................................................
45 //........................................................................
47 using ::com::sun::star::uno::Reference
;
48 using ::com::sun::star::uno::XInterface
;
49 using ::com::sun::star::uno::UNO_QUERY
;
50 using ::com::sun::star::uno::UNO_QUERY_THROW
;
51 using ::com::sun::star::uno::UNO_SET_THROW
;
52 using ::com::sun::star::uno::Exception
;
53 using ::com::sun::star::uno::RuntimeException
;
54 using ::com::sun::star::uno::Any
;
55 using ::com::sun::star::uno::makeAny
;
56 using ::com::sun::star::uno::Sequence
;
57 using ::com::sun::star::uno::Type
;
58 using ::com::sun::star::container::XEnumerableMap
;
59 using ::com::sun::star::lang::NoSupportException
;
60 using ::com::sun::star::beans::IllegalTypeException
;
61 using ::com::sun::star::container::NoSuchElementException
;
62 using ::com::sun::star::lang::IllegalArgumentException
;
63 using ::com::sun::star::lang::XInitialization
;
64 using ::com::sun::star::ucb::AlreadyInitializedException
;
65 using ::com::sun::star::beans::Pair
;
66 using ::com::sun::star::uno::TypeClass
;
67 using ::com::sun::star::uno::TypeClass_VOID
;
68 using ::com::sun::star::uno::TypeClass_UNKNOWN
;
69 using ::com::sun::star::uno::TypeClass_ANY
;
70 using ::com::sun::star::uno::TypeClass_EXCEPTION
;
71 using ::com::sun::star::uno::TypeClass_STRUCT
;
72 using ::com::sun::star::uno::TypeClass_UNION
;
73 using ::com::sun::star::uno::TypeClass_FLOAT
;
74 using ::com::sun::star::uno::TypeClass_DOUBLE
;
75 using ::com::sun::star::uno::TypeClass_INTERFACE
;
76 using ::com::sun::star::lang::XServiceInfo
;
77 using ::com::sun::star::uno::XComponentContext
;
78 using ::com::sun::star::container::XEnumeration
;
79 using ::com::sun::star::uno::TypeDescription
;
80 using ::com::sun::star::lang::WrappedTargetException
;
81 using ::com::sun::star::lang::DisposedException
;
83 //====================================================================
85 //====================================================================
86 class IMapModificationListener
;
87 typedef ::std::vector
< IMapModificationListener
* > MapListeners
;
89 typedef ::std::map
< Any
, Any
, LessPredicateAdapter
> KeyedValues
;
94 ::std::auto_ptr
< KeyedValues
> m_pValues
;
95 ::boost::shared_ptr
< IKeyPredicateLess
> m_pKeyCompare
;
97 MapListeners m_aModListeners
;
104 MapData( const MapData
& _source
)
105 :m_aKeyType( _source
.m_aKeyType
)
106 ,m_aValueType( _source
.m_aValueType
)
107 ,m_pValues( new KeyedValues( *_source
.m_pValues
) )
108 ,m_pKeyCompare( _source
.m_pKeyCompare
)
114 MapData
& operator=( const MapData
& _source
); // not implemented
117 //====================================================================
118 //= IMapModificationListener
119 //====================================================================
120 /** implemented by components who want to be notified of modifications in the MapData they work with
122 class SAL_NO_VTABLE IMapModificationListener
125 /// called when the map was modified
126 virtual void mapModified() = 0;
127 virtual ~IMapModificationListener()
132 //====================================================================
134 //====================================================================
135 //--------------------------------------------------------------------
136 static void lcl_registerMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
138 #if OSL_DEBUG_LEVEL > 0
139 for ( MapListeners::const_iterator lookup
= _mapData
.m_aModListeners
.begin();
140 lookup
!= _mapData
.m_aModListeners
.end();
144 OSL_ENSURE( *lookup
!= &_listener
, "lcl_registerMapModificationListener: this listener is already registered!" );
147 _mapData
.m_aModListeners
.push_back( &_listener
);
150 //--------------------------------------------------------------------
151 static void lcl_revokeMapModificationListener( MapData
& _mapData
, IMapModificationListener
& _listener
)
153 for ( MapListeners::iterator lookup
= _mapData
.m_aModListeners
.begin();
154 lookup
!= _mapData
.m_aModListeners
.end();
158 if ( *lookup
== &_listener
)
160 _mapData
.m_aModListeners
.erase( lookup
);
164 OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" );
167 //--------------------------------------------------------------------
168 static void lcl_notifyMapDataListeners_nothrow( const MapData
& _mapData
)
170 for ( MapListeners::const_iterator loop
= _mapData
.m_aModListeners
.begin();
171 loop
!= _mapData
.m_aModListeners
.end();
175 (*loop
)->mapModified();
179 //====================================================================
181 //====================================================================
182 typedef ::cppu::WeakAggComponentImplHelper3
< XInitialization
187 class COMPHELPER_DLLPRIVATE EnumerableMap
:public Map_IFace
188 ,public ComponentBase
192 virtual ~EnumerableMap();
195 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) throw (Exception
, RuntimeException
);
198 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createKeyEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
199 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createValueEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
200 virtual ::com::sun::star::uno::Reference
< ::com::sun::star::container::XEnumeration
> SAL_CALL
createElementEnumeration( ::sal_Bool _Isolated
) throw (::com::sun::star::lang::NoSupportException
, ::com::sun::star::uno::RuntimeException
);
203 virtual Type SAL_CALL
getKeyType() throw (RuntimeException
);
204 virtual Type SAL_CALL
getValueType() throw (RuntimeException
);
205 virtual void SAL_CALL
clear( ) throw (NoSupportException
, RuntimeException
);
206 virtual ::sal_Bool SAL_CALL
containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
207 virtual ::sal_Bool SAL_CALL
containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
208 virtual Any SAL_CALL
get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
209 virtual Any SAL_CALL
put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
);
210 virtual Any SAL_CALL
remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
);
212 // XElementAccess (base of XMap)
213 virtual Type SAL_CALL
getElementType() throw (RuntimeException
);
214 virtual ::sal_Bool SAL_CALL
hasElements() throw (RuntimeException
);
217 virtual OUString SAL_CALL
getImplementationName( ) throw (RuntimeException
);
218 virtual ::sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) throw (RuntimeException
);
219 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames( ) throw (RuntimeException
);
222 // XServiceInfo, static version (used for component registration)
223 static OUString SAL_CALL
getImplementationName_static( );
224 static Sequence
< OUString
> SAL_CALL
getSupportedServiceNames_static( );
225 static Reference
< XInterface
> SAL_CALL
Create( const Reference
< XComponentContext
>& );
228 void impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
);
230 /// throws a IllegalTypeException if the given value is not compatible with our ValueType
231 void impl_checkValue_throw( const Any
& _value
) const;
232 void impl_checkKey_throw( const Any
& _key
) const;
233 void impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const;
234 void impl_checkMutable_throw() const;
237 ::osl::Mutex m_aMutex
;
240 ::std::vector
< ::com::sun::star::uno::WeakReference
< XInterface
> >
241 m_aDependentComponents
;
244 //====================================================================
246 //====================================================================
249 eKeys
, eValues
, eBoth
252 //====================================================================
254 //====================================================================
255 class MapEnumerator
: public IMapModificationListener
258 MapEnumerator( ::cppu::OWeakObject
& _rParent
, MapData
& _mapData
, const EnumerationType _type
)
259 :m_rParent( _rParent
)
260 ,m_rMapData( _mapData
)
262 ,m_mapPos( _mapData
.m_pValues
->begin() )
265 lcl_registerMapModificationListener( m_rMapData
, *this );
268 virtual ~MapEnumerator()
277 lcl_revokeMapModificationListener( m_rMapData
, *this );
282 // XEnumeration equivalents
283 ::sal_Bool
hasMoreElements();
286 // IMapModificationListener
287 virtual void mapModified();
290 ::cppu::OWeakObject
& m_rParent
;
292 const EnumerationType m_eType
;
293 KeyedValues::const_iterator m_mapPos
;
297 MapEnumerator(); // not implemented
298 MapEnumerator( const MapEnumerator
& ); // not implemented
299 MapEnumerator
& operator=( const MapEnumerator
& ); // not implemented
302 //====================================================================
304 //====================================================================
305 typedef ::cppu::WeakImplHelper1
< XEnumeration
306 > MapEnumeration_Base
;
307 class MapEnumeration
:public ComponentBase
308 ,public MapEnumeration_Base
311 MapEnumeration( ::cppu::OWeakObject
& _parentMap
, MapData
& _mapData
, ::cppu::OBroadcastHelper
& _rBHelper
,
312 const EnumerationType _type
, const bool _isolated
)
313 :ComponentBase( _rBHelper
, ComponentBase::NoInitializationNeeded() )
314 ,m_xKeepMapAlive( _parentMap
)
315 ,m_pMapDataCopy( _isolated
? new MapData( _mapData
) : NULL
)
316 ,m_aEnumerator( *this, _isolated
? *m_pMapDataCopy
: _mapData
, _type
)
321 virtual ::sal_Bool SAL_CALL
hasMoreElements( ) throw (RuntimeException
);
322 virtual Any SAL_CALL
nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
325 virtual ~MapEnumeration()
329 ::osl::MutexGuard
aGuard( getMutex() );
330 m_aEnumerator
.dispose();
331 m_pMapDataCopy
.reset();
336 // sicne we share our mutex with the main map, we need to keep it alive as long as we live
337 Reference
< XInterface
> m_xKeepMapAlive
;
338 ::std::auto_ptr
< MapData
> m_pMapDataCopy
;
339 MapEnumerator m_aEnumerator
;
342 //====================================================================
344 //====================================================================
345 //--------------------------------------------------------------------
346 EnumerableMap::EnumerableMap()
347 :Map_IFace( m_aMutex
)
348 ,ComponentBase( Map_IFace::rBHelper
)
352 //--------------------------------------------------------------------
353 EnumerableMap::~EnumerableMap()
355 if ( !impl_isDisposed() )
362 //--------------------------------------------------------------------
363 void SAL_CALL
EnumerableMap::initialize( const Sequence
< Any
>& _arguments
) throw (Exception
, RuntimeException
)
365 ComponentMethodGuard
aGuard( *this, ComponentMethodGuard::WithoutInit
);
366 if ( impl_isInitialized_nothrow() )
367 throw AlreadyInitializedException();
369 sal_Int32 nArgumentCount
= _arguments
.getLength();
370 if ( ( nArgumentCount
!= 2 ) && ( nArgumentCount
!= 3 ) )
371 throw IllegalArgumentException();
373 Type aKeyType
, aValueType
;
374 if ( !( _arguments
[0] >>= aKeyType
) )
375 throw IllegalArgumentException( OUString("com.sun.star.uno.Type expected."), *this, 1 );
376 if ( !( _arguments
[1] >>= aValueType
) )
377 throw IllegalArgumentException( OUString("com.sun.star.uno.Type expected."), *this, 2 );
379 Sequence
< Pair
< Any
, Any
> > aInitialValues
;
380 bool bMutable
= true;
381 if ( nArgumentCount
== 3 )
383 if ( !( _arguments
[2] >>= aInitialValues
) )
384 throw IllegalArgumentException( OUString("[]com.sun.star.beans.Pair<any,any> expected."), *this, 2 );
388 // for the value, anything is allowed, except VOID
389 if ( ( aValueType
.getTypeClass() == TypeClass_VOID
) || ( aValueType
.getTypeClass() == TypeClass_UNKNOWN
) )
390 throw IllegalTypeException( OUString( "Unsupported value type." ), *this );
392 // create the comparator for the KeyType, and throw if the type is not supported
393 ::std::auto_ptr
< IKeyPredicateLess
> pComparator( getStandardLessPredicate( aKeyType
, NULL
) );
394 if ( !pComparator
.get() )
395 throw IllegalTypeException( OUString( "Unsupported key type." ), *this );
398 m_aData
.m_aKeyType
= aKeyType
;
399 m_aData
.m_aValueType
= aValueType
;
400 m_aData
.m_pKeyCompare
= pComparator
;
401 m_aData
.m_pValues
.reset( new KeyedValues( *m_aData
.m_pKeyCompare
) );
402 m_aData
.m_bMutable
= bMutable
;
404 if ( aInitialValues
.getLength() )
405 impl_initValues_throw( aInitialValues
);
410 //--------------------------------------------------------------------
411 void EnumerableMap::impl_initValues_throw( const Sequence
< Pair
< Any
, Any
> >& _initialValues
)
413 OSL_PRECOND( m_aData
.m_pValues
.get() && m_aData
.m_pValues
->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
414 if ( !m_aData
.m_pValues
.get() || !m_aData
.m_pValues
->empty() )
415 throw RuntimeException();
417 const Pair
< Any
, Any
>* mapping
= _initialValues
.getConstArray();
418 const Pair
< Any
, Any
>* mappingEnd
= mapping
+ _initialValues
.getLength();
420 for ( ; mapping
!= mappingEnd
; ++mapping
)
422 impl_checkValue_throw( mapping
->Second
);
423 (*m_aData
.m_pValues
)[ mapping
->First
] = mapping
->Second
;
427 //--------------------------------------------------------------------
428 void EnumerableMap::impl_checkValue_throw( const Any
& _value
) const
430 if ( !_value
.hasValue() )
431 // nothing to do, NULL values are always allowed, regardless of the ValueType
434 TypeClass eAllowedTypeClass
= m_aData
.m_aValueType
.getTypeClass();
437 switch ( eAllowedTypeClass
)
440 bValid
= ( _value
.getValueTypeClass() == eAllowedTypeClass
);
445 case TypeClass_INTERFACE
:
447 // special treatment: _value might contain the proper type, but the interface
448 // might actually be NULL. Which is still valid ...
449 if ( m_aData
.m_aValueType
.isAssignableFrom( _value
.getValueType() ) )
450 // this also catches the special case where XFoo is our value type,
451 // and _value contains a NULL-reference to XFoo, or a derived type
455 Reference
< XInterface
> xValue( _value
, UNO_QUERY
);
458 // XInterface is not-NULL, but is X(ValueType) not-NULL, too?
459 xValue
.set( xValue
->queryInterface( m_aData
.m_aValueType
), UNO_QUERY
);
460 bValid
= xValue
.is();
464 case TypeClass_EXCEPTION
:
465 case TypeClass_STRUCT
:
466 case TypeClass_UNION
:
468 // values are accepted if and only if their type equals, or is derived from, our value type
470 if ( _value
.getValueTypeClass() != eAllowedTypeClass
)
474 const TypeDescription
aValueTypeDesc( _value
.getValueType() );
475 const TypeDescription
aRequiredTypeDesc( m_aData
.m_aValueType
);
477 const _typelib_CompoundTypeDescription
* pValueCompoundTypeDesc
=
478 reinterpret_cast< const _typelib_CompoundTypeDescription
* >( aValueTypeDesc
.get() );
480 while ( pValueCompoundTypeDesc
)
482 if ( typelib_typedescription_equals( &pValueCompoundTypeDesc
->aBase
, aRequiredTypeDesc
.get() ) )
484 pValueCompoundTypeDesc
= pValueCompoundTypeDesc
->pBaseTypeDescription
;
486 bValid
= ( pValueCompoundTypeDesc
!= NULL
);
494 OUStringBuffer aMessage
;
495 aMessage
.appendAscii( "Incompatible value type. Found '" );
496 aMessage
.append( _value
.getValueTypeName() );
497 aMessage
.appendAscii( "', where '" );
498 aMessage
.append( m_aData
.m_aValueType
.getTypeName() );
499 aMessage
.appendAscii( "' (or compatible type) is expected." );
500 throw IllegalTypeException( aMessage
.makeStringAndClear(), *const_cast< EnumerableMap
* >( this ) );
503 impl_checkNaN_throw( _value
, m_aData
.m_aValueType
);
506 //--------------------------------------------------------------------
507 void EnumerableMap::impl_checkNaN_throw( const Any
& _keyOrValue
, const Type
& _keyOrValueType
) const
509 if ( ( _keyOrValueType
.getTypeClass() == TypeClass_DOUBLE
)
510 || ( _keyOrValueType
.getTypeClass() == TypeClass_FLOAT
)
514 if ( _keyOrValue
>>= nValue
)
515 if ( ::rtl::math::isNan( nValue
) )
516 throw IllegalArgumentException(
517 OUString( "NaN (not-a-number) not supported by this implementation." ),
518 *const_cast< EnumerableMap
* >( this ), 0 );
519 // (note that the case of _key not containing a float/double value is handled in the
520 // respective IKeyPredicateLess implementation, so there's no need to handle this here.)
524 //--------------------------------------------------------------------
525 void EnumerableMap::impl_checkKey_throw( const Any
& _key
) const
527 if ( !_key
.hasValue() )
528 throw IllegalArgumentException(
529 OUString( "NULL keys not supported by this implementation." ),
530 *const_cast< EnumerableMap
* >( this ), 0 );
532 impl_checkNaN_throw( _key
, m_aData
.m_aKeyType
);
535 //--------------------------------------------------------------------
536 void EnumerableMap::impl_checkMutable_throw() const
538 if ( !m_aData
.m_bMutable
)
539 throw NoSupportException(
540 OUString( "The map is immutable." ),
541 *const_cast< EnumerableMap
* >( this ) );
544 //--------------------------------------------------------------------
545 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
547 ComponentMethodGuard
aGuard( *this );
548 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eKeys
, _Isolated
);
551 //--------------------------------------------------------------------
552 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
554 ComponentMethodGuard
aGuard( *this );
555 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eValues
, _Isolated
);
558 //--------------------------------------------------------------------
559 Reference
< XEnumeration
> SAL_CALL
EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated
) throw (NoSupportException
, RuntimeException
)
561 ComponentMethodGuard
aGuard( *this );
562 return new MapEnumeration( *this, m_aData
, getBroadcastHelper(), eBoth
, _Isolated
);
565 //--------------------------------------------------------------------
566 Type SAL_CALL
EnumerableMap::getKeyType() throw (RuntimeException
)
568 ComponentMethodGuard
aGuard( *this );
569 return m_aData
.m_aKeyType
;
572 //--------------------------------------------------------------------
573 Type SAL_CALL
EnumerableMap::getValueType() throw (RuntimeException
)
575 ComponentMethodGuard
aGuard( *this );
576 return m_aData
.m_aValueType
;
579 //--------------------------------------------------------------------
580 void SAL_CALL
EnumerableMap::clear( ) throw (NoSupportException
, RuntimeException
)
582 ComponentMethodGuard
aGuard( *this );
583 impl_checkMutable_throw();
585 m_aData
.m_pValues
->clear();
587 lcl_notifyMapDataListeners_nothrow( m_aData
);
590 //--------------------------------------------------------------------
591 ::sal_Bool SAL_CALL
EnumerableMap::containsKey( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
593 ComponentMethodGuard
aGuard( *this );
594 impl_checkKey_throw( _key
);
596 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
597 return ( pos
!= m_aData
.m_pValues
->end() );
600 //--------------------------------------------------------------------
601 ::sal_Bool SAL_CALL
EnumerableMap::containsValue( const Any
& _value
) throw (IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
603 ComponentMethodGuard
aGuard( *this );
604 impl_checkValue_throw( _value
);
606 for ( KeyedValues::const_iterator mapping
= m_aData
.m_pValues
->begin();
607 mapping
!= m_aData
.m_pValues
->end();
611 if ( mapping
->second
== _value
)
617 //--------------------------------------------------------------------
618 Any SAL_CALL
EnumerableMap::get( const Any
& _key
) throw (IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
620 ComponentMethodGuard
aGuard( *this );
621 impl_checkKey_throw( _key
);
623 KeyedValues::const_iterator pos
= m_aData
.m_pValues
->find( _key
);
624 if ( pos
== m_aData
.m_pValues
->end() )
625 throw NoSuchElementException( anyToString( _key
), *this );
630 //--------------------------------------------------------------------
631 Any SAL_CALL
EnumerableMap::put( const Any
& _key
, const Any
& _value
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, RuntimeException
)
633 ComponentMethodGuard
aGuard( *this );
634 impl_checkMutable_throw();
635 impl_checkKey_throw( _key
);
636 impl_checkValue_throw( _value
);
640 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
641 if ( pos
!= m_aData
.m_pValues
->end() )
643 previousValue
= pos
->second
;
644 pos
->second
= _value
;
648 (*m_aData
.m_pValues
)[ _key
] = _value
;
651 lcl_notifyMapDataListeners_nothrow( m_aData
);
653 return previousValue
;
656 //--------------------------------------------------------------------
657 Any SAL_CALL
EnumerableMap::remove( const Any
& _key
) throw (NoSupportException
, IllegalTypeException
, IllegalArgumentException
, NoSuchElementException
, RuntimeException
)
659 ComponentMethodGuard
aGuard( *this );
660 impl_checkMutable_throw();
661 impl_checkKey_throw( _key
);
665 KeyedValues::iterator pos
= m_aData
.m_pValues
->find( _key
);
666 if ( pos
!= m_aData
.m_pValues
->end() )
668 previousValue
= pos
->second
;
669 m_aData
.m_pValues
->erase( pos
);
672 lcl_notifyMapDataListeners_nothrow( m_aData
);
674 return previousValue
;
677 //--------------------------------------------------------------------
678 Type SAL_CALL
EnumerableMap::getElementType() throw (RuntimeException
)
680 return ::cppu::UnoType
< Pair
< Any
, Any
> >::get();
683 //--------------------------------------------------------------------
684 ::sal_Bool SAL_CALL
EnumerableMap::hasElements() throw (RuntimeException
)
686 ComponentMethodGuard
aGuard( *this );
687 return m_aData
.m_pValues
->empty();
690 //--------------------------------------------------------------------
691 OUString SAL_CALL
EnumerableMap::getImplementationName( ) throw (RuntimeException
)
693 return getImplementationName_static();
696 //--------------------------------------------------------------------
697 ::sal_Bool SAL_CALL
EnumerableMap::supportsService( const OUString
& _serviceName
) throw (RuntimeException
)
699 Sequence
< OUString
> aServices( getSupportedServiceNames() );
700 for ( sal_Int32 i
=0; i
<aServices
.getLength(); ++i
)
701 if ( _serviceName
== aServices
[i
] )
706 //--------------------------------------------------------------------
707 Sequence
< OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException
)
709 return getSupportedServiceNames_static();
712 //--------------------------------------------------------------------
713 OUString SAL_CALL
EnumerableMap::getImplementationName_static( )
715 return OUString( "org.openoffice.comp.comphelper.EnumerableMap" );
718 //--------------------------------------------------------------------
719 Sequence
< OUString
> SAL_CALL
EnumerableMap::getSupportedServiceNames_static( )
721 Sequence
< OUString
> aServiceNames(1);
722 aServiceNames
[0] = "com.sun.star.container.EnumerableMap";
723 return aServiceNames
;
726 //--------------------------------------------------------------------
727 Reference
< XInterface
> SAL_CALL
EnumerableMap::Create( SAL_UNUSED_PARAMETER
const Reference
< XComponentContext
>& )
729 return *new EnumerableMap
;
732 //====================================================================
734 //====================================================================
735 //--------------------------------------------------------------------
736 ::sal_Bool
MapEnumerator::hasMoreElements()
739 throw DisposedException( OUString(), m_rParent
);
740 return m_mapPos
!= m_rMapData
.m_pValues
->end();
743 //--------------------------------------------------------------------
744 Any
MapEnumerator::nextElement()
747 throw DisposedException( OUString(), m_rParent
);
748 if ( m_mapPos
== m_rMapData
.m_pValues
->end() )
749 throw NoSuchElementException( OUString( "No more elements." ), m_rParent
);
754 case eKeys
: aNextElement
= m_mapPos
->first
; break;
755 case eValues
: aNextElement
= m_mapPos
->second
; break;
756 case eBoth
: aNextElement
<<= Pair
< Any
, Any
>( m_mapPos
->first
, m_mapPos
->second
); break;
762 //--------------------------------------------------------------------
763 void MapEnumerator::mapModified()
768 //====================================================================
769 //= MapEnumeration - implementation
770 //====================================================================
771 //--------------------------------------------------------------------
772 ::sal_Bool SAL_CALL
MapEnumeration::hasMoreElements( ) throw (RuntimeException
)
774 ComponentMethodGuard
aGuard( *this );
775 return m_aEnumerator
.hasMoreElements();
778 //--------------------------------------------------------------------
779 Any SAL_CALL
MapEnumeration::nextElement( ) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
781 ComponentMethodGuard
aGuard( *this );
782 return m_aEnumerator
.nextElement();
785 //........................................................................
786 } // namespace comphelper
787 //........................................................................
789 void createRegistryInfo_Map()
791 ::comphelper::module::OAutoRegistration
< ::comphelper::EnumerableMap
> aAutoRegistration
;
794 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */