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