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