1dde7d3faSAndrew Rist /**************************************************************
2*e2530cf9Smseidel  *
3dde7d3faSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4dde7d3faSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5dde7d3faSAndrew Rist  * distributed with this work for additional information
6dde7d3faSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7dde7d3faSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8dde7d3faSAndrew Rist  * "License"); you may not use this file except in compliance
9dde7d3faSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*e2530cf9Smseidel  *
11dde7d3faSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e2530cf9Smseidel  *
13dde7d3faSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14dde7d3faSAndrew Rist  * software distributed under the License is distributed on an
15dde7d3faSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16dde7d3faSAndrew Rist  * KIND, either express or implied.  See the License for the
17dde7d3faSAndrew Rist  * specific language governing permissions and limitations
18dde7d3faSAndrew Rist  * under the License.
19*e2530cf9Smseidel  *
20dde7d3faSAndrew Rist  *************************************************************/
21dde7d3faSAndrew Rist 
22dde7d3faSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "comphelper_module.hxx"
27cdf0e10cSrcweir #include "comphelper/anytostring.hxx"
28cdf0e10cSrcweir #include "comphelper/anycompare.hxx"
29cdf0e10cSrcweir #include "comphelper/componentbase.hxx"
30cdf0e10cSrcweir #include "comphelper/componentcontext.hxx"
31cdf0e10cSrcweir #include "comphelper/extract.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir /** === begin UNO includes === **/
34cdf0e10cSrcweir #include <com/sun/star/container/XEnumerableMap.hpp>
35cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
36cdf0e10cSrcweir #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
37cdf0e10cSrcweir #include <com/sun/star/beans/Pair.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
39cdf0e10cSrcweir /** === end UNO includes === **/
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <cppuhelper/compbase3.hxx>
42cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
43cdf0e10cSrcweir #include <rtl/math.hxx>
44cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
45cdf0e10cSrcweir #include <typelib/typedescription.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <map>
48cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir //........................................................................
51cdf0e10cSrcweir namespace comphelper
52cdf0e10cSrcweir {
53cdf0e10cSrcweir //........................................................................
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 	/** === begin UNO using === **/
56cdf0e10cSrcweir 	using ::com::sun::star::uno::Reference;
57cdf0e10cSrcweir 	using ::com::sun::star::uno::XInterface;
58cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY;
59cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY_THROW;
60cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_SET_THROW;
61cdf0e10cSrcweir 	using ::com::sun::star::uno::Exception;
62cdf0e10cSrcweir 	using ::com::sun::star::uno::RuntimeException;
63cdf0e10cSrcweir 	using ::com::sun::star::uno::Any;
64cdf0e10cSrcweir 	using ::com::sun::star::uno::makeAny;
65cdf0e10cSrcweir 	using ::com::sun::star::uno::Sequence;
66cdf0e10cSrcweir 	using ::com::sun::star::uno::Type;
67*e2530cf9Smseidel 	using ::com::sun::star::container::XEnumerableMap;
68*e2530cf9Smseidel 	using ::com::sun::star::lang::NoSupportException;
69*e2530cf9Smseidel 	using ::com::sun::star::beans::IllegalTypeException;
70*e2530cf9Smseidel 	using ::com::sun::star::container::NoSuchElementException;
71*e2530cf9Smseidel 	using ::com::sun::star::lang::IllegalArgumentException;
72*e2530cf9Smseidel 	using ::com::sun::star::lang::XInitialization;
73*e2530cf9Smseidel 	using ::com::sun::star::ucb::AlreadyInitializedException;
74*e2530cf9Smseidel 	using ::com::sun::star::beans::Pair;
75*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass;
76*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_VOID;
77*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_UNKNOWN;
78*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_ANY;
79*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_EXCEPTION;
80*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_STRUCT;
81*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_UNION;
82*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_FLOAT;
83*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_DOUBLE;
84*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeClass_INTERFACE;
85*e2530cf9Smseidel 	using ::com::sun::star::lang::XServiceInfo;
86*e2530cf9Smseidel 	using ::com::sun::star::uno::XComponentContext;
87*e2530cf9Smseidel 	using ::com::sun::star::container::XEnumeration;
88*e2530cf9Smseidel 	using ::com::sun::star::uno::TypeDescription;
89*e2530cf9Smseidel 	using ::com::sun::star::lang::WrappedTargetException;
90*e2530cf9Smseidel 	using ::com::sun::star::lang::DisposedException;
91cdf0e10cSrcweir 	/** === end UNO using === **/
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 	//====================================================================
94cdf0e10cSrcweir 	//= MapData
95cdf0e10cSrcweir 	//====================================================================
96*e2530cf9Smseidel 	class IMapModificationListener;
97*e2530cf9Smseidel 	typedef ::std::vector< IMapModificationListener* > MapListeners;
98*e2530cf9Smseidel 
99*e2530cf9Smseidel 	typedef ::std::map< Any, Any, LessPredicateAdapter > KeyedValues;
100*e2530cf9Smseidel 	struct MapData
101*e2530cf9Smseidel 	{
102*e2530cf9Smseidel 		Type										m_aKeyType;
103*e2530cf9Smseidel 		Type										m_aValueType;
104*e2530cf9Smseidel 		::std::auto_ptr< KeyedValues >				m_pValues;
105*e2530cf9Smseidel 		::boost::shared_ptr< IKeyPredicateLess >	m_pKeyCompare;
106*e2530cf9Smseidel 		bool										m_bMutable;
107*e2530cf9Smseidel 		MapListeners								m_aModListeners;
108*e2530cf9Smseidel 
MapDatacomphelper::MapData109*e2530cf9Smseidel 		MapData()
110*e2530cf9Smseidel 			:m_bMutable( true )
111*e2530cf9Smseidel 		{
112*e2530cf9Smseidel 		}
113*e2530cf9Smseidel 
MapDatacomphelper::MapData114*e2530cf9Smseidel 		MapData( const MapData& _source )
115*e2530cf9Smseidel 			:m_aKeyType( _source.m_aKeyType )
116*e2530cf9Smseidel 			,m_aValueType( _source.m_aValueType )
117*e2530cf9Smseidel 			,m_pValues( new KeyedValues( *_source.m_pValues ) )
118*e2530cf9Smseidel 			,m_pKeyCompare( _source.m_pKeyCompare )
119*e2530cf9Smseidel 			,m_bMutable( false )
120*e2530cf9Smseidel 			,m_aModListeners()
121*e2530cf9Smseidel 		{
122*e2530cf9Smseidel 		}
123*e2530cf9Smseidel 	private:
124*e2530cf9Smseidel 		MapData& operator=( const MapData& _source ); // not implemented
125*e2530cf9Smseidel 	};
126*e2530cf9Smseidel 
127*e2530cf9Smseidel 	//====================================================================
128cdf0e10cSrcweir 	//= IMapModificationListener
129cdf0e10cSrcweir 	//====================================================================
130*e2530cf9Smseidel 	/** implemented by components who want to be notified of modifications in the MapData they work with
131*e2530cf9Smseidel 	*/
132*e2530cf9Smseidel 	class SAL_NO_VTABLE IMapModificationListener
133*e2530cf9Smseidel 	{
134*e2530cf9Smseidel 	public:
135*e2530cf9Smseidel 		/// called when the map was modified
136*e2530cf9Smseidel 		virtual void mapModified() = 0;
~IMapModificationListener()137*e2530cf9Smseidel 		virtual ~IMapModificationListener()
138*e2530cf9Smseidel 		{
139*e2530cf9Smseidel 		}
140*e2530cf9Smseidel 	};
141*e2530cf9Smseidel 
142*e2530cf9Smseidel 	//====================================================================
143cdf0e10cSrcweir 	//= MapData helpers
144cdf0e10cSrcweir 	//====================================================================
145cdf0e10cSrcweir 	//--------------------------------------------------------------------
lcl_registerMapModificationListener(MapData & _mapData,IMapModificationListener & _listener)146*e2530cf9Smseidel 	static void lcl_registerMapModificationListener( MapData& _mapData, IMapModificationListener& _listener )
147*e2530cf9Smseidel 	{
148*e2530cf9Smseidel 	#if OSL_DEBUG_LEVEL > 0
149*e2530cf9Smseidel 		for (   MapListeners::const_iterator lookup = _mapData.m_aModListeners.begin();
150*e2530cf9Smseidel 				lookup != _mapData.m_aModListeners.end();
151*e2530cf9Smseidel 				++lookup
152*e2530cf9Smseidel 			)
153*e2530cf9Smseidel 		{
154*e2530cf9Smseidel 			OSL_ENSURE( *lookup != &_listener, "lcl_registerMapModificationListener: this listener is already registered!" );
155*e2530cf9Smseidel 		}
156*e2530cf9Smseidel 	#endif
157*e2530cf9Smseidel 		_mapData.m_aModListeners.push_back( &_listener );
158*e2530cf9Smseidel 	}
159*e2530cf9Smseidel 
160*e2530cf9Smseidel 	//--------------------------------------------------------------------
lcl_revokeMapModificationListener(MapData & _mapData,IMapModificationListener & _listener)161*e2530cf9Smseidel 	static void lcl_revokeMapModificationListener( MapData& _mapData, IMapModificationListener& _listener )
162*e2530cf9Smseidel 	{
163*e2530cf9Smseidel 		for (   MapListeners::iterator lookup = _mapData.m_aModListeners.begin();
164*e2530cf9Smseidel 				lookup != _mapData.m_aModListeners.end();
165*e2530cf9Smseidel 				++lookup
166*e2530cf9Smseidel 			)
167*e2530cf9Smseidel 		{
168*e2530cf9Smseidel 			if ( *lookup == &_listener )
169*e2530cf9Smseidel 			{
170*e2530cf9Smseidel 				_mapData.m_aModListeners.erase( lookup );
171*e2530cf9Smseidel 				return;
172*e2530cf9Smseidel 			}
173*e2530cf9Smseidel 		}
174*e2530cf9Smseidel 		OSL_ENSURE( false, "lcl_revokeMapModificationListener: the listener is not registered!" );
175*e2530cf9Smseidel 	}
176*e2530cf9Smseidel 
177*e2530cf9Smseidel 	//--------------------------------------------------------------------
lcl_notifyMapDataListeners_nothrow(const MapData & _mapData)178*e2530cf9Smseidel 	static void lcl_notifyMapDataListeners_nothrow( const MapData& _mapData )
179*e2530cf9Smseidel 	{
180*e2530cf9Smseidel 		for (   MapListeners::const_iterator loop = _mapData.m_aModListeners.begin();
181*e2530cf9Smseidel 				loop != _mapData.m_aModListeners.end();
182*e2530cf9Smseidel 				++loop
183*e2530cf9Smseidel 			)
184*e2530cf9Smseidel 		{
185*e2530cf9Smseidel 			(*loop)->mapModified();
186*e2530cf9Smseidel 		}
187*e2530cf9Smseidel 	}
188cdf0e10cSrcweir 
189cdf0e10cSrcweir 	//====================================================================
190cdf0e10cSrcweir 	//= EnumerableMap
191cdf0e10cSrcweir 	//====================================================================
192*e2530cf9Smseidel 	typedef ::cppu::WeakAggComponentImplHelper3 <   XInitialization
193*e2530cf9Smseidel 												,   XEnumerableMap
194*e2530cf9Smseidel 												,   XServiceInfo
195*e2530cf9Smseidel 												> Map_IFace;
196*e2530cf9Smseidel 
197*e2530cf9Smseidel 	class COMPHELPER_DLLPRIVATE EnumerableMap :public Map_IFace
198*e2530cf9Smseidel 									,public ComponentBase
199*e2530cf9Smseidel 	{
200*e2530cf9Smseidel 	protected:
201*e2530cf9Smseidel 		EnumerableMap( const ComponentContext& _rContext );
202*e2530cf9Smseidel 		virtual ~EnumerableMap();
203*e2530cf9Smseidel 
204*e2530cf9Smseidel 		// XInitialization
205*e2530cf9Smseidel 		virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
206*e2530cf9Smseidel 
207*e2530cf9Smseidel 		// XEnumerableMap
208*e2530cf9Smseidel 		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);
209*e2530cf9Smseidel 		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);
210*e2530cf9Smseidel 		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);
211*e2530cf9Smseidel 
212*e2530cf9Smseidel 		// XMap
213*e2530cf9Smseidel 		virtual Type SAL_CALL getKeyType() throw (RuntimeException);
214*e2530cf9Smseidel 		virtual Type SAL_CALL getValueType() throw (RuntimeException);
215*e2530cf9Smseidel 		virtual void SAL_CALL clear(  ) throw (NoSupportException, RuntimeException);
216*e2530cf9Smseidel 		virtual ::sal_Bool SAL_CALL containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException);
217*e2530cf9Smseidel 		virtual ::sal_Bool SAL_CALL containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException);
218*e2530cf9Smseidel 		virtual Any SAL_CALL get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException);
219*e2530cf9Smseidel 		virtual Any SAL_CALL put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException);
220*e2530cf9Smseidel 		virtual Any SAL_CALL remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException);
221*e2530cf9Smseidel 
222*e2530cf9Smseidel 		// XElementAccess (base of XMap)
223*e2530cf9Smseidel 		virtual Type SAL_CALL getElementType() throw (RuntimeException);
224*e2530cf9Smseidel 		virtual ::sal_Bool SAL_CALL hasElements() throw (RuntimeException);
225*e2530cf9Smseidel 
226*e2530cf9Smseidel 		// XServiceInfo
227*e2530cf9Smseidel 		virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (RuntimeException);
228*e2530cf9Smseidel 		virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
229*e2530cf9Smseidel 		virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException);
230*e2530cf9Smseidel 
231*e2530cf9Smseidel 	public:
232*e2530cf9Smseidel 		// XServiceInfo, static version (used for component registration)
233*e2530cf9Smseidel 		static ::rtl::OUString SAL_CALL getImplementationName_static(  );
234*e2530cf9Smseidel 		static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(  );
235*e2530cf9Smseidel 		static Reference< XInterface > SAL_CALL Create( const Reference< XComponentContext >& );
236*e2530cf9Smseidel 
237*e2530cf9Smseidel 	private:
238*e2530cf9Smseidel 		void impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues );
239*e2530cf9Smseidel 
240*e2530cf9Smseidel 		/// throws a IllegalTypeException if the given value is not compatible with our ValueType
241*e2530cf9Smseidel 		void impl_checkValue_throw( const Any& _value ) const;
242*e2530cf9Smseidel 		void impl_checkKey_throw( const Any& _key ) const;
243*e2530cf9Smseidel 		void impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const;
244*e2530cf9Smseidel 		void impl_checkMutable_throw() const;
245*e2530cf9Smseidel 
246*e2530cf9Smseidel 	private:
247*e2530cf9Smseidel 		::osl::Mutex		m_aMutex;
248*e2530cf9Smseidel 		ComponentContext	m_aContext;
249*e2530cf9Smseidel 		MapData				m_aData;
250*e2530cf9Smseidel 
251*e2530cf9Smseidel 		::std::vector< ::com::sun::star::uno::WeakReference< XInterface > >
252*e2530cf9Smseidel 							m_aDependentComponents;
253*e2530cf9Smseidel 	};
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	//====================================================================
256cdf0e10cSrcweir 	//= EnumerationType
257cdf0e10cSrcweir 	//====================================================================
258*e2530cf9Smseidel 	enum EnumerationType
259*e2530cf9Smseidel 	{
260*e2530cf9Smseidel 		eKeys, eValues, eBoth
261*e2530cf9Smseidel 	};
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	//====================================================================
264cdf0e10cSrcweir 	//= MapEnumerator
265cdf0e10cSrcweir 	//====================================================================
266*e2530cf9Smseidel 	class MapEnumerator : public IMapModificationListener
267*e2530cf9Smseidel 	{
268*e2530cf9Smseidel 	public:
MapEnumerator(::cppu::OWeakObject & _rParent,MapData & _mapData,const EnumerationType _type)269*e2530cf9Smseidel 		MapEnumerator( ::cppu::OWeakObject& _rParent, MapData& _mapData, const EnumerationType _type )
270*e2530cf9Smseidel 			:m_rParent( _rParent )
271*e2530cf9Smseidel 			,m_rMapData( _mapData )
272*e2530cf9Smseidel 			,m_eType( _type )
273*e2530cf9Smseidel 			,m_mapPos( _mapData.m_pValues->begin() )
274*e2530cf9Smseidel 			,m_disposed( false )
275*e2530cf9Smseidel 		{
276*e2530cf9Smseidel 			lcl_registerMapModificationListener( m_rMapData, *this );
277*e2530cf9Smseidel 		}
278*e2530cf9Smseidel 
~MapEnumerator()279*e2530cf9Smseidel 		virtual ~MapEnumerator()
280*e2530cf9Smseidel 		{
281*e2530cf9Smseidel 			dispose();
282*e2530cf9Smseidel 		}
283*e2530cf9Smseidel 
dispose()284*e2530cf9Smseidel 		void dispose()
285*e2530cf9Smseidel 		{
286*e2530cf9Smseidel 			if ( !m_disposed )
287*e2530cf9Smseidel 			{
288*e2530cf9Smseidel 				lcl_revokeMapModificationListener( m_rMapData, *this );
289*e2530cf9Smseidel 				m_disposed = true;
290*e2530cf9Smseidel 			}
291*e2530cf9Smseidel 		}
292*e2530cf9Smseidel 
293*e2530cf9Smseidel 		// XEnumeration equivalents
294*e2530cf9Smseidel 		::sal_Bool hasMoreElements();
295*e2530cf9Smseidel 		Any nextElement();
296*e2530cf9Smseidel 
297*e2530cf9Smseidel 		// IMapModificationListener
298*e2530cf9Smseidel 		virtual void mapModified();
299*e2530cf9Smseidel 
300*e2530cf9Smseidel 	private:
301*e2530cf9Smseidel 		::cppu::OWeakObject&		m_rParent;
302*e2530cf9Smseidel 		MapData&					m_rMapData;
303*e2530cf9Smseidel 		const EnumerationType		m_eType;
304*e2530cf9Smseidel 		KeyedValues::const_iterator	m_mapPos;
305*e2530cf9Smseidel 		bool						m_disposed;
306*e2530cf9Smseidel 
307*e2530cf9Smseidel 	private:
308*e2530cf9Smseidel 		MapEnumerator(); // not implemented
309*e2530cf9Smseidel 		MapEnumerator( const MapEnumerator& ); // not implemented
310*e2530cf9Smseidel 		MapEnumerator& operator=( const MapEnumerator& ); // not implemented
311*e2530cf9Smseidel 	};
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 	//====================================================================
314cdf0e10cSrcweir 	//= MapEnumeration
315cdf0e10cSrcweir 	//====================================================================
316*e2530cf9Smseidel 	typedef ::cppu::WeakImplHelper1 <   XEnumeration
317*e2530cf9Smseidel 									>   MapEnumeration_Base;
318*e2530cf9Smseidel 	class MapEnumeration :public ComponentBase
319*e2530cf9Smseidel 						 ,public MapEnumeration_Base
320*e2530cf9Smseidel 	{
321*e2530cf9Smseidel 	public:
MapEnumeration(::cppu::OWeakObject & _parentMap,MapData & _mapData,::cppu::OBroadcastHelper & _rBHelper,const EnumerationType _type,const bool _isolated)322*e2530cf9Smseidel 		MapEnumeration( ::cppu::OWeakObject& _parentMap, MapData& _mapData, ::cppu::OBroadcastHelper& _rBHelper,
323*e2530cf9Smseidel 						const EnumerationType _type, const bool _isolated )
324*e2530cf9Smseidel 			:ComponentBase( _rBHelper, ComponentBase::NoInitializationNeeded() )
325*e2530cf9Smseidel 			,m_xKeepMapAlive( _parentMap )
326*e2530cf9Smseidel 			,m_pMapDataCopy( _isolated ? new MapData( _mapData ) : NULL )
327*e2530cf9Smseidel 			,m_aEnumerator( *this, _isolated ? *m_pMapDataCopy : _mapData, _type )
328*e2530cf9Smseidel 		{
329*e2530cf9Smseidel 		}
330*e2530cf9Smseidel 
331*e2530cf9Smseidel 		// XEnumeration
332*e2530cf9Smseidel 		virtual ::sal_Bool SAL_CALL hasMoreElements(  ) throw (RuntimeException);
333*e2530cf9Smseidel 		virtual Any SAL_CALL nextElement(  ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
334*e2530cf9Smseidel 
335*e2530cf9Smseidel 	protected:
~MapEnumeration()336*e2530cf9Smseidel 		virtual ~MapEnumeration()
337*e2530cf9Smseidel 		{
338*e2530cf9Smseidel 			acquire();
339*e2530cf9Smseidel 			{
340*e2530cf9Smseidel 				::osl::MutexGuard aGuard( getMutex() );
341*e2530cf9Smseidel 				m_aEnumerator.dispose();
342*e2530cf9Smseidel 				m_pMapDataCopy.reset();
343*e2530cf9Smseidel 			}
344*e2530cf9Smseidel 		}
345*e2530cf9Smseidel 
346*e2530cf9Smseidel 	private:
347*e2530cf9Smseidel 		// since we share our mutex with the main map, we need to keep it alive as long as we live
348*e2530cf9Smseidel 		Reference< XInterface >		m_xKeepMapAlive;
349*e2530cf9Smseidel 		::std::auto_ptr< MapData >	m_pMapDataCopy;
350*e2530cf9Smseidel 		MapEnumerator				m_aEnumerator;
351*e2530cf9Smseidel 	};
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 	//====================================================================
354cdf0e10cSrcweir 	//= EnumerableMap
355cdf0e10cSrcweir 	//====================================================================
356cdf0e10cSrcweir 	//--------------------------------------------------------------------
EnumerableMap(const ComponentContext & _rContext)357*e2530cf9Smseidel 	EnumerableMap::EnumerableMap( const ComponentContext& _rContext )
358*e2530cf9Smseidel 		:Map_IFace( m_aMutex )
359*e2530cf9Smseidel 		,ComponentBase( Map_IFace::rBHelper )
360*e2530cf9Smseidel 		,m_aContext( _rContext )
361*e2530cf9Smseidel 	{
362*e2530cf9Smseidel 	}
363*e2530cf9Smseidel 
364*e2530cf9Smseidel 	//--------------------------------------------------------------------
~EnumerableMap()365*e2530cf9Smseidel 	EnumerableMap::~EnumerableMap()
366*e2530cf9Smseidel 	{
367*e2530cf9Smseidel 		if ( !impl_isDisposed() )
368*e2530cf9Smseidel 		{
369*e2530cf9Smseidel 			acquire();
370*e2530cf9Smseidel 			dispose();
371*e2530cf9Smseidel 		}
372*e2530cf9Smseidel 	}
373*e2530cf9Smseidel 
374*e2530cf9Smseidel 	//--------------------------------------------------------------------
initialize(const Sequence<Any> & _arguments)375*e2530cf9Smseidel 	void SAL_CALL EnumerableMap::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
376*e2530cf9Smseidel 	{
377*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this, ComponentMethodGuard::WithoutInit );
378*e2530cf9Smseidel 		if ( impl_isInitialized_nothrow() )
379*e2530cf9Smseidel 			throw AlreadyInitializedException();
380*e2530cf9Smseidel 
381*e2530cf9Smseidel 		sal_Int32 nArgumentCount = _arguments.getLength();
382*e2530cf9Smseidel 		if ( ( nArgumentCount != 2 ) && ( nArgumentCount != 3 ) )
383*e2530cf9Smseidel 			throw IllegalArgumentException();
384*e2530cf9Smseidel 
385*e2530cf9Smseidel 		Type aKeyType, aValueType;
386*e2530cf9Smseidel 		if ( !( _arguments[0] >>= aKeyType ) )
387*e2530cf9Smseidel 			throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "com.sun.star.uno.Type expected." ), *this, 1 );
388*e2530cf9Smseidel 		if ( !( _arguments[1] >>= aValueType ) )
389*e2530cf9Smseidel 			throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "com.sun.star.uno.Type expected." ), *this, 2 );
390*e2530cf9Smseidel 
391*e2530cf9Smseidel 		Sequence< Pair< Any, Any > > aInitialValues;
392*e2530cf9Smseidel 		bool bMutable = true;
393*e2530cf9Smseidel 		if ( nArgumentCount == 3 )
394*e2530cf9Smseidel 		{
395*e2530cf9Smseidel 			if ( !( _arguments[2] >>= aInitialValues ) )
396*e2530cf9Smseidel 				throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "[]com.sun.star.beans.Pair<any,any> expected." ), *this, 2 );
397*e2530cf9Smseidel 			bMutable = false;
398*e2530cf9Smseidel 		}
399*e2530cf9Smseidel 
400*e2530cf9Smseidel 		// for the value, anything is allowed, except VOID
401*e2530cf9Smseidel 		if ( ( aValueType.getTypeClass() == TypeClass_VOID ) || ( aValueType.getTypeClass() == TypeClass_UNKNOWN ) )
402*e2530cf9Smseidel 			throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported value type." ) ), *this );
403*e2530cf9Smseidel 
404*e2530cf9Smseidel 		// create the comparator for the KeyType, and throw if the type is not supported
405*e2530cf9Smseidel 		::std::auto_ptr< IKeyPredicateLess > pComparator( getStandardLessPredicate( aKeyType, NULL ) );
406*e2530cf9Smseidel 		if ( !pComparator.get() )
407*e2530cf9Smseidel 			throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unsupported key type." ) ), *this );
408*e2530cf9Smseidel 
409*e2530cf9Smseidel 		// init members
410*e2530cf9Smseidel 		m_aData.m_aKeyType = aKeyType;
411*e2530cf9Smseidel 		m_aData.m_aValueType = aValueType;
412*e2530cf9Smseidel 		m_aData.m_pKeyCompare = pComparator;
413*e2530cf9Smseidel 		m_aData.m_pValues.reset( new KeyedValues( *m_aData.m_pKeyCompare ) );
414*e2530cf9Smseidel 		m_aData.m_bMutable = bMutable;
415*e2530cf9Smseidel 
416*e2530cf9Smseidel 		if ( aInitialValues.getLength() )
417*e2530cf9Smseidel 			impl_initValues_throw( aInitialValues );
418*e2530cf9Smseidel 
419*e2530cf9Smseidel 		setInitialized();
420*e2530cf9Smseidel 	}
421*e2530cf9Smseidel 
422*e2530cf9Smseidel 	//--------------------------------------------------------------------
impl_initValues_throw(const Sequence<Pair<Any,Any>> & _initialValues)423*e2530cf9Smseidel 	void EnumerableMap::impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues )
424*e2530cf9Smseidel 	{
425*e2530cf9Smseidel 		OSL_PRECOND( m_aData.m_pValues.get() && m_aData.m_pValues->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
426*e2530cf9Smseidel 		if ( !m_aData.m_pValues.get() || !m_aData.m_pValues->empty() )
427*e2530cf9Smseidel 			throw RuntimeException();
428*e2530cf9Smseidel 
429*e2530cf9Smseidel 		const Pair< Any, Any >* mapping = _initialValues.getConstArray();
430*e2530cf9Smseidel 		const Pair< Any, Any >* mappingEnd = mapping + _initialValues.getLength();
431*e2530cf9Smseidel 		Any normalizedValue;
432*e2530cf9Smseidel 		for ( ; mapping != mappingEnd; ++mapping )
433*e2530cf9Smseidel 		{
434*e2530cf9Smseidel 			impl_checkValue_throw( mapping->Second );
435*e2530cf9Smseidel 			(*m_aData.m_pValues)[ mapping->First ] = mapping->Second;
436*e2530cf9Smseidel 		}
437*e2530cf9Smseidel 	}
438*e2530cf9Smseidel 
439*e2530cf9Smseidel 	//--------------------------------------------------------------------
impl_checkValue_throw(const Any & _value) const440*e2530cf9Smseidel 	void EnumerableMap::impl_checkValue_throw( const Any& _value ) const
441*e2530cf9Smseidel 	{
442*e2530cf9Smseidel 		if ( !_value.hasValue() )
443*e2530cf9Smseidel 			// nothing to do, NULL values are always allowed, regardless of the ValueType
444*e2530cf9Smseidel 			return;
445*e2530cf9Smseidel 
446*e2530cf9Smseidel 		TypeClass eAllowedTypeClass = m_aData.m_aValueType.getTypeClass();
447*e2530cf9Smseidel 		bool bValid = false;
448*e2530cf9Smseidel 
449*e2530cf9Smseidel 		switch ( eAllowedTypeClass )
450*e2530cf9Smseidel 		{
451*e2530cf9Smseidel 		default:
452*e2530cf9Smseidel 			bValid = ( _value.getValueTypeClass() == eAllowedTypeClass );
453*e2530cf9Smseidel 			break;
454*e2530cf9Smseidel 		case TypeClass_ANY:
455*e2530cf9Smseidel 			bValid = true;
456*e2530cf9Smseidel 			break;
457*e2530cf9Smseidel 		case TypeClass_INTERFACE:
458*e2530cf9Smseidel 		{
459*e2530cf9Smseidel 			// special treatment: _value might contain the proper type, but the interface
460*e2530cf9Smseidel 			// might actually be NULL. Which is still valid...
461*e2530cf9Smseidel 			if ( m_aData.m_aValueType.isAssignableFrom( _value.getValueType() ) )
462*e2530cf9Smseidel 				// this also catches the special case where XFoo is our value type,
463*e2530cf9Smseidel 				// and _value contains a NULL-reference to XFoo, or a derived type
464*e2530cf9Smseidel 				bValid = true;
465*e2530cf9Smseidel 			else
466*e2530cf9Smseidel 			{
467*e2530cf9Smseidel 				Reference< XInterface > xValue( _value, UNO_QUERY );
468*e2530cf9Smseidel 				Any aTypedValue;
469*e2530cf9Smseidel 				if ( xValue.is() )
470*e2530cf9Smseidel 					// XInterface is not-NULL, but is X(ValueType) not-NULL, too?
471*e2530cf9Smseidel 					xValue.set( xValue->queryInterface( m_aData.m_aValueType ), UNO_QUERY );
472*e2530cf9Smseidel 				bValid = xValue.is();
473*e2530cf9Smseidel 			}
474*e2530cf9Smseidel 		}
475*e2530cf9Smseidel 		break;
476*e2530cf9Smseidel 		case TypeClass_EXCEPTION:
477*e2530cf9Smseidel 		case TypeClass_STRUCT:
478*e2530cf9Smseidel 		case TypeClass_UNION:
479*e2530cf9Smseidel 		{
480*e2530cf9Smseidel 			// values are accepted if and only if their type equals, or is derived from, our value type
481*e2530cf9Smseidel 
482*e2530cf9Smseidel 			if ( _value.getValueTypeClass() != eAllowedTypeClass )
483*e2530cf9Smseidel 				bValid = false;
484*e2530cf9Smseidel 			else
485*e2530cf9Smseidel 			{
486*e2530cf9Smseidel 				const TypeDescription aValueTypeDesc( _value.getValueType() );
487*e2530cf9Smseidel 				const TypeDescription aRequiredTypeDesc( m_aData.m_aValueType );
488*e2530cf9Smseidel 
489*e2530cf9Smseidel 				const _typelib_CompoundTypeDescription* pValueCompoundTypeDesc =
490*e2530cf9Smseidel 					reinterpret_cast< const _typelib_CompoundTypeDescription* >( aValueTypeDesc.get() );
491*e2530cf9Smseidel 
492*e2530cf9Smseidel 				while ( pValueCompoundTypeDesc )
493*e2530cf9Smseidel 				{
494*e2530cf9Smseidel 					if ( typelib_typedescription_equals( &pValueCompoundTypeDesc->aBase, aRequiredTypeDesc.get() ) )
495*e2530cf9Smseidel 						break;
496*e2530cf9Smseidel 					pValueCompoundTypeDesc = pValueCompoundTypeDesc->pBaseTypeDescription;
497*e2530cf9Smseidel 				}
498*e2530cf9Smseidel 				bValid = ( pValueCompoundTypeDesc != NULL );
499*e2530cf9Smseidel 			}
500*e2530cf9Smseidel 		}
501*e2530cf9Smseidel 		break;
502*e2530cf9Smseidel 		}
503*e2530cf9Smseidel 
504*e2530cf9Smseidel 		if ( !bValid )
505*e2530cf9Smseidel 		{
506*e2530cf9Smseidel 			::rtl::OUStringBuffer aMessage;
507*e2530cf9Smseidel 			aMessage.appendAscii( "Incompatible value type. Found '" );
508*e2530cf9Smseidel 			aMessage.append( _value.getValueTypeName() );
509*e2530cf9Smseidel 			aMessage.appendAscii( "', where '" );
510*e2530cf9Smseidel 			aMessage.append( m_aData.m_aValueType.getTypeName() );
511*e2530cf9Smseidel 			aMessage.appendAscii( "' (or compatible type) is expected." );
512*e2530cf9Smseidel 			throw IllegalTypeException( aMessage.makeStringAndClear(), *const_cast< EnumerableMap* >( this ) );
513*e2530cf9Smseidel 		}
514*e2530cf9Smseidel 
515*e2530cf9Smseidel 		impl_checkNaN_throw( _value, m_aData.m_aValueType );
516*e2530cf9Smseidel 	}
517*e2530cf9Smseidel 
518*e2530cf9Smseidel 	//--------------------------------------------------------------------
impl_checkNaN_throw(const Any & _keyOrValue,const Type & _keyOrValueType) const519*e2530cf9Smseidel 	void EnumerableMap::impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const
520*e2530cf9Smseidel 	{
521*e2530cf9Smseidel 		if  (   ( _keyOrValueType.getTypeClass() == TypeClass_DOUBLE )
522*e2530cf9Smseidel 			||  ( _keyOrValueType.getTypeClass() == TypeClass_FLOAT )
523*e2530cf9Smseidel 			)
524*e2530cf9Smseidel 		{
525*e2530cf9Smseidel 			double nValue(0);
526*e2530cf9Smseidel 			if ( _keyOrValue >>= nValue )
527*e2530cf9Smseidel 				if ( ::rtl::math::isNan( nValue ) )
528*e2530cf9Smseidel 					throw IllegalArgumentException(
529*e2530cf9Smseidel 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NaN (not-a-number) not supported by this implementation." ) ),
530*e2530cf9Smseidel 						*const_cast< EnumerableMap* >( this ), 0 );
531*e2530cf9Smseidel 			// (note that the case of _key not containing a float/double value is handled in the
532*e2530cf9Smseidel 			// respective IKeyPredicateLess implementation, so there's no need to handle this here.)
533*e2530cf9Smseidel 		}
534*e2530cf9Smseidel 	}
535*e2530cf9Smseidel 
536*e2530cf9Smseidel 	//--------------------------------------------------------------------
impl_checkKey_throw(const Any & _key) const537*e2530cf9Smseidel 	void EnumerableMap::impl_checkKey_throw( const Any& _key ) const
538*e2530cf9Smseidel 	{
539*e2530cf9Smseidel 		if ( !_key.hasValue() )
540*e2530cf9Smseidel 			throw IllegalArgumentException(
541*e2530cf9Smseidel 				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NULL keys not supported by this implementation." ) ),
542*e2530cf9Smseidel 				*const_cast< EnumerableMap* >( this ), 0 );
543*e2530cf9Smseidel 
544*e2530cf9Smseidel 		impl_checkNaN_throw( _key, m_aData.m_aKeyType );
545*e2530cf9Smseidel 	}
546*e2530cf9Smseidel 
547*e2530cf9Smseidel 	//--------------------------------------------------------------------
impl_checkMutable_throw() const548*e2530cf9Smseidel 	void EnumerableMap::impl_checkMutable_throw() const
549*e2530cf9Smseidel 	{
550*e2530cf9Smseidel 		if ( !m_aData.m_bMutable )
551*e2530cf9Smseidel 			throw NoSupportException(
552*e2530cf9Smseidel 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The map is immutable." ) ),
553*e2530cf9Smseidel 					*const_cast< EnumerableMap* >( this ) );
554*e2530cf9Smseidel 	}
555*e2530cf9Smseidel 
556*e2530cf9Smseidel 	//--------------------------------------------------------------------
createKeyEnumeration(::sal_Bool _Isolated)557*e2530cf9Smseidel 	Reference< XEnumeration > SAL_CALL EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
558*e2530cf9Smseidel 	{
559*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
560*e2530cf9Smseidel 		return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eKeys, _Isolated );
561*e2530cf9Smseidel 	}
562*e2530cf9Smseidel 
563*e2530cf9Smseidel 	//--------------------------------------------------------------------
createValueEnumeration(::sal_Bool _Isolated)564*e2530cf9Smseidel 	Reference< XEnumeration > SAL_CALL EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
565*e2530cf9Smseidel 	{
566*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
567*e2530cf9Smseidel 		return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eValues, _Isolated );
568*e2530cf9Smseidel 	}
569*e2530cf9Smseidel 
570*e2530cf9Smseidel 	//--------------------------------------------------------------------
createElementEnumeration(::sal_Bool _Isolated)571*e2530cf9Smseidel 	Reference< XEnumeration > SAL_CALL EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
572*e2530cf9Smseidel 	{
573*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
574*e2530cf9Smseidel 		return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eBoth, _Isolated );
575*e2530cf9Smseidel 	}
576*e2530cf9Smseidel 
577*e2530cf9Smseidel 	//--------------------------------------------------------------------
getKeyType()578*e2530cf9Smseidel 	Type SAL_CALL EnumerableMap::getKeyType() throw (RuntimeException)
579*e2530cf9Smseidel 	{
580*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
581*e2530cf9Smseidel 		return m_aData.m_aKeyType;
582*e2530cf9Smseidel 	}
583*e2530cf9Smseidel 
584*e2530cf9Smseidel 	//--------------------------------------------------------------------
getValueType()585*e2530cf9Smseidel 	Type SAL_CALL EnumerableMap::getValueType() throw (RuntimeException)
586*e2530cf9Smseidel 	{
587*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
588*e2530cf9Smseidel 		return m_aData.m_aValueType;
589*e2530cf9Smseidel 	}
590*e2530cf9Smseidel 
591*e2530cf9Smseidel 	//--------------------------------------------------------------------
clear()592*e2530cf9Smseidel 	void SAL_CALL EnumerableMap::clear(  ) throw (NoSupportException, RuntimeException)
593*e2530cf9Smseidel 	{
594*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
595*e2530cf9Smseidel 		impl_checkMutable_throw();
596*e2530cf9Smseidel 
597*e2530cf9Smseidel 		m_aData.m_pValues->clear();
598*e2530cf9Smseidel 
599*e2530cf9Smseidel 		lcl_notifyMapDataListeners_nothrow( m_aData );
600*e2530cf9Smseidel 	}
601*e2530cf9Smseidel 
602*e2530cf9Smseidel 	//--------------------------------------------------------------------
containsKey(const Any & _key)603*e2530cf9Smseidel 	::sal_Bool SAL_CALL EnumerableMap::containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException)
604*e2530cf9Smseidel 	{
605*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
606*e2530cf9Smseidel 		impl_checkKey_throw( _key );
607*e2530cf9Smseidel 
608*e2530cf9Smseidel 		KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
609*e2530cf9Smseidel 		return ( pos != m_aData.m_pValues->end() );
610*e2530cf9Smseidel 	}
611*e2530cf9Smseidel 
612*e2530cf9Smseidel 	//--------------------------------------------------------------------
containsValue(const Any & _value)613*e2530cf9Smseidel 	::sal_Bool SAL_CALL EnumerableMap::containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException)
614*e2530cf9Smseidel 	{
615*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
616*e2530cf9Smseidel 		impl_checkValue_throw( _value );
617*e2530cf9Smseidel 
618*e2530cf9Smseidel 		for (   KeyedValues::const_iterator mapping = m_aData.m_pValues->begin();
619*e2530cf9Smseidel 				mapping != m_aData.m_pValues->end();
620*e2530cf9Smseidel 				++mapping
621*e2530cf9Smseidel 			)
622*e2530cf9Smseidel 		{
623*e2530cf9Smseidel 			if ( mapping->second == _value )
624*e2530cf9Smseidel 				return sal_True;
625*e2530cf9Smseidel 		}
626*e2530cf9Smseidel 		return sal_False;
627*e2530cf9Smseidel 	}
628*e2530cf9Smseidel 
629*e2530cf9Smseidel 	//--------------------------------------------------------------------
get(const Any & _key)630*e2530cf9Smseidel 	Any SAL_CALL EnumerableMap::get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException)
631*e2530cf9Smseidel 	{
632*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
633*e2530cf9Smseidel 		impl_checkKey_throw( _key );
634*e2530cf9Smseidel 
635*e2530cf9Smseidel 		KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
636*e2530cf9Smseidel 		if ( pos == m_aData.m_pValues->end() )
637*e2530cf9Smseidel 			throw NoSuchElementException( anyToString( _key ), *this );
638*e2530cf9Smseidel 
639*e2530cf9Smseidel 		return pos->second;
640*e2530cf9Smseidel 	}
641*e2530cf9Smseidel 
642*e2530cf9Smseidel 	//--------------------------------------------------------------------
put(const Any & _key,const Any & _value)643*e2530cf9Smseidel 	Any SAL_CALL EnumerableMap::put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException)
644*e2530cf9Smseidel 	{
645*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
646*e2530cf9Smseidel 		impl_checkMutable_throw();
647*e2530cf9Smseidel 		impl_checkKey_throw( _key );
648*e2530cf9Smseidel 		impl_checkValue_throw( _value );
649*e2530cf9Smseidel 
650*e2530cf9Smseidel 		Any previousValue;
651*e2530cf9Smseidel 
652*e2530cf9Smseidel 		KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
653*e2530cf9Smseidel 		if ( pos != m_aData.m_pValues->end() )
654*e2530cf9Smseidel 		{
655*e2530cf9Smseidel 			previousValue = pos->second;
656*e2530cf9Smseidel 			pos->second = _value;
657*e2530cf9Smseidel 		}
658*e2530cf9Smseidel 		else
659*e2530cf9Smseidel 		{
660*e2530cf9Smseidel 			(*m_aData.m_pValues)[ _key ] = _value;
661*e2530cf9Smseidel 		}
662*e2530cf9Smseidel 
663*e2530cf9Smseidel 		lcl_notifyMapDataListeners_nothrow( m_aData );
664*e2530cf9Smseidel 
665*e2530cf9Smseidel 		return previousValue;
666*e2530cf9Smseidel 	}
667*e2530cf9Smseidel 
668*e2530cf9Smseidel 	//--------------------------------------------------------------------
remove(const Any & _key)669*e2530cf9Smseidel 	Any SAL_CALL EnumerableMap::remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException)
670*e2530cf9Smseidel 	{
671*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
672*e2530cf9Smseidel 		impl_checkMutable_throw();
673*e2530cf9Smseidel 		impl_checkKey_throw( _key );
674*e2530cf9Smseidel 
675*e2530cf9Smseidel 		Any previousValue;
676*e2530cf9Smseidel 
677*e2530cf9Smseidel 		KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
678*e2530cf9Smseidel 		if ( pos != m_aData.m_pValues->end() )
679*e2530cf9Smseidel 		{
680*e2530cf9Smseidel 			previousValue = pos->second;
681*e2530cf9Smseidel 			m_aData.m_pValues->erase( pos );
682*e2530cf9Smseidel 		}
683*e2530cf9Smseidel 
684*e2530cf9Smseidel 		lcl_notifyMapDataListeners_nothrow( m_aData );
685*e2530cf9Smseidel 
686*e2530cf9Smseidel 		return previousValue;
687*e2530cf9Smseidel 	}
688*e2530cf9Smseidel 
689*e2530cf9Smseidel 	//--------------------------------------------------------------------
getElementType()690*e2530cf9Smseidel 	Type SAL_CALL EnumerableMap::getElementType() throw (RuntimeException)
691*e2530cf9Smseidel 	{
692*e2530cf9Smseidel 		return ::cppu::UnoType< Pair< Any, Any > >::get();
693*e2530cf9Smseidel 	}
694*e2530cf9Smseidel 
695*e2530cf9Smseidel 	//--------------------------------------------------------------------
hasElements()696*e2530cf9Smseidel 	::sal_Bool SAL_CALL EnumerableMap::hasElements() throw (RuntimeException)
697*e2530cf9Smseidel 	{
698*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
699*e2530cf9Smseidel 		return m_aData.m_pValues->empty();
700*e2530cf9Smseidel 	}
701*e2530cf9Smseidel 
702*e2530cf9Smseidel 	//--------------------------------------------------------------------
getImplementationName()703*e2530cf9Smseidel 	::rtl::OUString SAL_CALL EnumerableMap::getImplementationName(  ) throw (RuntimeException)
704*e2530cf9Smseidel 	{
705*e2530cf9Smseidel 		return getImplementationName_static();
706*e2530cf9Smseidel 	}
707*e2530cf9Smseidel 
708*e2530cf9Smseidel 	//--------------------------------------------------------------------
supportsService(const::rtl::OUString & _serviceName)709*e2530cf9Smseidel 	::sal_Bool SAL_CALL EnumerableMap::supportsService( const ::rtl::OUString& _serviceName ) throw (RuntimeException)
710*e2530cf9Smseidel 	{
711*e2530cf9Smseidel 		Sequence< ::rtl::OUString > aServices( getSupportedServiceNames() );
712*e2530cf9Smseidel 		for ( sal_Int32 i=0; i<aServices.getLength(); ++i )
713*e2530cf9Smseidel 			if ( _serviceName == aServices[i] )
714*e2530cf9Smseidel 				return sal_True;
715*e2530cf9Smseidel 		return sal_False;
716*e2530cf9Smseidel 	}
717*e2530cf9Smseidel 
718*e2530cf9Smseidel 	//--------------------------------------------------------------------
getSupportedServiceNames()719*e2530cf9Smseidel 	Sequence< ::rtl::OUString > SAL_CALL EnumerableMap::getSupportedServiceNames(  ) throw (RuntimeException)
720*e2530cf9Smseidel 	{
721*e2530cf9Smseidel 		return getSupportedServiceNames_static();
722*e2530cf9Smseidel 	}
723*e2530cf9Smseidel 
724*e2530cf9Smseidel 	//--------------------------------------------------------------------
getImplementationName_static()725*e2530cf9Smseidel 	::rtl::OUString SAL_CALL EnumerableMap::getImplementationName_static(  )
726*e2530cf9Smseidel 	{
727*e2530cf9Smseidel 		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.comphelper.EnumerableMap" ) );
728*e2530cf9Smseidel 	}
729*e2530cf9Smseidel 
730*e2530cf9Smseidel 	//--------------------------------------------------------------------
getSupportedServiceNames_static()731*e2530cf9Smseidel 	Sequence< ::rtl::OUString > SAL_CALL EnumerableMap::getSupportedServiceNames_static(  )
732*e2530cf9Smseidel 	{
733*e2530cf9Smseidel 		Sequence< ::rtl::OUString > aServiceNames(1);
734*e2530cf9Smseidel 		aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.container.EnumerableMap" ) );
735*e2530cf9Smseidel 		return aServiceNames;
736*e2530cf9Smseidel 	}
737*e2530cf9Smseidel 
738*e2530cf9Smseidel 	//--------------------------------------------------------------------
Create(const Reference<XComponentContext> & _context)739*e2530cf9Smseidel 	Reference< XInterface > SAL_CALL EnumerableMap::Create( const Reference< XComponentContext >& _context )
740*e2530cf9Smseidel 	{
741*e2530cf9Smseidel 		return *new EnumerableMap( ComponentContext( _context ) );
742*e2530cf9Smseidel 	}
743cdf0e10cSrcweir 
744cdf0e10cSrcweir 	//====================================================================
745cdf0e10cSrcweir 	//= MapEnumerator
746cdf0e10cSrcweir 	//====================================================================
747*e2530cf9Smseidel 	//--------------------------------------------------------------------
hasMoreElements()748*e2530cf9Smseidel 	::sal_Bool MapEnumerator::hasMoreElements()
749*e2530cf9Smseidel 	{
750*e2530cf9Smseidel 		if ( m_disposed )
751*e2530cf9Smseidel 			throw DisposedException( ::rtl::OUString(), m_rParent );
752*e2530cf9Smseidel 		return m_mapPos != m_rMapData.m_pValues->end();
753*e2530cf9Smseidel 	}
754*e2530cf9Smseidel 
755*e2530cf9Smseidel 	//--------------------------------------------------------------------
nextElement()756*e2530cf9Smseidel 	Any MapEnumerator::nextElement()
757*e2530cf9Smseidel 	{
758*e2530cf9Smseidel 		if ( m_disposed )
759*e2530cf9Smseidel 			throw DisposedException( ::rtl::OUString(), m_rParent );
760*e2530cf9Smseidel 		if ( m_mapPos == m_rMapData.m_pValues->end() )
761*e2530cf9Smseidel 			throw NoSuchElementException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No more elements." ) ), m_rParent );
762*e2530cf9Smseidel 
763*e2530cf9Smseidel 		Any aNextElement;
764*e2530cf9Smseidel 		switch ( m_eType )
765*e2530cf9Smseidel 		{
766*e2530cf9Smseidel 		case eKeys:		aNextElement = m_mapPos->first; break;
767*e2530cf9Smseidel 		case eValues:	aNextElement = m_mapPos->second; break;
768*e2530cf9Smseidel 		case eBoth:		aNextElement <<= Pair< Any, Any >( m_mapPos->first, m_mapPos->second ); break;
769*e2530cf9Smseidel 		}
770*e2530cf9Smseidel 		++m_mapPos;
771*e2530cf9Smseidel 		return aNextElement;
772*e2530cf9Smseidel 	}
773*e2530cf9Smseidel 
774*e2530cf9Smseidel 	//--------------------------------------------------------------------
mapModified()775*e2530cf9Smseidel 	void MapEnumerator::mapModified()
776*e2530cf9Smseidel 	{
777*e2530cf9Smseidel 		m_disposed = true;
778*e2530cf9Smseidel 	}
779cdf0e10cSrcweir 
780cdf0e10cSrcweir 	//====================================================================
781cdf0e10cSrcweir 	//= MapEnumeration - implementation
782cdf0e10cSrcweir 	//====================================================================
783*e2530cf9Smseidel 	//--------------------------------------------------------------------
hasMoreElements()784*e2530cf9Smseidel 	::sal_Bool SAL_CALL MapEnumeration::hasMoreElements(  ) throw (RuntimeException)
785*e2530cf9Smseidel 	{
786*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
787*e2530cf9Smseidel 		return m_aEnumerator.hasMoreElements();
788*e2530cf9Smseidel 	}
789*e2530cf9Smseidel 
790*e2530cf9Smseidel 	//--------------------------------------------------------------------
nextElement()791*e2530cf9Smseidel 	Any SAL_CALL MapEnumeration::nextElement(  ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
792*e2530cf9Smseidel 	{
793*e2530cf9Smseidel 		ComponentMethodGuard aGuard( *this );
794*e2530cf9Smseidel 		return m_aEnumerator.nextElement();
795*e2530cf9Smseidel 	}
796cdf0e10cSrcweir 
797cdf0e10cSrcweir //........................................................................
798*e2530cf9Smseidel }	// namespace comphelper
799cdf0e10cSrcweir //........................................................................
800cdf0e10cSrcweir 
createRegistryInfo_Map()801cdf0e10cSrcweir void createRegistryInfo_Map()
802cdf0e10cSrcweir {
803*e2530cf9Smseidel 	::comphelper::module::OAutoRegistration< ::comphelper::EnumerableMap > aAutoRegistration;
804cdf0e10cSrcweir }
805