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